$include_dir="/home/hyper-archives/boost/include"; include("$include_dir/msg-header.inc") ?>
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