Boost logo

Proto :

Subject: Re: [proto] : Proto transform with state
From: Thomas Heller (thom.heller_at_[hidden])
Date: 2010-11-18 06:57:06


Thomas Heller <thom.heller_at_...> writes:

>
> Eric Niebler <eric_at_...> writes:
<snip>
> >
> > Notice that the Renumber algorithm needs to be invoked twice with the
> > same arguments. In this case, we can avoid the runtime overhead of the
> > second invocation by just using the type information, but that's not
> > always going to be the case. There doesn't seem to be a way around it,
> > either.
> >
> > I think Proto transforms need a "let" statement for storing intermediate
> > results. Maybe something like this:
> >
> > struct RenumberFun
> > : proto::fold<
> > _
> > , make_pair(fusion::vector0<>(), proto::_state)
> > , let<
> > _a( Renumber(_, second(proto::_state))> )
> > , make_pair(
> > push_back(
> > first(proto::_state)
> > , first(_a)
> > )
> > , type_of<second(_a) >
> > )
> > >
> > >
> > {};
> >
> > I haven't a clue how this would be implemented.
> >
> > It's fun to think about this stuff, but I wish it actually payed the bills.
>
> Ok ... I implemented let!
>
> Here goes the renumbering example:
> http://codepad.org/K0TZamPb
>
> The change is in line 296 rendering RenumberFun to:
> struct RenumberFun
> : proto::fold<
> _
> , make_pair(fusion::vector<>(), proto::_state)
> , let<
> _a(Renumber(_, second(proto::_state)))
> , make_pair(
> push_back(
> first(proto::_state)
> , first(_a)
> )
> , type_of<second(_a) >
> )
> >
> >
> {};
>
> The implementation of let actually was quite easy ... here is how it works:
>
> let<Locals, Transform> is a transform taking definitions of local variables
and
> the transform these locals will get applied to.
> A local definition is in the form of: LocalName(LocalTransform)
> If the specified transform has LocalName embedded, it will get replaced by
> LocalTransform.
> I also implemented the definition of more than one local ... this is done by
> reusing proto::and_:
>
> let<proto::and_<LocalName0(LocalTransform0), ... LocalNameN(LocalTransformN)>,
> Transform>
> The replacement is done from the end to the beginning, making it possible to
> refer in a LocalTransformN to a LocalNameN-1, this gets replaced
automatically!
>
> Hope that helps!
>
> Thomas
>
>

Ok, the implementation in the previous post had some bugs.
Here is a updated one: http://codepad.org/ljjBYqHr

With the relevant example, showing of reuse of locals:

struct RenumberFun
  : proto::fold<
        _
      , make_pair(fusion::vector<>(), proto::_state)
      , let<
            proto::and_<
                _a(second(proto::_state))
              , _b(Renumber(_, _a))
>
          , make_pair(
                push_back(
                    first(proto::_state)
                  , first(_b)
                )
              , type_of<second(_b) >
            )
>
>
{};


Proto list run by eric at boostpro.com