|
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
mpl::second<mpl::_2>.
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:
http://www.boost.org/doc/libs/1_49_0/libs/multi_index/doc/tutorial/techniques.html#mpl_synthesis
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
mind...
Thanks & kind regards,
Peter
//-------------------------------------------------
#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
{
ATTR_1,
ATTR_2,
ATTR_3
};
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<
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 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,
bmi::ordered_unique<
bmi::member<
Attribute<boost::mpl::second<boost::mpl::_2> >,
AttrTraits<boost::mpl::second<boost::mpl::_2>::value>::type,
&Attribute<boost::mpl::second<boost::mpl::_2> >::value
// Attribute<boost::mpl::int_<0> >,
// int,
// &Attribute<boost::mpl::int_<0> >::value
>
>
>,
mpl::push_back<
mpl::_1,
bmi::ordered_non_unique<
bmi::member<
Attribute<boost::mpl::second<boost::mpl::_2> >,
AttrTraits<boost::mpl::second<boost::mpl::_2>::value>::type,
&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<
boost::mpl::int_<ATTR_1>,
boost::mpl::int_<ATTR_2>,
boost::mpl::int_<ATTR_3>
> 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 hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net