On Thu, Mar 15, 2012 at 3:29 AM, Peter Nyssen <peter@dynsws.com> 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