Boost logo

Boost :

Subject: [boost] changes to Proto since review (was: request permission to merge Proto to release)
From: Eric Niebler (eric_at_[hidden])
Date: 2008-09-14 14:37:30


Manuel Jung wrote:
> Eric Niebler wrote:
>> Manuel Jung wrote:
>>> Could you give a pointer or a list, what changed in the trunk?
>>
>> Lots changes in trunk all the time. What are you referring to? The
>> recent problems with Boost.Test? Changes to Proto? Something else?
>
> Oh, I mean the changes to Proto since the review.

A lot has changed. First the simple things:

* Proto lives at boost/proto/, not boost/xpressive/proto
* boost/proto/proto.hpp now includes all of proto with the
    exception of the typeof registrations. That includes the
    contexts, the transforms and the debugging utilities. If
    you just want the core of proto without the other stuff,
    there is boost/proto/core.hpp
* s/posit/unary_plus/
* s/arg/child, s/arg_c/child_c/, s/_argN/_childN
* s/bind/lazy/
* s/_visitor/_data/
* The proto::transform namespace is no more.
* There is a new _default transform, that is analogous to the
   default_context.

Some bigger changes:

The protocol for defining a primitive transform has changed. Previously,
primitive transforms were just ternary function objects like this:

struct MyTransform : proto::callable
{
    template<class Sig>
    struct result;

    template<class This, class Expr, class State, class Data>
    struct result<This(Expr, State, Data)>
    {
      typedef ... type;
    };

    template<class Expr, class State, class Data>
    typename result<void(Expr, State, Data)>::type
    operator()(Expr const &expr, State const &state, Data &data) const
    {
      return ...;
    }
};

You would now write this as:

struct MyTransform : proto::transform<MyTransform>
{
    template<class Expr, class State, class Data>
    struct impl : proto::transform_impl<Expr, State, Data>
    {
      typedef ... result_type;

      result_type operator()(
        typename impl::expr_param expr
      , typename impl::state_param state
      , typename impl::data_param data
      ) const
      {
        return ...;
      }
    };
};

With proto v4, the Expr, State, and Data parameters may be reference
types. With v3 they could not.

Along with the change to the transform protocol comes the ability to
leave off the state and data parameters when invoking a transform. With
v3, you had to pass dummy state and data parameters, even if your
transform didn't need them.

In a related change, when using result_of to calculate the return type
of a transform, you need to think about the constness and lvalue-ness of
the arguments you pass. So instead of:

    result_of<MyTransform(E, S, V)>::type

you might have to say

    result_of<MyTransform(E const &, S const &, V &)>::type

Finally, the behavior of result_of::child_c (formerly known as
result_of::arg_c) has changed. It is now sensitive to const and reference.

Old
------------------------------------------
1) result_of::arg_c<Expr, N>::type
2) result_of::arg_c<Expr, N>::reference
3) result_of::arg_c<Expr, N>::const_reference

New
------------------------------------------
1) result_of::child_c<Expr, N>::type
2) result_of::child_c<Expr &, N>::type
3) result_of::child_c<Expr const &, N>::type

These are some internal changes that probably should affect anybody:

* ref_ is no more. Children are held by plain reference, not
    by reference wrapper.
* s/args0/term, s/argsN/listN/

That's it, I think. The result is a *much* more expressive, powerful and
optimal system of transforms.

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

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