Eric Niebler | 8 Apr 02:40

Proto v4

No library ever made it through a review unscathed and proto is no 
exception. There's a new version of proto in branches/proto/v4, and 
Spirit-2 will need some changes to work with it. This is the version 
that will be merged into trunk, eventually.

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.

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.

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
Boost Consulting
www.boost-consulting.com

-------------------------------------------------------------------------
This SF.net email is sponsored by the 2008 JavaOne(SM) Conference 
Register now and save $200. Hurry, offer ends at 11:59 p.m., 
Monday, April 7! Use priority code J8TLD2. 
http://ad.doubleclick.net/clk;198757673;13503038;p?http://java.sun.com/javaone

Gmane