Boost logo

Boost Users :

Subject: Re: [Boost-users] Collecting boost multi-index meta data
From: joaquin_at_[hidden]
Date: 2011-03-24 07:13:40


Gokulakannan Somasundaram escribió:
> Hi Joaquín ,
> I am extremely sorry, i missed your mail. First of all thanks
> a lot for replying.

No problem. Please don't top-post:
http://www.boost.org/community/policy.html#quoting

> I have fixed the issue for now. But i am actually explaining the issue
> i had. Please take a shot at it.
> Say i have an object and i have created multi index on some
> members of the object. Now since,
> this is being used in a multi-threaded code, i will acquire a mutex on
> the whole multi-index, only if i have
> updated those attributes involved in the multi-index build. Else i
> won't take the mutex.
> Now my problem is, i have multi-indexed many such classes.
> what is the best way to check whether
> the updated attribute is part of multi-index. Currently we have
> written a python code which scans the C++
> files and creates a list of attribute numbers ( each member attribute
> has a number associated with it ).
> Whenever there is an update, we check against the list produced by the
> python code in C++.
> My question was if there is a way to do this within C++ itself.

If we had the following metafunction to check whether a particular
key extractor is used with a multi_index_container or not:

   template<typename KeyExtractor,typename MultiIndexContainer>
   struct is_key_extractor_of{};

then it is easy to know at compile time if a particular member of a class is
referenced by a member<...> key extractor (composite keys are harder and
left as an exercise to the reader):

   struct A
   {
     int a,b,c,d,e,f;
   };

   typedef multi_index_container<
     int,
     indexed_by<
       ordered_unique<member<A,int,&A::a> >,
       sequenced<>,
>
> multi_t;

   BOOST_MPL_ASSERT ((is_key_extractor_of<member<A,int,&A::a>,multi_t>));
   BOOST_MPL_ASSERT_NOT((is_key_extractor_of<member<A,int,&A::e>,multi_t>));

Full code provided in the attachment. Does this help to implement your
scenario?

Joaquín M López Muñoz
Telefónica, Investigación y Desarrollo

Este mensaje se dirige exclusivamente a su destinatario. Puede consultar nuestra política de envío y recepción de correo electrónico en el enlace situado más abajo.
This message is intended exclusively for its addressee. We only send and receive email on the basis of the terms set out at.
http://www.tid.es/ES/PAGINAS/disclaimer.aspx


#include <boost/mpl/contains.hpp>
#include <boost/mpl/transform.hpp>
#include <boost/multi_index/ordered_index_fwd.hpp>
#include <boost/multi_index/hashed_index_fwd.hpp>

struct no_key_extractor{};

template<typename IndexSpecifier,typename Index>
struct key_extractor
{
  typedef no_key_extractor type;
};

template<
  typename Arg1,typename Arg2,typename Arg3,
  typename Index>
struct key_extractor<
  boost::multi_index::ordered_unique<Arg1,Arg2,Arg3>,Index>
{
  typedef typename Index::key_from_value type;
};

template<
  typename Arg1,typename Arg2,typename Arg3,
  typename Index>
struct key_extractor<
  boost::multi_index::ordered_non_unique<Arg1,Arg2,Arg3>,Index>
{
  typedef typename Index::key_from_value type;
};

template<
  typename Arg1,typename Arg2,typename Arg3,typename Arg4,
  typename Index>
struct key_extractor<
  boost::multi_index::hashed_unique<Arg1,Arg2,Arg3,Arg4>,Index>
{
  typedef typename Index::key_from_value type;
};

template<
  typename Arg1,typename Arg2,typename Arg3,typename Arg4,
  typename Index>
struct key_extractor<
  boost::multi_index::hashed_non_unique<Arg1,Arg2,Arg3,Arg4>,Index>
{
  typedef typename Index::key_from_value type;
};

template<typename MultiIndexContainer>
struct key_extractor_list:
  boost::mpl::transform<
    typename MultiIndexContainer::index_specifier_type_list,
    typename MultiIndexContainer::index_type_list,
    key_extractor<boost::mpl::_,boost::mpl::_>
>
{};

template<typename KeyExtractor,typename MultiIndexContainer>
struct is_key_extractor_of:
  boost::mpl::contains<
    typename key_extractor_list<MultiIndexContainer>::type,
    KeyExtractor
>
{};

/* testing */

#include <boost/multi_index_container.hpp>
#include <boost/multi_index/hashed_index.hpp>
#include <boost/multi_index/ordered_index.hpp>
#include <boost/multi_index/random_access_index.hpp>
#include <boost/multi_index/sequenced_index.hpp>
#include <boost/multi_index/member.hpp>
#include <boost/mpl/assert.hpp>

using namespace boost::multi_index;

struct A
{
  int a,b,c,d,e,f;
};

typedef multi_index_container<
  int,
  indexed_by<
    ordered_unique<member<A,int,&A::a> >,
    ordered_non_unique<member<A,int,&A::b> >,
    hashed_unique<member<A,int,&A::c> >,
    hashed_non_unique<member<A,int,&A::d> >,
    sequenced<>,
    random_access<>
>
> multi_t;

BOOST_MPL_ASSERT ((is_key_extractor_of<member<A,int,&A::a>,multi_t>));
BOOST_MPL_ASSERT ((is_key_extractor_of<member<A,int,&A::b>,multi_t>));
BOOST_MPL_ASSERT ((is_key_extractor_of<member<A,int,&A::c>,multi_t>));
BOOST_MPL_ASSERT ((is_key_extractor_of<member<A,int,&A::d>,multi_t>));
BOOST_MPL_ASSERT_NOT((is_key_extractor_of<member<A,int,&A::e>,multi_t>));
BOOST_MPL_ASSERT_NOT((is_key_extractor_of<member<A,int,&A::f>,multi_t>));

int main(){}


Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net