Boost logo

Boost Users :

Subject: [Boost-users] [MPL] Generating multi-index container indices based on MPL tag dispatching
From: Peter Nyssen (peter_at_[hidden])
Date: 2012-03-15 06:29:23

Hi all,

this is a follow-up of my question of yesterday (Fold a vector of pairs).
The example here is a lot more elaborate and more like the final code
I'd like to achieve.
I still get errors when compiling the code below related the use of

I'm trying to generate a multi-index container type that will store
objects generated using inherit_linearly.
The objects contain a number of attributes (all int in this example)
based on a typelist of attribute tags.
I want to generate this container by providing the object type and a
index_list as shown here:

I'm trying to compose the index_list using some kind of MPL tag dispatch
based on the unique & non_unique tags to generate unique & non_unique
ordered indices for the container.
It's clear to me that the errors have to do with the MPL placeholder
expressions used in the 3 types passed to the multi_index::member
template class. This is confirmed because if I replace these 3 template
parameters by the ones which are comment out just below the program
compiles fine.

 From my previous question I get that the placeholder expressions need
to be evaluated lazily (so no ::type or ::value - obviously the code
below is thus incorrect).
I've been reading section 3.3 of the MPL book on 'Handling Placeholders'
a couple of times and from this it seems I need 3 metafunctions that
call apply<> on the passed placeholder expressions and which would
return each of the types to be passed to multi_index::member<>?

I've been trying different approaches but none have been successful...
I'm still not grasping how to handle these placeholder expressions...

I hope the great minds on this list can bring some light in my clouded

Thanks & kind regards,


#include <boost/mpl/at.hpp>
#include <boost/mpl/if.hpp>
#include <boost/mpl/inherit.hpp>
#include <boost/mpl/inherit_linearly.hpp>
#include <boost/mpl/int.hpp>
#include <boost/mpl/fold.hpp>
#include <boost/mpl/pair.hpp>
#include <boost/mpl/push_back.hpp>
#include <boost/mpl/vector.hpp>

#include <boost/multi_index_container.hpp>
#include <boost/multi_index/indexed_by.hpp>
#include <boost/multi_index/member.hpp>
#include <boost/multi_index/ordered_index.hpp>

namespace mpl = boost::mpl;
namespace bmi = boost::multi_index;

enum attributeTags

template <int attrId>
struct AttrTraits
     typedef int type;

template <typename AttrT>
struct Attribute
     typedef AttrTraits<AttrT::value> ATraits;

     typename ATraits::type value;

template <typename AttrList>
struct Object : public boost::mpl::inherit_linearly<
                             Attribute<boost::mpl::_2> >
>::type {};

struct unique {};
struct non_unique {};

template <typename T>
struct is_unique : boost::false_type {};

template <>
struct is_unique<unique> : boost::true_type {};

template<typename ObjectT, typename IndicesMap>
struct ObjectContainer
     typedef typename mpl::fold<
             is_unique<mpl::first<mpl::_2> >,
                         Attribute<boost::mpl::second<boost::mpl::_2> >,
&Attribute<boost::mpl::second<boost::mpl::_2> >::value
// Attribute<boost::mpl::int_<0> >,
// int,
// &Attribute<boost::mpl::int_<0> >::value
                         Attribute<boost::mpl::second<boost::mpl::_2> >,
&Attribute<boost::mpl::second<boost::mpl::_2> >::value
// Attribute<boost::mpl::int_<1> >,
// int,
// &Attribute<boost::mpl::int_<1> >::value
>::type IndexList;

     typedef boost::multi_index_container<ObjectT, IndexList> Container_t;

     Container_t Container;

int main()
     typedef boost::mpl::vector<
> AttributeList_1;

     typedef Object<AttributeList_1> Object_1;

     typedef mpl::vector<
         mpl::pair<unique, mpl::int_<ATTR_1> >,
         mpl::pair<non_unique, mpl::int_<ATTR_2> >
> Object_1_Indicex;

     ObjectContainer<Object_1, Object_1_Indicex> Object1Container;

     return 0;


Boost-users list run by williamkempf at, kalb at, bjorn.karlsson at, gregod at, wekempf at