Boost logo

Boost Users :

Subject: Re: [Boost-users] [Proto] Building a mpl::vector from an expression
From: Eric Niebler (eric_at_[hidden])
Date: 2009-08-19 11:51:26


christophe henry wrote:
> "Eric Niebler" schrieb im Newsbeitrag
>> Steven Watanabe wrote:
>>> christophe henry wrote:
>>>> I am trying to build a mpl::vector from an expression like
>>>>
>>>> (string(),ClassA(),ClassB())
>>>>
>>>> To get a mpl::vector
>>>>
>>>>
>>>> Is there a way to do this or I should give up the idea?
>>>
>>> Does fold_tree help?
>>
>> It does.
>
> *snip*
>
> Ah It see. Thanks a lot, I think I got the idea.
> I just have a concern with:
>
> template<class T> struct is_my : mpl::false_ {};
> template<> struct is_my<std::string> : mpl::true_ {};
> template<> struct is_my<ClassA> : mpl::true_ {};
> template<> struct is_my<ClassB> : mpl::true_ {};
>
> As it forces extra declarations which not everybody is willing to make.
> But based on the same fold idea I can allow something like:
> attributes_ << int() << std::map<int,int>() << bool()
>
> Where attributes_ is made a proto terminal<my_tag> with proto::extends

Sure, that's a reasonable approach.

> and the following grammar (which I shamelessly stole from the doc):
>
> struct BuildAttributes
> : proto::or_<
> // Don't add the flag terminal to the list
> proto::when<
> proto::terminal< my_tag >
> , proto::_state
> >
> // Put all other terminals at the head of the
> // list that we're building in the "state" parameter
> , proto::when<
> proto::terminal<proto::_>
> , fusion::cons<proto::_value, proto::_state>(proto::_value, proto::_state)
> >
> // For left-shift operations, first fold the right
> // child to a list using the current state. Use
> // the result as the state parameter when folding
> // the left child to a list.
> , proto::when<
> proto::shift_left<BuildAttributes, BuildAttributes>
> , proto::fold<
> proto::_
> , fusion::nil()
> , BuildAttributes>()
> >
> >
> {};
>
> I then just have to invert the order again as it gets reversed (ok a few
> seconds more to compile...):
>
> boost::mpl::copy<typename
> boost::result_of<BuildAttributes(Attr)>::type,boost::mpl::front_inserter<boost::mpl::vector<>
> > >::type
>
> Correct?

You could use reverse_fold instead of reversing the whole list after the
transform. Or you could use reverse_fold_tree to get the vector and then
pop the attribute_ off the front. That's probably fastest and simplest.

-- 
Eric Niebler
BoostPro Computing
http://www.boostpro.com

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