Boost logo

Boost Users :

Subject: Re: [Boost-users] [MPL] Generating multi-index container indices based on MPL tag dispatching
From: Jeffrey Lee Hellrung, Jr. (jeffrey.hellrung_at_[hidden])
Date: 2012-03-15 13:28:27


On Thu, Mar 15, 2012 at 3:29 AM, Peter Nyssen <peter_at_[hidden]> wrote:

> 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>.
>
[...]

(My response is independent of your provided context.)

>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'm not sure what you mean here.

> 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
>
>
> //-------------------------------------------------
>
> [...snip includes...]

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

Okay, AttrTraits is not a proper MPL-compatible member function, as it
operates on non-type template parameters. This has problems below...

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

I don't know where the "&"s came from (email problems at some point), but
the ::value and ::type are, as you've observed, triggering immediate
evaluation, and you want lazy evaluation. But like I mentioned above,
Boost.MPL can only handle metafunctions which take type template
parameters, so your use of AttrTraits is DOA. I suggest either redefine
AttrTraits to take a Boost.MPL integral constant or define a wrapper that
has the same effect.

> // 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,
>

Ditto.

> &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;
> };
>
>
>
[...snip main...]

See if the above suggestion gets you anywhere.

- Jeff



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