Boost logo

Boost :

From: Aleksey Gurtovoy (agurtovoy_at_[hidden])
Date: 2003-11-13 03:37:40


Matthias Schabel wrote:
> I've been trying to teach myself some MPL, but have found the
> documentation pretty difficult to follow in places - I think a bunch
> of practical examples, preferably with STL analogies, would be
> tremendously helpful, especially for those of us who've spent our
> entire lives trapped in the imperative programming ghetto and think
> LISP is a funny way of pronouncing 's'...

May be you can suggest some topics for such examples?

> A couple of particular
> questions :
>
> How does one implement append? That is, given
>
> typedef mpl::list<t1,t2,t3> l1;
> typedef mpl::list<t4,t5> l2;
>
> typedef append<l1,l2> --> mpl::list<t1,t2,t3,t4,t5>
>
> I've tried things like
>
> typedef typename mpl::iter_fold<S2,S1,push_back<_1,deref<_2> > >::type
> a;
>
> (and various permutations), but can't get it to work and suspect that
> I'm missing something fundamental. Any suggestions?

Besides using too-low level algorithm for the task, your code is fine -
well, algorithmically, that is. It doesn't compile because you cannot
'push_back' into 'list' - given the internal 'list' structure, inserting
at the end is O(n) operation, and therefore it's not given a notational
shortcut.

If you re-write things as

    typedef list<bool,char,int> l1;
    typedef list<long,float> l2;
    typedef iter_fold_backward<l1,l2,push_front<_1,deref<_2> > >::type l;

everything will work as expected, although of course the recommended
solution would be the one posted by Daniel Wallin.

>
> The more complex problem which I'm trying to resolve is to accomplish
> something like this :
>
> template<class T1,class T2>
> struct pair_type
> {
> typedef T1 type1;
> typedef T2 type2;
> };
>
> template<class T>
> struct get_type1
> {
> typedef typename T::type1 type;
> };
>
> template<class T>
> struct get_type1
> {
> typedef typename T::type2 type;
> };
>
> template<class T1,class T2>
> struct equality_op
> {
> typedef typename mpl::equal<get_type1<T1>,get_type1<T2> >::type type;
> };
>
> template<class T1,class T2>
> struct combine_op
> {
> BOOST_STATIC_ASSERT((boost::is_same<get_type1<T1>::
> type,get_type1<T2>::type>::value == true));
>
> typedef typename
> pair_type<get_type1<T1>::type,pair_type<get_type2<T1>::
> type,get_type2<T2>::type> > type;
> };
>
> template<class S1>
> struct collapse
> {
> typedef typename collapsed_type<S1>::type type;
> };
>
> what I would like is for collapsed_type<S1> to return a sequence
> composed of all the unique types in S1, with uniqueness defined by
> equality_op, concatenated, with combine_op applied to all duplicate
> types. For example
>
> typedef
> list<pair_type<T1,V1>,pair_type<T2,V2>,pair_type<T1,V3>,pair_type<T4,V2>
> > S1;
>
> collapse<S1> --> list<combine_op<pair_type<T1,V1>,pair_type<T1,V3>
> >::type, pair_type<T2,V2>,pair_type<T4,V2> >
>

I think 'set' would make implementing something like this much easier
(and efficient), but unfortunately we don't have a complete
implementation of that one yet. Meanwhile (and in any case), I would
say the fist step to approach your problem would be formulating the
algorithm in general terms, e.g. [STL] pseudocode. Translating it later
to MPL should be trivial, and if not, you'll definitely get more help
here once the first step is done.

HTH,
Aleksey


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk