Boost logo

Boost Users :

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


Thanks a lot jeff!
It did put me on the right track...
This is the compilable version.

Thanks & kind regards,
Peter

//-------------------------------------------------------------

#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;

struct ATTR_1 {};
struct ATTR_2 {};
struct ATTR_3 {};

template <typename attrT>
struct AttrTraits
{
     typedef int type;
};

template <typename AttrT>
struct Attribute
{
     typedef AttrTraits<AttrT> ATraits;

     typename ATraits::type value;
};

template <typename AttrList>
struct Object : public boost::mpl::inherit_linearly<
         AttrList,
         boost::mpl::inherit<boost::mpl::_1,
                             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 AttrT>
struct GetUnique
{
     typedef bmi::ordered_unique<
             bmi::tag<AttrT>,
             bmi::member<
                 Attribute<AttrT>,
                 typename AttrTraits<AttrT>::type,
&Attribute<AttrT>::value
>
> type;
};

template <typename AttrT>
struct GetNonUnique
{
     typedef bmi::ordered_non_unique<
             bmi::tag<AttrT>,
             bmi::member<
                 Attribute<AttrT>,
                 typename AttrTraits<AttrT>::type,
&Attribute<AttrT>::value
>
> type;
};

template<typename ObjectT, typename IndicesMap>
struct ObjectContainer
{
     typedef typename mpl::fold<
         IndicesMap,
         mpl::vector<>,
         mpl::if_<
             is_unique<mpl::first<mpl::_2> >,
             mpl::push_back<
                 mpl::_1,
                 GetUnique<mpl::second<mpl::_2> >
>,
             mpl::push_back<
                 mpl::_1,
                 GetNonUnique<mpl::second<mpl::_2> >
>
>
>::type IndexList;

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

     Container_t Container;
};

int main()
{
     typedef boost::mpl::vector<
         ATTR_1,
         ATTR_2,
         ATTR_3
> AttributeList_1;

     typedef Object<AttributeList_1> Object_1;

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

     ObjectContainer<Object_1, Object_1_Indices> Object1Container;

     Object_1 obj1;
     Object1Container.Container.get<ATTR_1>().insert(obj1);

     return 0;
}

//-------------------------------------------------------------


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