Boost logo

Boost-Commit :

From: eric_at_[hidden]
Date: 2008-04-06 02:19:47


Author: eric_niebler
Date: 2008-04-06 02:19:35 EDT (Sun, 06 Apr 2008)
New Revision: 44068
URL: http://svn.boost.org/trac/boost/changeset/44068

Log:
initial proto v4, the post-review version
Added:
   branches/proto/v4/boost/proto/
   branches/proto/v4/boost/proto/args.hpp (contents, props changed)
   branches/proto/v4/boost/proto/context/
   branches/proto/v4/boost/proto/context.hpp (contents, props changed)
   branches/proto/v4/boost/proto/context/callable.hpp (contents, props changed)
   branches/proto/v4/boost/proto/context/default.hpp (contents, props changed)
   branches/proto/v4/boost/proto/context/null.hpp (contents, props changed)
   branches/proto/v4/boost/proto/core.hpp (contents, props changed)
   branches/proto/v4/boost/proto/debug.hpp (contents, props changed)
   branches/proto/v4/boost/proto/deep_copy.hpp (contents, props changed)
   branches/proto/v4/boost/proto/detail/
   branches/proto/v4/boost/proto/detail/as_lvalue.hpp (contents, props changed)
   branches/proto/v4/boost/proto/detail/decltype.hpp (contents, props changed)
   branches/proto/v4/boost/proto/detail/dont_care.hpp (contents, props changed)
   branches/proto/v4/boost/proto/detail/funop.hpp (contents, props changed)
   branches/proto/v4/boost/proto/detail/ignore_unused.hpp (contents, props changed)
   branches/proto/v4/boost/proto/detail/pop_front.hpp (contents, props changed)
   branches/proto/v4/boost/proto/detail/prefix.hpp (contents, props changed)
   branches/proto/v4/boost/proto/detail/reverse.hpp (contents, props changed)
   branches/proto/v4/boost/proto/detail/suffix.hpp (contents, props changed)
   branches/proto/v4/boost/proto/domain.hpp (contents, props changed)
   branches/proto/v4/boost/proto/eval.hpp (contents, props changed)
   branches/proto/v4/boost/proto/expr.hpp (contents, props changed)
   branches/proto/v4/boost/proto/extends.hpp (contents, props changed)
   branches/proto/v4/boost/proto/fusion.hpp (contents, props changed)
   branches/proto/v4/boost/proto/generate.hpp (contents, props changed)
   branches/proto/v4/boost/proto/literal.hpp (contents, props changed)
   branches/proto/v4/boost/proto/make_expr.hpp (contents, props changed)
   branches/proto/v4/boost/proto/matches.hpp (contents, props changed)
   branches/proto/v4/boost/proto/operators.hpp (contents, props changed)
   branches/proto/v4/boost/proto/proto.hpp (contents, props changed)
   branches/proto/v4/boost/proto/proto_fwd.hpp (contents, props changed)
   branches/proto/v4/boost/proto/proto_typeof.hpp (contents, props changed)
   branches/proto/v4/boost/proto/ref.hpp (contents, props changed)
   branches/proto/v4/boost/proto/tags.hpp (contents, props changed)
   branches/proto/v4/boost/proto/traits.hpp (contents, props changed)
   branches/proto/v4/boost/proto/transform/
   branches/proto/v4/boost/proto/transform.hpp (contents, props changed)
   branches/proto/v4/boost/proto/transform/arg.hpp (contents, props changed)
   branches/proto/v4/boost/proto/transform/call.hpp (contents, props changed)
   branches/proto/v4/boost/proto/transform/default.hpp (contents, props changed)
   branches/proto/v4/boost/proto/transform/fold.hpp (contents, props changed)
   branches/proto/v4/boost/proto/transform/fold_tree.hpp (contents, props changed)
   branches/proto/v4/boost/proto/transform/impl.hpp (contents, props changed)
   branches/proto/v4/boost/proto/transform/lazy.hpp (contents, props changed)
   branches/proto/v4/boost/proto/transform/make.hpp (contents, props changed)
   branches/proto/v4/boost/proto/transform/pass_through.hpp (contents, props changed)
   branches/proto/v4/boost/proto/transform/when.hpp (contents, props changed)
   branches/proto/v4/libs/proto/
   branches/proto/v4/libs/proto/doc/
   branches/proto/v4/libs/proto/doc/Jamfile.v2 (contents, props changed)
   branches/proto/v4/libs/proto/doc/acknowledgements.qbk (contents, props changed)
   branches/proto/v4/libs/proto/doc/calculator.qbk (contents, props changed)
   branches/proto/v4/libs/proto/doc/concepts/
   branches/proto/v4/libs/proto/doc/concepts/CallableTransform.xml (contents, props changed)
   branches/proto/v4/libs/proto/doc/concepts/PolymorphicFunctionObject.xml (contents, props changed)
   branches/proto/v4/libs/proto/doc/concepts/PrimitiveTransform.xml (contents, props changed)
   branches/proto/v4/libs/proto/doc/concepts/Transform.xml (contents, props changed)
   branches/proto/v4/libs/proto/doc/construction.qbk (contents, props changed)
   branches/proto/v4/libs/proto/doc/definitions.qbk (contents, props changed)
   branches/proto/v4/libs/proto/doc/evaluation.qbk (contents, props changed)
   branches/proto/v4/libs/proto/doc/examples.qbk (contents, props changed)
   branches/proto/v4/libs/proto/doc/extensibility.qbk (contents, props changed)
   branches/proto/v4/libs/proto/doc/grammars.qbk (contents, props changed)
   branches/proto/v4/libs/proto/doc/history.qbk (contents, props changed)
   branches/proto/v4/libs/proto/doc/implementation.qbk (contents, props changed)
   branches/proto/v4/libs/proto/doc/installation.qbk (contents, props changed)
   branches/proto/v4/libs/proto/doc/preface.qbk (contents, props changed)
   branches/proto/v4/libs/proto/doc/propdocs.sh (contents, props changed)
   branches/proto/v4/libs/proto/doc/proto.qbk (contents, props changed)
   branches/proto/v4/libs/proto/doc/proto.xml (contents, props changed)
   branches/proto/v4/libs/proto/doc/protodoc.xml (contents, props changed)
   branches/proto/v4/libs/proto/doc/quick_start.qbk (contents, props changed)
   branches/proto/v4/libs/proto/doc/rationale.qbk (contents, props changed)
   branches/proto/v4/libs/proto/doc/transforms.qbk (contents, props changed)
   branches/proto/v4/libs/proto/doc/wave.sh (contents, props changed)
   branches/proto/v4/libs/proto/example/
   branches/proto/v4/libs/proto/example/Jamfile.v2 (contents, props changed)
   branches/proto/v4/libs/proto/example/calc1.cpp (contents, props changed)
   branches/proto/v4/libs/proto/example/calc2.cpp (contents, props changed)
   branches/proto/v4/libs/proto/example/calc3.cpp (contents, props changed)
   branches/proto/v4/libs/proto/example/futures.cpp (contents, props changed)
   branches/proto/v4/libs/proto/example/hello.cpp (contents, props changed)
   branches/proto/v4/libs/proto/example/lambda.cpp (contents, props changed)
   branches/proto/v4/libs/proto/example/lazy_vector.cpp (contents, props changed)
   branches/proto/v4/libs/proto/example/map_assign.cpp (contents, props changed)
   branches/proto/v4/libs/proto/example/mixed.cpp (contents, props changed)
   branches/proto/v4/libs/proto/example/rgb.cpp (contents, props changed)
   branches/proto/v4/libs/proto/example/tarray.cpp (contents, props changed)
   branches/proto/v4/libs/proto/example/vec3.cpp (contents, props changed)
   branches/proto/v4/libs/proto/example/vector.cpp (contents, props changed)
   branches/proto/v4/libs/proto/test/
   branches/proto/v4/libs/proto/test/Jamfile.v2 (contents, props changed)
   branches/proto/v4/libs/proto/test/calculator.cpp (contents, props changed)
   branches/proto/v4/libs/proto/test/deep_copy.cpp (contents, props changed)
   branches/proto/v4/libs/proto/test/examples.cpp (contents, props changed)
   branches/proto/v4/libs/proto/test/lambda.cpp (contents, props changed)
   branches/proto/v4/libs/proto/test/make_expr.cpp (contents, props changed)
   branches/proto/v4/libs/proto/test/matches.cpp (contents, props changed)
   branches/proto/v4/libs/proto/test/proto_fusion.cpp (contents, props changed)
   branches/proto/v4/libs/proto/test/proto_fusion_s.cpp (contents, props changed)
   branches/proto/v4/libs/proto/test/toy_spirit.cpp (contents, props changed)
   branches/proto/v4/libs/proto/test/toy_spirit2.cpp (contents, props changed)
Removed:
   branches/proto/v4/boost/xpressive/proto/
   branches/proto/v4/libs/xpressive/proto/
Text files modified:
   branches/proto/v4/boost/xpressive/basic_regex.hpp | 18 +-
   branches/proto/v4/boost/xpressive/detail/core/access.hpp | 4
   branches/proto/v4/boost/xpressive/detail/core/matcher/action_matcher.hpp | 227 +++++++++++++------------
   branches/proto/v4/boost/xpressive/detail/core/matcher/end_matcher.hpp | 2
   branches/proto/v4/boost/xpressive/detail/core/matcher/predicate_matcher.hpp | 12
   branches/proto/v4/boost/xpressive/detail/detail_fwd.hpp | 10
   branches/proto/v4/boost/xpressive/detail/static/compile.hpp | 15 +
   branches/proto/v4/boost/xpressive/detail/static/grammar.hpp | 18 +-
   branches/proto/v4/boost/xpressive/detail/static/is_pure.hpp | 28 +-
   branches/proto/v4/boost/xpressive/detail/static/modifier.hpp | 6
   branches/proto/v4/boost/xpressive/detail/static/placeholders.hpp | 1
   branches/proto/v4/boost/xpressive/detail/static/static.hpp | 2
   branches/proto/v4/boost/xpressive/detail/static/transforms/as_action.hpp | 256 +++++++++++++---------------
   branches/proto/v4/boost/xpressive/detail/static/transforms/as_alternate.hpp | 94 ++++++----
   branches/proto/v4/boost/xpressive/detail/static/transforms/as_independent.hpp | 184 +++++++++++---------
   branches/proto/v4/boost/xpressive/detail/static/transforms/as_inverse.hpp | 2
   branches/proto/v4/boost/xpressive/detail/static/transforms/as_marker.hpp | 42 ++--
   branches/proto/v4/boost/xpressive/detail/static/transforms/as_matcher.hpp | 32 +-
   branches/proto/v4/boost/xpressive/detail/static/transforms/as_modifier.hpp | 56 ++++--
   branches/proto/v4/boost/xpressive/detail/static/transforms/as_quantifier.hpp | 349 ++++++++++++++++++++++-----------------
   branches/proto/v4/boost/xpressive/detail/static/transforms/as_sequence.hpp | 42 ++--
   branches/proto/v4/boost/xpressive/detail/static/transforms/as_set.hpp | 131 ++++++++------
   branches/proto/v4/boost/xpressive/detail/static/visitor.hpp | 1
   branches/proto/v4/boost/xpressive/detail/static/width_of.hpp | 112 ++++++++----
   branches/proto/v4/boost/xpressive/match_results.hpp | 10
   branches/proto/v4/boost/xpressive/regex_actions.hpp | 46 ++--
   branches/proto/v4/boost/xpressive/regex_algorithms.hpp | 4
   branches/proto/v4/boost/xpressive/regex_primitives.hpp | 73 ++++---
   branches/proto/v4/boost/xpressive/xpressive_fwd.hpp | 4
   branches/proto/v4/boost/xpressive/xpressive_typeof.hpp | 2
   branches/proto/v4/libs/xpressive/doc/acknowledgements.qbk | 6
   branches/proto/v4/libs/xpressive/doc/actions.qbk | 60 +++---
   branches/proto/v4/libs/xpressive/doc/dynamic_regexes.qbk | 2
   branches/proto/v4/libs/xpressive/doc/history.qbk | 2
   branches/proto/v4/libs/xpressive/doc/installation.qbk | 2
   branches/proto/v4/libs/xpressive/doc/introduction.qbk | 2
   branches/proto/v4/libs/xpressive/doc/matching.qbk | 8
   branches/proto/v4/libs/xpressive/doc/nyi.qbk | 2
   branches/proto/v4/libs/xpressive/doc/substitutions.qbk | 17 +
   branches/proto/v4/libs/xpressive/doc/symbols.qbk | 4
   40 files changed, 1024 insertions(+), 864 deletions(-)

Added: branches/proto/v4/boost/proto/args.hpp
==============================================================================
--- (empty file)
+++ branches/proto/v4/boost/proto/args.hpp 2008-04-06 02:19:35 EDT (Sun, 06 Apr 2008)
@@ -0,0 +1,143 @@
+#ifndef BOOST_PP_IS_ITERATING
+ ///////////////////////////////////////////////////////////////////////////////
+ /// \file args.hpp
+ /// Contains definition of args\<\> class template.
+ //
+ // Copyright 2008 Eric Niebler. Distributed under the Boost
+ // Software License, Version 1.0. (See accompanying file
+ // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+ #ifndef BOOST_PROTO_ARGS_HPP_EAN_04_01_2005
+ #define BOOST_PROTO_ARGS_HPP_EAN_04_01_2005
+
+ #include <boost/proto/detail/prefix.hpp>
+ #include <boost/config.hpp>
+ #include <boost/detail/workaround.hpp>
+ #include <boost/preprocessor/cat.hpp>
+ #include <boost/preprocessor/arithmetic/dec.hpp>
+ #include <boost/preprocessor/iteration/iterate.hpp>
+ #include <boost/preprocessor/repetition/enum_params.hpp>
+ #include <boost/preprocessor/repetition/repeat.hpp>
+ #include <boost/preprocessor/repetition/repeat_from_to.hpp>
+ #include <boost/mpl/void.hpp>
+ #include <boost/proto/proto_fwd.hpp>
+ #include <boost/proto/detail/suffix.hpp>
+
+ namespace boost { namespace proto
+ {
+ ////////////////////////////////////////////////////////////////////////////////////////////
+ BOOST_PROTO_BEGIN_ADL_NAMESPACE(argsns_)
+
+ #define BOOST_PROTO_DEFINE_CHILD_N(Z, N, DATA) \
+ typedef BOOST_PP_CAT(Arg, N) BOOST_PP_CAT(child, N); \
+ typedef expr_ref<BOOST_PP_CAT(Arg, N)> BOOST_PP_CAT(child_ref, N); \
+
+ #define BOOST_PROTO_DEFINE_VOID_N(z, n, data) \
+ typedef mpl::void_ BOOST_PP_CAT(child, n); \
+ typedef mpl::void_ BOOST_PP_CAT(child_ref, n); \
+ /**/
+
+ /// INTERNAL ONLY
+ template<typename Expr>
+ struct expr_ref
+ {
+ typedef typename Expr::proto_base_expr proto_base_expr;
+ typedef typename Expr::proto_derived_expr proto_derived_expr;
+ typedef typename Expr::proto_tag proto_tag;
+ typedef typename Expr::proto_args proto_args;
+ typedef typename Expr::proto_arity proto_arity;
+ typedef typename Expr::proto_domain proto_domain;
+ };
+
+ /// INTERNAL ONLY
+ template<typename Expr>
+ struct expr_ref<Expr &>
+ {
+ typedef typename Expr::proto_base_expr proto_base_expr;
+ typedef typename Expr::proto_derived_expr proto_derived_expr;
+ typedef typename Expr::proto_tag proto_tag;
+ typedef typename Expr::proto_args proto_args;
+ typedef typename Expr::proto_arity proto_arity;
+ typedef typename Expr::proto_domain proto_domain;
+ };
+
+ /// INTERNAL ONLY
+ template<typename T>
+ struct term_ref
+ {
+ typedef T type;
+ };
+
+ /// INTERNAL ONLY
+ template<typename T>
+ struct term_ref<T &>
+ {
+ typedef T type;
+ };
+
+ template<typename T>
+ struct term_ref<T const &>
+ {
+ typedef T type;
+ };
+
+ /// \brief A type sequence, for use as the 2nd parameter to the \c expr\<\> class template.
+ ///
+ /// A type sequence, for use as the 2nd parameter to the \c expr\<\> class template.
+ /// The types in the sequence correspond to the children of a node in an expression tree.
+ template< typename Arg0 >
+ struct term
+ {
+ BOOST_STATIC_CONSTANT(long, arity = 0);
+ typedef Arg0 child0;
+ typedef term_ref<Arg0> child_ref0;
+
+ #if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1500))
+ BOOST_PP_REPEAT_FROM_TO(1, BOOST_PROTO_MAX_ARITY, BOOST_PROTO_DEFINE_VOID_N, ~)
+ #endif
+
+ /// INTERNAL ONLY
+ ///
+ typedef Arg0 back_;
+ };
+
+ #define BOOST_PP_ITERATION_PARAMS_1 (3, (1, BOOST_PROTO_MAX_ARITY, <boost/proto/args.hpp>))
+ #include BOOST_PP_ITERATE()
+
+ #undef BOOST_PROTO_DEFINE_CHILD_N
+
+ BOOST_PROTO_END_ADL_NAMESPACE(argsns_)
+ ////////////////////////////////////////////////////////////////////////////////////////////
+
+ #ifndef BOOST_PROTO_BUILDING_DOCS
+ using namespace argsns_;
+ #endif
+ }}
+ #endif
+
+#else
+
+ #define N BOOST_PP_ITERATION()
+
+ /// \brief A type sequence, for use as the 2nd parameter to the \c expr\<\> class template.
+ ///
+ /// A type sequence, for use as the 2nd parameter to the \c expr\<\> class template.
+ /// The types in the sequence correspond to the children of a node in an expression tree.
+ template< BOOST_PP_ENUM_PARAMS(N, typename Arg) >
+ struct BOOST_PP_CAT(list, N)
+ {
+ BOOST_STATIC_CONSTANT(long, arity = N);
+ BOOST_PP_REPEAT(N, BOOST_PROTO_DEFINE_CHILD_N, ~)
+
+ #if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1500))
+ BOOST_PP_REPEAT_FROM_TO(N, BOOST_PROTO_MAX_ARITY, BOOST_PROTO_DEFINE_VOID_N, ~)
+ #endif
+
+ /// INTERNAL ONLY
+ ///
+ typedef BOOST_PP_CAT(Arg, BOOST_PP_DEC(N)) back_;
+ };
+
+ #undef N
+
+#endif

Added: branches/proto/v4/boost/proto/context.hpp
==============================================================================
--- (empty file)
+++ branches/proto/v4/boost/proto/context.hpp 2008-04-06 02:19:35 EDT (Sun, 06 Apr 2008)
@@ -0,0 +1,18 @@
+///////////////////////////////////////////////////////////////////////////////
+/// \file context.hpp
+/// Includes all the context classes in the context/ sub-directory.
+//
+// Copyright 2008 Eric Niebler. Distributed under the Boost
+// Software License, Version 1.0. (See accompanying file
+// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_PROTO_CONTEXT_HPP_EAN_06_23_2007
+#define BOOST_PROTO_CONTEXT_HPP_EAN_06_23_2007
+
+#include <boost/proto/detail/prefix.hpp> // must be first include
+#include <boost/proto/context/null.hpp>
+#include <boost/proto/context/default.hpp>
+#include <boost/proto/context/callable.hpp>
+#include <boost/proto/detail/suffix.hpp> // must be last include
+
+#endif

Added: branches/proto/v4/boost/proto/context/callable.hpp
==============================================================================
--- (empty file)
+++ branches/proto/v4/boost/proto/context/callable.hpp 2008-04-06 02:19:35 EDT (Sun, 06 Apr 2008)
@@ -0,0 +1,282 @@
+#ifndef BOOST_PP_IS_ITERATING
+ ///////////////////////////////////////////////////////////////////////////////
+ /// \file callable.hpp
+ /// Definintion of callable_context\<\>, an evaluation context for
+ /// proto::eval() that explodes each node and calls the derived context
+ /// type with the expressions constituents. If the derived context doesn't
+ /// have an overload that handles this node, fall back to some other
+ /// context.
+ //
+ // Copyright 2008 Eric Niebler. Distributed under the Boost
+ // Software License, Version 1.0. (See accompanying file
+ // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+ #ifndef BOOST_PROTO_CONTEXT_CALLABLE_HPP_EAN_06_23_2007
+ #define BOOST_PROTO_CONTEXT_CALLABLE_HPP_EAN_06_23_2007
+
+ #include <boost/proto/detail/prefix.hpp> // must be first include
+ #include <boost/config.hpp>
+ #include <boost/detail/workaround.hpp>
+ #include <boost/preprocessor/cat.hpp>
+ #include <boost/preprocessor/iteration/iterate.hpp>
+ #include <boost/preprocessor/facilities/intercept.hpp>
+ #include <boost/preprocessor/repetition/repeat.hpp>
+ #include <boost/preprocessor/repetition/enum_params.hpp>
+ #include <boost/preprocessor/repetition/enum_trailing.hpp>
+ #include <boost/preprocessor/repetition/enum_trailing_params.hpp>
+ #include <boost/preprocessor/arithmetic/inc.hpp>
+ #include <boost/preprocessor/selection/max.hpp>
+ #include <boost/mpl/if.hpp>
+ #include <boost/mpl/bool.hpp>
+ #include <boost/utility/result_of.hpp>
+ #include <boost/type_traits/remove_cv.hpp>
+ #include <boost/proto/proto_fwd.hpp>
+ #include <boost/proto/traits.hpp> // for child_c
+ #include <boost/proto/detail/suffix.hpp> // must be last include
+
+ namespace boost { namespace proto
+ {
+ namespace detail
+ {
+ template<typename T>
+ yes_type check_is_expr_handled(T const &);
+
+ no_type check_is_expr_handled(private_type_ const &);
+
+ template<typename Context, long Arity>
+ struct callable_context_wrapper;
+
+ template<typename Expr, typename Context, long Arity = Expr::proto_arity::value>
+ struct is_expr_handled;
+ }
+
+ namespace context
+ {
+ /// \brief A BinaryFunction that accepts a Proto expression and a
+ /// callable context and calls the context with the expression tag
+ /// and children as arguments, effectively fanning the expression
+ /// out.
+ ///
+ /// <tt>callable_eval\<\></tt> requires that \c Context is a
+ /// PolymorphicFunctionObject that can be invoked with \c Expr's
+ /// tag and children as expressions, as follows:
+ ///
+ /// \code
+ /// context(Expr::proto_tag(), child_c<0>(expr), child_c<1>(expr), ...)
+ /// \endcode
+ template<
+ typename Expr
+ , typename Context
+ , long Arity BOOST_PROTO_WHEN_BUILDING_DOCS(= Expr::proto_arity::value)
+ >
+ struct callable_eval
+ {};
+
+ /// \brief An evaluation context adaptor that makes authoring a
+ /// context a simple matter of writing function overloads, rather
+ /// then writing template specializations.
+ ///
+ /// <tt>callable_context\<\></tt> is a base class that implements
+ /// the context protocol by passing fanned-out expression nodes to
+ /// the derived context, making it easy to customize the handling
+ /// of expression types by writing function overloads. Only those
+ /// expression types needing special handling require explicit
+ /// handling. All others are dispatched to a user-specified
+ /// default context, \c DefaultCtx.
+ ///
+ /// <tt>callable_context\<\></tt> is defined simply as:
+ ///
+ /// \code
+ /// template<typename Context, typename DefaultCtx = default_context>
+ /// struct callable_context
+ /// {
+ /// template<typename Expr, typename ThisContext = Context>
+ /// struct eval
+ /// : mpl::if_<
+ /// is_expr_handled_<Expr, Context> // For exposition
+ /// , callable_eval<Expr, ThisContext>
+ /// , typename DefaultCtx::template eval<Expr, Context>
+ /// >::type
+ /// {};
+ /// };
+ /// \endcode
+ ///
+ /// The Boolean metafunction <tt>is_expr_handled_\<\></tt> uses
+ /// metaprogramming tricks to determine whether \c Context has
+ /// an overloaded function call operator that accepts the
+ /// fanned-out constituents of an expression of type \c Expr.
+ /// If so, the handling of the expression is dispatched to
+ /// <tt>callable_eval\<\></tt>. If not, it is dispatched to
+ /// the user-specified \c DefaultCtx.
+ ///
+ /// Below is an example of how to use <tt>callable_context\<\></tt>:
+ ///
+ /// \code
+ /// // An evaluation context that increments all
+ /// // integer terminals in-place.
+ /// struct increment_ints
+ /// : callable_context<
+ /// increment_ints const // derived context
+ /// , null_context const // fall-back context
+ /// >
+ /// {
+ /// typedef void result_type;
+ ///
+ /// // Handle int terminals here:
+ /// void operator()(proto::tag::terminal, int &i) const
+ /// {
+ /// ++i;
+ /// }
+ /// };
+ /// \endcode
+ ///
+ /// With \c increment_ints, we can do the following:
+ ///
+ /// \code
+ /// literal<int> i = 0, j = 10;
+ /// proto::eval( i - j * 3.14, increment_ints() );
+ ///
+ /// assert( i.get() == 1 && j.get() == 11 );
+ /// \endcode
+ template<
+ typename Context
+ , typename DefaultCtx BOOST_PROTO_WHEN_BUILDING_DOCS(= default_context)
+ >
+ struct callable_context
+ {
+ /// A BinaryFunction that accepts an \c Expr and a
+ /// \c Context, and either fans out the expression and passes
+ /// it to the context, or else hands off the expression to
+ /// \c DefaultCtx.
+ ///
+ /// If \c Context is a PolymorphicFunctionObject such that
+ /// it can be invoked with the tag and children of \c Expr,
+ /// as <tt>ctx(Expr::proto_tag(), child_c\<0\>(expr), child_c\<1\>(expr)...)</tt>,
+ /// then <tt>eval\<Expr, ThisContext\></tt> inherits from
+ /// <tt>callable_eval\<Expr, ThisContext\></tt>. Otherwise,
+ /// <tt>eval\<Expr, ThisContext\></tt> inherits from
+ /// <tt>DefaultCtx::eval\<Expr, Context\></tt>.
+ template<typename Expr, typename ThisContext = Context>
+ struct eval
+ : mpl::if_<
+ detail::is_expr_handled<Expr, Context>
+ , callable_eval<Expr, ThisContext>
+ , typename DefaultCtx::template eval<Expr, Context>
+ >::type
+ {};
+ };
+ }
+
+ #define BOOST_PROTO_CHILD_N_TYPE(Z, N, Expr) \
+ typedef typename proto::result_of::child_c<Expr const &, N>::type BOOST_PP_CAT(child, N); \
+ /**/
+
+ #define BOOST_PROTO_CHILD_N(Z, N, expr) \
+ proto::child_c<N>(expr) \
+ /**/
+
+ #define BOOST_PP_ITERATION_PARAMS_1 \
+ (3, (0, BOOST_PROTO_MAX_ARITY, <boost/proto/context/callable.hpp>)) \
+ /**/
+
+ #include BOOST_PP_ITERATE()
+
+ #undef BOOST_PROTO_CHILD_N_TYPE
+ #undef BOOST_PROTO_CHILD_N
+
+ }}
+
+ #endif
+
+#else
+
+ #define N BOOST_PP_ITERATION()
+ #define ARG_COUNT BOOST_PP_MAX(1, N)
+
+ namespace detail
+ {
+ #if N > 0
+ template<typename Context>
+ struct callable_context_wrapper<Context, N>
+ : remove_cv<Context>::type
+ {
+ callable_context_wrapper();
+ typedef
+ private_type_ const &fun_type(
+ BOOST_PP_ENUM_PARAMS(
+ BOOST_PP_INC(ARG_COUNT)
+ , detail::dont_care BOOST_PP_INTERCEPT
+ )
+ );
+ operator fun_type *() const;
+ };
+ #endif
+
+ template<typename Expr, typename Context>
+ struct is_expr_handled<Expr, Context, N>
+ {
+ static callable_context_wrapper<Context, ARG_COUNT> &sctx_;
+ static Expr &sexpr_;
+ static typename Expr::proto_tag &stag_;
+
+ BOOST_STATIC_CONSTANT(bool, value =
+ (
+ sizeof(yes_type) ==
+ sizeof(
+ detail::check_is_expr_handled(
+ (sctx_(
+ stag_
+ BOOST_PP_ENUM_TRAILING(ARG_COUNT, BOOST_PROTO_CHILD_N, sexpr_)
+ ), 0)
+ )
+ )));
+
+ typedef mpl::bool_<value> type;
+ };
+ }
+
+ namespace context
+ {
+ /// \brief A BinaryFunction that accepts a Proto expression and a
+ /// callable context and calls the context with the expression tag
+ /// and children as arguments, effectively fanning the expression
+ /// out.
+ ///
+ /// <tt>callable_eval\<\></tt> requires that \c Context is a
+ /// PolymorphicFunctionObject that can be invoked with \c Expr's
+ /// tag and children as expressions, as follows:
+ ///
+ /// \code
+ /// context(Expr::proto_tag(), child_c\<0\>(expr), child_c\<1\>(expr), ...)
+ /// \endcode
+ template<typename Expr, typename Context>
+ struct callable_eval<Expr, Context, N>
+ {
+ BOOST_PP_REPEAT(ARG_COUNT, BOOST_PROTO_CHILD_N_TYPE, Expr)
+
+ typedef
+ typename boost::result_of<
+ Context(
+ typename Expr::proto_tag
+ BOOST_PP_ENUM_TRAILING_PARAMS(ARG_COUNT, child)
+ )
+ >::type
+ result_type;
+
+ /// \param expr The current expression
+ /// \param context The callable evaluation context
+ /// \return <tt>context(Expr::proto_tag(), child_c\<0\>(expr), child_c\<1\>(expr), ...)</tt>
+ result_type operator ()(Expr &expr, Context &context) const
+ {
+ return context(
+ typename Expr::proto_tag()
+ BOOST_PP_ENUM_TRAILING(ARG_COUNT, BOOST_PROTO_CHILD_N, expr)
+ );
+ }
+ };
+ }
+
+ #undef N
+ #undef ARG_COUNT
+
+#endif

Added: branches/proto/v4/boost/proto/context/default.hpp
==============================================================================
--- (empty file)
+++ branches/proto/v4/boost/proto/context/default.hpp 2008-04-06 02:19:35 EDT (Sun, 06 Apr 2008)
@@ -0,0 +1,299 @@
+#ifndef BOOST_PP_IS_ITERATING
+ ///////////////////////////////////////////////////////////////////////////////
+ /// \file default.hpp
+ /// Definintion of default_context, a default evaluation context for
+ /// proto::eval() that uses Boost.Typeof to deduce return types
+ /// of the built-in operators.
+ //
+ // Copyright 2008 Eric Niebler. Distributed under the Boost
+ // Software License, Version 1.0. (See accompanying file
+ // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+ #ifndef BOOST_PROTO_CONTEXT_DEFAULT_HPP_EAN_01_08_2007
+ #define BOOST_PROTO_CONTEXT_DEFAULT_HPP_EAN_01_08_2007
+
+ #include <boost/proto/detail/prefix.hpp> // must be first include
+ #include <boost/config.hpp>
+ #include <boost/preprocessor/iteration/iterate.hpp>
+ #include <boost/preprocessor/repetition/enum_shifted.hpp>
+ #include <boost/utility/result_of.hpp>
+ #include <boost/type_traits/is_const.hpp>
+ #include <boost/type_traits/is_function.hpp>
+ #include <boost/type_traits/remove_reference.hpp>
+ #include <boost/proto/proto_fwd.hpp>
+ #include <boost/proto/tags.hpp>
+ #include <boost/proto/eval.hpp>
+ #include <boost/proto/traits.hpp> // for proto::child_c()
+ #include <boost/proto/detail/decltype.hpp>
+ #include <boost/proto/detail/suffix.hpp> // must be last include
+
+ namespace boost { namespace proto
+ {
+ /// INTERNAL ONLY
+ ///
+ #define UNREF(x) typename boost::remove_reference<x>::type
+
+ namespace context
+ {
+ template<
+ typename Expr
+ , typename Context
+ , typename Tag BOOST_PROTO_WHEN_BUILDING_DOCS(= typename Expr::proto_tag)
+ , long Arity BOOST_PROTO_WHEN_BUILDING_DOCS(= Expr::proto_arity::value)
+ >
+ struct default_eval
+ {};
+
+ /// INTERNAL ONLY
+ ///
+ #define BOOST_PROTO_UNARY_OP_RESULT(OP, TAG) \
+ template<typename Expr, typename Context> \
+ struct default_eval<Expr, Context, TAG, 1> \
+ { \
+ private: \
+ typedef typename proto::result_of::child_c<Expr, 0>::type e0; \
+ typedef typename proto::result_of::eval<UNREF(e0), Context>::type r0; \
+ public: \
+ BOOST_PROTO_DECLTYPE_(OP proto::detail::make<r0>(), result_type) \
+ result_type operator ()(Expr &expr, Context &ctx) const \
+ { \
+ return OP proto::eval(proto::child_c<0>(expr), ctx); \
+ } \
+ }; \
+ /**/
+
+ /// INTERNAL ONLY
+ ///
+ #define BOOST_PROTO_BINARY_OP_RESULT(OP, TAG) \
+ template<typename Expr, typename Context> \
+ struct default_eval<Expr, Context, TAG, 2> \
+ { \
+ private: \
+ typedef typename proto::result_of::child_c<Expr, 0>::type e0; \
+ typedef typename proto::result_of::child_c<Expr, 1>::type e1; \
+ typedef typename proto::result_of::eval<UNREF(e0), Context>::type r0; \
+ typedef typename proto::result_of::eval<UNREF(e1), Context>::type r1; \
+ public: \
+ BOOST_PROTO_DECLTYPE_( \
+ proto::detail::make<r0>() OP proto::detail::make<r1>() \
+ , result_type \
+ ) \
+ result_type operator ()(Expr &expr, Context &ctx) const \
+ { \
+ return proto::eval( \
+ proto::child_c<0>(expr), ctx) OP proto::eval(proto::child_c<1>(expr) \
+ , ctx \
+ ); \
+ } \
+ }; \
+ /**/
+
+ BOOST_PROTO_UNARY_OP_RESULT(+, proto::tag::unary_plus)
+ BOOST_PROTO_UNARY_OP_RESULT(-, proto::tag::negate)
+ BOOST_PROTO_UNARY_OP_RESULT(*, proto::tag::dereference)
+ BOOST_PROTO_UNARY_OP_RESULT(~, proto::tag::complement)
+ BOOST_PROTO_UNARY_OP_RESULT(&, proto::tag::address_of)
+ BOOST_PROTO_UNARY_OP_RESULT(!, proto::tag::logical_not)
+ BOOST_PROTO_UNARY_OP_RESULT(++, proto::tag::pre_inc)
+ BOOST_PROTO_UNARY_OP_RESULT(--, proto::tag::pre_dec)
+
+ BOOST_PROTO_BINARY_OP_RESULT(<<, proto::tag::shift_left)
+ BOOST_PROTO_BINARY_OP_RESULT(>>, proto::tag::shift_right)
+ BOOST_PROTO_BINARY_OP_RESULT(*, proto::tag::multiplies)
+ BOOST_PROTO_BINARY_OP_RESULT(/, proto::tag::divides)
+ BOOST_PROTO_BINARY_OP_RESULT(%, proto::tag::modulus)
+ BOOST_PROTO_BINARY_OP_RESULT(+, proto::tag::plus)
+ BOOST_PROTO_BINARY_OP_RESULT(-, proto::tag::minus)
+ BOOST_PROTO_BINARY_OP_RESULT(<, proto::tag::less)
+ BOOST_PROTO_BINARY_OP_RESULT(>, proto::tag::greater)
+ BOOST_PROTO_BINARY_OP_RESULT(<=, proto::tag::less_equal)
+ BOOST_PROTO_BINARY_OP_RESULT(>=, proto::tag::greater_equal)
+ BOOST_PROTO_BINARY_OP_RESULT(==, proto::tag::equal_to)
+ BOOST_PROTO_BINARY_OP_RESULT(!=, proto::tag::not_equal_to)
+ BOOST_PROTO_BINARY_OP_RESULT(||, proto::tag::logical_or)
+ BOOST_PROTO_BINARY_OP_RESULT(&&, proto::tag::logical_and)
+ BOOST_PROTO_BINARY_OP_RESULT(&, proto::tag::bitwise_and)
+ BOOST_PROTO_BINARY_OP_RESULT(|, proto::tag::bitwise_or)
+ BOOST_PROTO_BINARY_OP_RESULT(^, proto::tag::bitwise_xor)
+ BOOST_PROTO_BINARY_OP_RESULT(->*, proto::tag::mem_ptr)
+
+ BOOST_PROTO_BINARY_OP_RESULT(=, proto::tag::assign)
+ BOOST_PROTO_BINARY_OP_RESULT(<<=, proto::tag::shift_left_assign)
+ BOOST_PROTO_BINARY_OP_RESULT(>>=, proto::tag::shift_right_assign)
+ BOOST_PROTO_BINARY_OP_RESULT(*=, proto::tag::multiplies_assign)
+ BOOST_PROTO_BINARY_OP_RESULT(/=, proto::tag::divides_assign)
+ BOOST_PROTO_BINARY_OP_RESULT(%=, proto::tag::modulus_assign)
+ BOOST_PROTO_BINARY_OP_RESULT(+=, proto::tag::plus_assign)
+ BOOST_PROTO_BINARY_OP_RESULT(-=, proto::tag::minus_assign)
+ BOOST_PROTO_BINARY_OP_RESULT(&=, proto::tag::bitwise_and_assign)
+ BOOST_PROTO_BINARY_OP_RESULT(|=, proto::tag::bitwise_or_assign)
+ BOOST_PROTO_BINARY_OP_RESULT(^=, proto::tag::bitwise_xor_assign)
+
+ #undef BOOST_PROTO_UNARY_OP_RESULT
+ #undef BOOST_PROTO_BINARY_OP_RESULT
+
+ template<typename Expr, typename Context>
+ struct default_eval<Expr, Context, proto::tag::terminal, 0>
+ {
+ typedef
+ typename proto::result_of::value<Expr &>::type
+ result_type;
+
+ result_type operator ()(Expr &expr, Context &) const
+ {
+ return proto::value(expr);
+ }
+ };
+
+ // Handle post-increment specially.
+ template<typename Expr, typename Context>
+ struct default_eval<Expr, Context, proto::tag::post_inc, 1>
+ {
+ private:
+ typedef typename proto::result_of::child_c<Expr, 0>::type e0;
+ typedef typename proto::result_of::eval<UNREF(e0), Context>::type r0;
+ public:
+ BOOST_PROTO_DECLTYPE_(proto::detail::make<r0>() ++, result_type)
+ result_type operator ()(Expr &expr, Context &ctx) const
+ {
+ return proto::eval(proto::child_c<0>(expr), ctx) ++;
+ }
+ };
+
+ // Handle post-decrement specially.
+ template<typename Expr, typename Context>
+ struct default_eval<Expr, Context, proto::tag::post_dec, 1>
+ {
+ private:
+ typedef typename proto::result_of::child_c<Expr, 0>::type e0;
+ typedef typename proto::result_of::eval<UNREF(e0), Context>::type r0;
+ public:
+ BOOST_PROTO_DECLTYPE_(proto::detail::make<r0>() --, result_type)
+ result_type operator ()(Expr &expr, Context &ctx) const
+ {
+ return proto::eval(proto::child_c<0>(expr), ctx) --;
+ }
+ };
+
+ // Handle subscript specially.
+ template<typename Expr, typename Context>
+ struct default_eval<Expr, Context, proto::tag::subscript, 2>
+ {
+ private:
+ typedef typename proto::result_of::child_c<Expr, 0>::type e0;
+ typedef typename proto::result_of::child_c<Expr, 1>::type e1;
+ typedef typename proto::result_of::eval<UNREF(e0), Context>::type r0;
+ typedef typename proto::result_of::eval<UNREF(e1), Context>::type r1;
+ public:
+ BOOST_PROTO_DECLTYPE_(proto::detail::make<r0>()[proto::detail::make<r1>()], result_type)
+ result_type operator ()(Expr &expr, Context &ctx) const
+ {
+ return proto::eval(proto::child_c<0>(expr), ctx)[proto::eval(proto::child_c<1>(expr), ctx)];
+ }
+ };
+
+ // Handle if_else_ specially.
+ template<typename Expr, typename Context>
+ struct default_eval<Expr, Context, proto::tag::if_else_, 3>
+ {
+ private:
+ typedef typename proto::result_of::child_c<Expr, 0>::type e0;
+ typedef typename proto::result_of::child_c<Expr, 1>::type e1;
+ typedef typename proto::result_of::child_c<Expr, 2>::type e2;
+ typedef typename proto::result_of::eval<UNREF(e0), Context>::type r0;
+ typedef typename proto::result_of::eval<UNREF(e1), Context>::type r1;
+ typedef typename proto::result_of::eval<UNREF(e2), Context>::type r2;
+ public:
+ BOOST_PROTO_DECLTYPE_(
+ proto::detail::make<r0>()
+ ? proto::detail::make<r1>()
+ : proto::detail::make<r2>()
+ , result_type
+ )
+ result_type operator ()(Expr &expr, Context &ctx) const
+ {
+ return proto::eval(proto::child_c<0>(expr), ctx)
+ ? proto::eval(proto::child_c<1>(expr), ctx)
+ : proto::eval(proto::child_c<2>(expr), ctx);
+ }
+ };
+
+ // Handle comma specially.
+ template<typename Expr, typename Context>
+ struct default_eval<Expr, Context, proto::tag::comma, 2>
+ {
+ private:
+ typedef typename proto::result_of::child_c<Expr, 0>::type e0;
+ typedef typename proto::result_of::child_c<Expr, 1>::type e1;
+ typedef typename proto::result_of::eval<UNREF(e0), Context>::type r0;
+ typedef typename proto::result_of::eval<UNREF(e1), Context>::type r1;
+ public:
+ typedef typename proto::detail::comma_result<r0, r1>::type result_type;
+ result_type operator ()(Expr &expr, Context &ctx) const
+ {
+ return proto::eval(proto::child_c<0>(expr), ctx), proto::eval(proto::child_c<1>(expr), ctx);
+ }
+ };
+
+ // Handle function specially
+ #define EVAL_TYPE(Z, N, DATA) \
+ typename proto::result_of::eval< \
+ typename remove_reference<typename proto::result_of::child_c<DATA, N>::type>::type\
+ , Context \
+ >::type
+
+ #define EVAL(Z, N, DATA) \
+ proto::eval(proto::child_c<N>(DATA), context)
+
+ #define BOOST_PP_ITERATION_PARAMS_1 (3, (1, BOOST_PROTO_MAX_ARITY, <boost/proto/context/default.hpp>))
+ #include BOOST_PP_ITERATE()
+
+ #undef EVAL_TYPE
+ #undef EVAL
+
+ /// default_context
+ ///
+ struct default_context
+ {
+ /// default_context::eval
+ ///
+ template<typename Expr, typename ThisContext = default_context const>
+ struct eval
+ : default_eval<Expr, ThisContext>
+ {};
+ };
+
+ } // namespace context
+
+ }} // namespace boost::proto
+
+ #undef UNREF
+
+ #endif
+
+#else
+
+ #define N BOOST_PP_ITERATION()
+
+ template<typename Expr, typename Context>
+ struct default_eval<Expr, Context, proto::tag::function, N>
+ {
+ typedef
+ typename proto::detail::result_of_fixup<EVAL_TYPE(~, 0, Expr)>::type
+ function_type;
+
+ typedef
+ typename boost::result_of<
+ function_type(BOOST_PP_ENUM_SHIFTED(N, EVAL_TYPE, Expr))
+ >::type
+ result_type;
+
+ result_type operator ()(Expr &expr, Context &context) const
+ {
+ return EVAL(~, 0, expr)(BOOST_PP_ENUM_SHIFTED(N, EVAL, expr));
+ }
+ };
+
+ #undef N
+
+#endif

Added: branches/proto/v4/boost/proto/context/null.hpp
==============================================================================
--- (empty file)
+++ branches/proto/v4/boost/proto/context/null.hpp 2008-04-06 02:19:35 EDT (Sun, 06 Apr 2008)
@@ -0,0 +1,87 @@
+#ifndef BOOST_PP_IS_ITERATING
+ ///////////////////////////////////////////////////////////////////////////////
+ /// \file null.hpp
+ /// Definintion of null_context\<\>, an evaluation context for
+ /// proto::eval() that simply evaluates each child expression, doesn't
+ /// combine the results at all, and returns void.
+ //
+ // Copyright 2008 Eric Niebler. Distributed under the Boost
+ // Software License, Version 1.0. (See accompanying file
+ // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+ #ifndef BOOST_PROTO_CONTEXT_NULL_HPP_EAN_06_24_2007
+ #define BOOST_PROTO_CONTEXT_NULL_HPP_EAN_06_24_2007
+
+ #include <boost/proto/detail/prefix.hpp> // must be first include
+ #include <boost/preprocessor/iteration/iterate.hpp>
+ #include <boost/preprocessor/repetition/repeat.hpp>
+ #include <boost/proto/proto_fwd.hpp>
+ #include <boost/proto/eval.hpp>
+ #include <boost/proto/traits.hpp>
+ #include <boost/proto/detail/suffix.hpp> // must be last include
+
+ namespace boost { namespace proto { namespace context
+ {
+
+ template<
+ typename Expr
+ , typename Context
+ , long Arity BOOST_PROTO_WHEN_BUILDING_DOCS(= Expr::proto_arity::value)
+ >
+ struct null_eval
+ {};
+
+ template<typename Expr, typename Context>
+ struct null_eval<Expr, Context, 0>
+ {
+ typedef void result_type;
+ void operator()(Expr &, Context &) const
+ {}
+ };
+
+ #define BOOST_PROTO_EVAL_N(Z, N, DATA) \
+ proto::eval(proto::child_c<N>(expr), ctx); \
+ /**/
+
+ #define BOOST_PP_ITERATION_PARAMS_1 \
+ (3, (1, BOOST_PROTO_MAX_ARITY, <boost/proto/context/null.hpp>)) \
+ /**/
+
+ #include BOOST_PP_ITERATE()
+
+ #undef BOOST_PROTO_EVAL_N
+
+ /// null_context
+ ///
+ struct null_context
+ {
+ /// null_context::eval
+ ///
+ template<typename Expr, typename ThisContext = null_context const>
+ struct eval
+ : null_eval<Expr, ThisContext>
+ {};
+ };
+
+ }}}
+
+ #endif
+
+#else
+
+ #define N BOOST_PP_ITERATION()
+
+ template<typename Expr, typename Context>
+ struct null_eval<Expr, Context, N>
+ {
+ typedef void result_type;
+
+ void operator ()(Expr &expr, Context &ctx) const
+ {
+ BOOST_PP_REPEAT(N, BOOST_PROTO_EVAL_N, ~)
+ }
+ };
+
+ #undef N
+
+#endif

Added: branches/proto/v4/boost/proto/core.hpp
==============================================================================
--- (empty file)
+++ branches/proto/v4/boost/proto/core.hpp 2008-04-06 02:19:35 EDT (Sun, 06 Apr 2008)
@@ -0,0 +1,32 @@
+///////////////////////////////////////////////////////////////////////////////
+/// \file core.hpp
+/// Includes the core of Proto. Not included are the contexts, transforms and
+/// debugging utilities.
+//
+// Copyright 2008 Eric Niebler. Distributed under the Boost
+// Software License, Version 1.0. (See accompanying file
+// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_PROTO_CORE_HPP_EAN_04_01_2005
+#define BOOST_PROTO_CORE_HPP_EAN_04_01_2005
+
+#include <boost/proto/detail/prefix.hpp>
+#include <boost/proto/proto_fwd.hpp>
+#include <boost/proto/ref.hpp>
+#include <boost/proto/args.hpp>
+#include <boost/proto/tags.hpp>
+#include <boost/proto/eval.hpp>
+#include <boost/proto/expr.hpp>
+#include <boost/proto/traits.hpp>
+#include <boost/proto/domain.hpp>
+#include <boost/proto/fusion.hpp>
+#include <boost/proto/matches.hpp>
+#include <boost/proto/extends.hpp>
+#include <boost/proto/literal.hpp>
+#include <boost/proto/generate.hpp>
+#include <boost/proto/operators.hpp>
+#include <boost/proto/deep_copy.hpp>
+#include <boost/proto/make_expr.hpp>
+#include <boost/proto/detail/suffix.hpp>
+
+#endif

Added: branches/proto/v4/boost/proto/debug.hpp
==============================================================================
--- (empty file)
+++ branches/proto/v4/boost/proto/debug.hpp 2008-04-06 02:19:35 EDT (Sun, 06 Apr 2008)
@@ -0,0 +1,210 @@
+///////////////////////////////////////////////////////////////////////////////
+/// \file debug.hpp
+/// Utilities for debugging Proto expression trees
+//
+// Copyright 2008 Eric Niebler. Distributed under the Boost
+// Software License, Version 1.0. (See accompanying file
+// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_PROTO_DEBUG_HPP_EAN_12_31_2006
+#define BOOST_PROTO_DEBUG_HPP_EAN_12_31_2006
+
+#include <boost/proto/detail/prefix.hpp>
+#include <boost/preprocessor/iteration/local.hpp>
+#include <boost/preprocessor/repetition/repeat.hpp>
+#include <iomanip>
+#include <iostream>
+#include <typeinfo>
+#include <boost/proto/proto_fwd.hpp>
+#include <boost/proto/expr.hpp>
+#include <boost/proto/traits.hpp>
+#include <boost/proto/detail/dont_care.hpp>
+#include <boost/proto/detail/suffix.hpp>
+
+namespace boost { namespace proto
+{
+ namespace tag
+ {
+ namespace hidden_detail_
+ {
+ typedef char (&not_ostream)[sizeof(std::ostream)+1];
+ not_ostream operator<<(std::ostream &, detail::dont_care);
+
+ template<typename Tag, std::size_t S>
+ struct printable_tag_
+ {
+ typedef char const *type;
+ static type call() { return typeid(Tag).name(); }
+ };
+
+ template<typename Tag>
+ struct printable_tag_<Tag, sizeof(std::ostream)>
+ {
+ typedef Tag type;
+ static type call() { return Tag(); }
+ };
+
+ template<typename Tag>
+ struct printable_tag
+ : printable_tag_<Tag, sizeof(std::cout << Tag())>
+ {};
+ }
+
+ /// INTERNAL ONLY
+ template<typename Tag>
+ inline typename hidden_detail_::printable_tag<Tag>::type proto_tag_name(Tag)
+ {
+ return hidden_detail_::printable_tag<Tag>::call();
+ }
+
+ #define BOOST_PROTO_DEFINE_TAG_NAME(Tag) \
+ /** \brief INTERNAL ONLY */ \
+ inline char const *proto_tag_name(tag::Tag) \
+ { \
+ return #Tag; \
+ } \
+ /**/
+
+ BOOST_PROTO_DEFINE_TAG_NAME(unary_plus)
+ BOOST_PROTO_DEFINE_TAG_NAME(negate)
+ BOOST_PROTO_DEFINE_TAG_NAME(dereference)
+ BOOST_PROTO_DEFINE_TAG_NAME(complement)
+ BOOST_PROTO_DEFINE_TAG_NAME(address_of)
+ BOOST_PROTO_DEFINE_TAG_NAME(logical_not)
+ BOOST_PROTO_DEFINE_TAG_NAME(pre_inc)
+ BOOST_PROTO_DEFINE_TAG_NAME(pre_dec)
+ BOOST_PROTO_DEFINE_TAG_NAME(post_inc)
+ BOOST_PROTO_DEFINE_TAG_NAME(post_dec)
+ BOOST_PROTO_DEFINE_TAG_NAME(shift_left)
+ BOOST_PROTO_DEFINE_TAG_NAME(shift_right)
+ BOOST_PROTO_DEFINE_TAG_NAME(multiplies)
+ BOOST_PROTO_DEFINE_TAG_NAME(divides)
+ BOOST_PROTO_DEFINE_TAG_NAME(modulus)
+ BOOST_PROTO_DEFINE_TAG_NAME(plus)
+ BOOST_PROTO_DEFINE_TAG_NAME(minus)
+ BOOST_PROTO_DEFINE_TAG_NAME(less)
+ BOOST_PROTO_DEFINE_TAG_NAME(greater)
+ BOOST_PROTO_DEFINE_TAG_NAME(less_equal)
+ BOOST_PROTO_DEFINE_TAG_NAME(greater_equal)
+ BOOST_PROTO_DEFINE_TAG_NAME(equal_to)
+ BOOST_PROTO_DEFINE_TAG_NAME(not_equal_to)
+ BOOST_PROTO_DEFINE_TAG_NAME(logical_or)
+ BOOST_PROTO_DEFINE_TAG_NAME(logical_and)
+ BOOST_PROTO_DEFINE_TAG_NAME(bitwise_and)
+ BOOST_PROTO_DEFINE_TAG_NAME(bitwise_or)
+ BOOST_PROTO_DEFINE_TAG_NAME(bitwise_xor)
+ BOOST_PROTO_DEFINE_TAG_NAME(comma)
+ BOOST_PROTO_DEFINE_TAG_NAME(mem_ptr)
+ BOOST_PROTO_DEFINE_TAG_NAME(assign)
+ BOOST_PROTO_DEFINE_TAG_NAME(shift_left_assign)
+ BOOST_PROTO_DEFINE_TAG_NAME(shift_right_assign)
+ BOOST_PROTO_DEFINE_TAG_NAME(multiplies_assign)
+ BOOST_PROTO_DEFINE_TAG_NAME(divides_assign)
+ BOOST_PROTO_DEFINE_TAG_NAME(modulus_assign)
+ BOOST_PROTO_DEFINE_TAG_NAME(plus_assign)
+ BOOST_PROTO_DEFINE_TAG_NAME(minus_assign)
+ BOOST_PROTO_DEFINE_TAG_NAME(bitwise_and_assign)
+ BOOST_PROTO_DEFINE_TAG_NAME(bitwise_or_assign)
+ BOOST_PROTO_DEFINE_TAG_NAME(bitwise_xor_assign)
+ BOOST_PROTO_DEFINE_TAG_NAME(subscript)
+ BOOST_PROTO_DEFINE_TAG_NAME(if_else_)
+ BOOST_PROTO_DEFINE_TAG_NAME(function)
+
+ #undef BOOST_PROTO_DEFINE_TAG_NAME
+ }
+
+ namespace functor
+ {
+ /// \brief Pretty-print a Proto expression tree.
+ ///
+ /// A PolymorphicFunctionObject which accepts a Proto expression
+ /// tree and pretty-prints it to an \c ostream for debugging
+ /// purposes.
+ struct display_expr
+ {
+ typedef void result_type;
+
+ /// \param sout The \c ostream to which the expression tree
+ /// will be written.
+ /// \param depth The starting indentation depth for this node.
+ /// Children nodes will be displayed at a starting
+ /// depth of <tt>depth+4</tt>.
+ explicit display_expr(std::ostream &sout = std::cout, int depth = 0)
+ : depth_(depth)
+ , first_(true)
+ , sout_(sout)
+ {}
+
+ /// \brief Pretty-print the current node in a Proto expression
+ /// tree.
+ template<typename Args>
+ void operator()(proto::expr<tag::terminal, Args, 0> const &expr) const
+ {
+ this->sout_ << std::setw(this->depth_) << (this->first_? "" : ", ")
+ << "terminal(" << proto::value(expr) << ")\n";
+ this->first_ = false;
+ }
+
+ #define BOOST_PROTO_CHILD(Z, N, DATA) \
+ display(proto::child_c<N>(expr)); \
+ /**/
+
+ #define BOOST_PP_LOCAL_MACRO(N) \
+ /** \overload */ \
+ template<typename Tag, typename Args> \
+ void operator()(proto::expr<Tag, Args, N> const &expr) const \
+ { \
+ using namespace tag; \
+ this->sout_ << std::setw(this->depth_) << (this->first_? "" : ", ") \
+ << proto_tag_name(Tag()) << "(\n"; \
+ display_expr display(this->sout_, this->depth_ + 4); \
+ BOOST_PP_REPEAT(N, BOOST_PROTO_CHILD, _) \
+ this->sout_ << std::setw(this->depth_) << "" << ")\n"; \
+ this->first_ = false; \
+ } \
+ /**/
+
+ #define BOOST_PP_LOCAL_LIMITS (1, BOOST_PROTO_MAX_ARITY)
+ #include BOOST_PP_LOCAL_ITERATE()
+ #undef BOOST_PROTO_CHILD
+
+ /// \overload
+ ///
+ template<typename T>
+ void operator()(T const &t) const
+ {
+ (*this)(t.proto_base());
+ }
+
+ private:
+ display_expr &operator =(display_expr const &);
+ int depth_;
+ mutable bool first_;
+ std::ostream &sout_;
+ };
+ }
+
+ /// \brief Pretty-print a Proto expression tree.
+ ///
+ /// \note Equivalent to <tt>functor::display_expr(0, sout)(expr)</tt>
+ /// \param expr The Proto expression tree to pretty-print
+ /// \param sout The \c ostream to which the output should be
+ /// written. If not specified, defaults to
+ /// <tt>std::cout</tt>.
+ template<typename Expr>
+ void display_expr(Expr const &expr, std::ostream &sout)
+ {
+ functor::display_expr(sout, 0)(expr);
+ }
+
+ /// \overload
+ ///
+ template<typename Expr>
+ void display_expr(Expr const &expr)
+ {
+ functor::display_expr()(expr);
+ }
+
+}}
+
+#endif

Added: branches/proto/v4/boost/proto/deep_copy.hpp
==============================================================================
--- (empty file)
+++ branches/proto/v4/boost/proto/deep_copy.hpp 2008-04-06 02:19:35 EDT (Sun, 06 Apr 2008)
@@ -0,0 +1,189 @@
+#ifndef BOOST_PP_IS_ITERATING
+ ///////////////////////////////////////////////////////////////////////////////
+ /// \file deep_copy.hpp
+ /// Replace all nodes stored by reference by nodes stored by value.
+ //
+ // Copyright 2008 Eric Niebler. Distributed under the Boost
+ // Software License, Version 1.0. (See accompanying file
+ // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+ #ifndef BOOST_PROTO_DEEP_COPY_HPP_EAN_11_21_2006
+ #define BOOST_PROTO_DEEP_COPY_HPP_EAN_11_21_2006
+
+ #include <boost/proto/detail/prefix.hpp>
+ #include <boost/preprocessor/cat.hpp>
+ #include <boost/preprocessor/repetition/enum.hpp>
+ #include <boost/preprocessor/iteration/iterate.hpp>
+ #include <boost/mpl/if.hpp>
+ #include <boost/type_traits/is_function.hpp>
+ #include <boost/type_traits/remove_reference.hpp>
+ #include <boost/proto/proto_fwd.hpp>
+ #include <boost/proto/expr.hpp>
+ #include <boost/proto/detail/suffix.hpp>
+
+ namespace boost { namespace proto
+ {
+ namespace detail
+ {
+ template<typename Expr, long Arity = Expr::proto_arity::value>
+ struct deep_copy_impl;
+
+ template<typename Expr>
+ struct deep_copy_impl<Expr, 0>
+ {
+ typedef BOOST_PROTO_UNCVREF(typename Expr::proto_child0) raw_terminal_type;
+ // can't store a function type in a terminal.
+ typedef
+ typename mpl::if_c<
+ is_function<raw_terminal_type>::value
+ , typename Expr::proto_child0
+ , raw_terminal_type
+ >::type
+ actual_terminal_type;
+ typedef typename terminal<actual_terminal_type>::type expr_type;
+ typedef typename Expr::proto_domain::template result<void(expr_type)>::type type;
+
+ template<typename Expr2>
+ static type call(Expr2 const &expr)
+ {
+ return typename Expr::proto_domain()(expr_type::make(proto::value(expr)));
+ }
+ };
+ }
+
+ namespace result_of
+ {
+ /// \brief A metafunction for calculating the return type
+ /// of \c proto::deep_copy().
+ ///
+ /// A metafunction for calculating the return type
+ /// of \c proto::deep_copy(). The type parameter \c Expr
+ /// should be the type of a Proto expression tree.
+ /// It should not be a reference type, nor should it
+ /// be cv-qualified.
+ template<typename Expr>
+ struct deep_copy
+ {
+ typedef
+ typename detail::deep_copy_impl<
+ BOOST_PROTO_UNCVREF(Expr)
+ >::type
+ type;
+ };
+ }
+
+ namespace functor
+ {
+ /// \brief A PolymorphicFunctionObject type for deep-copying
+ /// Proto expression trees.
+ ///
+ /// A PolymorphicFunctionObject type for deep-copying
+ /// Proto expression trees. When a tree is deep-copied,
+ /// all internal nodes and most terminals held by reference
+ /// are instead held by value.
+ ///
+ /// \attention Terminals of reference-to-function type are
+ /// left unchanged. Terminals of reference-to-array type are
+ /// stored by value, which can cause a large amount of data
+ /// to be passed by value and stored on the stack.
+ struct deep_copy
+ {
+ BOOST_PROTO_CALLABLE()
+
+ template<typename Sig>
+ struct result;
+
+ template<typename This, typename Expr>
+ struct result<This(Expr)>
+ {
+ typedef
+ typename result_of::deep_copy<Expr>::type
+ type;
+ };
+
+ /// \brief Deep-copies a Proto expression tree, turning all
+ /// nodes and terminals held by reference into ones held by
+ /// value.
+ template<typename Expr>
+ typename result_of::deep_copy<Expr>::type
+ operator()(Expr const &expr) const
+ {
+ return proto::detail::deep_copy_impl<Expr>::call(expr);
+ }
+ };
+ }
+
+ /// \brief A function for deep-copying
+ /// Proto expression trees.
+ ///
+ /// A function for deep-copying
+ /// Proto expression trees. When a tree is deep-copied,
+ /// all internal nodes and most terminals held by reference
+ /// are instead held by value.
+ ///
+ /// \attention Terminals of reference-to-array type and of
+ /// reference-to-function type are left unchanged.
+ ///
+ /// \sa proto::functor::deep_copy.
+ template<typename Expr>
+ typename proto::result_of::deep_copy<Expr>::type
+ deep_copy(Expr const &expr)
+ {
+ return proto::detail::deep_copy_impl<Expr>::call(expr);
+ }
+
+ namespace detail
+ {
+ #define BOOST_PROTO_DEFINE_DEEP_COPY_TYPE(Z, N, DATA) \
+ typename deep_copy_impl< \
+ BOOST_PROTO_UNCVREF( \
+ typename Expr::BOOST_PP_CAT(proto_child, N) \
+ ) \
+ >::type
+
+ #define BOOST_PROTO_DEFINE_DEEP_COPY_FUN(Z, N, DATA) \
+ proto::deep_copy(expr.proto_base().BOOST_PP_CAT(child, N))
+
+ #define BOOST_PP_ITERATION_PARAMS_1 (3, (1, BOOST_PROTO_MAX_ARITY, <boost/proto/deep_copy.hpp>))
+ #include BOOST_PP_ITERATE()
+
+ #undef BOOST_PROTO_DEFINE_DEEP_COPY_FUN
+ #undef BOOST_PROTO_DEFINE_DEEP_COPY_TYPE
+ }
+
+ }}
+
+ #endif // BOOST_PROTO_COMPILER_DEEP_COPY_HPP_EAN_11_21_2006
+
+#else
+
+ #define N BOOST_PP_ITERATION()
+
+ template<typename Expr>
+ struct deep_copy_impl<Expr, N>
+ {
+ typedef
+ proto::expr<
+ typename Expr::proto_tag
+ , BOOST_PP_CAT(list, N)<
+ BOOST_PP_ENUM(N, BOOST_PROTO_DEFINE_DEEP_COPY_TYPE, ~)
+ >
+ >
+ expr_type;
+
+ typedef typename Expr::proto_domain::template result<void(expr_type)>::type type;
+
+ template<typename Expr2>
+ static type call(Expr2 const &expr)
+ {
+ expr_type that = {
+ BOOST_PP_ENUM(N, BOOST_PROTO_DEFINE_DEEP_COPY_FUN, ~)
+ };
+
+ return typename Expr::proto_domain()(that);
+ }
+ };
+
+ #undef N
+
+#endif

Added: branches/proto/v4/boost/proto/detail/as_lvalue.hpp
==============================================================================
--- (empty file)
+++ branches/proto/v4/boost/proto/detail/as_lvalue.hpp 2008-04-06 02:19:35 EDT (Sun, 06 Apr 2008)
@@ -0,0 +1,36 @@
+///////////////////////////////////////////////////////////////////////////////
+/// \file as_lvalue.hpp
+/// Contains definition the as_lvalue() and as_nonconst_lvalue() functions.
+//
+// Copyright 2008 Eric Niebler. Distributed under the Boost
+// Software License, Version 1.0. (See accompanying file
+// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_PROTO_TRANSFORM_AS_LVALUE_HPP_EAN_12_27_2007
+#define BOOST_PROTO_TRANSFORM_AS_LVALUE_HPP_EAN_12_27_2007
+
+namespace boost { namespace proto
+{
+ namespace detail
+ {
+ template<typename T>
+ T &as_lvalue(T &t)
+ {
+ return t;
+ }
+
+ template<typename T>
+ T const &as_lvalue(T const &t)
+ {
+ return t;
+ }
+
+ template<typename T>
+ T &as_nonconst_lvalue(T const &t)
+ {
+ return const_cast<T &>(t);
+ }
+ }
+}}
+
+#endif

Added: branches/proto/v4/boost/proto/detail/decltype.hpp
==============================================================================
--- (empty file)
+++ branches/proto/v4/boost/proto/detail/decltype.hpp 2008-04-06 02:19:35 EDT (Sun, 06 Apr 2008)
@@ -0,0 +1,117 @@
+///////////////////////////////////////////////////////////////////////////////
+/// \file decltype.hpp
+/// Contains definition the BOOST_PROTO_DECLTYPE_() macro and assorted helpers
+//
+// Copyright 2008 Eric Niebler. Distributed under the Boost
+// Software License, Version 1.0. (See accompanying file
+// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_PROTO_DETAIL_DECLTYPE_HPP_EAN_04_04_2008
+#define BOOST_PROTO_DETAIL_DECLTYPE_HPP_EAN_04_04_2008
+
+#include <boost/proto/detail/prefix.hpp> // must be first include
+#include <boost/config.hpp>
+#include <boost/preprocessor/cat.hpp>
+#include <boost/mpl/if.hpp>
+#include <boost/type_traits/is_function.hpp>
+#include <boost/typeof/typeof.hpp>
+#include <boost/proto/detail/suffix.hpp> // must be last include
+
+// If we're generating doxygen documentation, hide all the nasty
+// Boost.Typeof gunk.
+#ifndef BOOST_PROTO_BUILDING_DOCS
+# ifdef BOOST_HAS_DECLTYPE
+# define BOOST_PROTO_DECLTYPE_(EXPR, TYPE) typedef decltype(EXPR) TYPE;
+# else
+# define BOOST_PROTO_DECLTYPE_NESTED_TYPEDEF_TPL_(NESTED, EXPR) \
+ BOOST_TYPEOF_NESTED_TYPEDEF_TPL(BOOST_PP_CAT(nested_and_hidden_, NESTED), EXPR) \
+ static int const sz = sizeof(boost::proto::detail::check_reference(EXPR)); \
+ struct NESTED \
+ : boost::mpl::if_c< \
+ 1==sz \
+ , typename BOOST_PP_CAT(nested_and_hidden_, NESTED)::type & \
+ , typename BOOST_PP_CAT(nested_and_hidden_, NESTED)::type \
+ > \
+ {};
+# define BOOST_PROTO_DECLTYPE_(EXPR, TYPE) \
+ BOOST_PROTO_DECLTYPE_NESTED_TYPEDEF_TPL_(BOOST_PP_CAT(nested_, TYPE), (EXPR)) \
+ typedef typename BOOST_PP_CAT(nested_, TYPE)::type TYPE;
+# endif
+#else
+/// INTERNAL ONLY
+///
+# define BOOST_PROTO_DECLTYPE_(EXPR, TYPE) \
+ typedef detail::unspecified TYPE;
+#endif
+
+namespace boost { namespace proto
+{
+ namespace detail
+ {
+ template<typename T> T make();
+
+ template<typename T>
+ char check_reference(T &);
+
+ template<typename T>
+ char (&check_reference(T const &))[2];
+
+ template<typename A0, typename A1>
+ struct comma_result
+ {
+ BOOST_PROTO_DECLTYPE_((proto::detail::make<A0>(), proto::detail::make<A1>()), type)
+ };
+
+ template<typename A0>
+ struct comma_result<A0, void>
+ {
+ typedef void type;
+ };
+
+ template<typename A1>
+ struct comma_result<void, A1>
+ {
+ typedef A1 type;
+ };
+
+ template<>
+ struct comma_result<void, void>
+ {
+ typedef void type;
+ };
+
+ template<typename T, typename U = T>
+ struct result_of_fixup
+ : mpl::if_<is_function<T>, T *, U>
+ {};
+
+ template<typename T, typename U>
+ struct result_of_fixup<T &, U>
+ : result_of_fixup<T, T>
+ {};
+
+ template<typename T, typename U>
+ struct result_of_fixup<T *, U>
+ : result_of_fixup<T, U>
+ {};
+
+ template<typename T, typename U>
+ struct result_of_fixup<T const, U>
+ : result_of_fixup<T, U>
+ {};
+
+ //// Tests for result_of_fixup
+ //struct bar {};
+ //BOOST_MPL_ASSERT((is_same<bar, result_of_fixup<bar>::type>));
+ //BOOST_MPL_ASSERT((is_same<bar const, result_of_fixup<bar const>::type>));
+ //BOOST_MPL_ASSERT((is_same<bar, result_of_fixup<bar &>::type>));
+ //BOOST_MPL_ASSERT((is_same<bar const, result_of_fixup<bar const &>::type>));
+ //BOOST_MPL_ASSERT((is_same<void(*)(), result_of_fixup<void(*)()>::type>));
+ //BOOST_MPL_ASSERT((is_same<void(*)(), result_of_fixup<void(* const)()>::type>));
+ //BOOST_MPL_ASSERT((is_same<void(*)(), result_of_fixup<void(* const &)()>::type>));
+ //BOOST_MPL_ASSERT((is_same<void(*)(), result_of_fixup<void(&)()>::type>));
+
+ } // namespace detail
+}}
+
+#endif

Added: branches/proto/v4/boost/proto/detail/dont_care.hpp
==============================================================================
--- (empty file)
+++ branches/proto/v4/boost/proto/detail/dont_care.hpp 2008-04-06 02:19:35 EDT (Sun, 06 Apr 2008)
@@ -0,0 +1,23 @@
+///////////////////////////////////////////////////////////////////////////////
+/// \file dont_care.hpp
+/// Definintion of dont_care, a dummy parameter
+//
+// Copyright 2008 Eric Niebler. Distributed under the Boost
+// Software License, Version 1.0. (See accompanying file
+// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_PROTO_DETAIL_DONT_CARE_HPP_EAN_11_07_2007
+#define BOOST_PROTO_DETAIL_DONT_CARE_HPP_EAN_11_07_2007
+
+namespace boost { namespace proto
+{
+ namespace detail
+ {
+ struct dont_care
+ {
+ dont_care(...);
+ };
+ }
+}}
+
+#endif

Added: branches/proto/v4/boost/proto/detail/funop.hpp
==============================================================================
--- (empty file)
+++ branches/proto/v4/boost/proto/detail/funop.hpp 2008-04-06 02:19:35 EDT (Sun, 06 Apr 2008)
@@ -0,0 +1,78 @@
+///////////////////////////////////////////////////////////////////////////////
+// funop.hpp
+// Contains definition of funop[n]\<\> class template.
+//
+// Copyright 2008 Eric Niebler. Distributed under the Boost
+// Software License, Version 1.0. (See accompanying file
+// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_PP_IS_ITERATING
+#error Do not include this file directly
+#endif
+
+#define M0(Z, N, DATA) \
+ typename proto::result_of::as_child<BOOST_PP_CAT(A, N), Domain>::type \
+ /**/
+
+#define M1(Z, N, DATA) \
+ proto::as_child<Domain>(BOOST_PP_CAT(a, N)) \
+ /**/
+
+ /// \brief A helper metafunction for computing the
+ /// return type of \c proto::expr\<\>::operator().
+ template<typename Expr, typename Domain BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PP_ITERATION(), typename A)>
+ struct BOOST_PP_CAT(funop, BOOST_PP_ITERATION())
+ {
+ typedef proto::expr<
+ tag::function
+ , BOOST_PP_CAT(list, BOOST_PP_INC(BOOST_PP_ITERATION()))<
+ Expr &
+ BOOST_PP_ENUM_TRAILING(BOOST_PP_ITERATION(), M0, ~)
+ >
+ > type;
+
+ static type const call(
+ Expr &expr
+ BOOST_PP_ENUM_TRAILING_BINARY_PARAMS(BOOST_PP_ITERATION(), A, &a)
+ )
+ {
+ type that = {
+ expr
+ BOOST_PP_ENUM_TRAILING(BOOST_PP_ITERATION(), M1, ~)
+ };
+ return that;
+ }
+ };
+
+ /// \brief A helper metafunction for computing the
+ /// return type of \c proto::expr\<\>::operator().
+ template<typename Expr BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PP_ITERATION(), typename A), typename This, typename Domain>
+ struct funop<Expr(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), A)), This, Domain>
+ : BOOST_PP_CAT(funop, BOOST_PP_ITERATION())<
+ This
+ , Domain
+ BOOST_PP_ENUM_TRAILING_BINARY_PARAMS(
+ BOOST_PP_ITERATION()
+ , typename remove_reference<A
+ , >::type BOOST_PP_INTERCEPT
+ )
+ >
+ {};
+
+ /// \brief A helper metafunction for computing the
+ /// return type of \c proto::expr\<\>::operator().
+ template<typename Expr BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PP_ITERATION(), typename A), typename This, typename Domain>
+ struct funop<Expr const(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), A)), This, Domain>
+ : BOOST_PP_CAT(funop, BOOST_PP_ITERATION())<
+ This const
+ , Domain
+ BOOST_PP_ENUM_TRAILING_BINARY_PARAMS(
+ BOOST_PP_ITERATION()
+ , typename remove_reference<A
+ , >::type BOOST_PP_INTERCEPT
+ )
+ >
+ {};
+
+#undef M0
+#undef M1

Added: branches/proto/v4/boost/proto/detail/ignore_unused.hpp
==============================================================================
--- (empty file)
+++ branches/proto/v4/boost/proto/detail/ignore_unused.hpp 2008-04-06 02:19:35 EDT (Sun, 06 Apr 2008)
@@ -0,0 +1,23 @@
+///////////////////////////////////////////////////////////////////////////////
+/// \file ignore_unused.hpp
+/// Definintion of ignore_unused, a dummy function for suppressing compiler
+/// warnings
+//
+// Copyright 2008 Eric Niebler. Distributed under the Boost
+// Software License, Version 1.0. (See accompanying file
+// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_PROTO_DETAIL_IGNORE_UNUSED_HPP_EAN_03_03_2008
+#define BOOST_PROTO_DETAIL_IGNORE_UNUSED_HPP_EAN_03_03_2008
+
+namespace boost { namespace proto
+{
+ namespace detail
+ {
+ template<typename T>
+ inline void ignore_unused(T const &)
+ {}
+ }
+}}
+
+#endif

Added: branches/proto/v4/boost/proto/detail/pop_front.hpp
==============================================================================
--- (empty file)
+++ branches/proto/v4/boost/proto/detail/pop_front.hpp 2008-04-06 02:19:35 EDT (Sun, 06 Apr 2008)
@@ -0,0 +1,43 @@
+/*=============================================================================
+ Copyright (c) 2001-2006 Joel de Guzman
+ Copyright (c) 2008 Eric Niebler
+
+ Distributed under the Boost Software License, Version 1.0. (See accompanying
+ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+#ifndef BOOST_PROTO_DETAIL_FUSION_POP_FRONT_EAH_01_22_2008
+#define BOOST_PROTO_DETAIL_FUSION_POP_FRONT_EAH_01_22_2008
+
+#include <boost/spirit/fusion/sequence/range.hpp>
+#include <boost/spirit/fusion/sequence/begin.hpp>
+#include <boost/spirit/fusion/sequence/end.hpp>
+#include <boost/spirit/fusion/iterator/next.hpp>
+
+namespace boost { namespace fusion
+{
+ namespace meta
+ {
+ template <typename Sequence>
+ struct pop_front
+ {
+ typedef
+ range<
+ typename next<
+ typename begin<Sequence>::type
+ >::type
+ , typename end<Sequence>::type
+ >
+ type;
+ };
+ }
+
+ template <typename Sequence>
+ inline typename meta::pop_front<Sequence const>::type
+ pop_front(Sequence const& seq)
+ {
+ typedef typename meta::pop_front<Sequence const>::type result;
+ return result(fusion::next(fusion::begin(seq)), fusion::end(seq));
+ }
+}}
+
+#endif

Added: branches/proto/v4/boost/proto/detail/prefix.hpp
==============================================================================
--- (empty file)
+++ branches/proto/v4/boost/proto/detail/prefix.hpp 2008-04-06 02:19:35 EDT (Sun, 06 Apr 2008)
@@ -0,0 +1,10 @@
+#if defined(__WAVE__) && defined(BOOST_PROTO_BUILDING_DOCS)
+#pragma wave option(output:push)
+#pragma wave option(output:null)
+#endif
+
+///////////////////////////////////////////////////////////////////////////////
+// Copyright 2008 Eric Niebler. Distributed under the Boost
+// Software License, Version 1.0. (See accompanying file
+// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+///////////////////////////////////////////////////////////////////////////////

Added: branches/proto/v4/boost/proto/detail/reverse.hpp
==============================================================================
--- (empty file)
+++ branches/proto/v4/boost/proto/detail/reverse.hpp 2008-04-06 02:19:35 EDT (Sun, 06 Apr 2008)
@@ -0,0 +1,189 @@
+/*=============================================================================
+ Copyright (c) 2001-2006 Joel de Guzman
+ Copyright (c) 2008 Eric Niebler
+
+ Distributed under the Boost Software License, Version 1.0. (See accompanying
+ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+#ifndef BOOST_PROTO_DETAIL_FUSION_REVERSE_EAH_01_22_2008
+#define BOOST_PROTO_DETAIL_FUSION_REVERSE_EAH_01_22_2008
+
+#include <boost/spirit/fusion/detail/access.hpp>
+#include <boost/spirit/fusion/iterator/as_fusion_iterator.hpp>
+#include <boost/spirit/fusion/iterator/detail/iterator_base.hpp>
+#include <boost/spirit/fusion/sequence/detail/sequence_base.hpp>
+#include <boost/spirit/fusion/iterator/next.hpp>
+#include <boost/spirit/fusion/iterator/prior.hpp>
+#include <boost/spirit/fusion/iterator/deref.hpp>
+#include <boost/spirit/fusion/iterator/value_of.hpp>
+#include <boost/spirit/fusion/sequence/begin.hpp>
+#include <boost/spirit/fusion/sequence/end.hpp>
+
+namespace boost { namespace fusion
+{
+ struct reverse_view_tag;
+ struct reverse_view_iterator_tag;
+
+ template <typename First>
+ struct reverse_view_iterator
+ : iterator_base<reverse_view_iterator<First> >
+ {
+ typedef as_fusion_iterator<First> converter;
+ typedef typename converter::type first_type;
+ typedef reverse_view_iterator_tag tag;
+
+ reverse_view_iterator(First const& first)
+ : first(converter::convert(first)) {}
+
+ first_type first;
+ };
+
+ template <typename Sequence>
+ struct reverse_view : sequence_base<reverse_view<Sequence> >
+ {
+ typedef as_fusion_sequence<Sequence> seq_converter;
+ typedef typename seq_converter::type seq;
+
+ typedef reverse_view_tag tag;
+ typedef typename meta::begin<seq>::type first_type;
+ typedef typename meta::end<seq>::type last_type;
+
+ reverse_view(Sequence& seq)
+ : first(fusion::begin(seq))
+ , last(fusion::end(seq))
+ {}
+
+ first_type first;
+ last_type last;
+ };
+
+ namespace meta
+ {
+ template <>
+ struct deref_impl<reverse_view_iterator_tag>
+ {
+ template <typename Iterator>
+ struct apply
+ {
+ typedef typename
+ meta::deref<
+ typename meta::prior<
+ typename Iterator::first_type
+ >::type
+ >::type
+ type;
+
+ static type
+ call(Iterator const& i)
+ {
+ return *fusion::prior(i.first);
+ }
+ };
+ };
+
+ template <>
+ struct prior_impl<reverse_view_iterator_tag>
+ {
+ template <typename Iterator>
+ struct apply
+ {
+ typedef typename Iterator::first_type first_type;
+ typedef typename next_impl<typename first_type::tag>::
+ template apply<first_type>
+ wrapped;
+
+ typedef reverse_view_iterator<typename wrapped::type> type;
+
+ static type
+ call(Iterator const& i)
+ {
+ return type(wrapped::call(i.first));
+ }
+ };
+ };
+
+ template <>
+ struct next_impl<reverse_view_iterator_tag>
+ {
+ template <typename Iterator>
+ struct apply
+ {
+ typedef typename Iterator::first_type first_type;
+ typedef typename prior_impl<typename first_type::tag>::
+ template apply<first_type>
+ wrapped;
+
+ typedef reverse_view_iterator<typename wrapped::type> type;
+
+ static type
+ call(Iterator const& i)
+ {
+ return type(wrapped::call(i.first));
+ }
+ };
+ };
+
+ template <>
+ struct value_impl<reverse_view_iterator_tag>
+ {
+ template <typename Iterator>
+ struct apply
+ {
+ typedef typename
+ meta::value_of<
+ typename meta::prior<
+ typename Iterator::first_type
+ >::type
+ >::type
+ type;
+ };
+ };
+
+ template <>
+ struct begin_impl<reverse_view_tag>
+ {
+ template <typename Sequence>
+ struct apply
+ {
+ typedef reverse_view_iterator<typename Sequence::last_type> type;
+
+ static type
+ call(Sequence const& s)
+ {
+ return type(s.last);
+ }
+ };
+ };
+
+ template <>
+ struct end_impl<reverse_view_tag>
+ {
+ template <typename Sequence>
+ struct apply
+ {
+ typedef reverse_view_iterator<typename Sequence::first_type> type;
+
+ static type
+ call(Sequence const& s)
+ {
+ return type(s.first);
+ }
+ };
+ };
+
+ template <typename Sequence>
+ struct reverse
+ {
+ typedef reverse_view<Sequence> type;
+ };
+ }
+
+ template <typename Sequence>
+ inline reverse_view<Sequence const>
+ reverse(Sequence const& view)
+ {
+ return reverse_view<Sequence const>(view);
+ }
+}}
+
+#endif

Added: branches/proto/v4/boost/proto/detail/suffix.hpp
==============================================================================
--- (empty file)
+++ branches/proto/v4/boost/proto/detail/suffix.hpp 2008-04-06 02:19:35 EDT (Sun, 06 Apr 2008)
@@ -0,0 +1,16 @@
+///////////////////////////////////////////////////////////////////////////////
+// Copyright 2008 Eric Niebler. Distributed under the Boost
+// Software License, Version 1.0. (See accompanying file
+// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+///////////////////////////////////////////////////////////////////////////////
+
+#if defined(__WAVE__) && defined(BOOST_PROTO_BUILDING_DOCS)
+#pragma wave option(output:pop)
+#endif
+
+#ifndef BOOST_PROTO_SUFFIX_DUMMY_STRUCT_DEFINED
+#define BOOST_PROTO_SUFFIX_DUMMY_STRUCT_DEFINED
+/// INTERNAL ONLY
+///
+struct a_dummy_struct;
+#endif

Added: branches/proto/v4/boost/proto/domain.hpp
==============================================================================
--- (empty file)
+++ branches/proto/v4/boost/proto/domain.hpp 2008-04-06 02:19:35 EDT (Sun, 06 Apr 2008)
@@ -0,0 +1,174 @@
+///////////////////////////////////////////////////////////////////////////////
+/// \file domain.hpp
+/// Contains definition of domain\<\> class template and helpers for
+/// defining domains with a generator and a grammar for controlling
+/// operator overloading.
+//
+// Copyright 2008 Eric Niebler. Distributed under the Boost
+// Software License, Version 1.0. (See accompanying file
+// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_PROTO_DOMAIN_HPP_EAN_02_13_2007
+#define BOOST_PROTO_DOMAIN_HPP_EAN_02_13_2007
+
+#include <boost/proto/detail/prefix.hpp>
+#include <boost/ref.hpp>
+#include <boost/mpl/bool.hpp>
+#include <boost/proto/proto_fwd.hpp>
+#include <boost/proto/generate.hpp>
+#include <boost/proto/detail/suffix.hpp>
+
+namespace boost { namespace proto
+{
+
+ namespace detail
+ {
+ struct not_a_generator
+ {};
+
+ struct not_a_grammar
+ {};
+ }
+
+ BOOST_PROTO_BEGIN_ADL_NAMESPACE(domainns_)
+
+ /// \brief For use in defining domain tags to be used
+ /// with \c proto::extends\<\>. A \e Domain associates
+ /// an expression type with a \e Generator, and optionally
+ /// a \e Grammar.
+ ///
+ /// The Generator determines how new expressions in the
+ /// domain are constructed. Typically, a generator wraps
+ /// all new expressions in a wrapper that imparts
+ /// domain-specific behaviors to expressions within its
+ /// domain. (See \c proto::extends\<\>.)
+ ///
+ /// The Grammar determines whether a given expression is
+ /// valid within the domain, and automatically disables
+ /// any operator overloads which would cause an invalid
+ /// expression to be created. By default, the Grammar
+ /// parameter defaults to the wildcard, \c proto::_, which
+ /// makes all expressions valid within the domain.
+ ///
+ /// Example:
+ /// \code
+ /// template<typename Expr>
+ /// struct MyExpr;
+ ///
+ /// struct MyGrammar
+ /// : or_< terminal<_>, plus<MyGrammar, MyGrammar> >
+ /// {};
+ ///
+ /// // Define MyDomain, in which all expressions are
+ /// // wrapped in MyExpr<> and only expressions that
+ /// // conform to MyGrammar are allowed.
+ /// struct MyDomain
+ /// : domain<generator<MyExpr>, MyGrammar>
+ /// {};
+ ///
+ /// // Use MyDomain to define MyExpr
+ /// template<typename Expr>
+ /// struct MyExpr
+ /// : extends<Expr, MyExpr<Expr>, MyDomain>
+ /// {
+ /// // ...
+ /// };
+ /// \endcode
+ ///
+ template<
+ typename Generator BOOST_PROTO_WHEN_BUILDING_DOCS(= default_generator)
+ , typename Grammar BOOST_PROTO_WHEN_BUILDING_DOCS(= proto::_)
+ >
+ struct domain
+ : Generator
+ {
+ typedef Grammar proto_grammar;
+ typedef void proto_is_domain_;
+ };
+
+ /// \brief The domain expressions have by default, if
+ /// \c proto::extends\<\> has not been used to associate
+ /// a domain with an expression.
+ ///
+ struct default_domain
+ : domain<>
+ {};
+
+ /// \brief A pseudo-domain for use in functions and
+ /// metafunctions that require a domain parameter. It
+ /// indicates that the domain of the parent node should
+ /// be inferred from the domains of the child nodes.
+ ///
+ /// \attention \c deduce_domain is not itself a valid domain.
+ ///
+ struct deduce_domain
+ : domain<detail::not_a_generator, detail::not_a_grammar>
+ {};
+
+ BOOST_PROTO_END_ADL_NAMESPACE(domainns_)
+
+ namespace result_of
+ {
+ /// A metafunction that returns \c mpl::true_
+ /// if the type \c T is the type of a Proto domain;
+ /// \c mpl::false_ otherwise. If \c T inherits from
+ /// \c proto::domain\<\>, \c is_domain\<T\> is
+ /// \c mpl::true_.
+ template<typename T, typename Void BOOST_PROTO_WHEN_BUILDING_DOCS(= void)>
+ struct is_domain
+ : mpl::false_
+ {};
+
+ /// INTERNAL ONLY
+ ///
+ template<typename T>
+ struct is_domain<T, typename T::proto_is_domain_>
+ : mpl::true_
+ {};
+
+ /// A metafunction that returns the domain of
+ /// a given type. If \c T is a Proto expression
+ /// type, it returns that expression's associated
+ /// domain. If not, it returns
+ /// \c proto::default_domain.
+ template<typename T, typename Void BOOST_PROTO_WHEN_BUILDING_DOCS(= void)>
+ struct domain_of
+ {
+ typedef default_domain type;
+ };
+
+ /// INTERNAL ONLY
+ ///
+ template<typename T>
+ struct domain_of<T, typename T::proto_is_expr_>
+ {
+ typedef typename T::proto_domain type;
+ };
+
+ /// INTERNAL ONLY
+ ///
+ template<typename T>
+ struct domain_of<T &, void>
+ {
+ typedef typename domain_of<T>::type type;
+ };
+
+ /// INTERNAL ONLY
+ ///
+ template<typename T>
+ struct domain_of<boost::reference_wrapper<T>, void>
+ {
+ typedef typename domain_of<T>::type type;
+ };
+
+ /// INTERNAL ONLY
+ ///
+ template<typename T>
+ struct domain_of<boost::reference_wrapper<T> const, void>
+ {
+ typedef typename domain_of<T>::type type;
+ };
+ }
+}}
+
+#endif

Added: branches/proto/v4/boost/proto/eval.hpp
==============================================================================
--- (empty file)
+++ branches/proto/v4/boost/proto/eval.hpp 2008-04-06 02:19:35 EDT (Sun, 06 Apr 2008)
@@ -0,0 +1,106 @@
+///////////////////////////////////////////////////////////////////////////////
+/// \file eval.hpp
+/// Contains the eval() expression evaluator.
+//
+// Copyright 2008 Eric Niebler. Distributed under the Boost
+// Software License, Version 1.0. (See accompanying file
+// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_PROTO_EVAL_HPP_EAN_03_29_2007
+#define BOOST_PROTO_EVAL_HPP_EAN_03_29_2007
+
+#include <boost/proto/detail/prefix.hpp> // must be first include
+#include <boost/proto/proto_fwd.hpp> // BOOST_PROTO_CALLABLE
+#include <boost/type_traits/remove_reference.hpp>
+#include <boost/proto/detail/suffix.hpp> // must be last include
+
+namespace boost { namespace proto
+{
+
+ namespace result_of
+ {
+ /// \brief A metafunction for calculating the return type
+ /// of \c proto::eval() given a certain \c Expr and \c Context
+ /// types.
+ ///
+ /// \note The types \c Expr and \c Context should not be
+ /// reference types. They may be cv-qualified, but the
+ /// cv-qualification on the \c Context parameter is ignored.
+ template<typename Expr, typename Context>
+ struct eval
+ {
+ typedef typename Context::template eval<Expr>::result_type type;
+ };
+ }
+
+ namespace functor
+ {
+ /// \brief A PolymorphicFunctionObject type for
+ /// evaluating a given Proto expression with a given
+ /// context.
+ struct eval
+ {
+ BOOST_PROTO_CALLABLE()
+
+ template<typename Sig>
+ struct result;
+
+ template<typename This, typename Expr, typename Context>
+ struct result<This(Expr, Context)>
+ {
+ typedef
+ typename proto::result_of::eval<
+ typename remove_reference<Expr>::type
+ , typename remove_reference<Context>::type
+ >::type
+ type;
+ };
+
+ /// \brief Evaluate a given Proto expression with a given
+ /// context.
+ /// \param expr The Proto expression to evaluate
+ /// \param context The context in which the expression should be
+ /// evaluated.
+ /// \return <tt>typename Context::template eval<Expr>()(expr, context)</tt>
+ template<typename Expr, typename Context>
+ typename proto::result_of::eval<Expr, Context>::type
+ operator ()(Expr &expr, Context &context) const
+ {
+ return typename Context::template eval<Expr>()(expr, context);
+ }
+
+ /// \overload
+ ///
+ template<typename Expr, typename Context>
+ typename proto::result_of::eval<Expr, Context>::type
+ operator ()(Expr &expr, Context const &context) const
+ {
+ return typename Context::template eval<Expr>()(expr, context);
+ }
+ };
+ }
+
+ /// \brief Evaluate a given Proto expression with a given
+ /// context.
+ /// \param expr The Proto expression to evaluate
+ /// \param context The context in which the expression should be
+ /// evaluated.
+ /// \return <tt>typename Context::template eval<Expr>()(expr, context)</tt>
+ template<typename Expr, typename Context>
+ typename proto::result_of::eval<Expr, Context>::type
+ eval(Expr &expr, Context &context)
+ {
+ return typename Context::template eval<Expr>()(expr, context);
+ }
+
+ /// \overload
+ ///
+ template<typename Expr, typename Context>
+ typename proto::result_of::eval<Expr, Context>::type
+ eval(Expr &expr, Context const &context)
+ {
+ return typename Context::template eval<Expr>()(expr, context);
+ }
+}}
+
+#endif

Added: branches/proto/v4/boost/proto/expr.hpp
==============================================================================
--- (empty file)
+++ branches/proto/v4/boost/proto/expr.hpp 2008-04-06 02:19:35 EDT (Sun, 06 Apr 2008)
@@ -0,0 +1,459 @@
+#ifndef BOOST_PP_IS_ITERATING
+ ///////////////////////////////////////////////////////////////////////////////
+ /// \file expr.hpp
+ /// Contains definition of expr\<\> class template.
+ //
+ // Copyright 2008 Eric Niebler. Distributed under the Boost
+ // Software License, Version 1.0. (See accompanying file
+ // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+ #ifndef BOOST_PROTO_EXPR_HPP_EAN_04_01_2005
+ #define BOOST_PROTO_EXPR_HPP_EAN_04_01_2005
+
+ #include <boost/proto/detail/prefix.hpp>
+ #include <boost/preprocessor/cat.hpp>
+ #include <boost/preprocessor/arithmetic/dec.hpp>
+ #include <boost/preprocessor/selection/max.hpp>
+ #include <boost/preprocessor/iteration/iterate.hpp>
+ #include <boost/preprocessor/repetition/repeat.hpp>
+ #include <boost/preprocessor/repetition/repeat_from_to.hpp>
+ #include <boost/preprocessor/repetition/enum_trailing.hpp>
+ #include <boost/preprocessor/repetition/enum_params.hpp>
+ #include <boost/preprocessor/repetition/enum_binary_params.hpp>
+ #include <boost/preprocessor/repetition/enum_trailing_params.hpp>
+ #include <boost/preprocessor/repetition/enum_trailing_binary_params.hpp>
+ #include <boost/utility/addressof.hpp>
+ #include <boost/proto/proto_fwd.hpp>
+ #include <boost/proto/ref.hpp>
+ #include <boost/proto/args.hpp>
+ #include <boost/proto/traits.hpp>
+ #include <boost/proto/detail/suffix.hpp>
+
+ #if defined(_MSC_VER) && (_MSC_VER >= 1020)
+ # pragma warning(push)
+ # pragma warning(disable : 4510) // default constructor could not be generated
+ # pragma warning(disable : 4512) // assignment operator could not be generated
+ # pragma warning(disable : 4610) // user defined constructor required
+ #endif
+
+ namespace boost { namespace proto
+ {
+
+ namespace detail
+ {
+ /// INTERNAL ONLY
+ ///
+ #define BOOST_PROTO_CHILD(Z, N, DATA) \
+ typedef typename Args::BOOST_PP_CAT(child, N) BOOST_PP_CAT(proto_child, N); \
+ typedef typename Args::BOOST_PP_CAT(child_ref, N) BOOST_PP_CAT(proto_child_ref, N); \
+ BOOST_PP_CAT(proto_child, N) BOOST_PP_CAT(child, N); \
+ /**/
+
+ /// INTERNAL ONLY
+ ///
+ #define BOOST_PROTO_VOID(Z, N, DATA) \
+ typedef void BOOST_PP_CAT(proto_child, N); \
+ typedef void BOOST_PP_CAT(proto_child_ref, N); \
+ /**/
+
+ /// INTERNAL ONLY
+ ///
+ #define BOOST_PROTO_UNREF_CHILD_TYPE(Z, N, DATA) \
+ typename result_of::unref<typename Args::BOOST_PP_CAT(child, N)>::const_reference \
+ /**/
+
+ /// INTERNAL ONLY
+ ///
+ #define BOOST_PROTO_UNREF_CHILD(Z, N, DATA) \
+ this->BOOST_PP_CAT(child, N) \
+ /**/
+
+ template<typename Tag, typename Arg>
+ struct address_of_hack
+ {
+ typedef address_of_hack type;
+ };
+
+ template<typename Expr>
+ struct address_of_hack<proto::tag::address_of, Expr &>
+ {
+ typedef Expr *type;
+ };
+
+ template<typename X, std::size_t N, typename Y>
+ void checked_copy(X (&x)[N], Y (&y)[N])
+ {
+ for(std::size_t i = 0; i < N; ++i)
+ {
+ y[i] = x[i];
+ }
+ }
+
+ template<typename T, std::size_t N>
+ struct if_is_array
+ {};
+
+ template<typename T, std::size_t N>
+ struct if_is_array<T[N], N>
+ {
+ typedef int type;
+ };
+
+ }
+
+ namespace result_of
+ {
+ /// \brief A helper metafunction for computing the
+ /// return type of \c proto::expr\<\>::operator().
+ template<typename Sig, typename This, typename Domain>
+ struct funop;
+
+ #define BOOST_PP_ITERATION_PARAMS_1 (3, (0, BOOST_PP_DEC(BOOST_PROTO_MAX_FUNCTION_CALL_ARITY), <boost/proto/detail/funop.hpp>))
+ #include BOOST_PP_ITERATE()
+ }
+
+ BOOST_PROTO_BEGIN_ADL_NAMESPACE(exprns_)
+ #define BOOST_PP_ITERATION_PARAMS_1 (3, (0, BOOST_PROTO_MAX_ARITY, <boost/proto/expr.hpp>))
+ #include BOOST_PP_ITERATE()
+ BOOST_PROTO_END_ADL_NAMESPACE(exprns_)
+
+ #undef BOOST_PROTO_CHILD
+ #undef BOOST_PROTO_VOID
+ #undef BOOST_PROTO_UNREF_CHILD_TYPE
+ #undef BOOST_PROTO_UNREF_CHILD
+ }}
+
+ #if defined(_MSC_VER) && (_MSC_VER >= 1020)
+ # pragma warning(pop)
+ #endif
+
+ #endif // BOOST_PROTO_EXPR_HPP_EAN_04_01_2005
+
+#elif BOOST_PP_ITERATION_DEPTH() == 1
+
+ #define ARG_COUNT BOOST_PP_MAX(1, BOOST_PP_ITERATION())
+ #define IS_TERMINAL 0 == BOOST_PP_ITERATION()
+
+ /// \brief Representation of a node in an expression tree.
+ ///
+ /// \c proto::expr\<\> is a node in an expression template tree. It
+ /// is a container for its child sub-trees. It also serves as
+ /// the terminal nodes of the tree.
+ ///
+ /// \c Tag is type that represents the operation encoded by
+ /// this expression. It is typically one of the structs
+ /// in the \c boost::proto::tag namespace, but it doesn't
+ /// have to be. If the \c Tag type is \c boost::proto::tag::terminal
+ /// then this \c expr\<\> type represents a leaf in the
+ /// expression tree.
+ ///
+ /// \c Args is a type list representing the type of the children
+ /// of this expression. It is an instantiation of one
+ /// of \c proto::list1\<\>, \c proto::list2\<\>, etc. The
+ /// child types must all themselves be either \c expr\<\>
+ /// or <tt>proto::expr\<\>&</tt>, unless the \c Tag
+ /// type is \c boost::proto::tag::terminal, in which case
+ /// \c Args must be \c proto::term\<T\>, where \c T can be any
+ /// type.
+ ///
+ /// \c proto::expr\<\> is a valid Fusion random-access sequence, where
+ /// the elements of the sequence are the child expressions.
+ template<typename Tag, typename Args>
+ struct expr<Tag, Args, BOOST_PP_ITERATION() >
+ {
+ typedef Tag proto_tag;
+ typedef mpl::long_<BOOST_PP_ITERATION() > proto_arity;
+ typedef expr proto_base_expr;
+ typedef Args proto_args;
+ typedef default_domain proto_domain;
+ BOOST_PROTO_FUSION_DEFINE_TAG(proto::tag::proto_expr)
+ typedef void proto_is_expr_;
+ typedef expr proto_derived_expr;
+
+ BOOST_PP_REPEAT(ARG_COUNT, BOOST_PROTO_CHILD, ~)
+ BOOST_PP_REPEAT_FROM_TO(ARG_COUNT, BOOST_PROTO_MAX_ARITY, BOOST_PROTO_VOID, ~)
+
+ /// \return *this
+ ///
+ expr const &proto_base() const
+ {
+ return *this;
+ }
+
+ /// \overload
+ ///
+ expr &proto_base()
+ {
+ return *this;
+ }
+
+ /// \return A new \c expr\<\> object initialized with the specified
+ /// arguments.
+ ///
+ template<BOOST_PP_ENUM_PARAMS(ARG_COUNT, typename A)>
+ static expr make(BOOST_PP_ENUM_BINARY_PARAMS(ARG_COUNT, A, const &a))
+ {
+ expr that = {BOOST_PP_ENUM_PARAMS(ARG_COUNT, a)};
+ return that;
+ }
+
+ #if IS_TERMINAL
+ /// \overload
+ ///
+ template<typename A0>
+ static expr make(A0 &a0)
+ {
+ expr that = {a0};
+ return that;
+ }
+
+ /// \overload
+ ///
+ template<typename A0, std::size_t N>
+ static expr make(A0 (&a0)[N], typename detail::if_is_array<proto_child0, N>::type = 0)
+ {
+ expr that;
+ detail::checked_copy(a0, that.child0);
+ return that;
+ }
+
+ /// \overload
+ ///
+ template<typename A0, std::size_t N>
+ static expr make(A0 const (&a0)[N], typename detail::if_is_array<proto_child0, N>::type = 0)
+ {
+ expr that;
+ detail::checked_copy(a0, that.child0);
+ return that;
+ }
+ #endif
+
+ #if 1 == BOOST_PP_ITERATION()
+ /// If \c Tag is \c boost::proto::tag::address_of and \c proto_child0 is
+ /// <tt>T&</tt>, then \c address_of_hack_type_ is <tt>T*</tt>.
+ /// Otherwise, it is some undefined type.
+ typedef typename detail::address_of_hack<Tag, proto_child0>::type address_of_hack_type_;
+
+ /// \return The address of <tt>this->child0</tt> if \c Tag is
+ /// \c boost::proto::tag::address_of. Otherwise, this function will
+ /// fail to compile.
+ ///
+ /// \attention Proto overloads <tt>operator&</tt>, which means that
+ /// proto-ified objects cannot have their addresses taken, unless we use
+ /// the following hack to make \c &x implicitly convertible to \c X*.
+ operator address_of_hack_type_() const
+ {
+ return boost::addressof(this->child0);
+ }
+ #endif
+
+ /// Assignment
+ ///
+ /// \param a The rhs.
+ /// \return A new \c expr\<\> node representing an assignment of \c a to \c *this.
+ template<typename A>
+ proto::expr<
+ proto::tag::assign
+ , list2<expr const &, typename result_of::as_child<A>::type>
+ > const
+ operator =(A &a) const
+ {
+ proto::expr<
+ proto::tag::assign
+ , list2<expr const &, typename result_of::as_child<A>::type>
+ > that = {*this, proto::as_child(a)};
+ return that;
+ }
+
+ /// \overload
+ ///
+ template<typename A>
+ proto::expr<
+ proto::tag::assign
+ , list2<expr const &, typename result_of::as_child<A const>::type>
+ > const
+ operator =(A const &a) const
+ {
+ proto::expr<
+ proto::tag::assign
+ , list2<expr const &, typename result_of::as_child<A const>::type>
+ > that = {*this, proto::as_child(a)};
+ return that;
+ }
+
+ #if IS_TERMINAL
+ /// \overload
+ ///
+ template<typename A>
+ proto::expr<
+ proto::tag::assign
+ , list2<expr &, typename result_of::as_child<A>::type>
+ > const
+ operator =(A &a)
+ {
+ proto::expr<
+ proto::tag::assign
+ , list2<expr &, typename result_of::as_child<A>::type>
+ > that = {*this, proto::as_child(a)};
+ return that;
+ }
+
+ /// \overload
+ ///
+ template<typename A>
+ proto::expr<
+ proto::tag::assign
+ , list2<expr &, typename result_of::as_child<A const>::type>
+ > const
+ operator =(A const &a)
+ {
+ proto::expr<
+ proto::tag::assign
+ , list2<expr &, typename result_of::as_child<A const>::type>
+ > that = {*this, proto::as_child(a)};
+ return that;
+ }
+ #endif
+
+ /// Subscript
+ ///
+ /// \param a The rhs.
+ /// \return A new \c expr\<\> node representing \c *this subscripted with \c a.
+ template<typename A>
+ proto::expr<
+ proto::tag::subscript
+ , list2<expr const &, typename result_of::as_child<A>::type>
+ > const
+ operator [](A &a) const
+ {
+ proto::expr<
+ proto::tag::subscript
+ , list2<expr const &, typename result_of::as_child<A>::type>
+ > that = {*this, proto::as_child(a)};
+ return that;
+ }
+
+ /// \overload
+ ///
+ template<typename A>
+ proto::expr<
+ proto::tag::subscript
+ , list2<expr const &, typename result_of::as_child<A const>::type> > const
+ operator [](A const &a) const
+ {
+ proto::expr<
+ proto::tag::subscript
+ , list2<expr const &, typename result_of::as_child<A const>::type>
+ > that = {*this, proto::as_child(a)};
+ return that;
+ }
+
+ #if IS_TERMINAL
+ /// \overload
+ ///
+ template<typename A>
+ proto::expr<
+ proto::tag::subscript
+ , list2<expr &, typename result_of::as_child<A>::type>
+ > const
+ operator [](A &a)
+ {
+ proto::expr<
+ proto::tag::subscript
+ , list2<expr &, typename result_of::as_child<A>::type>
+ > that = {*this, proto::as_child(a)};
+ return that;
+ }
+
+ /// \overload
+ ///
+ template<typename A>
+ proto::expr<
+ proto::tag::subscript
+ , list2<expr &, typename result_of::as_child<A const>::type>
+ > const
+ operator [](A const &a)
+ {
+ proto::expr<
+ proto::tag::subscript
+ , list2<expr &, typename result_of::as_child<A const>::type>
+ > that = {*this, proto::as_child(a)};
+ return that;
+ }
+ #endif
+
+ /// Encodes the return type of \c expr\<\>::operator(), for use with \c boost::result_of\<\>
+ ///
+ template<typename Sig>
+ struct result
+ {
+ typedef typename result_of::funop<Sig, expr, default_domain>::type type;
+ };
+
+ /// Function call
+ ///
+ /// \return A new \c expr\<\> node representing the function invocation of \c (*this)().
+ proto::expr<proto::tag::function, list1<expr const &> > const
+ operator ()() const
+ {
+ proto::expr<proto::tag::function, list1<expr const &> > that = {*this};
+ return that;
+ }
+
+ #if IS_TERMINAL
+ /// \overload
+ ///
+ proto::expr<proto::tag::function, list1<expr &> > const
+ operator ()()
+ {
+ proto::expr<proto::tag::function, list1<expr &> > that = {*this};
+ return that;
+ }
+ #endif
+
+ #define BOOST_PP_ITERATION_PARAMS_2 (3, (1, BOOST_PP_DEC(BOOST_PROTO_MAX_FUNCTION_CALL_ARITY), <boost/proto/expr.hpp>))
+ #include BOOST_PP_ITERATE()
+ };
+
+ #undef ARG_COUNT
+ #undef IS_TERMINAL
+
+#elif BOOST_PP_ITERATION_DEPTH() == 2
+
+ #define N BOOST_PP_ITERATION()
+
+ /// \overload
+ ///
+ template<BOOST_PP_ENUM_PARAMS(N, typename A)>
+ typename result_of::BOOST_PP_CAT(funop, N)<
+ expr const
+ , default_domain BOOST_PP_ENUM_TRAILING_PARAMS(N, const A)
+ >::type const
+ operator ()(BOOST_PP_ENUM_BINARY_PARAMS(N, A, const &a)) const
+ {
+ return result_of::BOOST_PP_CAT(funop, N)<
+ expr const
+ , default_domain BOOST_PP_ENUM_TRAILING_PARAMS(N, const A)
+ >::call(*this BOOST_PP_ENUM_TRAILING_PARAMS(N, a));
+ }
+
+ #if IS_TERMINAL
+ /// \overload
+ ///
+ template<BOOST_PP_ENUM_PARAMS(N, typename A)>
+ typename result_of::BOOST_PP_CAT(funop, N)<
+ expr
+ , default_domain BOOST_PP_ENUM_TRAILING_PARAMS(N, const A)
+ >::type const
+ operator ()(BOOST_PP_ENUM_BINARY_PARAMS(N, A, const &a))
+ {
+ return result_of::BOOST_PP_CAT(funop, N)<
+ expr
+ , default_domain BOOST_PP_ENUM_TRAILING_PARAMS(N, const A)
+ >::call(*this BOOST_PP_ENUM_TRAILING_PARAMS(N, a));
+ }
+ #endif
+
+ #undef N
+
+#endif

Added: branches/proto/v4/boost/proto/extends.hpp
==============================================================================
--- (empty file)
+++ branches/proto/v4/boost/proto/extends.hpp 2008-04-06 02:19:35 EDT (Sun, 06 Apr 2008)
@@ -0,0 +1,448 @@
+///////////////////////////////////////////////////////////////////////////////
+/// \file extends.hpp
+/// Macros and a base class for defining end-user expression types
+//
+// Copyright 2008 Eric Niebler. Distributed under the Boost
+// Software License, Version 1.0. (See accompanying file
+// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_PROTO_EXTENDS_HPP_EAN_11_1_2006
+#define BOOST_PROTO_EXTENDS_HPP_EAN_11_1_2006
+
+#include <boost/proto/detail/prefix.hpp>
+#include <boost/preprocessor/tuple/elem.hpp>
+#include <boost/preprocessor/control/if.hpp>
+#include <boost/preprocessor/arithmetic/inc.hpp>
+#include <boost/preprocessor/arithmetic/dec.hpp>
+#include <boost/preprocessor/iteration/local.hpp>
+#include <boost/preprocessor/repetition/enum_params.hpp>
+#include <boost/preprocessor/repetition/repeat_from_to.hpp>
+#include <boost/preprocessor/repetition/enum_binary_params.hpp>
+#include <boost/preprocessor/repetition/enum_trailing_params.hpp>
+#include <boost/preprocessor/repetition/enum_trailing_binary_params.hpp>
+#include <boost/utility/result_of.hpp>
+#include <boost/proto/proto_fwd.hpp>
+#include <boost/proto/traits.hpp>
+#include <boost/proto/expr.hpp>
+#include <boost/proto/args.hpp>
+#include <boost/proto/traits.hpp>
+#include <boost/proto/generate.hpp>
+#include <boost/proto/detail/suffix.hpp>
+
+namespace boost { namespace proto
+{
+ /// INTERNAL ONLY
+ ///
+ #define BOOST_PROTO_CONST0
+
+ /// INTERNAL ONLY
+ ///
+ #define BOOST_PROTO_CONST1 const
+
+ /// INTERNAL ONLY
+ ///
+ #define BOOST_PROTO_TEMPLATE_YES_(Z, N) template<BOOST_PP_ENUM_PARAMS_Z(Z, N, typename A)>
+
+ /// INTERNAL ONLY
+ ///
+ #define BOOST_PROTO_TEMPLATE_NO_(Z, N)
+
+ /// INTERNAL ONLY
+ ///
+ #define BOOST_PROTO_DEFINE_FUN_OP_IMPL_(Z, N, DATA, Const) \
+ BOOST_PP_IF(N, BOOST_PROTO_TEMPLATE_YES_, BOOST_PROTO_TEMPLATE_NO_)(Z, N) \
+ typename boost::result_of< \
+ proto_domain( \
+ typename boost::proto::result_of::BOOST_PP_CAT(funop, N)< \
+ proto_derived_expr BOOST_PROTO_CONST ## Const \
+ , proto_domain \
+ BOOST_PP_ENUM_TRAILING_PARAMS_Z(Z, N, const A) \
+ >::type \
+ ) \
+ >::type const \
+ operator ()(BOOST_PP_ENUM_BINARY_PARAMS_Z(Z, N, A, const &a)) BOOST_PROTO_CONST ## Const \
+ { \
+ typedef boost::proto::result_of::BOOST_PP_CAT(funop, N)< \
+ proto_derived_expr BOOST_PROTO_CONST ## Const \
+ , proto_domain \
+ BOOST_PP_ENUM_TRAILING_PARAMS_Z(Z, N, const A) \
+ > funop; \
+ return proto_domain()( \
+ funop::call( \
+ *static_cast<proto_derived_expr BOOST_PROTO_CONST ## Const *>(this) \
+ BOOST_PP_ENUM_TRAILING_PARAMS_Z(Z, N, a) \
+ ) \
+ ); \
+ } \
+ /**/
+
+ /// INTERNAL ONLY
+ ///
+ #define BOOST_PROTO_DEFINE_FUN_OP_CONST(Z, N, DATA) \
+ BOOST_PROTO_DEFINE_FUN_OP_IMPL_(Z, N, DATA, 1)
+
+ /// INTERNAL ONLY
+ ///
+ #define BOOST_PROTO_DEFINE_FUN_OP_NON_CONST(Z, N, DATA) \
+ BOOST_PROTO_DEFINE_FUN_OP_IMPL_(Z, N, DATA, 0)
+
+ /// INTERNAL ONLY
+ ///
+ #define BOOST_PROTO_DEFINE_FUN_OP(Z, N, DATA) \
+ BOOST_PROTO_DEFINE_FUN_OP_CONST(Z, N, DATA) \
+ BOOST_PROTO_DEFINE_FUN_OP_NON_CONST(Z, N, DATA) \
+ /**/
+
+ /// INTERNAL ONLY
+ ///
+ #define BOOST_PROTO_EXTENDS_CHILD(Z, N, DATA) \
+ typedef \
+ typename proto_base_expr::BOOST_PP_CAT(proto_child, N) \
+ BOOST_PP_CAT(proto_child, N); \
+ /**/
+
+ #define BOOST_PROTO_BASIC_EXTENDS(Expr, Derived, Domain) \
+ Expr expr; \
+ \
+ typedef typename Expr::proto_base_expr proto_base_expr; \
+ typedef Domain proto_domain; \
+ typedef Derived proto_derived_expr; \
+ typedef typename proto_base_expr::proto_tag proto_tag; \
+ typedef typename proto_base_expr::proto_args proto_args; \
+ typedef typename proto_base_expr::proto_arity proto_arity; \
+ typedef void proto_is_expr_; \
+ BOOST_PROTO_FUSION_DEFINE_TAG(boost::proto::tag::proto_expr) \
+ BOOST_PP_REPEAT(BOOST_PROTO_MAX_ARITY, BOOST_PROTO_EXTENDS_CHILD, ~) \
+ \
+ static proto_derived_expr const make(Expr const &expr) \
+ { \
+ proto_derived_expr that = {expr}; \
+ return that; \
+ } \
+ \
+ proto_base_expr &proto_base() \
+ { \
+ return this->expr.proto_base(); \
+ } \
+ \
+ proto_base_expr const &proto_base() const \
+ { \
+ return this->expr.proto_base(); \
+ } \
+ /**/
+
+ /// INTERNAL ONLY
+ ///
+ #define BOOST_PROTO_EXTENDS_ASSIGN_IMPL_(Const) \
+ template<typename A> \
+ typename boost::result_of< \
+ proto_domain( \
+ boost::proto::expr< \
+ boost::proto::tag::assign \
+ , boost::proto::list2< \
+ proto_derived_expr BOOST_PROTO_CONST ## Const & \
+ , typename boost::proto::result_of::as_child<A, proto_domain>::type \
+ > \
+ > \
+ ) \
+ >::type const \
+ operator =(A &a) BOOST_PROTO_CONST ## Const \
+ { \
+ typedef boost::proto::expr< \
+ boost::proto::tag::assign \
+ , boost::proto::list2< \
+ proto_derived_expr BOOST_PROTO_CONST ## Const & \
+ , typename boost::proto::result_of::as_child<A, proto_domain>::type \
+ > \
+ > that_type; \
+ that_type that = { \
+ *static_cast<proto_derived_expr BOOST_PROTO_CONST ## Const *>(this) \
+ , boost::proto::as_child<proto_domain>(a) \
+ }; \
+ return proto_domain()(that); \
+ } \
+ \
+ template<typename A> \
+ typename boost::result_of< \
+ proto_domain( \
+ boost::proto::expr< \
+ boost::proto::tag::assign \
+ , boost::proto::list2< \
+ proto_derived_expr BOOST_PROTO_CONST ## Const & \
+ , typename boost::proto::result_of::as_child<A const, proto_domain>::type \
+ > \
+ > \
+ ) \
+ >::type const \
+ operator =(A const &a) BOOST_PROTO_CONST ## Const \
+ { \
+ typedef boost::proto::expr< \
+ boost::proto::tag::assign \
+ , boost::proto::list2< \
+ proto_derived_expr BOOST_PROTO_CONST ## Const & \
+ , typename boost::proto::result_of::as_child<A const, proto_domain>::type \
+ > \
+ > that_type; \
+ that_type that = { \
+ *static_cast<proto_derived_expr BOOST_PROTO_CONST ## Const *>(this) \
+ , boost::proto::as_child<proto_domain>(a) \
+ }; \
+ return proto_domain()(that); \
+ } \
+ /**/
+
+ #define BOOST_PROTO_EXTENDS_ASSIGN_CONST() \
+ BOOST_PROTO_EXTENDS_ASSIGN_IMPL_(1)
+
+ #define BOOST_PROTO_EXTENDS_ASSIGN_NON_CONST() \
+ BOOST_PROTO_EXTENDS_ASSIGN_IMPL_(0)
+
+ #define BOOST_PROTO_EXTENDS_ASSIGN() \
+ BOOST_PROTO_EXTENDS_ASSIGN_CONST() \
+ BOOST_PROTO_EXTENDS_ASSIGN_NON_CONST() \
+ /**/
+
+ /// INTERNAL ONLY
+ ///
+ #define BOOST_PROTO_EXTENDS_SUBSCRIPT_IMPL_(Const) \
+ template<typename A> \
+ typename boost::result_of< \
+ proto_domain( \
+ boost::proto::expr< \
+ boost::proto::tag::subscript \
+ , boost::proto::list2< \
+ proto_derived_expr BOOST_PROTO_CONST ## Const & \
+ , typename boost::proto::result_of::as_child<A, proto_domain>::type \
+ > \
+ > \
+ ) \
+ >::type const \
+ operator [](A &a) BOOST_PROTO_CONST ## Const \
+ { \
+ typedef boost::proto::expr< \
+ boost::proto::tag::subscript \
+ , boost::proto::list2< \
+ proto_derived_expr BOOST_PROTO_CONST ## Const & \
+ , typename boost::proto::result_of::as_child<A, proto_domain>::type \
+ > \
+ > that_type; \
+ that_type that = { \
+ *static_cast<proto_derived_expr BOOST_PROTO_CONST ## Const *>(this) \
+ , boost::proto::as_child<proto_domain>(a) \
+ }; \
+ return proto_domain()(that); \
+ } \
+ \
+ template<typename A> \
+ typename boost::result_of< \
+ proto_domain( \
+ boost::proto::expr< \
+ boost::proto::tag::subscript \
+ , boost::proto::list2< \
+ proto_derived_expr BOOST_PROTO_CONST ## Const & \
+ , typename boost::proto::result_of::as_child<A const, proto_domain>::type \
+ > \
+ > \
+ ) \
+ >::type const \
+ operator [](A const &a) BOOST_PROTO_CONST ## Const \
+ { \
+ typedef boost::proto::expr< \
+ boost::proto::tag::subscript \
+ , boost::proto::list2< \
+ proto_derived_expr BOOST_PROTO_CONST ## Const & \
+ , typename boost::proto::result_of::as_child<A const, proto_domain>::type \
+ > \
+ > that_type; \
+ that_type that = { \
+ *static_cast<proto_derived_expr BOOST_PROTO_CONST ## Const *>(this) \
+ , boost::proto::as_child<proto_domain>(a) \
+ }; \
+ return proto_domain()(that); \
+ } \
+ /**/
+
+ #define BOOST_PROTO_EXTENDS_SUBSCRIPT_CONST() \
+ BOOST_PROTO_EXTENDS_SUBSCRIPT_IMPL_(1)
+
+ #define BOOST_PROTO_EXTENDS_SUBSCRIPT_NON_CONST() \
+ BOOST_PROTO_EXTENDS_SUBSCRIPT_IMPL_(0)
+
+ #define BOOST_PROTO_EXTENDS_SUBSCRIPT() \
+ BOOST_PROTO_EXTENDS_SUBSCRIPT_CONST() \
+ BOOST_PROTO_EXTENDS_SUBSCRIPT_NON_CONST() \
+ /**/
+
+ /// INTERNAL ONLY
+ ///
+ #define BOOST_PROTO_EXTENDS_FUNCTION_() \
+ template<typename Sig> \
+ struct result \
+ { \
+ typedef \
+ typename boost::result_of< \
+ proto_domain( \
+ typename boost::proto::result_of::funop< \
+ Sig \
+ , proto_derived_expr \
+ , proto_domain \
+ >::type \
+ ) \
+ >::type \
+ type; \
+ }; \
+ /**/
+
+ #define BOOST_PROTO_EXTENDS_FUNCTION_CONST() \
+ BOOST_PROTO_EXTENDS_FUNCTION_() \
+ BOOST_PP_REPEAT_FROM_TO( \
+ 0 \
+ , BOOST_PP_DEC(BOOST_PROTO_MAX_FUNCTION_CALL_ARITY) \
+ , BOOST_PROTO_DEFINE_FUN_OP_CONST \
+ , ~ \
+ ) \
+ /**/
+
+ #define BOOST_PROTO_EXTENDS_FUNCTION_NON_CONST() \
+ BOOST_PROTO_EXTENDS_FUNCTION_() \
+ BOOST_PP_REPEAT_FROM_TO( \
+ 0 \
+ , BOOST_PP_DEC(BOOST_PROTO_MAX_FUNCTION_CALL_ARITY) \
+ , BOOST_PROTO_DEFINE_FUN_OP_NON_CONST \
+ , ~ \
+ ) \
+ /**/
+
+ #define BOOST_PROTO_EXTENDS_FUNCTION() \
+ BOOST_PROTO_EXTENDS_FUNCTION_() \
+ BOOST_PP_REPEAT_FROM_TO( \
+ 0 \
+ , BOOST_PP_DEC(BOOST_PROTO_MAX_FUNCTION_CALL_ARITY) \
+ , BOOST_PROTO_DEFINE_FUN_OP \
+ , ~ \
+ ) \
+ /**/
+
+ #define BOOST_PROTO_EXTENDS(Expr, Derived, Domain) \
+ BOOST_PROTO_BASIC_EXTENDS(Expr, Derived, Domain) \
+ BOOST_PROTO_EXTENDS_ASSIGN() \
+ BOOST_PROTO_EXTENDS_SUBSCRIPT() \
+ BOOST_PROTO_EXTENDS_FUNCTION() \
+ /**/
+
+ BOOST_PROTO_BEGIN_ADL_NAMESPACE(exprns_)
+
+ /// \brief Empty type to be used as a dummy template parameter of
+ /// POD expression wrappers. It allows argument-dependent lookup
+ /// to find Proto's operator overloads.
+ ///
+ /// \c proto::is_proto_expr allows argument-dependent lookup
+ /// to find Proto's operator overloads. For example:
+ ///
+ /// \code
+ /// template<typename T, typename Dummy = proto::is_proto_expr>
+ /// struct my_terminal
+ /// {
+ /// BOOST_PROTO_BASIC_EXTENDS(
+ /// typename proto::terminal<T>::type
+ /// , my_terminal<T>
+ /// , default_domain
+ /// )
+ /// };
+ ///
+ /// // ...
+ /// my_terminal<int> _1, _2;
+ /// _1 + _2; // OK, uses proto::operator+
+ /// \endcode
+ ///
+ /// Without the second \c Dummy template parameter, Proto's operator
+ /// overloads would not be considered by name lookup.
+ struct is_proto_expr
+ {};
+
+ /// \brief extends\<\> class template for adding behaviors to a Proto expression template
+ ///
+ template<
+ typename Expr
+ , typename Derived
+ , typename Domain BOOST_PROTO_WHEN_BUILDING_DOCS(= default_domain)
+ , typename Tag BOOST_PROTO_WHEN_BUILDING_DOCS(= typename Expr::proto_tag)
+ >
+ struct extends
+ {
+ extends()
+ : expr()
+ {}
+
+ extends(extends const &that)
+ : expr(that.expr)
+ {}
+
+ extends(Expr const &expr_)
+ : expr(expr_)
+ {}
+
+ BOOST_PROTO_BASIC_EXTENDS(Expr, Derived, Domain)
+ BOOST_PROTO_EXTENDS_ASSIGN_CONST()
+ BOOST_PROTO_EXTENDS_SUBSCRIPT_CONST()
+
+ // Instead of using BOOST_PROTO_EXTENDS_FUNCTION, which uses
+ // nested preprocessor loops, use file iteration here to generate
+ // the operator() overloads, which is more efficient.
+ BOOST_PROTO_EXTENDS_FUNCTION_()
+
+ /// INTERNAL ONLY
+ ///
+ #define BOOST_PP_LOCAL_MACRO(N) \
+ BOOST_PROTO_DEFINE_FUN_OP_CONST(1, N, ~) \
+ /**/
+
+ /// INTERNAL ONLY
+ ///
+ #define BOOST_PP_LOCAL_LIMITS (0, BOOST_PP_DEC(BOOST_PROTO_MAX_FUNCTION_CALL_ARITY))
+ #include BOOST_PP_LOCAL_ITERATE()
+ };
+
+ /// \brief extends\<\> class template for adding behaviors to a Proto expression template
+ ///
+ template<typename Expr, typename Derived, typename Domain>
+ struct extends<Expr, Derived, Domain, tag::terminal>
+ {
+ extends()
+ : expr()
+ {}
+
+ extends(extends const &that)
+ : expr(that.expr)
+ {}
+
+ extends(Expr const &expr_)
+ : expr(expr_)
+ {}
+
+ BOOST_PROTO_BASIC_EXTENDS(Expr, Derived, Domain)
+ BOOST_PROTO_EXTENDS_ASSIGN()
+ BOOST_PROTO_EXTENDS_SUBSCRIPT()
+
+ // Instead of using BOOST_PROTO_EXTENDS_FUNCTION, which uses
+ // nested preprocessor loops, use file iteration here to generate
+ // the operator() overloads, which is more efficient.
+ BOOST_PROTO_EXTENDS_FUNCTION_()
+
+ /// INTERNAL ONLY
+ ///
+ #define BOOST_PP_LOCAL_MACRO(N) \
+ BOOST_PROTO_DEFINE_FUN_OP(1, N, ~) \
+ /**/
+
+ /// INTERNAL ONLY
+ ///
+ #define BOOST_PP_LOCAL_LIMITS (0, BOOST_PP_DEC(BOOST_PROTO_MAX_FUNCTION_CALL_ARITY))
+ #include BOOST_PP_LOCAL_ITERATE()
+ };
+
+ BOOST_PROTO_END_ADL_NAMESPACE(exprns_)
+
+}}
+
+#endif

Added: branches/proto/v4/boost/proto/fusion.hpp
==============================================================================
--- (empty file)
+++ branches/proto/v4/boost/proto/fusion.hpp 2008-04-06 02:19:35 EDT (Sun, 06 Apr 2008)
@@ -0,0 +1,656 @@
+///////////////////////////////////////////////////////////////////////////////
+/// \file fusion.hpp
+/// Make any Proto expression a valid Fusion sequence
+//
+// Copyright 2008 Eric Niebler. Distributed under the Boost
+// Software License, Version 1.0. (See accompanying file
+// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_PROTO_FUSION_HPP_EAN_11_04_2006
+#define BOOST_PROTO_FUSION_HPP_EAN_11_04_2006
+
+#include <boost/proto/detail/prefix.hpp>
+#include <boost/config.hpp>
+#include <boost/version.hpp>
+#include <boost/type_traits/remove_reference.hpp>
+#include <boost/mpl/if.hpp>
+#include <boost/mpl/long.hpp>
+#if BOOST_VERSION >= 103500
+#include <boost/fusion/include/is_view.hpp>
+#include <boost/fusion/include/tag_of_fwd.hpp>
+#include <boost/fusion/include/category_of.hpp>
+#include <boost/fusion/include/iterator_base.hpp>
+#include <boost/fusion/include/intrinsic.hpp>
+#include <boost/fusion/include/pop_front.hpp>
+#include <boost/fusion/include/reverse.hpp>
+#include <boost/fusion/include/single_view.hpp>
+#include <boost/fusion/include/transform_view.hpp>
+#include <boost/fusion/support/ext_/is_segmented.hpp>
+#include <boost/fusion/sequence/intrinsic/ext_/segments.hpp>
+#include <boost/fusion/sequence/intrinsic/ext_/size_s.hpp>
+#include <boost/fusion/view/ext_/segmented_iterator.hpp>
+#else
+#include <boost/spirit/fusion/sequence/is_sequence.hpp>
+#include <boost/spirit/fusion/sequence/begin.hpp>
+#include <boost/spirit/fusion/sequence/end.hpp>
+#include <boost/spirit/fusion/sequence/at.hpp>
+#include <boost/spirit/fusion/sequence/value_at.hpp>
+#include <boost/spirit/fusion/sequence/single_view.hpp>
+#include <boost/spirit/fusion/sequence/transform_view.hpp>
+#include <boost/proto/detail/reverse.hpp>
+#include <boost/proto/detail/pop_front.hpp>
+#endif
+#include <boost/proto/proto_fwd.hpp>
+#include <boost/proto/traits.hpp>
+#include <boost/proto/eval.hpp>
+#include <boost/proto/detail/suffix.hpp>
+
+#if BOOST_MSVC
+#pragma warning(push)
+#pragma warning(disable : 4510) // default constructor could not be generated
+#pragma warning(disable : 4512) // assignment operator could not be generated
+#pragma warning(disable : 4610) // can never be instantiated - user defined constructor required
+#endif
+
+namespace boost { namespace proto
+{
+
+/// INTERNAL ONLY
+///
+#define UNREF(x) typename boost::remove_reference<x>::type
+
+ namespace detail
+ {
+
+ template<typename Expr, long Pos>
+ struct expr_iterator
+ : fusion::iterator_base<expr_iterator<Expr, Pos> >
+ {
+ typedef Expr expr_type;
+ BOOST_STATIC_CONSTANT(long, index = Pos);
+ BOOST_PROTO_FUSION_DEFINE_CATEGORY(fusion::random_access_traversal_tag)
+ BOOST_PROTO_FUSION_DEFINE_TAG(tag::proto_expr_iterator)
+
+ expr_iterator(Expr const &e)
+ : expr(e)
+ {}
+
+ Expr const &expr;
+ };
+
+ template<typename Expr>
+ struct flat_view
+ {
+ typedef Expr expr_type;
+ typedef typename Expr::proto_tag proto_tag;
+ BOOST_PROTO_FUSION_DEFINE_CATEGORY(fusion::forward_traversal_tag)
+ BOOST_PROTO_FUSION_DEFINE_TAG(tag::proto_flat_view)
+
+ explicit flat_view(Expr &expr)
+ : expr_(expr)
+ {}
+
+ Expr &expr_;
+ };
+
+ template<typename Tag>
+ struct as_element
+ {
+ template<typename Sig>
+ struct result;
+
+ template<typename This, typename Expr>
+ struct result<This(Expr)>
+ : mpl::if_<
+ is_same<Tag, UNREF(Expr)::proto_tag>
+ , flat_view<UNREF(Expr) const>
+ , fusion::single_view<UNREF(Expr) const &>
+ >
+ {};
+
+ template<typename Expr>
+ typename result<as_element(Expr const &)>::type
+ operator ()(Expr const &expr) const
+ {
+ return typename result<as_element(Expr const &)>::type(expr);
+ }
+ };
+
+ }
+
+ namespace functor
+ {
+ /// \brief A PolymorphicFunctionObject type that returns a "flattened"
+ /// view of a Proto expression tree.
+ ///
+ /// A PolymorphicFunctionObject type that returns a "flattened"
+ /// view of a Proto expression tree. For a tree with a top-most node
+ /// tag of type \c T, the elements of the flattened sequence are
+ /// determined by recursing into each child node with the same
+ /// tag type and returning those nodes of different type. So for
+ /// instance, the Proto expression tree corresponding to the
+ /// expression <tt>a | b | c</tt> has a flattened view with elements
+ /// [a, b, c], even though the tree is grouped as
+ /// <tt>((a | b) | c)</tt>.
+ struct flatten
+ {
+ BOOST_PROTO_CALLABLE()
+
+ template<typename Sig>
+ struct result;
+
+ template<typename This, typename Expr>
+ struct result<This(Expr)>
+ {
+ typedef proto::detail::flat_view<UNREF(Expr) const> type;
+ };
+
+ template<typename Expr>
+ proto::detail::flat_view<Expr const>
+ operator ()(Expr const &expr) const
+ {
+ return proto::detail::flat_view<Expr const>(expr);
+ }
+ };
+
+ /// \brief A PolymorphicFunctionObject type that invokes the
+ /// \c fusion::pop_front() algorithm on its argument.
+ ///
+ /// A PolymorphicFunctionObject type that invokes the
+ /// \c fusion::pop_front() algorithm on its argument. This is
+ /// useful for defining a CallableTransform like \c pop_front(_)
+ /// which removes the first child from a Proto expression node.
+ /// Such a transform might be used as the first argument to the
+ /// \c proto::fold\<\> transform; that is, fold all but
+ /// the first child.
+ struct pop_front
+ {
+ BOOST_PROTO_CALLABLE()
+
+ template<typename Sig>
+ struct result;
+
+ template<typename This, typename Expr>
+ struct result<This(Expr)>
+ {
+ typedef
+ typename fusion::BOOST_PROTO_FUSION_RESULT_OF::pop_front<UNREF(Expr) const>::type
+ type;
+ };
+
+ template<typename Expr>
+ typename fusion::BOOST_PROTO_FUSION_RESULT_OF::pop_front<Expr const>::type
+ operator ()(Expr const &expr) const
+ {
+ return fusion::pop_front(expr);
+ }
+ };
+
+ /// \brief A PolymorphicFunctionObject type that invokes the
+ /// \c fusion::reverse() algorithm on its argument.
+ ///
+ /// A PolymorphicFunctionObject type that invokes the
+ /// \c fusion::reverse() algorithm on its argument. This is
+ /// useful for defining a CallableTransform like \c reverse(_)
+ /// which reverses the order of the children of a Proto
+ /// expression node.
+ struct reverse
+ {
+ BOOST_PROTO_CALLABLE()
+
+ template<typename Sig>
+ struct result;
+
+ template<typename This, typename Expr>
+ struct result<This(Expr)>
+ {
+ typedef
+ typename fusion::BOOST_PROTO_FUSION_RESULT_OF::reverse<UNREF(Expr) const>::type
+ type;
+ };
+
+ template<typename Expr>
+ typename fusion::BOOST_PROTO_FUSION_RESULT_OF::reverse<Expr const>::type
+ operator ()(Expr const &expr) const
+ {
+ return fusion::reverse(expr);
+ }
+ };
+ }
+
+ /// \brief A function that returns a "flattened"
+ /// view of a Proto expression tree.
+ ///
+ /// For a tree with a top-most node
+ /// tag of type \c T, the elements of the flattened sequence are
+ /// determined by recursing into each child node with the same
+ /// tag type and returning those nodes of different type. So for
+ /// instance, the Proto expression tree corresponding to the
+ /// expression <tt>a | b | c</tt> has a flattened view with elements
+ /// [a, b, c], even though the tree is grouped as
+ /// <tt>((a | b) | c)</tt>.
+ template<typename Expr>
+ proto::detail::flat_view<Expr const>
+ flatten(Expr const &expr)
+ {
+ return proto::detail::flat_view<Expr const>(expr);
+ }
+
+ /// INTERNAL ONLY
+ ///
+ template<>
+ struct is_callable<functor::flatten>
+ : mpl::true_
+ {};
+
+ /// INTERNAL ONLY
+ ///
+ template<>
+ struct is_callable<functor::pop_front>
+ : mpl::true_
+ {};
+
+ /// INTERNAL ONLY
+ ///
+ template<>
+ struct is_callable<functor::reverse>
+ : mpl::true_
+ {};
+
+ /// INTERNAL ONLY
+ ///
+ template<typename Context>
+ struct eval_fun
+ {
+ explicit eval_fun(Context &ctx)
+ : ctx_(ctx)
+ {}
+
+ template<typename Sig>
+ struct result;
+
+ template<typename This, typename Expr>
+ struct result<This(Expr)>
+ {
+ typedef
+ typename proto::result_of::eval<UNREF(Expr), Context>::type
+ type;
+ };
+
+ template<typename Expr>
+ typename proto::result_of::eval<Expr, Context>::type
+ operator ()(Expr &expr) const
+ {
+ return proto::eval(expr, this->ctx_);
+ }
+
+ private:
+ Context &ctx_;
+ };
+}}
+
+// Don't bother emitting all this into the Doxygen-generated
+// reference section. It's enough to say that Proto expressions
+// are valid Fusion sequence without showing all this gunk.
+#ifndef BOOST_PROTO_BUILDING_DOCS
+
+namespace boost { namespace fusion
+{
+ #if BOOST_VERSION < 103500
+ template<typename Tag, typename Args, long Arity>
+ struct is_sequence<proto::expr<Tag, Args, Arity> >
+ : mpl::true_
+ {};
+
+ template<typename Tag, typename Args, long Arity>
+ struct is_sequence<proto::expr<Tag, Args, Arity> const>
+ : mpl::true_
+ {};
+ #endif
+
+ namespace BOOST_PROTO_FUSION_EXTENSION
+ {
+
+ template<typename Tag>
+ struct is_view_impl;
+
+ template<>
+ struct is_view_impl<proto::tag::proto_flat_view>
+ {
+ template<typename Sequence>
+ struct apply
+ : mpl::true_
+ {};
+ };
+
+ template<>
+ struct is_view_impl<proto::tag::proto_expr>
+ {
+ template<typename Sequence>
+ struct apply
+ : mpl::false_
+ {};
+ };
+
+ template<typename Tag>
+ struct value_of_impl;
+
+ template<>
+ struct value_of_impl<proto::tag::proto_expr_iterator>
+ {
+ template<typename Iterator>
+ struct apply
+ {
+ typedef
+ typename proto::result_of::child_c<
+ typename Iterator::expr_type
+ , Iterator::index
+ >::wrapped_type
+ type;
+ };
+ };
+
+ #if BOOST_VERSION < 103500
+ template<typename Tag>
+ struct value_impl;
+
+ template<>
+ struct value_impl<proto::tag::proto_expr_iterator>
+ : value_of_impl<proto::tag::proto_expr_iterator>
+ {};
+ #endif
+
+ template<typename Tag>
+ struct deref_impl;
+
+ template<>
+ struct deref_impl<proto::tag::proto_expr_iterator>
+ {
+ template<typename Iterator>
+ struct apply
+ {
+ typedef
+ typename proto::result_of::child_c<
+ typename Iterator::expr_type const
+ , Iterator::index
+ >::type const &
+ type;
+
+ static type call(Iterator const &iter)
+ {
+ return proto::child_c<Iterator::index>(iter.expr);
+ }
+ };
+ };
+
+ template<typename Tag>
+ struct advance_impl;
+
+ template<>
+ struct advance_impl<proto::tag::proto_expr_iterator>
+ {
+ template<typename Iterator, typename N>
+ struct apply
+ {
+ typedef
+ typename proto::detail::expr_iterator<
+ typename Iterator::expr_type
+ , Iterator::index + N::value
+ >
+ type;
+
+ static type call(Iterator const &iter)
+ {
+ return type(iter.expr);
+ }
+ };
+ };
+
+ template<typename Tag>
+ struct distance_impl;
+
+ template<>
+ struct distance_impl<proto::tag::proto_expr_iterator>
+ {
+ template<typename IteratorFrom, typename IteratorTo>
+ struct apply
+ : mpl::long_<IteratorTo::index - IteratorFrom::index>
+ {};
+ };
+
+ template<typename Tag>
+ struct next_impl;
+
+ template<>
+ struct next_impl<proto::tag::proto_expr_iterator>
+ {
+ template<typename Iterator>
+ struct apply
+ : advance_impl<proto::tag::proto_expr_iterator>::template apply<Iterator, mpl::long_<1> >
+ {};
+ };
+
+ template<typename Tag>
+ struct prior_impl;
+
+ template<>
+ struct prior_impl<proto::tag::proto_expr_iterator>
+ {
+ template<typename Iterator>
+ struct apply
+ : advance_impl<proto::tag::proto_expr_iterator>::template apply<Iterator, mpl::long_<-1> >
+ {};
+ };
+
+ #if BOOST_VERSION >= 103500
+ template<typename Tag>
+ struct category_of_impl;
+
+ template<>
+ struct category_of_impl<proto::tag::proto_expr>
+ {
+ template<typename Sequence>
+ struct apply
+ {
+ typedef random_access_traversal_tag type;
+ };
+ };
+ #endif
+
+ template<typename Tag>
+ struct size_impl;
+
+ template<>
+ struct size_impl<proto::tag::proto_expr>
+ {
+ template<typename Sequence>
+ struct apply
+ : mpl::long_<0 == Sequence::proto_arity::value ? 1 : Sequence::proto_arity::value>
+ {};
+ };
+
+ template<typename Tag>
+ struct begin_impl;
+
+ template<>
+ struct begin_impl<proto::tag::proto_expr>
+ {
+ template<typename Sequence>
+ struct apply
+ {
+ typedef proto::detail::expr_iterator<Sequence, 0> type;
+
+ static type call(Sequence const &seq)
+ {
+ return type(seq);
+ }
+ };
+ };
+
+ template<typename Tag>
+ struct end_impl;
+
+ template<>
+ struct end_impl<proto::tag::proto_expr>
+ {
+ template<typename Sequence>
+ struct apply
+ {
+ typedef
+ proto::detail::expr_iterator<
+ Sequence
+ , 0 == Sequence::proto_arity::value ? 1 : Sequence::proto_arity::value
+ >
+ type;
+
+ static type call(Sequence const &seq)
+ {
+ return type(seq);
+ }
+ };
+ };
+
+ template<typename Tag>
+ struct value_at_impl;
+
+ template<>
+ struct value_at_impl<proto::tag::proto_expr>
+ {
+ template<typename Sequence, typename Index>
+ struct apply
+ {
+ typedef
+ typename proto::result_of::child_c<
+ Sequence
+ , Index::value
+ >::wrapped_type
+ type;
+ };
+ };
+
+ template<typename Tag>
+ struct at_impl;
+
+ template<>
+ struct at_impl<proto::tag::proto_expr>
+ {
+ template<typename Sequence, typename Index>
+ struct apply
+ {
+ typedef
+ typename proto::result_of::child_c<
+ Sequence &
+ , Index::value
+ >::type
+ type;
+
+ static type call(Sequence &seq)
+ {
+ return proto::child_c<Index::value>(seq);
+ }
+ };
+
+ template<typename Sequence, typename Index>
+ struct apply<Sequence const, Index>
+ {
+ typedef
+ typename proto::result_of::child_c<
+ Sequence const &
+ , Index::value
+ >::type
+ type;
+
+ static type call(Sequence const &seq)
+ {
+ return proto::child_c<Index::value>(seq);
+ }
+ };
+ };
+
+ #if BOOST_VERSION >= 103500
+ template<typename Tag>
+ struct is_segmented_impl;
+
+ template<>
+ struct is_segmented_impl<proto::tag::proto_flat_view>
+ {
+ template<typename Iterator>
+ struct apply
+ : mpl::true_
+ {};
+ };
+
+ template<typename Tag>
+ struct segments_impl;
+
+ template<>
+ struct segments_impl<proto::tag::proto_flat_view>
+ {
+ template<typename Sequence>
+ struct apply
+ {
+ typedef typename Sequence::proto_tag proto_tag;
+
+ typedef fusion::transform_view<
+ typename Sequence::expr_type
+ , proto::detail::as_element<proto_tag>
+ > type;
+
+ static type call(Sequence &sequence)
+ {
+ return type(sequence.expr_, proto::detail::as_element<proto_tag>());
+ }
+ };
+ };
+
+ template<>
+ struct category_of_impl<proto::tag::proto_flat_view>
+ {
+ template<typename Sequence>
+ struct apply
+ {
+ typedef forward_traversal_tag type;
+ };
+ };
+
+ template<>
+ struct begin_impl<proto::tag::proto_flat_view>
+ {
+ template<typename Sequence>
+ struct apply
+ : fusion::segmented_begin<Sequence>
+ {};
+ };
+
+ template<>
+ struct end_impl<proto::tag::proto_flat_view>
+ {
+ template<typename Sequence>
+ struct apply
+ : fusion::segmented_end<Sequence>
+ {};
+ };
+
+ template<>
+ struct size_impl<proto::tag::proto_flat_view>
+ {
+ template<typename Sequence>
+ struct apply
+ : fusion::segmented_size<Sequence>
+ {};
+ };
+ #endif
+
+ }
+
+}}
+
+#endif // BOOST_PROTO_BUILDING_DOCS
+
+#undef UNREF
+
+#if BOOST_MSVC
+#pragma warning(pop)
+#endif
+
+#endif

Added: branches/proto/v4/boost/proto/generate.hpp
==============================================================================
--- (empty file)
+++ branches/proto/v4/boost/proto/generate.hpp 2008-04-06 02:19:35 EDT (Sun, 06 Apr 2008)
@@ -0,0 +1,283 @@
+#ifndef BOOST_PP_IS_ITERATING
+ ///////////////////////////////////////////////////////////////////////////////
+ /// \file generate.hpp
+ /// Contains definition of generate\<\> class template, which end users can
+ /// specialize for generating domain-specific expression wrappers.
+ //
+ // Copyright 2008 Eric Niebler. Distributed under the Boost
+ // Software License, Version 1.0. (See accompanying file
+ // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+ #ifndef BOOST_PROTO_GENERATE_HPP_EAN_02_13_2007
+ #define BOOST_PROTO_GENERATE_HPP_EAN_02_13_2007
+
+ #include <boost/proto/detail/prefix.hpp>
+ #include <boost/preprocessor/cat.hpp>
+ #include <boost/preprocessor/iteration/iterate.hpp>
+ #include <boost/preprocessor/repetition/enum.hpp>
+ #include <boost/utility/enable_if.hpp>
+ #include <boost/proto/proto_fwd.hpp>
+ #include <boost/proto/matches.hpp>
+ #include <boost/proto/detail/suffix.hpp>
+
+ namespace boost { namespace proto
+ {
+
+ namespace detail
+ {
+ template<typename Domain, typename Expr>
+ struct generate_if
+ : lazy_enable_if<
+ matches<Expr, typename Domain::proto_grammar>
+ , typename Domain::template result<void(Expr)>
+ >
+ {};
+
+ // Optimization, generate fewer templates...
+ template<typename Expr>
+ struct generate_if<proto::default_domain, Expr>
+ {
+ typedef Expr type;
+ };
+
+ template<typename Expr>
+ struct expr_traits;
+
+ template<typename Tag, typename Args, long N>
+ struct expr_traits<proto::expr<Tag, Args, N> >
+ {
+ typedef Tag tag;
+ typedef Args args;
+ BOOST_STATIC_CONSTANT(long, arity = N);
+ };
+
+ template<typename Expr, long Arity = expr_traits<Expr>::arity>
+ struct by_value_generator_;
+
+ #define BOOST_PROTO_DEFINE_BY_VALUE_TYPE(Z, N, Expr) \
+ typename result_of::unref< \
+ typename expr_traits<Expr>::args::BOOST_PP_CAT(child, N) \
+ >::type \
+ /**/
+
+ #define BOOST_PROTO_DEFINE_BY_VALUE(Z, N, expr) \
+ expr.BOOST_PP_CAT(child, N) \
+ /**/
+
+ template<typename Expr>
+ struct by_value_generator_<Expr, 0>
+ {
+ typedef proto::expr<
+ tag::terminal
+ , term<BOOST_PROTO_DEFINE_BY_VALUE_TYPE(~, 0, Expr) >
+ > type;
+
+ static type const make(Expr const &expr)
+ {
+ type that = {BOOST_PROTO_DEFINE_BY_VALUE(~, 0, expr)};
+ return that;
+ }
+ };
+
+ #define BOOST_PP_ITERATION_PARAMS_1 (3, (1, BOOST_PROTO_MAX_ARITY, <boost/proto/generate.hpp>))
+ #include BOOST_PP_ITERATE()
+
+ #undef BOOST_PROTO_DEFINE_BY_VALUE
+ #undef BOOST_PROTO_DEFINE_BY_VALUE_TYPE
+
+ }
+
+ BOOST_PROTO_BEGIN_ADL_NAMESPACE(generatorns_)
+
+ /// \brief A simple generator that passes an expression
+ /// through unchanged.
+ ///
+ /// Generators are intended for use as the first template parameter
+ /// to the \c domain\<\> class template and control if and how
+ /// expressions within that domain are to be customized.
+ /// The \c default_generator makes no modifications to the expressions
+ /// passed to it.
+ struct default_generator
+ {
+ template<typename Sig>
+ struct result;
+
+ template<typename This, typename Expr>
+ struct result<This(Expr)>
+ {
+ typedef Expr type;
+ };
+
+ /// \param expr A Proto expression
+ /// \return expr
+ template<typename Expr>
+ Expr const &operator ()(Expr const &expr) const
+ {
+ return expr;
+ }
+ };
+
+ /// \brief A generator that wraps expressions passed
+ /// to it in the specified extension wrapper.
+ ///
+ /// Generators are intended for use as the first template parameter
+ /// to the \c domain\<\> class template and control if and how
+ /// expressions within that domain are to be customized.
+ /// \c generator\<\> wraps each expression passed to it in
+ /// the \c Extends\<\> wrapper.
+ template<template<typename> class Extends>
+ struct generator
+ {
+ template<typename Sig>
+ struct result;
+
+ template<typename This, typename Expr>
+ struct result<This(Expr)>
+ {
+ typedef Extends<Expr> type;
+ };
+
+ /// \param expr A Proto expression
+ /// \return Extends<Expr>(expr)
+ template<typename Expr>
+ Extends<Expr> operator ()(Expr const &expr) const
+ {
+ return Extends<Expr>(expr);
+ }
+ };
+
+ /// \brief A generator that wraps expressions passed
+ /// to it in the specified extension wrapper and uses
+ /// aggregate initialization for the wrapper.
+ ///
+ /// Generators are intended for use as the first template parameter
+ /// to the \c domain\<\> class template and control if and how
+ /// expressions within that domain are to be customized.
+ /// \c pod_generator\<\> wraps each expression passed to it in
+ /// the \c Extends\<\> wrapper, and uses aggregate initialzation
+ /// for the wrapped object.
+ template<template<typename> class Extends>
+ struct pod_generator
+ {
+ template<typename Sig>
+ struct result;
+
+ template<typename This, typename Expr>
+ struct result<This(Expr)>
+ {
+ typedef Extends<Expr> type;
+ };
+
+ /// \param expr The expression to wrap
+ /// \return <tt>Extends\<Expr\> that = {expr}; return that;</tt>
+ template<typename Expr>
+ Extends<Expr> operator ()(Expr const &expr) const
+ {
+ Extends<Expr> that = {expr};
+ return that;
+ }
+ };
+
+ /// \brief A generator that replaces child nodes held by
+ /// reference with ones held by value. Use with
+ /// \c compose_generators to forward that result to another
+ /// generator.
+ ///
+ /// Generators are intended for use as the first template parameter
+ /// to the \c domain\<\> class template and control if and how
+ /// expressions within that domain are to be customized.
+ /// \c by_value_generator ensures all child nodes are
+ /// held by value. This generator is typically composed with a
+ /// second generator for further processing, as
+ /// <tt>compose_generators\<by_value_generator, MyGenerator\></tt>.
+ struct by_value_generator
+ {
+ template<typename Sig>
+ struct result;
+
+ template<typename This, typename Expr>
+ struct result<This(Expr)>
+ {
+ typedef
+ typename detail::by_value_generator_<Expr>::type
+ type;
+ };
+
+ /// \param expr The expression to modify.
+ /// \return <tt>deep_copy(expr)</tt>
+ template<typename Expr>
+ typename result<void(Expr)>::type operator ()(Expr const &expr) const
+ {
+ return detail::by_value_generator_<Expr>::make(expr);
+ }
+ };
+
+ /// \brief A composite generator that first applies one
+ /// transform to an expression and then forwards the result
+ /// on to another generator for further transformation.
+ ///
+ /// Generators are intended for use as the first template parameter
+ /// to the \c domain\<\> class template and control if and how
+ /// expressions within that domain are to be customized.
+ /// \c compose_generators\<\> is a composite generator that first
+ /// applies one transform to an expression and then forwards the
+ /// result on to another generator for further transformation.
+ template<typename First, typename Second>
+ struct compose_generators
+ {
+ template<typename Sig>
+ struct result;
+
+ template<typename This, typename Expr>
+ struct result<This(Expr)>
+ {
+ typedef
+ typename Second::template result<
+ typename First::template result<void(Expr)>::type
+ >::type
+ type;
+ };
+
+ /// \param expr The expression to modify.
+ /// \return Second()(First()(expr))
+ template<typename Expr>
+ typename result<void(Expr)>::type operator ()(Expr const &expr) const
+ {
+ return Second()(First()(expr));
+ }
+ };
+
+ BOOST_PROTO_END_ADL_NAMESPACE(generatorns_)
+
+ }}
+
+ #endif // BOOST_PROTO_GENERATE_HPP_EAN_02_13_2007
+
+#else // BOOST_PP_IS_ITERATING
+
+ #define N BOOST_PP_ITERATION()
+
+ template<typename Expr>
+ struct by_value_generator_<Expr, N>
+ {
+ typedef proto::expr<
+ typename expr_traits<Expr>::tag
+ , BOOST_PP_CAT(list, N)<
+ // typename result_of::unref<typename expr_traits<Expr>::args::child0>::type, ...
+ BOOST_PP_ENUM(N, BOOST_PROTO_DEFINE_BY_VALUE_TYPE, Expr)
+ >
+ > type;
+
+ static type const make(Expr const &expr)
+ {
+ type that = {
+ // expr.child0, ...
+ BOOST_PP_ENUM(N, BOOST_PROTO_DEFINE_BY_VALUE, expr)
+ };
+ return that;
+ }
+ };
+
+ #undef N
+
+#endif

Added: branches/proto/v4/boost/proto/literal.hpp
==============================================================================
--- (empty file)
+++ branches/proto/v4/boost/proto/literal.hpp 2008-04-06 02:19:35 EDT (Sun, 06 Apr 2008)
@@ -0,0 +1,109 @@
+///////////////////////////////////////////////////////////////////////////////
+/// \file literal.hpp
+/// The literal\<\> terminal wrapper, and the proto::lit() function for
+/// creating literal\<\> wrappers.
+//
+// Copyright 2008 Eric Niebler. Distributed under the Boost
+// Software License, Version 1.0. (See accompanying file
+// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_PROTO_LITERAL_HPP_EAN_01_03_2007
+#define BOOST_PROTO_LITERAL_HPP_EAN_01_03_2007
+
+#include <boost/proto/detail/prefix.hpp>
+#include <boost/config.hpp>
+#include <boost/proto/proto_fwd.hpp>
+#include <boost/proto/expr.hpp>
+#include <boost/proto/traits.hpp>
+#include <boost/proto/extends.hpp>
+#include <boost/proto/detail/suffix.hpp>
+
+namespace boost { namespace proto
+{
+ namespace utility
+ {
+ /// \brief A simple wrapper for a terminal, provided for
+ /// ease of use.
+ ///
+ /// A simple wrapper for a terminal, provided for
+ /// ease of use. In all cases, <tt>literal\<X\> l(x);</tt>
+ /// is equivalent to <tt>terminal\<X\>::::type l = {x};</tt>.
+ ///
+ /// The \c Domain template parameter defaults to
+ /// \c proto::default_domain.
+ template<
+ typename T
+ , typename Domain BOOST_PROTO_WHEN_BUILDING_DOCS(= default_domain)
+ >
+ struct literal
+ : extends<typename terminal<T>::type, literal<T, Domain>, Domain>
+ {
+ private:
+ typedef typename terminal<T>::type terminal_type;
+ typedef extends<terminal_type, literal<T, Domain>, Domain> base_type;
+
+ public:
+ typedef typename proto::result_of::unref<T>::type value_type;
+ typedef typename proto::result_of::unref<T>::reference reference;
+ typedef typename proto::result_of::unref<T>::const_reference const_reference;
+
+ template<typename U>
+ literal(U &u)
+ : base_type(terminal_type::make(u))
+ {}
+
+ template<typename U>
+ literal(U const &u)
+ : base_type(terminal_type::make(u))
+ {}
+
+ template<typename U>
+ literal(literal<U, Domain> const &u)
+ : base_type(terminal_type::make(u.get()))
+ {}
+
+ using base_type::operator =;
+
+ reference get()
+ {
+ return proto::value(*this);
+ }
+
+ const_reference get() const
+ {
+ return proto::value(*this);
+ }
+ };
+ }
+
+ /// \brief A helper function for creating a \c literal\<\> wrapper.
+ /// \param t The object to wrap.
+ /// \return literal\<T &\>(t)
+ /// \attention The returned value holds the argument by reference.
+ /// \throw nothrow
+ template<typename T>
+ inline literal<T &> const lit(T &t)
+ {
+ return literal<T &>(t);
+ }
+
+ /// \overload
+ ///
+ template<typename T>
+ inline literal<T const &> const lit(T const &t)
+ {
+ #ifdef BOOST_MSVC
+ #pragma warning(push)
+ #pragma warning(disable: 4180) // warning C4180: qualifier applied to function type has no meaning; ignored
+ #endif
+
+ return literal<T const &>(t);
+
+ #ifdef BOOST_MSVC
+ #pragma warning(pop)
+ #endif
+ }
+
+}}
+
+#endif

Added: branches/proto/v4/boost/proto/make_expr.hpp
==============================================================================
--- (empty file)
+++ branches/proto/v4/boost/proto/make_expr.hpp 2008-04-06 02:19:35 EDT (Sun, 06 Apr 2008)
@@ -0,0 +1,1153 @@
+#ifndef BOOST_PP_IS_ITERATING
+ ///////////////////////////////////////////////////////////////////////////////
+ /// \file make_expr.hpp
+ /// Definition of the \c make_expr() and \c unpack_expr() utilities for
+ /// building Proto expression nodes from child nodes or from a Fusion
+ /// sequence of child nodes, respectively.
+ //
+ // Copyright 2008 Eric Niebler. Distributed under the Boost
+ // Software License, Version 1.0. (See accompanying file
+ // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+ #ifndef BOOST_PROTO_MAKE_EXPR_HPP_EAN_04_01_2005
+ #define BOOST_PROTO_MAKE_EXPR_HPP_EAN_04_01_2005
+
+ #include <boost/proto/detail/prefix.hpp>
+ #include <boost/version.hpp>
+ #include <boost/preprocessor/cat.hpp>
+ #include <boost/preprocessor/control/if.hpp>
+ #include <boost/preprocessor/control/expr_if.hpp>
+ #include <boost/preprocessor/arithmetic/inc.hpp>
+ #include <boost/preprocessor/arithmetic/dec.hpp>
+ #include <boost/preprocessor/arithmetic/sub.hpp>
+ #include <boost/preprocessor/punctuation/comma_if.hpp>
+ #include <boost/preprocessor/iteration/iterate.hpp>
+ #include <boost/preprocessor/facilities/intercept.hpp>
+ #include <boost/preprocessor/comparison/greater.hpp>
+ #include <boost/preprocessor/tuple/elem.hpp>
+ #include <boost/preprocessor/tuple/to_list.hpp>
+ #include <boost/preprocessor/logical/and.hpp>
+ #include <boost/preprocessor/repetition/enum.hpp>
+ #include <boost/preprocessor/repetition/enum_params.hpp>
+ #include <boost/preprocessor/repetition/enum_trailing.hpp>
+ #include <boost/preprocessor/repetition/enum_binary_params.hpp>
+ #include <boost/preprocessor/repetition/enum_shifted_params.hpp>
+ #include <boost/preprocessor/repetition/enum_trailing_params.hpp>
+ #include <boost/preprocessor/repetition/enum_shifted_binary_params.hpp>
+ #include <boost/preprocessor/repetition/enum_trailing_binary_params.hpp>
+ #include <boost/preprocessor/repetition/repeat.hpp>
+ #include <boost/preprocessor/repetition/repeat_from_to.hpp>
+ #include <boost/preprocessor/seq/size.hpp>
+ #include <boost/preprocessor/seq/enum.hpp>
+ #include <boost/preprocessor/seq/seq.hpp>
+ #include <boost/preprocessor/seq/to_tuple.hpp>
+ #include <boost/preprocessor/seq/for_each_i.hpp>
+ #include <boost/preprocessor/seq/pop_back.hpp>
+ #include <boost/preprocessor/seq/push_back.hpp>
+ #include <boost/preprocessor/seq/push_front.hpp>
+ #include <boost/preprocessor/list/for_each_i.hpp>
+ #include <boost/ref.hpp>
+ #include <boost/mpl/if.hpp>
+ #include <boost/mpl/assert.hpp>
+ #include <boost/mpl/eval_if.hpp>
+ #include <boost/utility/enable_if.hpp>
+ #include <boost/type_traits/is_same.hpp>
+ #include <boost/type_traits/add_const.hpp>
+ #include <boost/type_traits/add_reference.hpp>
+ #include <boost/type_traits/remove_reference.hpp>
+ #include <boost/proto/proto_fwd.hpp>
+ #include <boost/proto/traits.hpp>
+ #include <boost/proto/domain.hpp>
+ #include <boost/proto/generate.hpp>
+ #if BOOST_VERSION >= 103500
+ # include <boost/fusion/include/at.hpp>
+ # include <boost/fusion/include/value_at.hpp>
+ # include <boost/fusion/include/size.hpp>
+ #else
+ # include <boost/spirit/fusion/sequence/at.hpp>
+ # include <boost/spirit/fusion/sequence/value_at.hpp>
+ # include <boost/spirit/fusion/sequence/size.hpp>
+ #endif
+ #include <boost/proto/detail/suffix.hpp>
+
+ namespace boost
+ {
+ /// INTERNAL ONLY
+ ///
+ namespace fusion
+ {
+ /// INTERNAL ONLY
+ ///
+ template<typename Function>
+ class unfused_generic;
+ }
+ }
+
+ namespace boost { namespace proto
+ {
+ /// INTERNAL ONLY
+ ///
+ #define BOOST_PROTO_AS_CHILD_TYPE(Z, N, DATA) \
+ typename boost::proto::detail::protoify_< \
+ BOOST_PP_CAT(BOOST_PP_TUPLE_ELEM(3, 0, DATA), N) \
+ , BOOST_PP_TUPLE_ELEM(3, 2, DATA) \
+ >::type \
+ /**/
+
+ /// INTERNAL ONLY
+ ///
+ #define BOOST_PROTO_AS_CHILD(Z, N, DATA) \
+ boost::proto::detail::protoify_< \
+ BOOST_PP_CAT(BOOST_PP_TUPLE_ELEM(3, 0, DATA), N) \
+ , BOOST_PP_TUPLE_ELEM(3, 2, DATA) \
+ >::call(BOOST_PP_CAT(BOOST_PP_TUPLE_ELEM(3, 1, DATA), N)) \
+ /**/
+
+ /// INTERNAL ONLY
+ ///
+ # define BOOST_PROTO_AT_TYPE(Z, N, DATA) \
+ typename add_const< \
+ typename fusion::BOOST_PROTO_FUSION_RESULT_OF::value_at_c< \
+ BOOST_PP_TUPLE_ELEM(3, 0, DATA) \
+ , N \
+ >::type \
+ >::type \
+ /**/
+
+ /// INTERNAL ONLY
+ ///
+ # define BOOST_PROTO_AT(Z, N, DATA) \
+ fusion::BOOST_PROTO_FUSION_AT_C(N, BOOST_PP_TUPLE_ELEM(3, 1, DATA)) \
+ /**/
+
+ /// INTERNAL ONLY
+ ///
+ #define BOOST_PROTO_AS_CHILD_AT_TYPE(Z, N, DATA) \
+ typename boost::proto::detail::protoify_< \
+ BOOST_PROTO_AT_TYPE(Z, N, DATA) \
+ , BOOST_PP_TUPLE_ELEM(3, 2, DATA) \
+ >::type \
+ /**/
+
+ /// INTERNAL ONLY
+ ///
+ #define BOOST_PROTO_AS_CHILD_AT(Z, N, DATA) \
+ boost::proto::detail::protoify_< \
+ BOOST_PROTO_AT_TYPE(Z, N, DATA) \
+ , BOOST_PP_TUPLE_ELEM(3, 2, DATA) \
+ >::call(BOOST_PROTO_AT(Z, N, DATA)) \
+ /**/
+
+ /// INTERNAL ONLY
+ ///
+ #define BOOST_PROTO_VARARG_TEMPLATE_AUX_(R, DATA, I, ELEM) \
+ (ELEM BOOST_PP_CAT(BOOST_PP_CAT(X, DATA), BOOST_PP_CAT(_, I))) \
+ /**/
+
+ /// INTERNAL ONLY
+ ///
+ #define BOOST_PROTO_VARARG_TEMPLATE_YES_(R, DATA, I, ELEM) \
+ BOOST_PP_LIST_FOR_EACH_I_R( \
+ R \
+ , BOOST_PROTO_VARARG_TEMPLATE_AUX_ \
+ , I \
+ , BOOST_PP_TUPLE_TO_LIST( \
+ BOOST_PP_DEC(BOOST_PP_SEQ_SIZE(ELEM)) \
+ , BOOST_PP_SEQ_TO_TUPLE(BOOST_PP_SEQ_TAIL(ELEM)) \
+ ) \
+ ) \
+ /**/
+
+ /// INTERNAL ONLY
+ ///
+ #define BOOST_PROTO_VARARG_TEMPLATE_NO_(R, DATA, I, ELEM) \
+ /**/
+
+ /// INTERNAL ONLY
+ ///
+ #define BOOST_PROTO_VARARG_TEMPLATE_(R, DATA, I, ELEM) \
+ BOOST_PP_IF( \
+ BOOST_PP_DEC(BOOST_PP_SEQ_SIZE(ELEM)) \
+ , BOOST_PROTO_VARARG_TEMPLATE_YES_ \
+ , BOOST_PROTO_VARARG_TEMPLATE_NO_ \
+ )(R, DATA, I, ELEM) \
+ /**/
+
+ /// INTERNAL ONLY
+ ///
+ #define BOOST_PROTO_VARARG_TYPE_AUX_(R, DATA, I, ELEM) \
+ (BOOST_PP_CAT(BOOST_PP_CAT(X, DATA), BOOST_PP_CAT(_, I))) \
+ /**/
+
+ /// INTERNAL ONLY
+ ///
+ #define BOOST_PROTO_TEMPLATE_PARAMS_YES_(R, DATA, I, ELEM) \
+ < \
+ BOOST_PP_SEQ_ENUM( \
+ BOOST_PP_LIST_FOR_EACH_I_R( \
+ R \
+ , BOOST_PROTO_VARARG_TYPE_AUX_ \
+ , I \
+ , BOOST_PP_TUPLE_TO_LIST( \
+ BOOST_PP_DEC(BOOST_PP_SEQ_SIZE(ELEM)) \
+ , BOOST_PP_SEQ_TO_TUPLE(BOOST_PP_SEQ_TAIL(ELEM)) \
+ ) \
+ ) \
+ ) \
+ > \
+ /**/
+
+ /// INTERNAL ONLY
+ ///
+ #define BOOST_PROTO_TEMPLATE_PARAMS_NO_(R, DATA, I, ELEM) \
+ /**/
+
+ /// INTERNAL ONLY
+ ///
+ #define BOOST_PROTO_VARARG_TYPE_(R, DATA, I, ELEM) \
+ BOOST_PP_COMMA_IF(I) \
+ BOOST_PP_SEQ_HEAD(ELEM) \
+ BOOST_PP_IF( \
+ BOOST_PP_DEC(BOOST_PP_SEQ_SIZE(ELEM)) \
+ , BOOST_PROTO_TEMPLATE_PARAMS_YES_ \
+ , BOOST_PROTO_TEMPLATE_PARAMS_NO_ \
+ )(R, DATA, I, ELEM) BOOST_PP_EXPR_IF(BOOST_PP_GREATER(I, 1), const) \
+ /**/
+
+ /// INTERNAL ONLY
+ ///
+ #define BOOST_PROTO_VARARG_AS_EXPR_(R, DATA, I, ELEM) \
+ BOOST_PP_EXPR_IF( \
+ BOOST_PP_GREATER(I, 1) \
+ , (( \
+ BOOST_PP_SEQ_HEAD(ELEM) \
+ BOOST_PP_IF( \
+ BOOST_PP_DEC(BOOST_PP_SEQ_SIZE(ELEM)) \
+ , BOOST_PROTO_TEMPLATE_PARAMS_YES_ \
+ , BOOST_PROTO_TEMPLATE_PARAMS_NO_ \
+ )(R, DATA, I, ELEM)() \
+ )) \
+ ) \
+ /**/
+
+ /// INTERNAL ONLY
+ ///
+ #define BOOST_PROTO_VARARG_AS_CHILD_(Z, N, DATA) \
+ (BOOST_PP_CAT(DATA, N)) \
+ /**/
+
+ /// INTERNAL ONLY
+ ///
+ #define BOOST_PROTO_SEQ_PUSH_FRONT(SEQ, ELEM) \
+ BOOST_PP_SEQ_POP_BACK(BOOST_PP_SEQ_PUSH_FRONT(BOOST_PP_SEQ_PUSH_BACK(SEQ, _dummy_), ELEM)) \
+ /**/
+
+ /// INTERNAL ONLY
+ ///
+ #define BOOST_PROTO_VARARG_AS_PARAM_(Z, N, DATA) \
+ (BOOST_PP_CAT(DATA, N)) \
+ /**/
+
+ /// INTERNAL ONLY
+ ///
+ #define BOOST_PROTO_VARARG_FUN_(Z, N, DATA) \
+ template< \
+ BOOST_PP_SEQ_ENUM( \
+ BOOST_PP_SEQ_FOR_EACH_I( \
+ BOOST_PROTO_VARARG_TEMPLATE_, ~ \
+ , BOOST_PP_SEQ_PUSH_FRONT( \
+ BOOST_PROTO_SEQ_PUSH_FRONT( \
+ BOOST_PP_TUPLE_ELEM(4, 2, DATA) \
+ , (BOOST_PP_TUPLE_ELEM(4, 3, DATA)) \
+ ) \
+ , BOOST_PP_TUPLE_ELEM(4, 1, DATA) \
+ ) \
+ ) \
+ BOOST_PP_REPEAT_ ## Z(N, BOOST_PROTO_VARARG_AS_PARAM_, typename A) \
+ ) \
+ > \
+ typename boost::proto::result_of::make_expr< \
+ BOOST_PP_SEQ_FOR_EACH_I( \
+ BOOST_PROTO_VARARG_TYPE_, ~ \
+ , BOOST_PP_SEQ_PUSH_FRONT( \
+ BOOST_PROTO_SEQ_PUSH_FRONT( \
+ BOOST_PP_TUPLE_ELEM(4, 2, DATA) \
+ , (BOOST_PP_TUPLE_ELEM(4, 3, DATA)) \
+ ) \
+ , BOOST_PP_TUPLE_ELEM(4, 1, DATA) \
+ ) \
+ ) \
+ BOOST_PP_ENUM_TRAILING_BINARY_PARAMS_Z(Z, N, A, const & BOOST_PP_INTERCEPT) \
+ >::type const \
+ BOOST_PP_TUPLE_ELEM(4, 0, DATA)(BOOST_PP_ENUM_BINARY_PARAMS_Z(Z, N, A, const &a)) \
+ { \
+ return boost::proto::detail::make_expr_< \
+ BOOST_PP_SEQ_FOR_EACH_I( \
+ BOOST_PROTO_VARARG_TYPE_, ~ \
+ , BOOST_PP_SEQ_PUSH_FRONT( \
+ BOOST_PROTO_SEQ_PUSH_FRONT( \
+ BOOST_PP_TUPLE_ELEM(4, 2, DATA) \
+ , (BOOST_PP_TUPLE_ELEM(4, 3, DATA)) \
+ ) \
+ , BOOST_PP_TUPLE_ELEM(4, 1, DATA) \
+ ) \
+ ) \
+ BOOST_PP_ENUM_TRAILING_BINARY_PARAMS_Z(Z, N, A, const & BOOST_PP_INTERCEPT) \
+ >::call( \
+ BOOST_PP_SEQ_ENUM( \
+ BOOST_PP_SEQ_FOR_EACH_I( \
+ BOOST_PROTO_VARARG_AS_EXPR_, ~ \
+ , BOOST_PP_SEQ_PUSH_FRONT( \
+ BOOST_PROTO_SEQ_PUSH_FRONT( \
+ BOOST_PP_TUPLE_ELEM(4, 2, DATA) \
+ , (BOOST_PP_TUPLE_ELEM(4, 3, DATA)) \
+ ) \
+ , BOOST_PP_TUPLE_ELEM(4, 1, DATA) \
+ ) \
+ ) \
+ BOOST_PP_REPEAT_ ## Z(N, BOOST_PROTO_VARARG_AS_CHILD_, a) \
+ ) \
+ ); \
+ } \
+ /**/
+
+ /// \code
+ /// BOOST_PROTO_DEFINE_FUNCTION_TEMPLATE(
+ /// 1
+ /// , construct
+ /// , boost::proto::default_domain
+ /// , (boost::proto::tag::function)
+ /// , ((op::construct)(typename)(int))
+ /// )
+ /// \endcode
+ #define BOOST_PROTO_DEFINE_FUNCTION_TEMPLATE(ARGCOUNT, NAME, DOMAIN, TAG, BOUNDARGS) \
+ BOOST_PP_REPEAT_FROM_TO( \
+ ARGCOUNT \
+ , BOOST_PP_INC(ARGCOUNT) \
+ , BOOST_PROTO_VARARG_FUN_ \
+ , (NAME, TAG, BOUNDARGS, DOMAIN) \
+ )\
+ /**/
+
+ /// \code
+ /// BOOST_PROTO_DEFINE_VARARG_FUNCTION_TEMPLATE(
+ /// construct
+ /// , boost::proto::default_domain
+ /// , (boost::proto::tag::function)
+ /// , ((op::construct)(typename)(int))
+ /// )
+ /// \endcode
+ #define BOOST_PROTO_DEFINE_VARARG_FUNCTION_TEMPLATE(NAME, DOMAIN, TAG, BOUNDARGS) \
+ BOOST_PP_REPEAT( \
+ BOOST_PP_SUB(BOOST_PP_INC(BOOST_PROTO_MAX_ARITY), BOOST_PP_SEQ_SIZE(BOUNDARGS)) \
+ , BOOST_PROTO_VARARG_FUN_ \
+ , (NAME, TAG, BOUNDARGS, DOMAIN) \
+ ) \
+ /**/
+
+ namespace detail
+ {
+ template<typename T, typename Domain>
+ struct protoify_
+ {
+ typedef
+ typename boost::unwrap_reference<T>::type
+ unref_type;
+
+ typedef
+ typename mpl::eval_if<
+ boost::is_reference_wrapper<T>
+ , proto::result_of::as_child<unref_type, Domain>
+ , proto::result_of::as_expr<unref_type, Domain>
+ >::type
+ type;
+
+ static type call(T &t)
+ {
+ return typename mpl::if_<
+ is_reference_wrapper<T>
+ , functor::as_child<Domain>
+ , functor::as_expr<Domain>
+ >::type()(static_cast<unref_type &>(t));
+ }
+ };
+
+ template<typename T, typename Domain>
+ struct protoify_<T &, Domain>
+ {
+ typedef
+ typename boost::unwrap_reference<T>::type
+ unref_type;
+
+ typedef
+ typename proto::result_of::as_child<unref_type, Domain>::type
+ type;
+
+ static type call(T &t)
+ {
+ return functor::as_child<Domain>()(static_cast<unref_type &>(t));
+ }
+ };
+
+ template<
+ int Index
+ BOOST_PP_ENUM_TRAILING_BINARY_PARAMS(
+ BOOST_PROTO_MAX_ARITY
+ , typename D
+ , = void BOOST_PP_INTERCEPT
+ )
+ >
+ struct select_nth
+ {
+ BOOST_MPL_ASSERT_MSG((false), PROTO_DOMAIN_MISMATCH, (select_nth));
+ typedef default_domain type;
+ };
+
+ template<typename Void = void>
+ struct deduce_domain0
+ {
+ typedef default_domain type;
+ };
+
+ template<int I>
+ struct sized
+ {
+ char buffer[I];
+ };
+
+ template<typename T>
+ struct nondeduced_domain
+ {
+ typedef nondeduced_domain type;
+ nondeduced_domain(T);
+ nondeduced_domain(default_domain);
+ };
+
+ template<>
+ struct nondeduced_domain<default_domain>
+ {
+ typedef nondeduced_domain type;
+ nondeduced_domain(default_domain);
+ };
+
+ template<typename Tag, typename Domain, typename Sequence, std::size_t Size>
+ struct unpack_expr_
+ {};
+
+ template<typename Domain, typename Sequence>
+ struct unpack_expr_<tag::terminal, Domain, Sequence, 1u>
+ {
+ typedef
+ typename add_const<
+ typename fusion::BOOST_PROTO_FUSION_RESULT_OF::value_at_c<
+ Sequence
+ , 0
+ >::type
+ >::type
+ terminal_type;
+
+ typedef
+ typename proto::detail::protoify_<
+ terminal_type
+ , Domain
+ >::type
+ type;
+
+ static type const call(Sequence const &sequence)
+ {
+ return proto::detail::protoify_<terminal_type, Domain>::call(fusion::BOOST_PROTO_FUSION_AT_C(0, sequence));
+ }
+ };
+
+ template<typename Sequence>
+ struct unpack_expr_<tag::terminal, deduce_domain, Sequence, 1u>
+ : unpack_expr_<tag::terminal, default_domain, Sequence, 1u>
+ {};
+
+ template<
+ typename Tag
+ , typename Domain
+ BOOST_PP_ENUM_TRAILING_BINARY_PARAMS(
+ BOOST_PROTO_MAX_ARITY
+ , typename A
+ , = void BOOST_PP_INTERCEPT
+ )
+ , typename _ = void
+ >
+ struct make_expr_
+ {};
+
+ template<typename Domain, typename A>
+ struct make_expr_<tag::terminal, Domain, A
+ BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PROTO_MAX_ARITY, void BOOST_PP_INTERCEPT)>
+ {
+ typedef typename proto::detail::protoify_<A, Domain>::type type;
+
+ static type const call(typename add_reference<A>::type a)
+ {
+ return proto::detail::protoify_<A, Domain>::call(a);
+ }
+ };
+
+ template<typename A>
+ struct make_expr_<tag::terminal, deduce_domain, A
+ BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PROTO_MAX_ARITY, void BOOST_PP_INTERCEPT)>
+ : make_expr_<tag::terminal, default_domain, A>
+ {};
+
+ #define BOOST_PP_ITERATION_PARAMS_1 \
+ (4, (1, BOOST_PROTO_MAX_ARITY, <boost/proto/make_expr.hpp>, 1)) \
+ /**/
+
+ #include BOOST_PP_ITERATE()
+ }
+
+ namespace result_of
+ {
+ /// \brief Metafunction that computes the return type of the
+ /// \c make_expr() function, with a domain deduced from the
+ /// domains of the children.
+ ///
+ /// Use the <tt>result_of::make_expr\<\></tt> metafunction to
+ /// compute the return type of the \c make_expr() function.
+ ///
+ /// In this specialization, the domain is deduced from the
+ /// domains of the child types. (If
+ /// <tt>is_domain\<A0\>::::value</tt> is \c true, then another
+ /// specialization is selected.)
+ template<
+ typename Tag
+ , typename A0
+ , BOOST_PP_ENUM_SHIFTED_BINARY_PARAMS(
+ BOOST_PROTO_MAX_ARITY
+ , typename A
+ , BOOST_PROTO_WHEN_BUILDING_DOCS(= void) BOOST_PP_INTERCEPT
+ )
+ , typename Void1 BOOST_PROTO_WHEN_BUILDING_DOCS(= void)
+ , typename Void2 BOOST_PROTO_WHEN_BUILDING_DOCS(= void)
+ >
+ struct make_expr
+ {
+ /// Same as <tt>result_of::make_expr\<Tag, D, A0, ... AN\>::::type</tt>
+ /// where \c D is the deduced domain, which is calculated as follows:
+ ///
+ /// For each \c x in <tt>[0,N)</tt> (proceeding in order beginning with
+ /// <tt>x=0</tt>), if <tt>domain_of\<Ax\>::::type</tt> is not
+ /// \c default_domain, then \c D is <tt>domain_of\<Ax\>::::type</tt>.
+ /// Otherwise, \c D is \c default_domain.
+ typedef
+ typename detail::make_expr_<
+ Tag
+ , deduce_domain
+ BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PROTO_MAX_ARITY, A)
+ >::type
+ type;
+ };
+
+ /// \brief Metafunction that computes the return type of the
+ /// \c make_expr() function, within the specified domain.
+ ///
+ /// Use the <tt>result_of::make_expr\<\></tt> metafunction to compute
+ /// the return type of the \c make_expr() function.
+ template<
+ typename Tag
+ , typename Domain
+ BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PROTO_MAX_ARITY, typename A)
+ >
+ struct make_expr<
+ Tag
+ , Domain
+ BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PROTO_MAX_ARITY, A)
+ , typename Domain::proto_is_domain_
+ >
+ {
+ /// If \c Tag is <tt>tag::terminal</tt>, then \c type is a
+ /// typedef for <tt>boost::result_of\<Domain(expr\<tag::terminal,
+ /// term\<A0\> \>)\>::::type</tt>.
+ ///
+ /// Otherwise, \c type is a typedef for <tt>boost::result_of\<Domain(expr\<Tag,
+ /// listN\< as_child\<A0\>::::type, ... as_child\<AN\>::::type\>)
+ /// \>::::type</tt>, where \c N is the number of non-void template
+ /// arguments, and <tt>as_child\<A\>::::type</tt> is evaluated as
+ /// follows:
+ ///
+ /// \li If <tt>is_expr\<A\>::::value</tt> is \c true, then the
+ /// child type is \c A.
+ /// \li If \c A is <tt>B &</tt> or <tt>cv boost::reference_wrapper\<B\></tt>,
+ /// and <tt>is_expr\<B\>::::value</tt> is \c true, then the
+ /// child type is <tt>B &</tt>.
+ /// \li If <tt>is_expr\<A\>::::value</tt> is \c false, then the
+ /// child type is <tt>boost::result_of\<Domain(expr\<tag::terminal, term\<A\> \>
+ /// )\>::::type</tt>.
+ /// \li If \c A is <tt>B &</tt> or <tt>cv boost::reference_wrapper\<B\></tt>,
+ /// and <tt>is_expr\<B\>::::value</tt> is \c false, then the
+ /// child type is <tt>boost::result_of\<Domain(expr\<tag::terminal, term\<B &\> \>
+ /// )\>::::type</tt>.
+ typedef
+ typename detail::make_expr_<
+ Tag
+ , Domain
+ BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PROTO_MAX_ARITY, A)
+ >::type
+ type;
+ };
+
+ /// \brief Metafunction that computes the return type of the
+ /// \c unpack_expr() function, with a domain deduced from the
+ /// domains of the children.
+ ///
+ /// Use the <tt>result_of::unpack_expr\<\></tt> metafunction to
+ /// compute the return type of the \c unpack_expr() function.
+ ///
+ /// \c Sequence is a Fusion Random Access Sequence.
+ ///
+ /// In this specialization, the domain is deduced from the
+ /// domains of the child types. (If
+ /// <tt>is_domain\<Sequence>::::value</tt> is \c true, then another
+ /// specialization is selected.)
+ template<
+ typename Tag
+ , typename Sequence
+ , typename Void1 BOOST_PROTO_WHEN_BUILDING_DOCS(= void)
+ , typename Void2 BOOST_PROTO_WHEN_BUILDING_DOCS(= void)
+ >
+ struct unpack_expr
+ {
+ /// Same as <tt>result_of::make_expr\<Tag,
+ /// fusion::value_at\<Sequence, 0\>::::type, ...
+ /// fusion::value_at\<Sequence, N-1\>::::type\>::::type</tt>,
+ /// where \c N is the size of \c Sequence.
+ typedef
+ typename detail::unpack_expr_<
+ Tag
+ , deduce_domain
+ , Sequence
+ , fusion::BOOST_PROTO_FUSION_RESULT_OF::size<Sequence>::type::value
+ >::type
+ type;
+ };
+
+ /// \brief Metafunction that computes the return type of the
+ /// \c unpack_expr() function, within the specified domain.
+ ///
+ /// Use the <tt>result_of::make_expr\<\></tt> metafunction to compute
+ /// the return type of the \c make_expr() function.
+ template<typename Tag, typename Domain, typename Sequence>
+ struct unpack_expr<Tag, Domain, Sequence, typename Domain::proto_is_domain_>
+ {
+ /// Same as <tt>result_of::make_expr\<Tag, Domain,
+ /// fusion::value_at\<Sequence, 0\>::::type, ...
+ /// fusion::value_at\<Sequence, N-1\>::::type\>::::type</tt>,
+ /// where \c N is the size of \c Sequence.
+ typedef
+ typename detail::unpack_expr_<
+ Tag
+ , Domain
+ , Sequence
+ , fusion::BOOST_PROTO_FUSION_RESULT_OF::size<Sequence>::type::value
+ >::type
+ type;
+ };
+ }
+
+ namespace functor
+ {
+ /// \brief A callable function object equivalent to the
+ /// \c proto::make_expr() function.
+ ///
+ /// In all cases, <tt>functor::make_expr\<Tag, Domain\>()(a0, ... aN)</tt>
+ /// is equivalent to <tt>proto::make_expr\<Tag, Domain\>(a0, ... aN)</tt>.
+ ///
+ /// <tt>functor::make_expr\<Tag\>()(a0, ... aN)</tt>
+ /// is equivalent to <tt>proto::make_expr\<Tag\>(a0, ... aN)</tt>.
+ template<typename Tag, typename Domain BOOST_PROTO_WHEN_BUILDING_DOCS(= deduce_domain)>
+ struct make_expr
+ {
+ BOOST_PROTO_CALLABLE()
+
+ template<typename Sig>
+ struct result;
+
+ template<typename This, typename A0>
+ struct result<This(A0)>
+ {
+ typedef
+ typename result_of::make_expr<
+ Tag
+ , Domain
+ , A0
+ >::type
+ type;
+ };
+
+ /// Construct an expression node with tag type \c Tag
+ /// and in the domain \c Domain.
+ ///
+ /// \return <tt>proto::make_expr\<Tag, Domain\>(a0,...aN)</tt>
+ template<typename A0>
+ typename result_of::make_expr<
+ Tag
+ , Domain
+ , A0 const
+ >::type const
+ operator ()(A0 const &a0) const
+ {
+ return proto::detail::make_expr_<
+ Tag
+ , Domain
+ , A0 const
+ >::call(a0);
+ }
+
+ // Additional overloads generated by the preprocessor ...
+
+ #define BOOST_PP_ITERATION_PARAMS_1 \
+ (4, (2, BOOST_PROTO_MAX_ARITY, <boost/proto/make_expr.hpp>, 2)) \
+ /**/
+
+ #include BOOST_PP_ITERATE()
+ };
+
+ /// \brief A callable function object equivalent to the
+ /// \c proto::unpack_expr() function.
+ ///
+ /// In all cases, <tt>functor::unpack_expr\<Tag, Domain\>()(seq)</tt>
+ /// is equivalent to <tt>proto::unpack_expr\<Tag, Domain\>(seq)</tt>.
+ ///
+ /// <tt>functor::unpack_expr\<Tag\>()(seq)</tt>
+ /// is equivalent to <tt>proto::unpack_expr\<Tag\>(seq)</tt>.
+ template<typename Tag, typename Domain BOOST_PROTO_WHEN_BUILDING_DOCS(= deduce_domain)>
+ struct unpack_expr
+ {
+ BOOST_PROTO_CALLABLE()
+
+ template<typename Sig>
+ struct result
+ {};
+
+ template<typename This, typename Sequence>
+ struct result<This(Sequence)>
+ {
+ typedef
+ typename result_of::unpack_expr<
+ Tag
+ , Domain
+ , typename remove_reference<Sequence>::type
+ >::type
+ type;
+ };
+
+ /// Construct an expression node with tag type \c Tag
+ /// and in the domain \c Domain.
+ ///
+ /// \param sequence A Fusion Random Access Sequence
+ /// \return <tt>proto::unpack_expr\<Tag, Domain\>(sequence)</tt>
+ template<typename Sequence>
+ typename result_of::unpack_expr<Tag, Domain, Sequence const>::type const
+ operator ()(Sequence const &sequence) const
+ {
+ return proto::detail::unpack_expr_<
+ Tag
+ , Domain
+ , Sequence const
+ , fusion::BOOST_PROTO_FUSION_RESULT_OF::size<Sequence>::type::value
+ >::call(sequence);
+ }
+ };
+
+ /// INTERNAL ONLY
+ ///
+ template<typename Tag, typename Domain>
+ struct unfused_expr_fun
+ {
+ BOOST_PROTO_CALLABLE()
+
+ template<typename Sig>
+ struct result;
+
+ template<typename This, typename Sequence>
+ struct result<This(Sequence)>
+ {
+ typedef
+ typename result_of::unpack_expr<
+ Tag
+ , Domain
+ , typename remove_reference<Sequence>::type
+ >::type
+ type;
+ };
+
+ template<typename Sequence>
+ typename proto::result_of::unpack_expr<Tag, Domain, Sequence const>::type const
+ operator ()(Sequence const &sequence) const
+ {
+ return proto::detail::unpack_expr_<
+ Tag
+ , Domain
+ , Sequence const
+ , fusion::BOOST_PROTO_FUSION_RESULT_OF::size<Sequence>::type::value
+ >::call(sequence);
+ }
+ };
+
+ /// INTERNAL ONLY
+ ///
+ template<typename Tag, typename Domain>
+ struct unfused_expr
+ : fusion::unfused_generic<unfused_expr_fun<Tag, Domain> >
+ {
+ BOOST_PROTO_CALLABLE()
+ };
+
+ } // namespace functor
+
+ /// \brief Construct an expression of the requested tag type
+ /// with a domain and with the specified arguments as children.
+ ///
+ /// This function template may be invoked either with or without
+ /// specifying a \c Domain argument. If no domain is specified,
+ /// the domain is deduced by examining in order the domains of
+ /// the given arguments and taking the first that is not
+ /// \c default_domain, if any such domain exists, or
+ /// \c default_domain otherwise.
+ ///
+ /// Let \c wrap_(x) be defined such that:
+ /// \li If \c x is a <tt>boost::reference_wrapper\<\></tt>,
+ /// \c wrap_(x) is equivalent to <tt>as_child\<Domain\>(x.get())</tt>.
+ /// \li Otherwise, \c wrap_(x) is equivalent to
+ /// <tt>as_expr\<Domain\>(x)</tt>.
+ ///
+ /// Let <tt>make_\<Tag\>(b0,...bN)</tt> be defined as
+ /// <tt>expr\<Tag, listN\<B0,...BN\> \>::::make(b0,...bN)</tt>
+ /// where \c Bx is the type of \c bx.
+ ///
+ /// \return <tt>Domain()(make_\<Tag\>(wrap_(a0),...wrap_(aN)))</tt>.
+ template<typename Tag, typename A0>
+ typename lazy_disable_if<
+ is_domain<A0>
+ , result_of::make_expr<
+ Tag
+ , A0 const
+ >
+ >::type const
+ make_expr(A0 const &a0)
+ {
+ return proto::detail::make_expr_<
+ Tag
+ , deduce_domain
+ , A0 const
+ >::call(a0);
+ }
+
+ /// \overload
+ ///
+ template<typename Tag, typename Domain, typename B0>
+ typename result_of::make_expr<
+ Tag
+ , Domain
+ , B0 const
+ >::type const
+ make_expr(B0 const &b0)
+ {
+ return proto::detail::make_expr_<
+ Tag
+ , Domain
+ , B0 const
+ >::call(b0);
+ }
+
+ // Additional overloads generated by the preprocessor...
+
+ #define BOOST_PP_ITERATION_PARAMS_1 \
+ (4, (2, BOOST_PROTO_MAX_ARITY, <boost/proto/make_expr.hpp>, 3)) \
+ /**/
+
+ #include BOOST_PP_ITERATE()
+
+ /// \brief Construct an expression of the requested tag type
+ /// with a domain and with childres from the specified Fusion
+ /// Random Access Sequence.
+ ///
+ /// This function template may be invoked either with or without
+ /// specifying a \c Domain argument. If no domain is specified,
+ /// the domain is deduced by examining in order the domains of the
+ /// elements of \c sequence and taking the first that is not
+ /// \c default_domain, if any such domain exists, or
+ /// \c default_domain otherwise.
+ ///
+ /// Let <tt>wrap_\<N\>(s)</tt>, where \c s has type \c S, be defined
+ /// such that:
+ /// \li If <tt>fusion::value_at\<S,N\>::::type</tt> is a reference,
+ /// <tt>wrap_\<N\>(s)</tt> is equivalent to
+ /// <tt>as_child\<Domain\>(fusion::at_c\<N\>(s))</tt>.
+ /// \li Otherwise, <tt>wrap_\<N\>(s)</tt> is equivalent to
+ /// <tt>as_expr\<Domain\>(fusion::at_c\<N\>(s))</tt>.
+ ///
+ /// Let <tt>make_\<Tag\>(b0,...bN)</tt> be defined as
+ /// <tt>expr\<Tag, listN\<B0,...BN\> \>::::make(b0,...bN)</tt>
+ /// where \c Bx is the type of \c bx.
+ ///
+ /// \param sequence a Fusion Random Access Sequence.
+ /// \return <tt>Domain()(make_\<Tag\>(wrap_\<0\>(s),...wrap_\<N-1\>(S)))</tt>,
+ /// where N is the size of \c Sequence.
+ template<typename Tag, typename Sequence>
+ typename lazy_disable_if<
+ is_domain<Sequence>
+ , result_of::unpack_expr<Tag, Sequence const>
+ >::type const
+ unpack_expr(Sequence const &sequence)
+ {
+ return proto::detail::unpack_expr_<
+ Tag
+ , deduce_domain
+ , Sequence const
+ , fusion::BOOST_PROTO_FUSION_RESULT_OF::size<Sequence>::type::value
+ >::call(sequence);
+ }
+
+ /// \overload
+ ///
+ template<typename Tag, typename Domain, typename Sequence2>
+ typename result_of::unpack_expr<Tag, Domain, Sequence2 const>::type const
+ unpack_expr(Sequence2 const &sequence2)
+ {
+ return proto::detail::unpack_expr_<
+ Tag
+ , Domain
+ , Sequence2 const
+ , fusion::BOOST_PROTO_FUSION_RESULT_OF::size<Sequence2>::type::value
+ >::call(sequence2);
+ }
+
+ /// INTERNAL ONLY
+ ///
+ template<typename Tag, typename Domain>
+ struct is_callable<functor::make_expr<Tag, Domain> >
+ : mpl::true_
+ {};
+
+ /// INTERNAL ONLY
+ ///
+ template<typename Tag, typename Domain>
+ struct is_callable<functor::unpack_expr<Tag, Domain> >
+ : mpl::true_
+ {};
+
+ /// INTERNAL ONLY
+ ///
+ template<typename Tag, typename Domain>
+ struct is_callable<functor::unfused_expr<Tag, Domain> >
+ : mpl::true_
+ {};
+
+ }}
+
+ #undef BOOST_PROTO_AT
+ #undef BOOST_PROTO_AT_TYPE
+ #undef BOOST_PROTO_AS_CHILD_AT
+ #undef BOOST_PROTO_AS_CHILD_AT_TYPE
+
+ #endif // BOOST_PROTO_MAKE_EXPR_HPP_EAN_04_01_2005
+
+#elif BOOST_PP_ITERATION_FLAGS() == 1
+
+ #define N BOOST_PP_ITERATION()
+ #define M BOOST_PP_SUB(BOOST_PROTO_MAX_ARITY, N)
+
+ template<BOOST_PP_ENUM_PARAMS(BOOST_PROTO_MAX_ARITY, typename T)>
+ struct select_nth<BOOST_PP_DEC(N), BOOST_PP_ENUM_PARAMS(BOOST_PROTO_MAX_ARITY, T)>
+ {
+ typedef BOOST_PP_CAT(T, BOOST_PP_DEC(N)) type;
+ };
+
+ // Use function overloading as an efficient mechanism for
+ // calculating the domain shared by a bunch of proto expressions
+ // (or non-expressions, assumed to be in the default_domain).
+ // The domain of a set of domains S is deduced as follows:
+ // - If S contains only default_domain, the deduced domain is
+ // default_domain.
+ // - If S contains only X and default_domain, the deduced domain
+ // is X.
+ // - If S contains different domains X and Y, neither of which is
+ // default_domain, it is an error.
+ template<BOOST_PP_ENUM_PARAMS(N, typename A)>
+ struct BOOST_PP_CAT(deduce_domain, N)
+ {
+ #if BOOST_WORKAROUND(BOOST_MSVC, == 1310)
+ // The function overloading trick doesn't work on MSVC-7.1, so
+ // do it the hard (expensive) way.
+ typedef
+ typename mpl::eval_if_c<
+ is_same<typename domain_of<A0>::type, default_domain>::value
+ , BOOST_PP_CAT(deduce_domain, BOOST_PP_DEC(N))<BOOST_PP_ENUM_SHIFTED_PARAMS(N, A)>
+ , domain_of<A0>
+ >::type
+ type;
+ #else
+ static sized<BOOST_PP_INC(BOOST_PROTO_MAX_ARITY)> deducer(
+ BOOST_PP_ENUM_PARAMS(N, dont_care BOOST_PP_INTERCEPT)
+ );
+ #define M0(Z, X, DATA) \
+ typedef typename domain_of<BOOST_PP_CAT(A, X)>::type BOOST_PP_CAT(D, X); \
+ static BOOST_PP_CAT(D, X) &BOOST_PP_CAT(d, X); \
+ template<typename T> \
+ static sized<BOOST_PP_INC(X)> deducer( \
+ BOOST_PP_ENUM_PARAMS_Z(Z, X, default_domain BOOST_PP_INTERCEPT) \
+ BOOST_PP_COMMA_IF(X) T \
+ BOOST_PP_ENUM_TRAILING_PARAMS_Z( \
+ Z \
+ , BOOST_PP_DEC(BOOST_PP_SUB(N, X)) \
+ , typename nondeduced_domain<T>::type BOOST_PP_INTERCEPT \
+ ) \
+ );
+ BOOST_PP_REPEAT(N, M0, ~)
+ #undef M0
+ BOOST_STATIC_CONSTANT(int, value = sizeof(deducer(BOOST_PP_ENUM_PARAMS(N, d))) - 1);
+ typedef typename select_nth<value, BOOST_PP_ENUM_PARAMS(N, D)>::type type;
+ #endif
+ };
+
+ template<typename Tag, typename Domain BOOST_PP_ENUM_TRAILING_PARAMS(N, typename A)>
+ struct make_expr_<Tag, Domain BOOST_PP_ENUM_TRAILING_PARAMS(N, A)
+ BOOST_PP_ENUM_TRAILING_PARAMS(M, void BOOST_PP_INTERCEPT), void>
+ {
+ typedef proto::expr<
+ Tag
+ , BOOST_PP_CAT(list, N)<BOOST_PP_ENUM(N, BOOST_PROTO_AS_CHILD_TYPE, (A, ~, Domain)) >
+ > expr_type;
+
+ typedef typename Domain::template result<void(expr_type)>::type type;
+
+ static type const call(BOOST_PP_ENUM_BINARY_PARAMS(N, typename add_reference<A, >::type a))
+ {
+ expr_type that = {
+ BOOST_PP_ENUM(N, BOOST_PROTO_AS_CHILD, (A, a, Domain))
+ };
+ return Domain()(that);
+ }
+ };
+
+ template<typename Tag BOOST_PP_ENUM_TRAILING_PARAMS(N, typename A)>
+ struct make_expr_<Tag, deduce_domain BOOST_PP_ENUM_TRAILING_PARAMS(N, A)
+ BOOST_PP_ENUM_TRAILING_PARAMS(M, void BOOST_PP_INTERCEPT), void>
+ : make_expr_<
+ Tag
+ , typename BOOST_PP_CAT(deduce_domain, N)<BOOST_PP_ENUM_PARAMS(N, A)>::type
+ BOOST_PP_ENUM_TRAILING_PARAMS(N, A)
+ >
+ {};
+
+ template<typename Tag, typename Domain, typename Sequence>
+ struct unpack_expr_<Tag, Domain, Sequence, N>
+ {
+ typedef proto::expr<
+ Tag
+ , BOOST_PP_CAT(list, N)<
+ BOOST_PP_ENUM(N, BOOST_PROTO_AS_CHILD_AT_TYPE, (Sequence const, ~, Domain))
+ >
+ > expr_type;
+
+ typedef typename Domain::template result<void(expr_type)>::type type;
+
+ static type const call(Sequence const &sequence)
+ {
+ expr_type that = {
+ BOOST_PP_ENUM(N, BOOST_PROTO_AS_CHILD_AT, (Sequence const, sequence, Domain))
+ };
+ return Domain()(that);
+ }
+ };
+
+ template<typename Tag, typename Sequence>
+ struct unpack_expr_<Tag, deduce_domain, Sequence, N>
+ : unpack_expr_<
+ Tag
+ , typename BOOST_PP_CAT(deduce_domain, N)<
+ BOOST_PP_ENUM(N, BOOST_PROTO_AT_TYPE, (Sequence const, ~, ~))
+ >::type
+ , Sequence
+ , N
+ >
+ {};
+
+ #undef N
+ #undef M
+
+#elif BOOST_PP_ITERATION_FLAGS() == 2
+
+ #define N BOOST_PP_ITERATION()
+
+ template<typename This BOOST_PP_ENUM_TRAILING_PARAMS(N, typename A)>
+ struct result<This(BOOST_PP_ENUM_PARAMS(N, A))>
+ {
+ typedef
+ typename result_of::make_expr<
+ Tag
+ , Domain
+ BOOST_PP_ENUM_TRAILING_PARAMS(N, A)
+ >::type
+ type;
+ };
+
+ /// \overload
+ ///
+ template<BOOST_PP_ENUM_PARAMS(N, typename A)>
+ typename result_of::make_expr<
+ Tag
+ , Domain
+ BOOST_PP_ENUM_TRAILING_PARAMS(N, const A)
+ >::type const
+ operator ()(BOOST_PP_ENUM_BINARY_PARAMS(N, const A, &a)) const
+ {
+ return proto::detail::make_expr_<
+ Tag
+ , Domain
+ BOOST_PP_ENUM_TRAILING_PARAMS(N, const A)
+ >::call(BOOST_PP_ENUM_PARAMS(N, a));
+ }
+
+ #undef N
+
+#elif BOOST_PP_ITERATION_FLAGS() == 3
+
+ #define N BOOST_PP_ITERATION()
+
+ /// \overload
+ ///
+ template<typename Tag BOOST_PP_ENUM_TRAILING_PARAMS(N, typename A)>
+ typename lazy_disable_if<
+ is_domain<A0>
+ , result_of::make_expr<
+ Tag
+ BOOST_PP_ENUM_TRAILING_PARAMS(N, const A)
+ >
+ >::type const
+ make_expr(BOOST_PP_ENUM_BINARY_PARAMS(N, const A, &a))
+ {
+ return proto::detail::make_expr_<
+ Tag
+ , deduce_domain
+ BOOST_PP_ENUM_TRAILING_PARAMS(N, const A)
+ >::call(BOOST_PP_ENUM_PARAMS(N, a));
+ }
+
+ /// \overload
+ ///
+ template<typename Tag, typename Domain BOOST_PP_ENUM_TRAILING_PARAMS(N, typename B)>
+ typename result_of::make_expr<
+ Tag
+ , Domain
+ BOOST_PP_ENUM_TRAILING_PARAMS(N, const B)
+ >::type const
+ make_expr(BOOST_PP_ENUM_BINARY_PARAMS(N, const B, &b))
+ {
+ return proto::detail::make_expr_<
+ Tag
+ , Domain
+ BOOST_PP_ENUM_TRAILING_PARAMS(N, const B)
+ >::call(BOOST_PP_ENUM_PARAMS(N, b));
+ }
+
+ #undef N
+
+#endif // BOOST_PP_IS_ITERATING

Added: branches/proto/v4/boost/proto/matches.hpp
==============================================================================
--- (empty file)
+++ branches/proto/v4/boost/proto/matches.hpp 2008-04-06 02:19:35 EDT (Sun, 06 Apr 2008)
@@ -0,0 +1,985 @@
+#ifndef BOOST_PP_IS_ITERATING
+ ///////////////////////////////////////////////////////////////////////////////
+ /// \file matches.hpp
+ /// Contains definition of matches\<\> metafunction for determining if
+ /// a given expression matches a given pattern.
+ //
+ // Copyright 2008 Eric Niebler. Distributed under the Boost
+ // Software License, Version 1.0. (See accompanying file
+ // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+ #ifndef BOOST_PROTO_MATCHES_HPP_EAN_11_03_2006
+ #define BOOST_PROTO_MATCHES_HPP_EAN_11_03_2006
+
+ #include <boost/proto/detail/prefix.hpp> // must be first include
+ #include <boost/detail/workaround.hpp>
+ #include <boost/preprocessor/cat.hpp>
+ #include <boost/preprocessor/arithmetic/dec.hpp>
+ #include <boost/preprocessor/arithmetic/sub.hpp>
+ #include <boost/preprocessor/repetition/enum.hpp>
+ #include <boost/preprocessor/iteration/iterate.hpp>
+ #include <boost/preprocessor/facilities/intercept.hpp>
+ #include <boost/preprocessor/punctuation/comma_if.hpp>
+ #include <boost/preprocessor/repetition/enum_params.hpp>
+ #include <boost/preprocessor/repetition/enum_shifted.hpp>
+ #include <boost/preprocessor/repetition/enum_shifted_params.hpp>
+ #include <boost/preprocessor/repetition/enum_trailing_params.hpp>
+ #include <boost/preprocessor/repetition/enum_params_with_a_default.hpp>
+ #include <boost/config.hpp>
+ #include <boost/mpl/logical.hpp>
+ #include <boost/mpl/eval_if.hpp>
+ #include <boost/mpl/aux_/template_arity.hpp>
+ #include <boost/mpl/aux_/lambda_arity_param.hpp>
+ #include <boost/utility/enable_if.hpp>
+ #if BOOST_WORKAROUND(BOOST_MSVC, == 1310)
+ #include <boost/type_traits/is_array.hpp>
+ #endif
+ #include <boost/type_traits/is_convertible.hpp>
+ #include <boost/type_traits/is_reference.hpp>
+ #include <boost/type_traits/is_pointer.hpp>
+ #include <boost/proto/proto_fwd.hpp>
+ #include <boost/proto/traits.hpp>
+ #include <boost/proto/transform/when.hpp>
+ #include <boost/proto/transform/impl.hpp>
+ #include <boost/proto/detail/suffix.hpp> // must be last include
+
+ // Some compilers (like GCC) need extra help figuring out a template's arity.
+ // I use MPL's BOOST_MPL_AUX_LAMBDA_ARITY_PARAM() macro to disambiguate, which
+ // which is controlled by the BOOST_MPL_LIMIT_METAFUNCTION_ARITY macro. If
+ // You define BOOST_PROTO_MAX_ARITY to be greater than
+ // BOOST_MPL_LIMIT_METAFUNCTION_ARITY on these compilers, things don't work.
+ // You must define BOOST_MPL_LIMIT_METAFUNCTION_ARITY to be greater.
+ #ifdef BOOST_MPL_CFG_EXTENDED_TEMPLATE_PARAMETERS_MATCHING
+ # if BOOST_PROTO_MAX_ARITY > BOOST_MPL_LIMIT_METAFUNCTION_ARITY
+ # error BOOST_MPL_LIMIT_METAFUNCTION_ARITY must be at least as large as BOOST_PROTO_MAX_ARITY
+ # endif
+ #endif
+
+ #if defined(_MSC_VER) && (_MSC_VER >= 1020)
+ # pragma warning(push)
+ # pragma warning(disable:4305) // 'specialization' : truncation from 'const int' to 'bool'
+ #endif
+
+ namespace boost { namespace proto
+ {
+
+ namespace detail
+ {
+ template<typename Expr, typename Grammar>
+ struct matches_;
+
+ // and_ and or_ implementation
+ template<bool B, typename Expr, typename G0>
+ struct or1
+ : mpl::bool_<B>
+ {
+ typedef G0 which;
+ };
+
+ template<bool B>
+ struct and1
+ : mpl::bool_<B>
+ {};
+
+ template<bool B, typename Pred>
+ struct and2;
+
+ template<typename And>
+ struct last;
+
+ template<typename T, typename U>
+ struct array_matches
+ : mpl::false_
+ {};
+
+ template<typename T, std::size_t M>
+ struct array_matches<T[M], T *>
+ : mpl::true_
+ {};
+
+ template<typename T, std::size_t M>
+ struct array_matches<T[M], T const *>
+ : mpl::true_
+ {};
+
+ template<typename T, std::size_t M>
+ struct array_matches<T[M], T[proto::N]>
+ : mpl::true_
+ {};
+
+ template<typename T, typename U
+ BOOST_MPL_AUX_LAMBDA_ARITY_PARAM(long Arity = mpl::aux::template_arity<U>::value)
+ >
+ struct lambda_matches
+ : mpl::false_
+ {};
+
+ template<typename T>
+ struct lambda_matches<T, proto::_ BOOST_MPL_AUX_LAMBDA_ARITY_PARAM(-1)>
+ : mpl::true_
+ {};
+
+ template<typename T>
+ struct lambda_matches<T, T BOOST_MPL_AUX_LAMBDA_ARITY_PARAM(-1)>
+ : mpl::true_
+ {};
+
+ template<typename T, std::size_t M, typename U>
+ struct lambda_matches<T[M], U BOOST_MPL_AUX_LAMBDA_ARITY_PARAM(-1)>
+ : array_matches<T[M], U>
+ {};
+
+ template<typename T, std::size_t M>
+ struct lambda_matches<T[M], T[M] BOOST_MPL_AUX_LAMBDA_ARITY_PARAM(-1)>
+ : mpl::true_
+ {};
+
+ template<template<typename> class T, typename Expr0, typename Grammar0>
+ struct lambda_matches<T<Expr0>, T<Grammar0> BOOST_MPL_AUX_LAMBDA_ARITY_PARAM(1) >
+ : lambda_matches<Expr0, Grammar0>
+ {};
+
+ // vararg_matches_impl
+ template<typename Args1, typename Back, long From, long To>
+ struct vararg_matches_impl;
+
+ // vararg_matches
+ template<typename Args1, typename Args2, typename Back, bool Can, bool Zero, typename Void = void>
+ struct vararg_matches
+ : mpl::false_
+ {};
+
+ template<typename Args1, typename Args2, typename Back>
+ struct vararg_matches<Args1, Args2, Back, true, true, typename Back::proto_is_vararg_>
+ : matches_<proto::expr<ignore, Args1, Args1::arity>, proto::expr<ignore, Args2, Args1::arity> >
+ {};
+
+ template<typename Args1, typename Args2, typename Back>
+ struct vararg_matches<Args1, Args2, Back, true, false, typename Back::proto_is_vararg_>
+ : and2<
+ matches_<proto::expr<ignore, Args1, Args2::arity>, proto::expr<ignore, Args2, Args2::arity> >::value
+ , vararg_matches_impl<Args1, typename Back::proto_base_expr, Args2::arity + 1, Args1::arity>
+ >
+ {};
+
+ // How terminal_matches<> handles references and cv-qualifiers.
+ // The cv and ref matter *only* if the grammar has a top-level ref.
+ //
+ // Expr | Grammar | Matches?
+ // -------------------------------------
+ // T T yes
+ // T & T yes
+ // T const & T yes
+ // T T & no
+ // T & T & yes
+ // T const & T & no
+ // T T const & no
+ // T & T const & no
+ // T const & T const & yes
+
+ template<typename T, typename U>
+ struct is_cv_ref_compatible
+ : mpl::true_
+ {};
+
+ template<typename T, typename U>
+ struct is_cv_ref_compatible<T, U &>
+ : mpl::false_
+ {};
+
+ template<typename T, typename U>
+ struct is_cv_ref_compatible<T &, U &>
+ : mpl::bool_<is_const<T>::value == is_const<U>::value>
+ {};
+
+ #if BOOST_WORKAROUND(BOOST_MSVC, == 1310)
+ // MSVC-7.1 has lots of problems with array types that have been
+ // deduced. Partially specializing terminal_matches<> on array types
+ // doesn't seem to work.
+ template<
+ typename T
+ , typename U
+ , bool B = is_array<BOOST_PROTO_UNCVREF(T)>::value
+ >
+ struct terminal_array_matches
+ : mpl::false_
+ {};
+
+ template<typename T, typename U, std::size_t M>
+ struct terminal_array_matches<T, U(&)[M], true>
+ : is_convertible<T, U(&)[M]>
+ {};
+
+ template<typename T, typename U>
+ struct terminal_array_matches<T, U(&)[proto::N], true>
+ : is_convertible<T, U *>
+ {};
+
+ template<typename T, typename U>
+ struct terminal_array_matches<T, U *, true>
+ : is_convertible<T, U *>
+ {};
+
+ // terminal_matches
+ template<typename T, typename U>
+ struct terminal_matches
+ : mpl::or_<
+ mpl::and_<
+ is_cv_ref_compatible<T, U>
+ , lambda_matches<
+ BOOST_PROTO_UNCVREF(T)
+ , BOOST_PROTO_UNCVREF(U)
+ >
+ >
+ , terminal_array_matches<T, U>
+ >
+ {};
+ #else
+ // terminal_matches
+ template<typename T, typename U>
+ struct terminal_matches
+ : mpl::and_<
+ is_cv_ref_compatible<T, U>
+ , lambda_matches<
+ BOOST_PROTO_UNCVREF(T)
+ , BOOST_PROTO_UNCVREF(U)
+ >
+ >
+ {};
+
+ template<typename T, std::size_t M>
+ struct terminal_matches<T(&)[M], T(&)[proto::N]>
+ : mpl::true_
+ {};
+
+ template<typename T, std::size_t M>
+ struct terminal_matches<T(&)[M], T *>
+ : mpl::true_
+ {};
+
+ // Avoid ambiguity errors on MSVC
+ #if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1500))
+ template<typename T, std::size_t M>
+ struct terminal_matches<T const (&)[M], T const[M]>
+ : mpl::true_
+ {};
+ #endif
+ #endif
+
+ template<typename T>
+ struct terminal_matches<T, T>
+ : mpl::true_
+ {};
+
+ template<typename T>
+ struct terminal_matches<T &, T>
+ : mpl::true_
+ {};
+
+ template<typename T>
+ struct terminal_matches<T const &, T>
+ : mpl::true_
+ {};
+
+ template<typename T>
+ struct terminal_matches<T, proto::_>
+ : mpl::true_
+ {};
+
+ template<typename T>
+ struct terminal_matches<T, exact<T> >
+ : mpl::true_
+ {};
+
+ template<typename T, typename U>
+ struct terminal_matches<T, proto::convertible_to<U> >
+ : is_convertible<T, U>
+ {};
+
+ // matches_
+ template<typename Expr, typename Grammar>
+ struct matches_
+ : mpl::false_
+ {};
+
+ template<typename Expr>
+ struct matches_< Expr, proto::_ >
+ : mpl::true_
+ {};
+
+ template<typename Tag, typename Args1, long N1, typename Args2, long N2>
+ struct matches_< proto::expr<Tag, Args1, N1>, proto::expr<Tag, Args2, N2> >
+ : vararg_matches< Args1, Args2, typename Args2::back_, (N1+2 > N2), (N2 > N1) >
+ {};
+
+ template<typename Tag, typename Args1, long N1, typename Args2, long N2>
+ struct matches_< proto::expr<Tag, Args1, N1>, proto::expr<proto::_, Args2, N2> >
+ : vararg_matches< Args1, Args2, typename Args2::back_, (N1+2 > N2), (N2 > N1) >
+ {};
+
+ template<typename Args1, typename Args2, long N2>
+ struct matches_< proto::expr<tag::terminal, Args1, 0>, proto::expr<proto::_, Args2, N2> >
+ : mpl::false_
+ {};
+
+ template<typename Tag, typename Args1, typename Args2>
+ struct matches_< proto::expr<Tag, Args1, 1>, proto::expr<Tag, Args2, 1> >
+ : matches_<typename Args1::child_ref0::proto_base_expr, typename Args2::child0::proto_base_expr>
+ {};
+
+ template<typename Tag, typename Args1, typename Args2>
+ struct matches_< proto::expr<Tag, Args1, 1>, proto::expr<proto::_, Args2, 1> >
+ : matches_<typename Args1::child_ref0::proto_base_expr, typename Args2::child0::proto_base_expr>
+ {};
+
+ template<typename Args1, typename Args2>
+ struct matches_< proto::expr<tag::terminal, Args1, 0>, proto::expr<tag::terminal, Args2, 0> >
+ : terminal_matches<typename Args1::child0, typename Args2::child0>
+ {};
+
+ #define BOOST_PROTO_MATCHES_N_FUN(Z, N, DATA) \
+ matches_< \
+ typename Args1::BOOST_PP_CAT(child_ref, N)::proto_base_expr \
+ , typename Args2::BOOST_PP_CAT(child, N)::proto_base_expr \
+ >
+
+ #define BOOST_PROTO_DEFINE_MATCHES(Z, N, DATA) \
+ matches_< \
+ typename Expr::proto_base_expr \
+ , typename BOOST_PP_CAT(G, N)::proto_base_expr \
+ >
+
+ #define BOOST_PROTO_DEFINE_LAMBDA_MATCHES(Z, N, DATA) \
+ lambda_matches< \
+ BOOST_PP_CAT(Expr, N) \
+ , BOOST_PP_CAT(Grammar, N) \
+ >
+
+ #if BOOST_PROTO_MAX_LOGICAL_ARITY > BOOST_PROTO_MAX_ARITY
+ #define BOOST_PP_ITERATION_PARAMS_1 (4, (2, BOOST_PROTO_MAX_LOGICAL_ARITY, <boost/proto/matches.hpp>, 1))
+ #else
+ #define BOOST_PP_ITERATION_PARAMS_1 (4, (2, BOOST_PROTO_MAX_ARITY, <boost/proto/matches.hpp>, 1))
+ #endif
+ #include BOOST_PP_ITERATE()
+
+ #define BOOST_PP_ITERATION_PARAMS_1 (4, (2, BOOST_PROTO_MAX_ARITY, <boost/proto/matches.hpp>, 2))
+ #include BOOST_PP_ITERATE()
+
+ #undef BOOST_PROTO_MATCHES_N_FUN
+ #undef BOOST_PROTO_DEFINE_MATCHES
+ #undef BOOST_PROTO_DEFINE_LAMBDA_MATCHES
+
+ // handle proto::if_
+ template<typename Expr, typename If, typename Then, typename Else>
+ struct matches_<Expr, proto::if_<If, Then, Else> >
+ : mpl::eval_if_c<
+ remove_reference<
+ typename when<_, If>::template impl<Expr, int, int>::result_type
+ >::type::value
+ , matches_<Expr, typename Then::proto_base_expr>
+ , matches_<Expr, typename Else::proto_base_expr>
+ >::type
+ {};
+
+ template<typename Expr, typename If>
+ struct matches_<Expr, proto::if_<If> >
+ : detail::uncvref<typename when<_, If>::template impl<Expr, int, int>::result_type>::type
+ {};
+
+ // handle proto::not_
+ template<typename Expr, typename Grammar>
+ struct matches_<Expr, not_<Grammar> >
+ : mpl::not_<matches_<Expr, typename Grammar::proto_base_expr> >
+ {};
+
+ // handle proto::switch_
+ template<typename Expr, typename Cases>
+ struct matches_<Expr, switch_<Cases> >
+ : matches_<
+ Expr
+ , typename Cases::template case_<typename Expr::proto_tag>::proto_base_expr
+ >
+ {};
+ }
+
+ namespace result_of
+ {
+ /// \brief A Boolean metafunction that evaluates whether a given
+ /// expression type matches a grammar.
+ ///
+ /// <tt>matches\<Expr,Grammar\></tt> inherits (indirectly) from
+ /// \c mpl::true_ if <tt>Expr::proto_base_expr</tt> matches
+ /// <tt>Grammar::proto_base_expr</tt>, and from \c mpl::false_
+ /// otherwise.
+ ///
+ /// Non-terminal expressions are matched against a grammar
+ /// according to the following rules:
+ ///
+ /// \li The wildcard pattern, \c _, matches any expression.
+ /// \li An expression <tt>expr\<AT, listN\<A0,A1,...An\> \></tt>
+ /// matches a grammar <tt>expr\<BT, listN\<B0,B1,...Bn\> \></tt>
+ /// if \c BT is \c _ or \c AT, and if \c Ax matches \c Bx for
+ /// each \c x in <tt>[0,n)</tt>.
+ /// \li An expression <tt>expr\<AT, listN\<A0,...An,U0,...Um\> \></tt>
+ /// matches a grammar <tt>expr\<BT, listM\<B0,...Bn,vararg\<V\> \> \></tt>
+ /// if \c BT is \c _ or \c AT, and if \c Ax matches \c Bx
+ /// for each \c x in <tt>[0,n)</tt> and if \c Ux matches \c V
+ /// for each \c x in <tt>[0,m)</tt>.
+ /// \li An expression \c E matches <tt>or_\<B0,B1,...Bn\></tt> if \c E
+ /// matches some \c Bx for \c x in <tt>[0,n)</tt>.
+ /// \li An expression \c E matches <tt>and_\<B0,B1,...Bn\></tt> if \c E
+ /// matches all \c Bx for \c x in <tt>[0,n)</tt>.
+ /// \li An expression \c E matches <tt>if_\<T,U,V\></tt> if
+ /// <tt>when\<_,T\>::::result\<void(E,int,int)\>::::type::value</tt>
+ /// is \c true and \c E matches \c U; or, if
+ /// <tt>when\<_,T\>::::result\<void(E,int,int)\>::::type::value</tt>
+ /// is \c false and \c E matches \c V. (Note: \c U defaults to \c _
+ /// and \c V defaults to \c not_\<_\>.)
+ /// \li An expression \c E matches <tt>not_\<T\></tt> if \c E does
+ /// not match \c T.
+ /// \li An expression \c E matches <tt>switch_\<C\></tt> if
+ /// \c E matches <tt>C::case_\<E::proto_tag\></tt>.
+ ///
+ /// A terminal expression <tt>expr\<tag::terminal,term\<A\> \></tt> matches
+ /// a grammar <tt>expr\<BT,term\<B\> \></tt> if \c BT is \c _ or
+ /// \c tag::terminal and one of the following is true:
+ ///
+ /// \li \c B is the wildcard pattern, \c _
+ /// \li \c A is \c B
+ /// \li \c A is <tt>B &</tt>
+ /// \li \c A is <tt>B const &</tt>
+ /// \li \c B is <tt>exact\<A\></tt>
+ /// \li \c B is <tt>convertible_to\<X\></tt> and
+ /// <tt>is_convertible\<A,X\>::::value</tt> is \c true.
+ /// \li \c A is <tt>X[M]</tt> or <tt>X(&)[M]</tt> and
+ /// \c B is <tt>X[proto::N]</tt>.
+ /// \li \c A is <tt>X(&)[M]</tt> and \c B is <tt>X(&)[proto::N]</tt>.
+ /// \li \c A is <tt>X[M]</tt> or <tt>X(&)[M]</tt> and
+ /// \c B is <tt>X*</tt>.
+ /// \li \c B lambda-matches \c A (see below).
+ ///
+ /// A type \c B lambda-matches \c A if one of the following is true:
+ ///
+ /// \li \c B is \c A
+ /// \li \c B is the wildcard pattern, \c _
+ /// \li \c B is <tt>T\<B0,B1,...Bn\></tt> and \c A is
+ /// <tt>T\<A0,A1,...An\></tt> and for each \c x in
+ /// <tt>[0,n)</tt>, \c Ax and \c Bx are types
+ /// such that \c Ax lambda-matches \c Bx
+ template<typename Expr, typename Grammar>
+ struct matches
+ : detail::matches_<
+ typename Expr::proto_base_expr
+ , typename Grammar::proto_base_expr
+ >
+ {};
+
+ template<typename Expr, typename Grammar>
+ struct matches<Expr &, Grammar>
+ : detail::matches_<
+ typename Expr::proto_base_expr
+ , typename Grammar::proto_base_expr
+ >
+ {};
+ }
+
+ namespace wildcardns_
+ {
+ /// \brief A wildcard grammar element that matches any expression,
+ /// and a transform that returns the current expression unchanged.
+ ///
+ /// The wildcard type, \c _, is a grammar element such that
+ /// <tt>matches\<E,_\>::::value</tt> is \c true for any expression
+ /// type \c E.
+ ///
+ /// The wildcard can also be used as a stand-in for a template
+ /// argument when matching terminals. For instance, the following
+ /// is a grammar that will match any <tt>std::complex\<\></tt>
+ /// terminal:
+ ///
+ /// \code
+ /// BOOST_MPL_ASSERT((
+ /// matches<
+ /// terminal<std::complex<double> >::type
+ /// , terminal<std::complex< _ > >
+ /// >
+ /// ));
+ /// \endcode
+ ///
+ /// When used as a transform, \c _ returns the current expression
+ /// unchanged. For instance, in the following, \c _ is used with
+ /// the \c fold\<\> transform to fold the children of a node:
+ ///
+ /// \code
+ /// struct CountChildren
+ /// : or_<
+ /// // Terminals have no children
+ /// when<terminal<_>, mpl::int_<0>()>
+ /// // Use fold<> to count the children of non-terminals
+ /// , otherwise<
+ /// fold<
+ /// _ // <-- fold the current expression
+ /// , mpl::int_<0>()
+ /// , mpl::plus<_state, mpl::int_<1> >()
+ /// >
+ /// >
+ /// >
+ /// {};
+ /// \endcode
+ struct _ : transform<_>
+ {
+ typedef _ proto_base_expr;
+
+ template<typename Expr, typename State, typename Data>
+ struct impl : transform_impl<Expr, State, Data>
+ {
+ typedef Expr result_type;
+
+ /// \param expr An expression
+ /// \return \c expr
+ typename impl::expr_param operator()(
+ typename impl::expr_param expr
+ , typename impl::state_param
+ , typename impl::data_param
+ ) const
+ {
+ return expr;
+ }
+ };
+ };
+ }
+
+ namespace control
+ {
+ /// \brief Inverts the set of expressions matched by a grammar. When
+ /// used as a transform, \c not_\<\> returns the current expression
+ /// unchanged.
+ ///
+ /// If an expression type \c E does not match a grammar \c G, then
+ /// \c E \e does match <tt>not_\<G\></tt>. For example,
+ /// <tt>not_\<terminal\<_\> \></tt> will match any non-terminal.
+ template<typename Grammar>
+ struct not_ : transform<not_<Grammar> >
+ {
+ typedef not_ proto_base_expr;
+
+ template<typename Expr, typename State, typename Data>
+ struct impl : transform_impl<Expr, State, Data>
+ {
+ typedef Expr result_type;
+
+ /// \param expr An expression
+ /// \pre <tt>matches\<Expr,not_\>::::value</tt> is \c true.
+ /// \return \c expr
+ typename impl::expr_param operator()(
+ typename impl::expr_param expr
+ , typename impl::state_param
+ , typename impl::data_param
+ ) const
+ {
+ return expr;
+ }
+ };
+ };
+
+ /// \brief Used to select one grammar or another based on the result
+ /// of a compile-time Boolean. When used as a transform, \c if_\<\>
+ /// selects between two transforms based on a compile-time Boolean.
+ ///
+ /// When <tt>if_\<If,Then,Else\></tt> is used as a grammar, \c If
+ /// must be a Proto transform and \c Then and \c Else must be grammars.
+ /// An expression type \c E matches <tt>if_\<If,Then,Else\></tt> if
+ /// <tt>when\<_,If\>::::result\<void(E,int,int)\>::::type::value</tt>
+ /// is \c true and \c E matches \c U; or, if
+ /// <tt>when\<_,If\>::::result\<void(E,int,int)\>::::type::value</tt>
+ /// is \c false and \c E matches \c V.
+ ///
+ /// The template parameter \c Then defaults to \c _
+ /// and \c Else defaults to \c not\<_\>, so an expression type \c E
+ /// will match <tt>if_\<If\></tt> if and only if
+ /// <tt>when\<_,If\>::::result\<void(E,int,int)\>::::type::value</tt>
+ /// is \c true.
+ ///
+ /// \code
+ /// // A grammar that only matches integral terminals,
+ /// // using is_integral<> from Boost.Type_traits.
+ /// struct IsIntegral
+ /// : and_<
+ /// terminal<_>
+ /// , if_< is_integral<_value>() >
+ /// >
+ /// {};
+ /// \endcode
+ ///
+ /// When <tt>if_\<If,Then,Else\></tt> is used as a transform, \c If,
+ /// \c Then and \c Else must be Proto transforms. When applying
+ /// the transform to an expression \c E, state \c S and data \c V,
+ /// if <tt>when\<_,If\>::::result\<void(E,S,V)\>::::type::value</tt>
+ /// is \c true then the \c Then transform is applied; otherwise
+ /// the \c Else transform is applied.
+ ///
+ /// \code
+ /// // Match a terminal. If the terminal is integral, return
+ /// // mpl::true_; otherwise, return mpl::false_.
+ /// struct IsIntegral2
+ /// : when<
+ /// terminal<_>
+ /// , if_<
+ /// is_integral<_value>()
+ /// , mpl::true_()
+ /// , mpl::false_()
+ /// >
+ /// >
+ /// {};
+ /// \endcode
+ template<
+ typename If
+ , typename Then BOOST_PROTO_WHEN_BUILDING_DOCS(= _)
+ , typename Else BOOST_PROTO_WHEN_BUILDING_DOCS(= not_<_>)
+ >
+ struct if_ : transform<if_<If, Then, Else> >
+ {
+ typedef if_ proto_base_expr;
+
+ template<typename Expr, typename State, typename Data>
+ struct impl : transform_impl<Expr, State, Data>
+ {
+ typedef
+ typename when<_, If>::template impl<Expr, State, Data>::result_type
+ condition;
+
+ typedef
+ typename mpl::if_c<
+ remove_reference<condition>::type::value
+ , when<_, Then>
+ , when<_, Else>
+ >::type
+ which;
+
+ typedef typename which::template impl<Expr, State, Data>::result_type result_type;
+
+ /// \param expr An expression
+ /// \param state The current state
+ /// \param data A data of arbitrary type
+ /// \return <tt>which::impl<Expr, State, Data>()(expr, state, data)</tt>
+ result_type operator ()(
+ typename impl::expr_param expr
+ , typename impl::state_param state
+ , typename impl::data_param data
+ ) const
+ {
+ return typename which::template impl<Expr, State, Data>()(expr, state, data);
+ }
+ };
+ };
+
+ /// \brief For matching one of a set of alternate grammars. Alternates
+ /// tried in order to avoid ambiguity. When used as a transform, \c or_\<\>
+ /// applies the transform associated with the first grammar that matches
+ /// the expression.
+ ///
+ /// An expression type \c E matches <tt>or_\<B0,B1,...Bn\></tt> if \c E
+ /// matches any \c Bx for \c x in <tt>[0,n)</tt>.
+ ///
+ /// When applying <tt>or_\<B0,B1,...Bn\></tt> as a transform with an
+ /// expression \c e of type \c E, state \c s and data \c v, it is
+ /// equivalent to <tt>Bx()(e, s, v)</tt>, where \c x is the lowest
+ /// number such that <tt>matches\<E,Bx\>::::value</tt> is \c true.
+ template<BOOST_PP_ENUM_PARAMS(BOOST_PROTO_MAX_LOGICAL_ARITY, typename G)>
+ struct or_ : transform<or_<BOOST_PP_ENUM_PARAMS(BOOST_PROTO_MAX_LOGICAL_ARITY, G)> >
+ {
+ typedef or_ proto_base_expr;
+
+ /// \param expr An expression
+ /// \param state The current state
+ /// \param data A data of arbitrary type
+ /// \pre <tt>matches\<Expr,or_\>::::value</tt> is \c true.
+ /// \return <tt>result\<void(Expr, State, Data)\>::::which()(expr, state, data)</tt>
+
+ template<typename Expr, typename State, typename Data>
+ struct impl
+ : detail::matches_<typename Expr::proto_base_expr, or_>
+ ::which::template impl<Expr, State, Data>
+ {};
+
+ template<typename Expr, typename State, typename Data>
+ struct impl<Expr &, State, Data>
+ : detail::matches_<typename Expr::proto_base_expr, or_>
+ ::which::template impl<Expr &, State, Data>
+ {};
+ };
+
+ /// \brief For matching all of a set of grammars. When used as a
+ /// transform, \c and_\<\> applies the transform associated with
+ /// the last grammar in the set.
+ ///
+ /// An expression type \c E matches <tt>and_\<B0,B1,...Bn\></tt> if \c E
+ /// matches all \c Bx for \c x in <tt>[0,n)</tt>.
+ ///
+ /// When applying <tt>and_\<B0,B1,...Bn\></tt> as a transform with an
+ /// expression \c e, state \c s and data \c v, it is
+ /// equivalent to <tt>Bn()(e, s, v)</tt>.
+ template<BOOST_PP_ENUM_PARAMS(BOOST_PROTO_MAX_LOGICAL_ARITY, typename G)>
+ struct and_ : transform<and_<BOOST_PP_ENUM_PARAMS(BOOST_PROTO_MAX_LOGICAL_ARITY, G)> >
+ {
+ typedef and_ proto_base_expr;
+
+ template<typename Expr, typename State, typename Data>
+ struct impl
+ : detail::last<and_>::type::template impl<Expr, State, Data>
+ {
+ /// \param expr An expression
+ /// \param state The current state
+ /// \param data A data of arbitrary type
+ /// \pre <tt>matches\<Expr,and_\>::::value</tt> is \c true.
+ /// \return <tt>result\<void(Expr, State, Data)\>::::which()(expr, state, data)</tt>
+ };
+ };
+
+ /// \brief For matching one of a set of alternate grammars, which
+ /// are looked up based on an expression's tag type. When used as a
+ /// transform, \c switch_\<\> applies the transform associated with
+ /// the grammar that matches the expression.
+ ///
+ /// \note \c switch_\<\> is functionally identical to \c or_\<\> but
+ /// is often more efficient. It does a fast, O(1) lookup based on an
+ /// expression's tag type to find a sub-grammar that may potentially
+ /// match the expression.
+ ///
+ /// An expression type \c E matches <tt>switch_\<C\></tt> if \c E
+ /// matches <tt>C::case_\<E::proto_tag\></tt>.
+ ///
+ /// When applying <tt>switch_\<C\></tt> as a transform with an
+ /// expression \c e of type \c E, state \c s and data \c v, it is
+ /// equivalent to <tt>C::case_\<E::proto_tag\>()(e, s, v)</tt>.
+ template<typename Cases>
+ struct switch_ : transform<switch_<Cases> >
+ {
+ typedef switch_ proto_base_expr;
+
+ /// \param expr An expression
+ /// \param state The current state
+ /// \param data A data of arbitrary type
+ /// \pre <tt>matches\<Expr,switch_\>::::value</tt> is \c true.
+ /// \return <tt>result\<void(Expr, State, Data)\>::::which()(expr, state, data)</tt>
+
+ template<typename Expr, typename State, typename Data>
+ struct impl
+ : Cases::template case_<typename Expr::proto_tag>::template impl<Expr, State, Data>
+ {};
+
+ template<typename Expr, typename State, typename Data>
+ struct impl<Expr &, State, Data>
+ : Cases::template case_<typename Expr::proto_tag>::template impl<Expr &, State, Data>
+ {};
+ };
+
+ /// \brief For forcing exact matches of terminal types.
+ ///
+ /// By default, matching terminals ignores references and
+ /// cv-qualifiers. For instance, a terminal expression of
+ /// type <tt>terminal\<int const &\>::::type</tt> will match
+ /// the grammar <tt>terminal\<int\></tt>. If that is not
+ /// desired, you can force an exact match with
+ /// <tt>terminal\<exact\<int\> \></tt>. This will only
+ /// match integer terminals where the terminal is held by
+ /// value.
+ template<typename T>
+ struct exact
+ {};
+
+ /// \brief For matching terminals that are convertible to
+ /// a type.
+ ///
+ /// Use \c convertible_to\<\> to match a terminal that is
+ /// convertible to some type. For example, the grammar
+ /// <tt>terminal\<convertible_to\<int\> \></tt> will match
+ /// any terminal whose argument is convertible to an integer.
+ ///
+ /// \note The trait \c is_convertible\<\> from Boost.Type_traits
+ /// is used to determinal convertibility.
+ template<typename T>
+ struct convertible_to
+ {};
+
+ /// \brief For matching a Grammar to a variable number of
+ /// sub-expressions.
+ ///
+ /// An expression type <tt>expr\<AT, listN\<A0,...An,U0,...Um\> \></tt>
+ /// matches a grammar <tt>expr\<BT, listM\<B0,...Bn,vararg\<V\> \> \></tt>
+ /// if \c BT is \c _ or \c AT, and if \c Ax matches \c Bx
+ /// for each \c x in <tt>[0,n)</tt> and if \c Ux matches \c V
+ /// for each \c x in <tt>[0,m)</tt>.
+ ///
+ /// For example:
+ ///
+ /// \code
+ /// // Match any function call expression, irregardless
+ /// // of the number of function arguments:
+ /// struct Function
+ /// : function< vararg<_> >
+ /// {};
+ /// \endcode
+ ///
+ /// When used as a transform, <tt>vararg\<G\></tt> applies
+ /// <tt>G</tt>'s transform.
+ template<typename Grammar>
+ struct vararg
+ : Grammar
+ {
+ typedef void proto_is_vararg_;
+ };
+ }
+
+ /// INTERNAL ONLY
+ ///
+ template<BOOST_PP_ENUM_PARAMS(BOOST_PROTO_MAX_LOGICAL_ARITY, typename G)>
+ struct is_callable<or_<BOOST_PP_ENUM_PARAMS(BOOST_PROTO_MAX_LOGICAL_ARITY, G)> >
+ : mpl::true_
+ {};
+
+ /// INTERNAL ONLY
+ ///
+ template<BOOST_PP_ENUM_PARAMS(BOOST_PROTO_MAX_LOGICAL_ARITY, typename G)>
+ struct is_callable<and_<BOOST_PP_ENUM_PARAMS(BOOST_PROTO_MAX_LOGICAL_ARITY, G)> >
+ : mpl::true_
+ {};
+
+ /// INTERNAL ONLY
+ ///
+ template<typename Grammar>
+ struct is_callable<not_<Grammar> >
+ : mpl::true_
+ {};
+
+ /// INTERNAL ONLY
+ ///
+ template<typename If, typename Then, typename Else>
+ struct is_callable<if_<If, Then, Else> >
+ : mpl::true_
+ {};
+
+ /// INTERNAL ONLY
+ ///
+ template<typename Grammar>
+ struct is_callable<vararg<Grammar> >
+ : mpl::true_
+ {};
+
+ }}
+
+ #if defined(_MSC_VER) && (_MSC_VER >= 1020)
+ # pragma warning(pop)
+ #endif
+
+ #endif
+
+#elif BOOST_PP_ITERATION_FLAGS() == 1
+
+ #define N BOOST_PP_ITERATION()
+
+ template<bool B, BOOST_PP_ENUM_PARAMS(BOOST_PP_DEC(N), typename P)>
+ struct BOOST_PP_CAT(and, N)
+ : BOOST_PP_CAT(and, BOOST_PP_DEC(N))<
+ P0::value BOOST_PP_COMMA_IF(BOOST_PP_SUB(N,2))
+ BOOST_PP_ENUM_SHIFTED_PARAMS(BOOST_PP_DEC(N), P)
+ >
+ {};
+
+ template<BOOST_PP_ENUM_PARAMS(BOOST_PP_DEC(N), typename P)>
+ struct BOOST_PP_CAT(and, N)<false, BOOST_PP_ENUM_PARAMS(BOOST_PP_DEC(N), P)>
+ : mpl::false_
+ {};
+
+ #if N <= BOOST_PROTO_MAX_LOGICAL_ARITY
+ template<BOOST_PP_ENUM_PARAMS(N, typename G)>
+ struct last<proto::and_<BOOST_PP_ENUM_PARAMS(N, G)> >
+ {
+ typedef BOOST_PP_CAT(G, BOOST_PP_DEC(N)) type;
+ };
+
+ template<bool B, typename Expr, BOOST_PP_ENUM_PARAMS(N, typename G)>
+ struct BOOST_PP_CAT(or, N)
+ : BOOST_PP_CAT(or, BOOST_PP_DEC(N))<
+ matches_<Expr, typename G1::proto_base_expr>::value
+ , Expr, BOOST_PP_ENUM_SHIFTED_PARAMS(N, G)
+ >
+ {};
+
+ template<typename Expr BOOST_PP_ENUM_TRAILING_PARAMS(N, typename G)>
+ struct BOOST_PP_CAT(or, N)<true, Expr, BOOST_PP_ENUM_PARAMS(N, G)>
+ : mpl::true_
+ {
+ typedef G0 which;
+ };
+
+ // handle proto::or_
+ template<typename Expr, BOOST_PP_ENUM_PARAMS(N, typename G)>
+ struct matches_<Expr, proto::or_<BOOST_PP_ENUM_PARAMS(N, G)> >
+ : BOOST_PP_CAT(or, N)<
+ matches_<typename Expr::proto_base_expr, typename G0::proto_base_expr>::value,
+ typename Expr::proto_base_expr, BOOST_PP_ENUM_PARAMS(N, G)
+ >
+ {};
+
+ // handle proto::and_
+ template<typename Expr, BOOST_PP_ENUM_PARAMS(N, typename G)>
+ struct matches_<Expr, proto::and_<BOOST_PP_ENUM_PARAMS(N, G)> >
+ : detail::BOOST_PP_CAT(and, N)<
+ BOOST_PROTO_DEFINE_MATCHES(~, 0, ~)::value,
+ BOOST_PP_ENUM_SHIFTED(N, BOOST_PROTO_DEFINE_MATCHES, ~)
+ >
+ {};
+ #endif
+
+ #undef N
+
+#elif BOOST_PP_ITERATION_FLAGS() == 2
+
+ #define N BOOST_PP_ITERATION()
+
+ template<typename Args, typename Back, long To>
+ struct vararg_matches_impl<Args, Back, N, To>
+ : and2<
+ matches_<typename Args::BOOST_PP_CAT(child_ref, BOOST_PP_DEC(N))::proto_base_expr, Back>::value
+ , vararg_matches_impl<Args, Back, N + 1, To>
+ >
+ {};
+
+ template<typename Args, typename Back>
+ struct vararg_matches_impl<Args, Back, N, N>
+ : matches_<typename Args::BOOST_PP_CAT(child_ref, BOOST_PP_DEC(N))::proto_base_expr, Back>
+ {};
+
+ template<
+ template<BOOST_PP_ENUM_PARAMS(N, typename BOOST_PP_INTERCEPT)> class T
+ BOOST_PP_ENUM_TRAILING_PARAMS(N, typename Expr)
+ BOOST_PP_ENUM_TRAILING_PARAMS(N, typename Grammar)
+ >
+ struct lambda_matches<T<BOOST_PP_ENUM_PARAMS(N, Expr)>, T<BOOST_PP_ENUM_PARAMS(N, Grammar)> BOOST_MPL_AUX_LAMBDA_ARITY_PARAM(N) >
+ : BOOST_PP_CAT(and, N)<
+ BOOST_PROTO_DEFINE_LAMBDA_MATCHES(~, 0, ~)::value,
+ BOOST_PP_ENUM_SHIFTED(N, BOOST_PROTO_DEFINE_LAMBDA_MATCHES, ~)
+ >
+ {};
+
+ template<typename Tag, typename Args1, typename Args2>
+ struct matches_< proto::expr<Tag, Args1, N>, proto::expr<Tag, Args2, N> >
+ : BOOST_PP_CAT(and, N)<
+ BOOST_PROTO_MATCHES_N_FUN(~, 0, ~)::value,
+ BOOST_PP_ENUM_SHIFTED(N, BOOST_PROTO_MATCHES_N_FUN, ~)
+ >
+ {};
+
+ template<typename Tag, typename Args1, typename Args2>
+ struct matches_< proto::expr<Tag, Args1, N>, proto::expr<proto::_, Args2, N> >
+ : BOOST_PP_CAT(and, N)<
+ BOOST_PROTO_MATCHES_N_FUN(~, 0, ~)::value,
+ BOOST_PP_ENUM_SHIFTED(N, BOOST_PROTO_MATCHES_N_FUN, ~)
+ >
+ {};
+
+ #undef N
+
+#endif
+

Added: branches/proto/v4/boost/proto/operators.hpp
==============================================================================
--- (empty file)
+++ branches/proto/v4/boost/proto/operators.hpp 2008-04-06 02:19:35 EDT (Sun, 06 Apr 2008)
@@ -0,0 +1,404 @@
+///////////////////////////////////////////////////////////////////////////////
+/// \file operators.hpp
+/// Contains all the overloaded operators that make it possible to build
+/// Proto expression trees.
+//
+// Copyright 2008 Eric Niebler. Distributed under the Boost
+// Software License, Version 1.0. (See accompanying file
+// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_PROTO_OPERATORS_HPP_EAN_04_01_2005
+#define BOOST_PROTO_OPERATORS_HPP_EAN_04_01_2005
+
+#include <boost/proto/detail/prefix.hpp>
+#include <boost/preprocessor/punctuation/comma.hpp>
+#include <boost/preprocessor/seq/seq.hpp>
+#include <boost/mpl/or.hpp>
+#include <boost/mpl/assert.hpp>
+#include <boost/type_traits/is_same.hpp>
+#include <boost/proto/proto_fwd.hpp>
+#include <boost/proto/tags.hpp>
+#include <boost/proto/expr.hpp>
+#include <boost/proto/generate.hpp>
+#include <boost/proto/make_expr.hpp>
+#include <boost/proto/detail/suffix.hpp>
+
+namespace boost { namespace proto
+{
+ namespace detail
+ {
+ template<typename Tag, typename Left, typename Right, typename Enable1 = void, typename Enable2 = void>
+ struct as_expr_if2
+ {};
+
+ template<typename Tag, typename Left, typename Right>
+ struct as_expr_if2<Tag, Left, Right, typename Left::proto_is_expr_, void>
+ : generate_if<
+ typename Left::proto_domain
+ , proto::expr<
+ Tag
+ , list2<
+ Left &
+ , typename Left::proto_domain::template result<void(proto::expr<tag::terminal, term<Right &> >)>::type
+ >
+ >
+ >
+ {
+ typedef proto::expr<tag::terminal, term<Right &> > term_type;
+ typedef proto::expr<Tag, list2<Left &, typename Left::proto_domain::template result<void(term_type)>::type> > expr_type;
+
+ static typename Left::proto_domain::template result<void(expr_type)>::type
+ make(Left &left, Right &right)
+ {
+ term_type term = {right};
+ expr_type that = {left, typename Left::proto_domain()(term)};
+ return typename Left::proto_domain()(that);
+ }
+ };
+
+ template<typename Tag, typename Left, typename Right>
+ struct as_expr_if2<Tag, Left, Right, void, typename Right::proto_is_expr_>
+ : generate_if<
+ typename Right::proto_domain
+ , proto::expr<
+ Tag
+ , list2<
+ typename Right::proto_domain::template result<void(proto::expr<tag::terminal, term<Left &> >)>::type
+ , Right &
+ >
+ >
+ >
+ {
+ typedef proto::expr<tag::terminal, term<Left &> > term_type;
+ typedef proto::expr<Tag, list2<typename Right::proto_domain::template result<void(term_type)>::type, Right &> > expr_type;
+
+ static typename Right::proto_domain::template result<void(expr_type)>::type
+ make(Left &left, Right &right)
+ {
+ term_type term = {left};
+ expr_type that = {typename Right::proto_domain()(term), right};
+ return typename Right::proto_domain()(that);
+ }
+ };
+
+ template<typename Tag, typename Left, typename Right, typename Enable1 = void, typename Enable2 = void>
+ struct as_expr_if
+ : as_expr_if2<Tag, Left, Right>
+ {};
+
+ template<typename Tag, typename Left, typename Right>
+ struct as_expr_if<Tag, Left, Right, typename Left::proto_is_expr_, typename Right::proto_is_expr_>
+ : generate_if<
+ typename Left::proto_domain
+ , proto::expr<Tag, list2<Left &, Right &> >
+ >
+ {
+ typedef proto::expr<Tag, list2<Left &, Right &> > expr_type;
+ BOOST_MPL_ASSERT((is_same<typename Left::proto_domain, typename Right::proto_domain>));
+
+ static typename Left::proto_domain::template result<void(expr_type)>::type
+ make(Left &left, Right &right)
+ {
+ expr_type that = {left, right};
+ return typename Left::proto_domain()(that);
+ }
+ };
+
+ template<typename Arg, typename Trait, typename Enable = void>
+ struct arg_weight
+ {
+ BOOST_STATIC_CONSTANT(int, value = 1 + Trait::value);
+ };
+
+ template<typename Arg, typename Trait>
+ struct arg_weight<Arg, Trait, typename Arg::proto_is_expr_>
+ {
+ BOOST_STATIC_CONSTANT(int, value = 0);
+ };
+
+ template<typename Domain, typename Trait, typename Arg, typename Expr>
+ struct enable_unary
+ : boost::enable_if<
+ boost::mpl::and_<Trait, boost::proto::matches<Expr, typename Domain::proto_grammar> >
+ , Expr
+ >
+ {};
+
+ template<typename Trait, typename Arg, typename Expr>
+ struct enable_unary<deduce_domain, Trait, Arg, Expr>
+ : boost::enable_if<
+ boost::mpl::and_<
+ Trait
+ , boost::proto::matches<Expr, typename domain_of<Arg>::type::proto_grammar>
+ >
+ , Expr
+ >
+ {};
+
+ template<typename Trait, typename Arg, typename Expr>
+ struct enable_unary<default_domain, Trait, Arg, Expr>
+ : boost::enable_if<Trait, Expr>
+ {};
+
+ template<typename Domain, typename Trait1, typename Arg1, typename Trait2, typename Arg2, typename Expr>
+ struct enable_binary
+ : boost::enable_if<
+ boost::mpl::and_<
+ mpl::bool_<(3 <= (arg_weight<Arg1, Trait1>::value + arg_weight<Arg2, Trait2>::value))>
+ , boost::proto::matches<Expr, typename Domain::proto_grammar>
+ >
+ , Expr
+ >
+ {};
+
+ template<typename Trait1, typename Arg1, typename Trait2, typename Arg2, typename Expr>
+ struct enable_binary<deduce_domain, Trait1, Arg1, Trait2, Arg2, Expr>
+ : boost::enable_if<
+ boost::mpl::and_<
+ mpl::bool_<(3 <= (arg_weight<Arg1, Trait1>::value + arg_weight<Arg2, Trait2>::value))>
+ , boost::proto::matches<Expr, typename deduce_domain2<Arg1, Arg2>::type::proto_grammar>
+ >
+ , Expr
+ >
+ {};
+
+ template<typename Trait1, typename Arg1, typename Trait2, typename Arg2, typename Expr>
+ struct enable_binary<default_domain, Trait1, Arg1, Trait2, Arg2, Expr>
+ : boost::enable_if_c<
+ (3 <= (arg_weight<Arg1, Trait1>::value + arg_weight<Arg2, Trait2>::value))
+ , Expr
+ >
+ {};
+
+ } // detail
+
+#define BOOST_PROTO_UNARY_OP_IS_POSTFIX_0
+#define BOOST_PROTO_UNARY_OP_IS_POSTFIX_1 , int
+
+#define BOOST_PROTO_DEFINE_UNARY_OPERATOR(OP, TAG, POST) \
+ template<typename Arg> \
+ typename detail::generate_if< \
+ typename Arg::proto_domain \
+ , proto::expr<TAG, list1<typename Arg::proto_derived_expr &> > \
+ >::type const \
+ operator OP(Arg &arg BOOST_PROTO_UNARY_OP_IS_POSTFIX_ ## POST) \
+ { \
+ typedef proto::expr<TAG, list1<typename Arg::proto_derived_expr &> > that_type; \
+ that_type that = {arg}; \
+ return typename Arg::proto_domain()(that); \
+ } \
+ template<typename Arg> \
+ typename detail::generate_if< \
+ typename Arg::proto_domain \
+ , proto::expr<TAG, list1<typename Arg::proto_derived_expr const &> > \
+ >::type const \
+ operator OP(Arg const &arg BOOST_PROTO_UNARY_OP_IS_POSTFIX_ ## POST) \
+ { \
+ typedef proto::expr<TAG, list1<typename Arg::proto_derived_expr const &> > that_type; \
+ that_type that = {arg}; \
+ return typename Arg::proto_domain()(that); \
+ } \
+ /**/
+
+#define BOOST_PROTO_DEFINE_BINARY_OPERATOR(OP, TAG) \
+ template<typename Left, typename Right> \
+ inline typename detail::as_expr_if<TAG, Left, Right>::type const \
+ operator OP(Left &left, Right &right) \
+ { \
+ return detail::as_expr_if<TAG, Left, Right>::make(left, right); \
+ } \
+ template<typename Left, typename Right> \
+ inline typename detail::as_expr_if<TAG, Left, Right const>::type const \
+ operator OP(Left &left, Right const &right) \
+ { \
+ return detail::as_expr_if<TAG, Left, Right const>::make(left, right); \
+ } \
+ template<typename Left, typename Right> \
+ inline typename detail::as_expr_if<TAG, Left const, Right>::type const \
+ operator OP(Left const &left, Right &right) \
+ { \
+ return detail::as_expr_if<TAG, Left const, Right>::make(left, right); \
+ } \
+ template<typename Left, typename Right> \
+ inline typename detail::as_expr_if<TAG, Left const, Right const>::type const \
+ operator OP(Left const &left, Right const &right) \
+ { \
+ return detail::as_expr_if<TAG, Left const, Right const>::make(left, right); \
+ } \
+ /**/
+
+ BOOST_PROTO_BEGIN_ADL_NAMESPACE(exprns_)
+
+ BOOST_PROTO_DEFINE_UNARY_OPERATOR(+, tag::unary_plus, 0)
+ BOOST_PROTO_DEFINE_UNARY_OPERATOR(-, tag::negate, 0)
+ BOOST_PROTO_DEFINE_UNARY_OPERATOR(*, tag::dereference, 0)
+ BOOST_PROTO_DEFINE_UNARY_OPERATOR(~, tag::complement, 0)
+ BOOST_PROTO_DEFINE_UNARY_OPERATOR(&, tag::address_of, 0)
+ BOOST_PROTO_DEFINE_UNARY_OPERATOR(!, tag::logical_not, 0)
+ BOOST_PROTO_DEFINE_UNARY_OPERATOR(++, tag::pre_inc, 0)
+ BOOST_PROTO_DEFINE_UNARY_OPERATOR(--, tag::pre_dec, 0)
+ BOOST_PROTO_DEFINE_UNARY_OPERATOR(++, tag::post_inc, 1)
+ BOOST_PROTO_DEFINE_UNARY_OPERATOR(--, tag::post_dec, 1)
+
+ BOOST_PROTO_DEFINE_BINARY_OPERATOR(<<, tag::shift_left)
+ BOOST_PROTO_DEFINE_BINARY_OPERATOR(>>, tag::shift_right)
+ BOOST_PROTO_DEFINE_BINARY_OPERATOR(*, tag::multiplies)
+ BOOST_PROTO_DEFINE_BINARY_OPERATOR(/, tag::divides)
+ BOOST_PROTO_DEFINE_BINARY_OPERATOR(%, tag::modulus)
+ BOOST_PROTO_DEFINE_BINARY_OPERATOR(+, tag::plus)
+ BOOST_PROTO_DEFINE_BINARY_OPERATOR(-, tag::minus)
+ BOOST_PROTO_DEFINE_BINARY_OPERATOR(<, tag::less)
+ BOOST_PROTO_DEFINE_BINARY_OPERATOR(>, tag::greater)
+ BOOST_PROTO_DEFINE_BINARY_OPERATOR(<=, tag::less_equal)
+ BOOST_PROTO_DEFINE_BINARY_OPERATOR(>=, tag::greater_equal)
+ BOOST_PROTO_DEFINE_BINARY_OPERATOR(==, tag::equal_to)
+ BOOST_PROTO_DEFINE_BINARY_OPERATOR(!=, tag::not_equal_to)
+ BOOST_PROTO_DEFINE_BINARY_OPERATOR(||, tag::logical_or)
+ BOOST_PROTO_DEFINE_BINARY_OPERATOR(&&, tag::logical_and)
+ BOOST_PROTO_DEFINE_BINARY_OPERATOR(&, tag::bitwise_and)
+ BOOST_PROTO_DEFINE_BINARY_OPERATOR(|, tag::bitwise_or)
+ BOOST_PROTO_DEFINE_BINARY_OPERATOR(^, tag::bitwise_xor)
+ BOOST_PROTO_DEFINE_BINARY_OPERATOR(BOOST_PP_COMMA(), tag::comma)
+ BOOST_PROTO_DEFINE_BINARY_OPERATOR(->*, tag::mem_ptr)
+
+ BOOST_PROTO_DEFINE_BINARY_OPERATOR(<<=, tag::shift_left_assign)
+ BOOST_PROTO_DEFINE_BINARY_OPERATOR(>>=, tag::shift_right_assign)
+ BOOST_PROTO_DEFINE_BINARY_OPERATOR(*=, tag::multiplies_assign)
+ BOOST_PROTO_DEFINE_BINARY_OPERATOR(/=, tag::divides_assign)
+ BOOST_PROTO_DEFINE_BINARY_OPERATOR(%=, tag::modulus_assign)
+ BOOST_PROTO_DEFINE_BINARY_OPERATOR(+=, tag::plus_assign)
+ BOOST_PROTO_DEFINE_BINARY_OPERATOR(-=, tag::minus_assign)
+ BOOST_PROTO_DEFINE_BINARY_OPERATOR(&=, tag::bitwise_and_assign)
+ BOOST_PROTO_DEFINE_BINARY_OPERATOR(|=, tag::bitwise_or_assign)
+ BOOST_PROTO_DEFINE_BINARY_OPERATOR(^=, tag::bitwise_xor_assign)
+
+ /// if_else
+ ///
+ BOOST_PROTO_DEFINE_FUNCTION_TEMPLATE(
+ 3
+ , if_else
+ , deduce_domain
+ , (tag::if_else_)
+ , BOOST_PP_SEQ_NIL
+ )
+
+ BOOST_PROTO_END_ADL_NAMESPACE(exprns_)
+
+ BOOST_PROTO_WHEN_NOT_BUILDING_DOCS(using exprns_::if_else;)
+
+#undef BOOST_PROTO_DEFINE_UNARY_OPERATOR
+#undef BOOST_PROTO_DEFINE_BINARY_OPERATOR
+
+#define BOOST_PROTO_DEFINE_UNARY_OPERATOR(OP, TAG, TRAIT, DOMAIN, POST) \
+ template<typename Arg> \
+ typename boost::proto::detail::enable_unary<DOMAIN, TRAIT<Arg>, Arg \
+ , typename boost::proto::result_of::make_expr<TAG, DOMAIN, Arg &>::type \
+ >::type const \
+ operator OP(Arg &arg BOOST_PROTO_UNARY_OP_IS_POSTFIX_ ## POST) \
+ { \
+ return boost::proto::make_expr<TAG, DOMAIN>(boost::ref(arg)); \
+ } \
+ template<typename Arg> \
+ typename boost::proto::detail::enable_unary<DOMAIN, TRAIT<Arg>, Arg \
+ , typename boost::proto::result_of::make_expr<TAG, DOMAIN, Arg const &>::type \
+ >::type const \
+ operator OP(Arg const &arg BOOST_PROTO_UNARY_OP_IS_POSTFIX_ ## POST) \
+ { \
+ return boost::proto::make_expr<TAG, DOMAIN>(boost::ref(arg)); \
+ } \
+ /**/
+
+#define BOOST_PROTO_DEFINE_BINARY_OPERATOR(OP, TAG, TRAIT, DOMAIN) \
+ template<typename Left, typename Right> \
+ typename boost::proto::detail::enable_binary<DOMAIN, TRAIT<Left>, Left, TRAIT<Right>, Right \
+ , typename boost::proto::result_of::make_expr<TAG, DOMAIN, Left &, Right &>::type \
+ >::type const \
+ operator OP(Left &left, Right &right) \
+ { \
+ return boost::proto::make_expr<TAG, DOMAIN>(boost::ref(left), boost::ref(right)); \
+ } \
+ template<typename Left, typename Right> \
+ typename boost::proto::detail::enable_binary<DOMAIN, TRAIT<Left>, Left, TRAIT<Right>, Right \
+ , typename boost::proto::result_of::make_expr<TAG, DOMAIN, Left &, Right const &>::type \
+ >::type const \
+ operator OP(Left &left, Right const &right) \
+ { \
+ return boost::proto::make_expr<TAG, DOMAIN>(boost::ref(left), boost::ref(right)); \
+ } \
+ template<typename Left, typename Right> \
+ typename boost::proto::detail::enable_binary<DOMAIN, TRAIT<Left>, Left, TRAIT<Right>, Right \
+ , typename boost::proto::result_of::make_expr<TAG, DOMAIN, Left const &, Right &>::type \
+ >::type const \
+ operator OP(Left const &left, Right &right) \
+ { \
+ return boost::proto::make_expr<TAG, DOMAIN>(boost::ref(left), boost::ref(right)); \
+ } \
+ template<typename Left, typename Right> \
+ typename boost::proto::detail::enable_binary<DOMAIN, TRAIT<Left>, Left, TRAIT<Right>, Right \
+ , typename boost::proto::result_of::make_expr<TAG, DOMAIN, Left const &, Right const &>::type\
+ >::type const \
+ operator OP(Left const &left, Right const &right) \
+ { \
+ return boost::proto::make_expr<TAG, DOMAIN>(boost::ref(left), boost::ref(right)); \
+ } \
+ /**/
+
+#define BOOST_PROTO_DEFINE_OPERATORS(TRAIT, DOMAIN) \
+ BOOST_PROTO_DEFINE_UNARY_OPERATOR(+, boost::proto::tag::unary_plus, TRAIT, DOMAIN, 0) \
+ BOOST_PROTO_DEFINE_UNARY_OPERATOR(-, boost::proto::tag::negate, TRAIT, DOMAIN, 0) \
+ BOOST_PROTO_DEFINE_UNARY_OPERATOR(*, boost::proto::tag::dereference, TRAIT, DOMAIN, 0) \
+ BOOST_PROTO_DEFINE_UNARY_OPERATOR(~, boost::proto::tag::complement, TRAIT, DOMAIN, 0) \
+ BOOST_PROTO_DEFINE_UNARY_OPERATOR(&, boost::proto::tag::address_of, TRAIT, DOMAIN, 0) \
+ BOOST_PROTO_DEFINE_UNARY_OPERATOR(!, boost::proto::tag::logical_not, TRAIT, DOMAIN, 0) \
+ BOOST_PROTO_DEFINE_UNARY_OPERATOR(++, boost::proto::tag::pre_inc, TRAIT, DOMAIN, 0) \
+ BOOST_PROTO_DEFINE_UNARY_OPERATOR(--, boost::proto::tag::pre_dec, TRAIT, DOMAIN, 0) \
+ BOOST_PROTO_DEFINE_UNARY_OPERATOR(++, boost::proto::tag::post_inc, TRAIT, DOMAIN, 1) \
+ BOOST_PROTO_DEFINE_UNARY_OPERATOR(--, boost::proto::tag::post_dec, TRAIT, DOMAIN, 1) \
+ BOOST_PROTO_DEFINE_BINARY_OPERATOR(<<, boost::proto::tag::shift_left, TRAIT, DOMAIN) \
+ BOOST_PROTO_DEFINE_BINARY_OPERATOR(>>, boost::proto::tag::shift_right, TRAIT, DOMAIN) \
+ BOOST_PROTO_DEFINE_BINARY_OPERATOR(*, boost::proto::tag::multiplies, TRAIT, DOMAIN) \
+ BOOST_PROTO_DEFINE_BINARY_OPERATOR(/, boost::proto::tag::divides, TRAIT, DOMAIN) \
+ BOOST_PROTO_DEFINE_BINARY_OPERATOR(%, boost::proto::tag::modulus, TRAIT, DOMAIN) \
+ BOOST_PROTO_DEFINE_BINARY_OPERATOR(+, boost::proto::tag::plus, TRAIT, DOMAIN) \
+ BOOST_PROTO_DEFINE_BINARY_OPERATOR(-, boost::proto::tag::minus, TRAIT, DOMAIN) \
+ BOOST_PROTO_DEFINE_BINARY_OPERATOR(<, boost::proto::tag::less, TRAIT, DOMAIN) \
+ BOOST_PROTO_DEFINE_BINARY_OPERATOR(>, boost::proto::tag::greater, TRAIT, DOMAIN) \
+ BOOST_PROTO_DEFINE_BINARY_OPERATOR(<=, boost::proto::tag::less_equal, TRAIT, DOMAIN) \
+ BOOST_PROTO_DEFINE_BINARY_OPERATOR(>=, boost::proto::tag::greater_equal, TRAIT, DOMAIN) \
+ BOOST_PROTO_DEFINE_BINARY_OPERATOR(==, boost::proto::tag::equal_to, TRAIT, DOMAIN) \
+ BOOST_PROTO_DEFINE_BINARY_OPERATOR(!=, boost::proto::tag::not_equal_to, TRAIT, DOMAIN) \
+ BOOST_PROTO_DEFINE_BINARY_OPERATOR(||, boost::proto::tag::logical_or, TRAIT, DOMAIN) \
+ BOOST_PROTO_DEFINE_BINARY_OPERATOR(&&, boost::proto::tag::logical_and, TRAIT, DOMAIN) \
+ BOOST_PROTO_DEFINE_BINARY_OPERATOR(&, boost::proto::tag::bitwise_and, TRAIT, DOMAIN) \
+ BOOST_PROTO_DEFINE_BINARY_OPERATOR(|, boost::proto::tag::bitwise_or, TRAIT, DOMAIN) \
+ BOOST_PROTO_DEFINE_BINARY_OPERATOR(^, boost::proto::tag::bitwise_xor, TRAIT, DOMAIN) \
+ BOOST_PROTO_DEFINE_BINARY_OPERATOR(BOOST_PP_COMMA(), boost::proto::tag::comma, TRAIT, DOMAIN) \
+ BOOST_PROTO_DEFINE_BINARY_OPERATOR(->*, boost::proto::tag::mem_ptr, TRAIT, DOMAIN) \
+ BOOST_PROTO_DEFINE_BINARY_OPERATOR(<<=, boost::proto::tag::shift_left_assign, TRAIT, DOMAIN) \
+ BOOST_PROTO_DEFINE_BINARY_OPERATOR(>>=, boost::proto::tag::shift_right_assign, TRAIT, DOMAIN) \
+ BOOST_PROTO_DEFINE_BINARY_OPERATOR(*=, boost::proto::tag::multiplies_assign, TRAIT, DOMAIN) \
+ BOOST_PROTO_DEFINE_BINARY_OPERATOR(/=, boost::proto::tag::divides_assign, TRAIT, DOMAIN) \
+ BOOST_PROTO_DEFINE_BINARY_OPERATOR(%=, boost::proto::tag::modulus_assign, TRAIT, DOMAIN) \
+ BOOST_PROTO_DEFINE_BINARY_OPERATOR(+=, boost::proto::tag::plus_assign, TRAIT, DOMAIN) \
+ BOOST_PROTO_DEFINE_BINARY_OPERATOR(-=, boost::proto::tag::minus_assign, TRAIT, DOMAIN) \
+ BOOST_PROTO_DEFINE_BINARY_OPERATOR(&=, boost::proto::tag::bitwise_and_assign, TRAIT, DOMAIN) \
+ BOOST_PROTO_DEFINE_BINARY_OPERATOR(|=, boost::proto::tag::bitwise_or_assign, TRAIT, DOMAIN) \
+ BOOST_PROTO_DEFINE_BINARY_OPERATOR(^=, boost::proto::tag::bitwise_xor_assign, TRAIT, DOMAIN) \
+ /**/
+
+ template<typename T>
+ struct is_extension
+ : mpl::false_
+ {};
+
+ #ifndef BOOST_PROTO_BUILDING_DOCS
+ namespace exops
+ {
+ BOOST_PROTO_DEFINE_OPERATORS(is_extension, default_domain)
+ using proto::if_else;
+ }
+ #endif
+
+}}
+
+#endif

Added: branches/proto/v4/boost/proto/proto.hpp
==============================================================================
--- (empty file)
+++ branches/proto/v4/boost/proto/proto.hpp 2008-04-06 02:19:35 EDT (Sun, 06 Apr 2008)
@@ -0,0 +1,19 @@
+///////////////////////////////////////////////////////////////////////////////
+/// \file proto.hpp
+/// Includes all of Proto.
+//
+// Copyright 2008 Eric Niebler. Distributed under the Boost
+// Software License, Version 1.0. (See accompanying file
+// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_PROTO_HPP_EAN_04_01_2005
+#define BOOST_PROTO_HPP_EAN_04_01_2005
+
+#include <boost/proto/detail/prefix.hpp>
+#include <boost/proto/core.hpp>
+#include <boost/proto/debug.hpp>
+#include <boost/proto/context.hpp>
+#include <boost/proto/transform.hpp>
+#include <boost/proto/detail/suffix.hpp>
+
+#endif

Added: branches/proto/v4/boost/proto/proto_fwd.hpp
==============================================================================
--- (empty file)
+++ branches/proto/v4/boost/proto/proto_fwd.hpp 2008-04-06 02:19:35 EDT (Sun, 06 Apr 2008)
@@ -0,0 +1,771 @@
+///////////////////////////////////////////////////////////////////////////////
+/// \file proto_fwd.hpp
+/// Forward declarations of all of proto's public types and functions.
+//
+// Copyright 2008 Eric Niebler. Distributed under the Boost
+// Software License, Version 1.0. (See accompanying file
+// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_PROTO_FWD_HPP_EAN_04_01_2005
+#define BOOST_PROTO_FWD_HPP_EAN_04_01_2005
+
+#include <boost/proto/detail/prefix.hpp> // must be first include
+#include <cstddef>
+#include <climits>
+#include <boost/config.hpp>
+#include <boost/version.hpp>
+#include <boost/detail/workaround.hpp>
+#include <boost/preprocessor/cat.hpp>
+#include <boost/preprocessor/arithmetic/sub.hpp>
+#include <boost/preprocessor/punctuation/comma.hpp>
+#include <boost/preprocessor/repetition/enum_params_with_a_default.hpp>
+#include <boost/preprocessor/repetition/enum_trailing_binary_params.hpp>
+#include <boost/preprocessor/repetition/repeat_from_to.hpp>
+#include <boost/ref.hpp>
+#include <boost/mpl/long.hpp>
+#include <boost/type_traits/remove_const.hpp>
+#include <boost/type_traits/remove_reference.hpp>
+
+#ifndef BOOST_PROTO_MAX_ARITY
+# define BOOST_PROTO_MAX_ARITY 5
+#endif
+
+#ifndef BOOST_PROTO_MAX_LOGICAL_ARITY
+# define BOOST_PROTO_MAX_LOGICAL_ARITY 8
+#endif
+
+#ifndef BOOST_PROTO_MAX_FUNCTION_CALL_ARITY
+# define BOOST_PROTO_MAX_FUNCTION_CALL_ARITY BOOST_PROTO_MAX_ARITY
+#endif
+
+#if BOOST_PROTO_MAX_ARITY < 3
+# error BOOST_PROTO_MAX_ARITY must be at least 3
+#endif
+
+#if BOOST_PROTO_MAX_FUNCTION_CALL_ARITY > BOOST_PROTO_MAX_ARITY
+# error BOOST_PROTO_MAX_FUNCTION_CALL_ARITY cannot be larger than BOOST_PROTO_MAX_ARITY
+#endif
+
+#ifndef BOOST_PROTO_BROKEN_CONST_OVERLOADS
+# if BOOST_WORKAROUND(__GNUC__, == 3) \
+ || BOOST_WORKAROUND(__EDG_VERSION__, BOOST_TESTED_AT(306))
+# define BOOST_PROTO_BROKEN_CONST_OVERLOADS
+# endif
+#endif
+
+#ifdef BOOST_PROTO_BROKEN_CONST_OVERLOADS
+# include <boost/utility/enable_if.hpp>
+# include <boost/type_traits/is_const.hpp>
+# define BOOST_PROTO_DISABLE_IF_IS_CONST(T)\
+ , typename boost::disable_if<boost::is_const<T>, boost::proto::detail::undefined>::type * = 0
+#else
+# define BOOST_PROTO_DISABLE_IF_IS_CONST(T)
+#endif
+
+#ifndef BOOST_PROTO_BROKEN_PTS
+# if BOOST_WORKAROUND(BOOST_MSVC, <= 1400)
+# define BOOST_PROTO_BROKEN_PTS
+# endif
+#endif
+
+#if BOOST_VERSION < 103500
+#define BOOST_PROTO_FUSION_DEFINE_TAG(X) typedef X tag;
+#define BOOST_PROTO_FUSION_DEFINE_CATEGORY(X)
+#define BOOST_PROTO_FUSION_RESULT_OF meta
+#define BOOST_PROTO_FUSION_EXTENSION meta
+#define BOOST_PROTO_FUSION_AT_C(N, X) at<N>(X)
+#else
+#define BOOST_PROTO_FUSION_DEFINE_TAG(X) typedef X fusion_tag;
+#define BOOST_PROTO_FUSION_DEFINE_CATEGORY(X) typedef X category;
+#define BOOST_PROTO_FUSION_RESULT_OF result_of
+#define BOOST_PROTO_FUSION_EXTENSION extension
+#define BOOST_PROTO_FUSION_AT_C(N, X) at_c<N>(X)
+#endif
+
+#include <boost/proto/detail/suffix.hpp> // must be last include
+
+#ifdef BOOST_PROTO_BUILDING_DOCS
+// HACKHACK so Doxygen shows inheritance from mpl::true_ and mpl::false_
+namespace boost
+{
+ /// INTERNAL ONLY
+ ///
+ namespace mpl
+ {
+ /// INTERNAL ONLY
+ ///
+ struct true_ {};
+ /// INTERNAL ONLY
+ ///
+ struct false_ {};
+ }
+
+ /// INTERNAL ONLY
+ ///
+ namespace fusion
+ {
+ /// INTERNAL ONLY
+ ///
+ template<typename Function>
+ class unfused_generic {};
+ }
+}
+#define BOOST_PROTO_WHEN_BUILDING_DOCS(x) x
+#define BOOST_PROTO_WHEN_NOT_BUILDING_DOCS(x)
+#define BOOST_PROTO_BEGIN_ADL_NAMESPACE(x)
+#define BOOST_PROTO_END_ADL_NAMESPACE(x)
+#else
+#define BOOST_PROTO_WHEN_BUILDING_DOCS(x)
+#define BOOST_PROTO_WHEN_NOT_BUILDING_DOCS(x) x
+#define BOOST_PROTO_BEGIN_ADL_NAMESPACE(x) namespace x {
+#define BOOST_PROTO_END_ADL_NAMESPACE(x) }
+#endif
+
+namespace boost { namespace proto
+{
+ namespace detail
+ {
+ typedef char yes_type;
+ typedef char (&no_type)[2];
+
+ struct dont_care;
+ struct undefined; // leave this undefined
+
+ struct private_type_
+ {
+ private_type_ const &operator ,(int) const;
+ };
+
+ template<typename T>
+ struct uncvref
+ {
+ typedef T type;
+ };
+
+ template<typename T>
+ struct uncvref<T const>
+ {
+ typedef T type;
+ };
+
+ template<typename T>
+ struct uncvref<T &>
+ {
+ typedef T type;
+ };
+
+ template<typename T>
+ struct uncvref<T const &>
+ {
+ typedef T type;
+ };
+
+ struct ignore
+ {
+ ignore()
+ {}
+
+ template<typename T>
+ ignore(T const &)
+ {}
+ };
+
+ /// INTERNAL ONLY
+ ///
+ #define BOOST_PROTO_UNCVREF(X) \
+ typename boost::remove_const<typename boost::remove_reference<X>::type>::type
+ }
+
+ typedef detail::ignore const ignore;
+
+ ///////////////////////////////////////////////////////////////////////////////
+ // Operator tags
+ namespace tag
+ {
+ struct terminal;
+ struct unary_plus;
+ struct negate;
+ struct dereference;
+ struct complement;
+ struct address_of;
+ struct logical_not;
+ struct pre_inc;
+ struct pre_dec;
+ struct post_inc;
+ struct post_dec;
+
+ struct shift_left;
+ struct shift_right;
+ struct multiplies;
+ struct divides;
+ struct modulus;
+ struct plus;
+ struct minus;
+ struct less;
+ struct greater;
+ struct less_equal;
+ struct greater_equal;
+ struct equal_to;
+ struct not_equal_to;
+ struct logical_or;
+ struct logical_and;
+ struct bitwise_and;
+ struct bitwise_or;
+ struct bitwise_xor;
+ struct comma;
+ struct mem_ptr;
+
+ struct assign;
+ struct shift_left_assign;
+ struct shift_right_assign;
+ struct multiplies_assign;
+ struct divides_assign;
+ struct modulus_assign;
+ struct plus_assign;
+ struct minus_assign;
+ struct bitwise_and_assign;
+ struct bitwise_or_assign;
+ struct bitwise_xor_assign;
+ struct subscript;
+ struct if_else_;
+ struct function;
+
+ // Fusion tags
+ struct proto_expr;
+ struct proto_expr_iterator;
+ struct proto_flat_view;
+ }
+
+ ////////////////////////////////////////////////////////////////////////////////////////////////
+ BOOST_PROTO_BEGIN_ADL_NAMESPACE(wildcardns_)
+ struct _;
+ BOOST_PROTO_END_ADL_NAMESPACE(wildcardns_)
+ ////////////////////////////////////////////////////////////////////////////////////////////////
+
+ #ifndef BOOST_PROTO_BUILDING_DOCS
+ using wildcardns_::_;
+ #endif
+
+ ////////////////////////////////////////////////////////////////////////////////////////////////
+ BOOST_PROTO_BEGIN_ADL_NAMESPACE(generatorns_)
+ struct default_generator;
+
+ template<template<typename> class Extends>
+ struct generator;
+
+ template<template<typename> class Extends>
+ struct pod_generator;
+
+ struct by_value_generator;
+
+ template<typename First, typename Second>
+ struct compose_generators;
+ BOOST_PROTO_END_ADL_NAMESPACE(generatorns_)
+ ////////////////////////////////////////////////////////////////////////////////////////////////
+
+ #ifndef BOOST_PROTO_BUILDING_DOCS
+ using generatorns_::default_generator;
+ using generatorns_::generator;
+ using generatorns_::pod_generator;
+ using generatorns_::by_value_generator;
+ using generatorns_::compose_generators;
+ #endif
+
+ ////////////////////////////////////////////////////////////////////////////////////////////////
+ BOOST_PROTO_BEGIN_ADL_NAMESPACE(domainns_)
+ template<typename Generator = default_generator, typename Grammar = proto::_>
+ struct domain;
+
+ struct default_domain;
+
+ struct deduce_domain;
+ BOOST_PROTO_END_ADL_NAMESPACE(domainns_)
+ ////////////////////////////////////////////////////////////////////////////////////////////////
+
+ #ifndef BOOST_PROTO_BUILDING_DOCS
+ using domainns_::domain;
+ using domainns_::default_domain;
+ using domainns_::deduce_domain;
+ #endif
+
+ ////////////////////////////////////////////////////////////////////////////////////////////////
+ BOOST_PROTO_BEGIN_ADL_NAMESPACE(exprns_)
+ template<typename Tag, typename Args, long Arity = Args::arity>
+ struct expr;
+
+ template<
+ typename Expr
+ , typename Derived
+ , typename Domain = default_domain
+ , typename Tag = typename Expr::proto_tag
+ >
+ struct extends;
+
+ struct is_proto_expr;
+ BOOST_PROTO_END_ADL_NAMESPACE(exprns_)
+ ////////////////////////////////////////////////////////////////////////////////////////////////
+
+ #ifndef BOOST_PROTO_BUILDING_DOCS
+ using exprns_::expr;
+ using exprns_::extends;
+ using exprns_::is_proto_expr;
+ #endif
+
+ namespace control
+ {
+ template<
+ typename Grammar0
+ , typename Grammar1
+ , BOOST_PP_ENUM_PARAMS_WITH_A_DEFAULT(
+ BOOST_PP_SUB(BOOST_PROTO_MAX_LOGICAL_ARITY,2)
+ , typename G
+ , void
+ )
+ >
+ struct or_;
+
+ template<
+ typename Grammar0
+ , typename Grammar1
+ , BOOST_PP_ENUM_PARAMS_WITH_A_DEFAULT(
+ BOOST_PP_SUB(BOOST_PROTO_MAX_LOGICAL_ARITY,2)
+ , typename G
+ , void
+ )
+ >
+ struct and_;
+
+ template<typename Grammar>
+ struct not_;
+
+ template<typename Condition, typename Then = _, typename Else = not_<_> >
+ struct if_;
+
+ template<typename Cases>
+ struct switch_;
+
+ template<typename T>
+ struct exact;
+
+ template<typename T>
+ struct convertible_to;
+
+ template<typename Grammar>
+ struct vararg;
+
+ int const N = INT_MAX;
+ }
+
+ using control::if_;
+ using control::or_;
+ using control::and_;
+ using control::not_;
+ using control::switch_;
+ using control::exact;
+ using control::convertible_to;
+ using control::vararg;
+ using control::N;
+
+ namespace context
+ {
+ struct null_context;
+
+ template<typename Expr, typename Context, long Arity = Expr::proto_arity::value>
+ struct null_eval;
+
+ struct default_context;
+
+ template<typename Expr, typename Context, typename Tag = typename Expr::proto_tag, long Arity = Expr::proto_arity::value>
+ struct default_eval;
+
+ template<typename Derived, typename DefaultCtx = default_context>
+ struct callable_context;
+
+ template<typename Expr, typename Context, long Arity = Expr::proto_arity::value>
+ struct callable_eval;
+ }
+
+ using context::null_context;
+ using context::null_eval;
+ using context::default_context;
+ using context::default_eval;
+ using context::callable_context;
+ using context::callable_eval;
+
+ namespace utility
+ {
+ template<typename T, typename Domain = default_domain>
+ struct literal;
+ }
+
+ using utility::literal;
+
+ namespace result_of
+ {
+ template<
+ typename T
+ , typename Domain = default_domain
+ , typename Void = void
+ #ifdef BOOST_PROTO_BROKEN_PTS
+ , typename Void2 = void
+ #endif
+ >
+ struct as_expr;
+
+ template<
+ typename T
+ , typename Domain = default_domain
+ , typename Void = void
+ #ifdef BOOST_PROTO_BROKEN_PTS
+ , typename Void2 = void
+ #endif
+ >
+ struct as_child;
+
+ template<typename Expr, typename N = mpl::long_<0> >
+ struct child;
+
+ template<typename Expr, long N>
+ struct child_c;
+
+ template<typename Expr>
+ struct left;
+
+ template<typename Expr>
+ struct right;
+
+ template<typename Expr>
+ struct deep_copy;
+
+ template<typename T>
+ struct unref;
+
+ template<typename Expr, typename Context>
+ struct eval;
+
+ template<
+ typename Tag
+ , typename DomainOrA0
+ BOOST_PP_ENUM_TRAILING_BINARY_PARAMS(
+ BOOST_PROTO_MAX_ARITY
+ , typename A
+ , = void BOOST_PP_INTERCEPT
+ )
+ , typename Void = void
+ >
+ struct make_expr;
+
+ template<typename Tag, typename DomainOrSequence, typename SequenceOrVoid = void, typename Void = void>
+ struct unpack_expr;
+
+ template<typename T, typename Void = void>
+ struct is_ref;
+
+ template<typename T, typename Void = void>
+ struct is_expr;
+
+ template<typename T, typename Void = void>
+ struct is_domain;
+
+ template<typename Expr>
+ struct tag_of;
+
+ template<typename T, typename Void = void>
+ struct domain_of;
+
+ template<typename Expr, typename Grammar>
+ struct matches;
+ }
+
+ using result_of::is_ref;
+ using result_of::is_expr;
+ using result_of::is_domain;
+ using result_of::tag_of;
+ using result_of::domain_of;
+ using result_of::matches;
+
+ namespace op
+ {
+ // Generic expression metafunctions and
+ // grammar elements
+ template<typename Tag, typename Arg>
+ struct unary_expr;
+
+ template<typename Tag, typename Left, typename Right>
+ struct binary_expr;
+
+ template<typename Tag, BOOST_PP_ENUM_PARAMS_WITH_A_DEFAULT(BOOST_PROTO_MAX_ARITY, typename A, void), typename Dummy = void>
+ struct nary_expr;
+
+ // Specific expression metafunctions and
+ // grammar elements, for convenience
+ template<typename T> struct terminal;
+ template<typename T> struct unary_plus;
+ template<typename T> struct negate;
+ template<typename T> struct dereference;
+ template<typename T> struct complement;
+ template<typename T> struct address_of;
+ template<typename T> struct logical_not;
+ template<typename T> struct pre_inc;
+ template<typename T> struct pre_dec;
+ template<typename T> struct post_inc;
+ template<typename T> struct post_dec;
+
+ template<typename T, typename U> struct shift_left;
+ template<typename T, typename U> struct shift_right;
+ template<typename T, typename U> struct multiplies;
+ template<typename T, typename U> struct divides;
+ template<typename T, typename U> struct modulus;
+ template<typename T, typename U> struct plus;
+ template<typename T, typename U> struct minus;
+ template<typename T, typename U> struct less;
+ template<typename T, typename U> struct greater;
+ template<typename T, typename U> struct less_equal;
+ template<typename T, typename U> struct greater_equal;
+ template<typename T, typename U> struct equal_to;
+ template<typename T, typename U> struct not_equal_to;
+ template<typename T, typename U> struct logical_or;
+ template<typename T, typename U> struct logical_and;
+ template<typename T, typename U> struct bitwise_and;
+ template<typename T, typename U> struct bitwise_or;
+ template<typename T, typename U> struct bitwise_xor;
+ template<typename T, typename U> struct comma;
+ template<typename T, typename U> struct mem_ptr;
+
+ template<typename T, typename U> struct assign;
+ template<typename T, typename U> struct shift_left_assign;
+ template<typename T, typename U> struct shift_right_assign;
+ template<typename T, typename U> struct multiplies_assign;
+ template<typename T, typename U> struct divides_assign;
+ template<typename T, typename U> struct modulus_assign;
+ template<typename T, typename U> struct plus_assign;
+ template<typename T, typename U> struct minus_assign;
+ template<typename T, typename U> struct bitwise_and_assign;
+ template<typename T, typename U> struct bitwise_or_assign;
+ template<typename T, typename U> struct bitwise_xor_assign;
+ template<typename T, typename U> struct subscript;
+ template<typename T, typename U, typename V> struct if_else_;
+
+ template<BOOST_PP_ENUM_PARAMS_WITH_A_DEFAULT(BOOST_PROTO_MAX_ARITY, typename A, void), typename Dummy = void>
+ struct function;
+ }
+
+ using namespace op;
+
+ namespace functor
+ {
+ struct left;
+ struct right;
+ struct eval;
+ struct deep_copy;
+
+ template<typename Domain = default_domain>
+ struct as_expr;
+
+ template<typename Domain = default_domain>
+ struct as_child;
+
+ template<typename N = mpl::long_<0> >
+ struct child;
+
+ template<long N>
+ struct child_c;
+
+ template<typename Tag, typename Domain = deduce_domain>
+ struct make_expr;
+
+ template<typename Tag, typename Domain = deduce_domain>
+ struct unpack_expr;
+
+ template<typename Tag, typename Domain = deduce_domain>
+ struct unfused_expr_fun;
+
+ template<typename Tag, typename Domain = deduce_domain>
+ struct unfused_expr;
+
+ typedef make_expr<tag::terminal> make_terminal;
+ typedef make_expr<tag::unary_plus> make_posit;
+ typedef make_expr<tag::negate> make_negate;
+ typedef make_expr<tag::dereference> make_dereference;
+ typedef make_expr<tag::complement> make_complement;
+ typedef make_expr<tag::address_of> make_address_of;
+ typedef make_expr<tag::logical_not> make_logical_not;
+ typedef make_expr<tag::pre_inc> make_pre_inc;
+ typedef make_expr<tag::pre_dec> make_pre_dec;
+ typedef make_expr<tag::post_inc> make_post_inc;
+ typedef make_expr<tag::post_dec> make_post_dec;
+ typedef make_expr<tag::shift_left> make_shift_left;
+ typedef make_expr<tag::shift_right> make_shift_right;
+ typedef make_expr<tag::multiplies> make_multiplies;
+ typedef make_expr<tag::divides> make_divides;
+ typedef make_expr<tag::modulus> make_modulus;
+ typedef make_expr<tag::plus> make_plus;
+ typedef make_expr<tag::minus> make_minus;
+ typedef make_expr<tag::less> make_less;
+ typedef make_expr<tag::greater> make_greater;
+ typedef make_expr<tag::less_equal> make_less_equal;
+ typedef make_expr<tag::greater_equal> make_greater_equal;
+ typedef make_expr<tag::equal_to> make_equal_to;
+ typedef make_expr<tag::not_equal_to> make_not_equal_to;
+ typedef make_expr<tag::logical_or> make_logical_or;
+ typedef make_expr<tag::logical_and> make_logical_and;
+ typedef make_expr<tag::bitwise_and> make_bitwise_and;
+ typedef make_expr<tag::bitwise_or> make_bitwise_or;
+ typedef make_expr<tag::bitwise_xor> make_bitwise_xor;
+ typedef make_expr<tag::comma> make_comma;
+ typedef make_expr<tag::mem_ptr> make_mem_ptr;
+ typedef make_expr<tag::assign> make_assign;
+ typedef make_expr<tag::shift_left_assign> make_shift_left_assign;
+ typedef make_expr<tag::shift_right_assign> make_shift_right_assign;
+ typedef make_expr<tag::multiplies_assign> make_multiplies_assign;
+ typedef make_expr<tag::divides_assign> make_divides_assign;
+ typedef make_expr<tag::modulus_assign> make_modulus_assign;
+ typedef make_expr<tag::plus_assign> make_plus_assign;
+ typedef make_expr<tag::minus_assign> make_minus_assign;
+ typedef make_expr<tag::bitwise_and_assign> make_bitwise_and_assign;
+ typedef make_expr<tag::bitwise_or_assign> make_bitwise_or_assign;
+ typedef make_expr<tag::bitwise_xor_assign> make_bitwise_xor_assign;
+ typedef make_expr<tag::subscript> make_subscript;
+ typedef make_expr<tag::if_else_> make_if_else;
+ typedef make_expr<tag::function> make_function;
+
+ struct flatten;
+ struct pop_front;
+ struct reverse;
+ }
+
+ typedef functor::make_terminal _make_terminal;
+ typedef functor::make_posit _make_posit;
+ typedef functor::make_negate _make_negate;
+ typedef functor::make_dereference _make_dereference;
+ typedef functor::make_complement _make_complement;
+ typedef functor::make_address_of _make_address_of;
+ typedef functor::make_logical_not _make_logical_not;
+ typedef functor::make_pre_inc _make_pre_inc;
+ typedef functor::make_pre_dec _make_pre_dec;
+ typedef functor::make_post_inc _make_post_inc;
+ typedef functor::make_post_dec _make_post_dec;
+ typedef functor::make_shift_left _make_shift_left;
+ typedef functor::make_shift_right _make_shift_right;
+ typedef functor::make_multiplies _make_multiplies;
+ typedef functor::make_divides _make_divides;
+ typedef functor::make_modulus _make_modulus;
+ typedef functor::make_plus _make_plus;
+ typedef functor::make_minus _make_minus;
+ typedef functor::make_less _make_less;
+ typedef functor::make_greater _make_greater;
+ typedef functor::make_less_equal _make_less_equal;
+ typedef functor::make_greater_equal _make_greater_equal;
+ typedef functor::make_equal_to _make_equal_to;
+ typedef functor::make_not_equal_to _make_not_equal_to;
+ typedef functor::make_logical_or _make_logical_or;
+ typedef functor::make_logical_and _make_logical_and;
+ typedef functor::make_bitwise_and _make_bitwise_and;
+ typedef functor::make_bitwise_or _make_bitwise_or;
+ typedef functor::make_bitwise_xor _make_bitwise_xor;
+ typedef functor::make_comma _make_comma;
+ typedef functor::make_mem_ptr _make_mem_ptr;
+ typedef functor::make_assign _make_assign;
+ typedef functor::make_shift_left_assign _make_shift_left_assign;
+ typedef functor::make_shift_right_assign _make_shift_right_assign;
+ typedef functor::make_multiplies_assign _make_multiplies_assign;
+ typedef functor::make_divides_assign _make_divides_assign;
+ typedef functor::make_modulus_assign _make_modulus_assign;
+ typedef functor::make_plus_assign _make_plus_assign;
+ typedef functor::make_minus_assign _make_minus_assign;
+ typedef functor::make_bitwise_and_assign _make_bitwise_and_assign;
+ typedef functor::make_bitwise_or_assign _make_bitwise_or_assign;
+ typedef functor::make_bitwise_xor_assign _make_bitwise_xor_assign;
+ typedef functor::make_subscript _make_subscript;
+ typedef functor::make_if_else _make_if_else;
+ typedef functor::make_function _make_function;
+
+ typedef functor::flatten _flatten;
+ typedef functor::pop_front _pop_front;
+ typedef functor::reverse _reverse;
+ typedef functor::eval _eval;
+ typedef functor::deep_copy _deep_copy;
+
+ template<typename T>
+ struct is_callable;
+
+ template<typename T>
+ struct is_aggregate;
+
+ template<typename T, typename Void = void>
+ struct is_transform;
+
+ #define BOOST_PROTO_CALLABLE() typedef void proto_is_callable_;
+
+ struct callable
+ {
+ BOOST_PROTO_CALLABLE()
+ };
+
+ template<typename Grammar, typename Fun = Grammar>
+ struct when;
+
+ template<typename Fun>
+ struct otherwise;
+
+ template<typename Fun>
+ struct call;
+
+ template<typename Fun>
+ struct make;
+
+ template<typename Fun>
+ struct bind;
+
+ template<typename Sequence, typename State, typename Fun>
+ struct fold;
+
+ template<typename Sequence, typename State, typename Fun>
+ struct reverse_fold;
+
+ // BUGBUG can we replace fold_tree with fold<flatten(_), state, fun> ?
+ template<typename Sequence, typename State, typename Fun>
+ struct fold_tree;
+
+ template<typename Sequence, typename State, typename Fun>
+ struct reverse_fold_tree;
+
+ template<typename Grammar>
+ struct pass_through;
+
+ struct _expr;
+ struct _state;
+ struct _data;
+
+ template<int I>
+ struct _child_c;
+
+ typedef _child_c<0> _child0;
+ typedef _child_c<1> _child1;
+ typedef _child_c<2> _child2;
+ typedef _child0 _child;
+ typedef _child0 _value;
+ typedef _child0 _left;
+ typedef _child1 _right;
+
+ // child3, child4, child5, ...
+ #define M0(Z, N, DATA) typedef _child_c<N> BOOST_PP_CAT(_child, N);
+ BOOST_PP_REPEAT_FROM_TO(
+ 3
+ , BOOST_PP_DEC(BOOST_PROTO_MAX_ARITY)
+ , M0
+ , ~
+ )
+ #undef M0
+
+ struct _ref;
+
+ template<typename T>
+ struct is_extension;
+
+ namespace exops
+ {}
+
+}} // namespace boost::proto
+
+#endif

Added: branches/proto/v4/boost/proto/proto_typeof.hpp
==============================================================================
--- (empty file)
+++ branches/proto/v4/boost/proto/proto_typeof.hpp 2008-04-06 02:19:35 EDT (Sun, 06 Apr 2008)
@@ -0,0 +1,134 @@
+///////////////////////////////////////////////////////////////////////////////
+/// \file proto_typeof.hpp
+/// Type registrations so that proto expression templates can be used together
+/// with the Boost.Typeof library.
+//
+// Copyright 2008 Eric Niebler. Distributed under the Boost
+// Software License, Version 1.0. (See accompanying file
+// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_XPRESSIVE_PROTO_PROTO_TYPEOF_H
+#define BOOST_XPRESSIVE_PROTO_PROTO_TYPEOF_H
+
+#include <boost/proto/detail/prefix.hpp>
+#include <boost/config.hpp>
+#include <boost/typeof/typeof.hpp>
+#include <boost/proto/proto_fwd.hpp>
+#include <boost/proto/deep_copy.hpp>
+#include BOOST_TYPEOF_INCREMENT_REGISTRATION_GROUP()
+#include <boost/proto/detail/suffix.hpp>
+
+BOOST_TYPEOF_REGISTER_TYPE(boost::proto::tag::terminal)
+BOOST_TYPEOF_REGISTER_TYPE(boost::proto::tag::unary_plus)
+BOOST_TYPEOF_REGISTER_TYPE(boost::proto::tag::negate)
+BOOST_TYPEOF_REGISTER_TYPE(boost::proto::tag::dereference)
+BOOST_TYPEOF_REGISTER_TYPE(boost::proto::tag::complement)
+BOOST_TYPEOF_REGISTER_TYPE(boost::proto::tag::address_of)
+BOOST_TYPEOF_REGISTER_TYPE(boost::proto::tag::logical_not)
+BOOST_TYPEOF_REGISTER_TYPE(boost::proto::tag::pre_inc)
+BOOST_TYPEOF_REGISTER_TYPE(boost::proto::tag::pre_dec)
+BOOST_TYPEOF_REGISTER_TYPE(boost::proto::tag::post_inc)
+BOOST_TYPEOF_REGISTER_TYPE(boost::proto::tag::post_dec)
+BOOST_TYPEOF_REGISTER_TYPE(boost::proto::tag::shift_left)
+BOOST_TYPEOF_REGISTER_TYPE(boost::proto::tag::shift_right)
+BOOST_TYPEOF_REGISTER_TYPE(boost::proto::tag::multiplies)
+BOOST_TYPEOF_REGISTER_TYPE(boost::proto::tag::divides)
+BOOST_TYPEOF_REGISTER_TYPE(boost::proto::tag::modulus)
+BOOST_TYPEOF_REGISTER_TYPE(boost::proto::tag::plus)
+BOOST_TYPEOF_REGISTER_TYPE(boost::proto::tag::minus)
+BOOST_TYPEOF_REGISTER_TYPE(boost::proto::tag::less)
+BOOST_TYPEOF_REGISTER_TYPE(boost::proto::tag::greater)
+BOOST_TYPEOF_REGISTER_TYPE(boost::proto::tag::less_equal)
+BOOST_TYPEOF_REGISTER_TYPE(boost::proto::tag::greater_equal)
+BOOST_TYPEOF_REGISTER_TYPE(boost::proto::tag::equal_to)
+BOOST_TYPEOF_REGISTER_TYPE(boost::proto::tag::not_equal_to)
+BOOST_TYPEOF_REGISTER_TYPE(boost::proto::tag::logical_or)
+BOOST_TYPEOF_REGISTER_TYPE(boost::proto::tag::logical_and)
+BOOST_TYPEOF_REGISTER_TYPE(boost::proto::tag::bitwise_and)
+BOOST_TYPEOF_REGISTER_TYPE(boost::proto::tag::bitwise_or)
+BOOST_TYPEOF_REGISTER_TYPE(boost::proto::tag::bitwise_xor)
+BOOST_TYPEOF_REGISTER_TYPE(boost::proto::tag::comma)
+BOOST_TYPEOF_REGISTER_TYPE(boost::proto::tag::mem_ptr)
+BOOST_TYPEOF_REGISTER_TYPE(boost::proto::tag::assign)
+BOOST_TYPEOF_REGISTER_TYPE(boost::proto::tag::shift_left_assign)
+BOOST_TYPEOF_REGISTER_TYPE(boost::proto::tag::shift_right_assign)
+BOOST_TYPEOF_REGISTER_TYPE(boost::proto::tag::multiplies_assign)
+BOOST_TYPEOF_REGISTER_TYPE(boost::proto::tag::divides_assign)
+BOOST_TYPEOF_REGISTER_TYPE(boost::proto::tag::modulus_assign)
+BOOST_TYPEOF_REGISTER_TYPE(boost::proto::tag::plus_assign)
+BOOST_TYPEOF_REGISTER_TYPE(boost::proto::tag::minus_assign)
+BOOST_TYPEOF_REGISTER_TYPE(boost::proto::tag::bitwise_and_assign)
+BOOST_TYPEOF_REGISTER_TYPE(boost::proto::tag::bitwise_or_assign)
+BOOST_TYPEOF_REGISTER_TYPE(boost::proto::tag::bitwise_xor_assign)
+BOOST_TYPEOF_REGISTER_TYPE(boost::proto::tag::subscript)
+BOOST_TYPEOF_REGISTER_TYPE(boost::proto::tag::if_else_)
+BOOST_TYPEOF_REGISTER_TYPE(boost::proto::tag::function)
+
+BOOST_TYPEOF_REGISTER_TYPE(boost::proto::exprns_::is_proto_expr)
+BOOST_TYPEOF_REGISTER_TEMPLATE(boost::proto::exprns_::expr, (typename)(typename)(long))
+BOOST_TYPEOF_REGISTER_TEMPLATE(boost::proto::utility::literal, (typename)(typename))
+
+BOOST_TYPEOF_REGISTER_TEMPLATE(boost::proto::argsns_::term, 1)
+BOOST_TYPEOF_REGISTER_TEMPLATE(boost::proto::argsns_::list1, 1)
+BOOST_TYPEOF_REGISTER_TEMPLATE(boost::proto::argsns_::list2, 2)
+// can't use PP metaprogramming here because all typeof registrations
+// must be on separate lines.
+#if BOOST_PROTO_MAX_ARITY >= 3
+BOOST_TYPEOF_REGISTER_TEMPLATE(boost::proto::argsns_::list3, 3)
+#endif
+#if BOOST_PROTO_MAX_ARITY >= 4
+BOOST_TYPEOF_REGISTER_TEMPLATE(boost::proto::argsns_::list4, 4)
+#endif
+#if BOOST_PROTO_MAX_ARITY >= 5
+BOOST_TYPEOF_REGISTER_TEMPLATE(boost::proto::argsns_::list5, 5)
+#endif
+#if BOOST_PROTO_MAX_ARITY >= 6
+BOOST_TYPEOF_REGISTER_TEMPLATE(boost::proto::argsns_::list6, 6)
+#endif
+#if BOOST_PROTO_MAX_ARITY >= 7
+BOOST_TYPEOF_REGISTER_TEMPLATE(boost::proto::argsns_::list7, 7)
+#endif
+#if BOOST_PROTO_MAX_ARITY >= 8
+BOOST_TYPEOF_REGISTER_TEMPLATE(boost::proto::argsns_::list8, 8)
+#endif
+#if BOOST_PROTO_MAX_ARITY >= 9
+BOOST_TYPEOF_REGISTER_TEMPLATE(boost::proto::argsns_::list9, 9)
+#endif
+#if BOOST_PROTO_MAX_ARITY >= 10
+BOOST_TYPEOF_REGISTER_TEMPLATE(boost::proto::argsns_::list10, 10)
+#endif
+#if BOOST_PROTO_MAX_ARITY >= 11
+BOOST_TYPEOF_REGISTER_TEMPLATE(boost::proto::argsns_::list11, 11)
+#endif
+#if BOOST_PROTO_MAX_ARITY >= 12
+BOOST_TYPEOF_REGISTER_TEMPLATE(boost::proto::argsns_::list12, 12)
+#endif
+#if BOOST_PROTO_MAX_ARITY >= 13
+BOOST_TYPEOF_REGISTER_TEMPLATE(boost::proto::argsns_::list13, 13)
+#endif
+#if BOOST_PROTO_MAX_ARITY >= 14
+BOOST_TYPEOF_REGISTER_TEMPLATE(boost::proto::argsns_::list14, 14)
+#endif
+#if BOOST_PROTO_MAX_ARITY >= 15
+BOOST_TYPEOF_REGISTER_TEMPLATE(boost::proto::argsns_::list15, 15)
+#endif
+#if BOOST_PROTO_MAX_ARITY >= 16
+BOOST_TYPEOF_REGISTER_TEMPLATE(boost::proto::argsns_::list16, 16)
+#endif
+#if BOOST_PROTO_MAX_ARITY >= 17
+BOOST_TYPEOF_REGISTER_TEMPLATE(boost::proto::argsns_::list17, 17)
+#endif
+#if BOOST_PROTO_MAX_ARITY >= 18
+BOOST_TYPEOF_REGISTER_TEMPLATE(boost::proto::argsns_::list18, 18)
+#endif
+#if BOOST_PROTO_MAX_ARITY >= 19
+BOOST_TYPEOF_REGISTER_TEMPLATE(boost::proto::argsns_::list19, 19)
+#endif
+#if BOOST_PROTO_MAX_ARITY >= 20
+BOOST_TYPEOF_REGISTER_TEMPLATE(boost::proto::argsns_::list20, 20)
+#endif
+
+#define BOOST_PROTO_AUTO(Var, Expr) BOOST_AUTO(Var, boost::proto::deep_copy(Expr))
+#define BOOST_PROTO_AUTO_TPL(Var, Expr) BOOST_AUTO_TPL(Var, boost::proto::deep_copy(Expr))
+
+#endif

Added: branches/proto/v4/boost/proto/ref.hpp
==============================================================================
--- (empty file)
+++ branches/proto/v4/boost/proto/ref.hpp 2008-04-06 02:19:35 EDT (Sun, 06 Apr 2008)
@@ -0,0 +1,108 @@
+///////////////////////////////////////////////////////////////////////////////
+/// \file ref.hpp
+/// Utility for storing a sub-expr by reference
+//
+// Copyright 2008 Eric Niebler. Distributed under the Boost
+// Software License, Version 1.0. (See accompanying file
+// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_PROTO_REF_HPP_EAN_04_01_2005
+#define BOOST_PROTO_REF_HPP_EAN_04_01_2005
+
+#include <boost/proto/detail/prefix.hpp>
+#include <boost/preprocessor/repetition/repeat.hpp>
+#include <boost/mpl/if.hpp>
+#include <boost/mpl/bool.hpp>
+#include <boost/type_traits/is_const.hpp>
+#include <boost/proto/proto_fwd.hpp>
+#include <boost/proto/detail/suffix.hpp>
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+# pragma warning(push)
+# pragma warning(disable : 4510) // default constructor could not be generated
+# pragma warning(disable : 4512) // assignment operator could not be generated
+# pragma warning(disable : 4610) // user defined constructor required
+#endif
+
+namespace boost { namespace proto
+{
+ namespace result_of
+ {
+ /// \brief Trait for stripping top-level references
+ /// and reference wrappers.
+ template<typename T>
+ struct unref
+ {
+ typedef T type; ///< Suitable for return by value
+ typedef T &reference; ///< Suitable for return by reference
+ typedef T const &const_reference; ///< Suitable for return by const reference
+ };
+
+ /// \brief Trait for stripping top-level references
+ /// and reference wrappers.
+ template<typename T>
+ struct unref<T &>
+ {
+ typedef T type; ///< Suitable for return by value
+ typedef T &reference; ///< Suitable for return by reference
+ typedef T &const_reference; ///< Suitable for return by const reference
+ };
+
+ /// \brief Trait for stripping top-level references
+ /// and reference wrappers.
+ template<typename T>
+ struct unref<T const &>
+ {
+ typedef T type; ///< Suitable for return by value
+ typedef T const &reference; ///< Suitable for return by reference
+ typedef T const &const_reference; ///< Suitable for return by const reference
+ };
+
+ /// \brief Trait for stripping top-level references
+ /// and reference wrappers.
+ template<typename T, std::size_t N>
+ struct unref<T (&)[N]>
+ {
+ typedef T (&type)[N]; ///< Suitable for return by value
+ typedef T (&reference)[N]; ///< Suitable for return by reference
+ typedef T (&const_reference)[N]; ///< Suitable for return by const reference
+ };
+
+ /// \brief Trait for stripping top-level references
+ /// and reference wrappers.
+ template<typename T, std::size_t N>
+ struct unref<T const (&)[N]>
+ {
+ typedef T const (&type)[N]; ///< Suitable for return by value
+ typedef T const (&reference)[N]; ///< Suitable for return by reference
+ typedef T const (&const_reference)[N]; ///< Suitable for return by const reference
+ };
+
+ /// \brief Trait for stripping top-level references
+ /// and reference wrappers.
+ template<typename T, std::size_t N>
+ struct unref<T[N]>
+ {
+ typedef T (&type)[N]; ///< Suitable for return by value
+ typedef T (&reference)[N]; ///< Suitable for return by reference
+ typedef T const (&const_reference)[N]; ///< Suitable for return by const reference
+ };
+
+ /// \brief Trait for stripping top-level references
+ /// and reference wrappers.
+ template<typename T, std::size_t N>
+ struct unref<T const[N]>
+ {
+ typedef T const (&type)[N]; ///< Suitable for return by value
+ typedef T const (&reference)[N]; ///< Suitable for return by reference
+ typedef T const (&const_reference)[N]; ///< Suitable for return by const reference
+ };
+ }
+
+}}
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+# pragma warning(pop)
+#endif
+
+#endif

Added: branches/proto/v4/boost/proto/tags.hpp
==============================================================================
--- (empty file)
+++ branches/proto/v4/boost/proto/tags.hpp 2008-04-06 02:19:35 EDT (Sun, 06 Apr 2008)
@@ -0,0 +1,156 @@
+///////////////////////////////////////////////////////////////////////////////
+/// \file tags.hpp
+/// Contains the tags for all the overloadable operators in C++
+//
+// Copyright 2008 Eric Niebler. Distributed under the Boost
+// Software License, Version 1.0. (See accompanying file
+// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_PROTO_TAGS_HPP_EAN_04_01_2005
+#define BOOST_PROTO_TAGS_HPP_EAN_04_01_2005
+
+#include <boost/proto/detail/prefix.hpp>
+#include <boost/proto/proto_fwd.hpp>
+#include <boost/proto/detail/suffix.hpp>
+
+namespace boost { namespace proto { namespace tag
+{
+
+ /// Tag type for terminals; aka, leaves in the expression tree.
+ struct terminal {};
+
+ /// Tag type for the unary + operator.
+ struct unary_plus {};
+
+ /// Tag type for the unary - operator.
+ struct negate {};
+
+ /// Tag type for the unary * operator.
+ struct dereference {};
+
+ /// Tag type for the unary ~ operator.
+ struct complement {};
+
+ /// Tag type for the unary & operator.
+ struct address_of {};
+
+ /// Tag type for the unary ! operator.
+ struct logical_not {};
+
+ /// Tag type for the unary prefix ++ operator.
+ struct pre_inc {};
+
+ /// Tag type for the unary prefix -- operator.
+ struct pre_dec {};
+
+ /// Tag type for the unary postfix ++ operator.
+ struct post_inc {};
+
+ /// Tag type for the unary postfix -- operator.
+ struct post_dec {};
+
+ /// Tag type for the binary \<\< operator.
+ struct shift_left {};
+
+ /// Tag type for the binary \>\> operator.
+ struct shift_right {};
+
+ /// Tag type for the binary * operator.
+ struct multiplies {};
+
+ /// Tag type for the binary / operator.
+ struct divides {};
+
+ /// Tag type for the binary % operator.
+ struct modulus {};
+
+ /// Tag type for the binary + operator.
+ struct plus {};
+
+ /// Tag type for the binary - operator.
+ struct minus {};
+
+ /// Tag type for the binary \< operator.
+ struct less {};
+
+ /// Tag type for the binary \> operator.
+ struct greater {};
+
+ /// Tag type for the binary \<= operator.
+ struct less_equal {};
+
+ /// Tag type for the binary \>= operator.
+ struct greater_equal {};
+
+ /// Tag type for the binary == operator.
+ struct equal_to {};
+
+ /// Tag type for the binary != operator.
+ struct not_equal_to {};
+
+ /// Tag type for the binary || operator.
+ struct logical_or {};
+
+ /// Tag type for the binary && operator.
+ struct logical_and {};
+
+ /// Tag type for the binary & operator.
+ struct bitwise_and {};
+
+ /// Tag type for the binary | operator.
+ struct bitwise_or {};
+
+ /// Tag type for the binary ^ operator.
+ struct bitwise_xor {};
+
+ /// Tag type for the binary , operator.
+ struct comma {};
+
+ /// Tag type for the binary ->* operator.
+ struct mem_ptr {};
+
+ /// Tag type for the binary = operator.
+ struct assign {};
+
+ /// Tag type for the binary \<\<= operator.
+ struct shift_left_assign {};
+
+ /// Tag type for the binary \>\>= operator.
+ struct shift_right_assign {};
+
+ /// Tag type for the binary *= operator.
+ struct multiplies_assign {};
+
+ /// Tag type for the binary /= operator.
+ struct divides_assign {};
+
+ /// Tag type for the binary %= operator.
+ struct modulus_assign {};
+
+ /// Tag type for the binary += operator.
+ struct plus_assign {};
+
+ /// Tag type for the binary -= operator.
+ struct minus_assign {};
+
+ /// Tag type for the binary &= operator.
+ struct bitwise_and_assign {};
+
+ /// Tag type for the binary |= operator.
+ struct bitwise_or_assign {};
+
+ /// Tag type for the binary ^= operator.
+ struct bitwise_xor_assign {};
+
+ /// Tag type for the binary subscript operator.
+ struct subscript {};
+
+ /// Tag type for the ternary ?: conditional operator.
+ struct if_else_ {};
+
+ /// Tag type for the n-ary function call operator.
+ struct function {};
+
+}}}
+
+#endif

Added: branches/proto/v4/boost/proto/traits.hpp
==============================================================================
--- (empty file)
+++ branches/proto/v4/boost/proto/traits.hpp 2008-04-06 02:19:35 EDT (Sun, 06 Apr 2008)
@@ -0,0 +1,2340 @@
+#ifndef BOOST_PP_IS_ITERATING
+ ///////////////////////////////////////////////////////////////////////////////
+ /// \file traits.hpp
+ /// Contains definitions for child\<\>, child_c\<\>, left\<\>,
+ /// right\<\>, tag_of\<\>, and the helper functions child(), child_c(),
+ /// value(), left() and right().
+ //
+ // Copyright 2008 Eric Niebler. Distributed under the Boost
+ // Software License, Version 1.0. (See accompanying file
+ // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+ #ifndef BOOST_PROTO_ARG_TRAITS_HPP_EAN_04_01_2005
+ #define BOOST_PROTO_ARG_TRAITS_HPP_EAN_04_01_2005
+
+ #include <boost/proto/detail/prefix.hpp>
+ #include <boost/config.hpp>
+ #include <boost/detail/workaround.hpp>
+ #include <boost/preprocessor/iteration/iterate.hpp>
+ #include <boost/preprocessor/repetition/enum.hpp>
+ #include <boost/preprocessor/repetition/enum_params.hpp>
+ #include <boost/preprocessor/repetition/enum_trailing.hpp>
+ #include <boost/preprocessor/repetition/enum_trailing_params.hpp>
+ #include <boost/preprocessor/repetition/repeat.hpp>
+ #include <boost/preprocessor/repetition/repeat_from_to.hpp>
+ #include <boost/preprocessor/facilities/intercept.hpp>
+ #include <boost/preprocessor/arithmetic/sub.hpp>
+ #include <boost/ref.hpp>
+ #include <boost/mpl/if.hpp>
+ #include <boost/mpl/or.hpp>
+ #include <boost/mpl/bool.hpp>
+ #include <boost/mpl/eval_if.hpp>
+ #include <boost/mpl/aux_/template_arity.hpp>
+ #include <boost/mpl/aux_/lambda_arity_param.hpp>
+ #include <boost/static_assert.hpp>
+ #include <boost/utility/result_of.hpp>
+ #include <boost/utility/enable_if.hpp>
+ #include <boost/type_traits/is_pod.hpp>
+ #include <boost/type_traits/is_same.hpp>
+ #include <boost/type_traits/is_function.hpp>
+ #include <boost/type_traits/remove_cv.hpp>
+ #include <boost/type_traits/remove_const.hpp>
+ #include <boost/type_traits/add_reference.hpp>
+ #include <boost/proto/proto_fwd.hpp>
+ #include <boost/proto/ref.hpp>
+ #include <boost/proto/args.hpp>
+ #include <boost/proto/tags.hpp>
+ #include <boost/proto/transform/pass_through.hpp>
+ #include <boost/proto/detail/suffix.hpp>
+
+ #if BOOST_WORKAROUND( BOOST_MSVC, >= 1400 )
+ #pragma warning(push)
+ #pragma warning(disable: 4180) // warning C4180: qualifier applied to function type has no meaning; ignored
+ #endif
+
+ namespace boost { namespace proto
+ {
+ namespace detail
+ {
+ template<typename T, typename Void = void>
+ struct if_vararg
+ {};
+
+ template<typename T>
+ struct if_vararg<T, typename T::proto_is_vararg_>
+ : T
+ {};
+
+ template<typename T, typename Void = void>
+ struct is_callable2_
+ : mpl::false_
+ {};
+
+ template<typename T>
+ struct is_callable2_<T, typename T::proto_is_callable_>
+ : mpl::true_
+ {};
+
+ template<typename T BOOST_MPL_AUX_LAMBDA_ARITY_PARAM(long Arity = mpl::aux::template_arity<T>::value)>
+ struct is_callable_
+ : is_callable2_<T>
+ {};
+ }
+
+ /// \brief Boolean metafunction which detects whether a type is
+ /// a callable function object type or not.
+ ///
+ /// <tt>is_callable\<\></tt> is used by the <tt>when\<\></tt> transform
+ /// to determine whether a function type <tt>R(A1,A2,...AN)</tt> is a
+ /// callable transform or an object transform. (The former are evaluated
+ /// using <tt>call\<\></tt> and the later with <tt>make\<\></tt>.) If
+ /// <tt>is_callable\<R\>::::value</tt> is \c true, the function type is
+ /// a callable transform; otherwise, it is an object transform.
+ ///
+ /// Unless specialized for a type \c T, <tt>is_callable\<T\>::::value</tt>
+ /// is computed as follows:
+ ///
+ /// \li If \c T is a template type <tt>X\<Y0,Y1,...YN\></tt>, where all \c Yx
+ /// are types for \c x in <tt>[0,N]</tt>, <tt>is_callable\<T\>::::value</tt>
+ /// is <tt>is_same\<YN, proto::callable\>::::value</tt>.
+ /// \li If \c T has a nested type \c proto_is_callable_ that is a typedef
+ /// for \c void, <tt>is_callable\<T\>::::value</tt> is \c true. (Note: this is
+ /// the case for any type that derives from \c proto::callable.)
+ /// \li Otherwise, <tt>is_callable\<T\>::::value</tt> is \c false.
+ template<typename T>
+ struct is_callable
+ : proto::detail::is_callable_<T>
+ {};
+
+ /// INTERNAL ONLY
+ ///
+ template<>
+ struct is_callable<proto::_>
+ : mpl::true_
+ {};
+
+ /// INTERNAL ONLY
+ ///
+ template<>
+ struct is_callable<proto::callable>
+ : mpl::false_
+ {};
+
+ #if BOOST_WORKAROUND(__GNUC__, == 3)
+ // work around GCC bug
+ template<typename Tag, typename Args, long N>
+ struct is_callable<proto::expr<Tag, Args, N> >
+ : mpl::false_
+ {};
+ #endif
+
+ /// \brief A Boolean metafunction that indicates whether a type requires
+ /// aggregate initialization.
+ ///
+ /// <tt>is_aggregate\<\></tt> is used by the <tt>make\<\></tt> transform
+ /// to determine how to construct an object of some type \c T, given some
+ /// initialization arguments <tt>a0,a1,...aN</tt>.
+ /// If <tt>is_aggregate\<T\>::::value</tt> is \c true, then an object of
+ /// type T will be initialized as <tt>T t = {a0,a1,...aN};</tt>. Otherwise,
+ /// it will be initialized as <tt>T t(a0,a1,...aN)</tt>.
+ template<typename T>
+ struct is_aggregate
+ : is_pod<T>
+ {};
+
+ /// \brief Specialization of <tt>is_aggregate\<\></tt> that indicates
+ /// that objects of <tt>expr\<\></tt> type require aggregate initialization.
+ template<typename Tag, typename Args, long N>
+ struct is_aggregate<proto::expr<Tag, Args, N> >
+ : mpl::true_
+ {};
+
+ /// TODO document me!
+ template<typename T, typename Void BOOST_PROTO_WHEN_BUILDING_DOCS(= void)>
+ struct is_transform
+ : mpl::false_
+ {};
+
+ template<typename T>
+ struct is_transform<T, typename T::proto_is_transform_>
+ : mpl::true_
+ {};
+
+ namespace result_of
+ {
+ /// \brief A Boolean metafunction that indicates whether a given
+ /// type \c T is a Proto expression type.
+ ///
+ /// If \c T has a nested type \c proto_is_expr_ that is a typedef
+ /// for \c void, <tt>is_expr\<T\>::::value</tt> is \c true. (Note, this
+ /// is the case for <tt>proto::expr\<\></tt>, any type that is derived
+ /// from <tt>proto::extends\<\></tt> or that uses the
+ /// <tt>BOOST_PROTO_BASIC_EXTENDS()</tt> macro.) Otherwise,
+ /// <tt>is_expr\<T\>::::value</tt> is \c false.
+ template<typename T, typename Void BOOST_PROTO_WHEN_BUILDING_DOCS(= void)>
+ struct is_expr
+ : mpl::false_
+ {};
+
+ /// \brief A Boolean metafunction that indicates whether a given
+ /// type \c T is a Proto expression type.
+ ///
+ /// If \c T has a nested type \c proto_is_expr_ that is a typedef
+ /// for \c void, <tt>is_expr\<T\>::::value</tt> is \c true. (Note, this
+ /// is the case for <tt>proto::expr\<\></tt>, any type that is derived
+ /// from <tt>proto::extends\<\></tt> or that uses the
+ /// <tt>BOOST_PROTO_BASIC_EXTENDS()</tt> macro.) Otherwise,
+ /// <tt>is_expr\<T\>::::value</tt> is \c false.
+ template<typename T>
+ struct is_expr<T, typename T::proto_is_expr_>
+ : mpl::true_
+ {};
+
+ /// \brief A metafunction that returns the tag type of a
+ /// Proto expression.
+ template<typename Expr>
+ struct tag_of
+ {
+ typedef typename Expr::proto_tag type;
+ };
+
+ /// INTERNAL ONLY
+ ///
+ template<typename T, typename Void BOOST_PROTO_WHEN_BUILDING_DOCS(= void)>
+ struct is_ref
+ : mpl::false_
+ {};
+
+ /// INTERNAL ONLY
+ ///
+ template<typename T>
+ struct is_ref<T, typename T::proto_is_ref_>
+ : mpl::true_
+ {};
+
+ /// \brief A metafunction that computes the return type of the \c as_expr()
+ /// function.
+ ///
+ /// The <tt>as_expr\<\></tt> metafunction turns types into Proto types, if
+ /// they are not already, by making them Proto terminals held by value if
+ /// possible. Types which are already Proto types are left alone.
+ ///
+ /// This specialization is selected when the type is not yet a Proto type.
+ /// The resulting terminal type is calculated as follows:
+ ///
+ /// If \c T is a function type, let \c A be <tt>T &</tt>.
+ /// Otherwise, let \c A be the type \c T stripped of cv-qualifiers.
+ /// Then, the result type <tt>as_expr\<T, Domain\>::::type</tt> is
+ /// <tt>boost::result_of\<Domain(expr\< tag::terminal, term\<A\> \>)\>::::type</tt>.
+ template<
+ typename T
+ , typename Domain BOOST_PROTO_WHEN_BUILDING_DOCS(= default_domain)
+ , typename Void BOOST_PROTO_WHEN_BUILDING_DOCS(= void)
+ #ifdef BOOST_PROTO_BROKEN_PTS
+ , typename Void2 BOOST_PROTO_WHEN_BUILDING_DOCS(= void)
+ #endif
+ >
+ struct as_expr
+ {
+ typedef
+ typename mpl::eval_if_c<
+ is_function<T>::value
+ , add_reference<T>
+ , remove_cv<T>
+ >::type
+ arg0_;
+ typedef proto::expr<proto::tag::terminal, term<arg0_> > expr_;
+ typedef typename Domain::template result<void(expr_)>::type type;
+ typedef type const reference;
+
+ /// INTERNAL ONLY
+ ///
+ template<typename T2>
+ static reference call(T2 &t)
+ {
+ return Domain()(expr_::make(t));
+ }
+ };
+
+ /// \brief A metafunction that computes the return type of the \c as_expr()
+ /// function.
+ ///
+ /// The <tt>as_expr\<\></tt> metafunction turns types into Proto types, if
+ /// they are not already, by making them Proto terminals held by value if
+ /// possible. Types which are already Proto types are left alone.
+ ///
+ /// This specialization is selected when the type is already a Proto type.
+ /// The result type <tt>as_expr\<T, Domain\>::::type</tt> is \c T stripped
+ /// of cv-qualifiers.
+ template<typename T, typename Domain>
+ struct as_expr<
+ T
+ , Domain
+ , typename T::proto_is_expr_
+ #ifdef BOOST_PROTO_BROKEN_PTS
+ , typename disable_if<is_same<Domain, typename T::proto_domain> >::type
+ #endif
+ >
+ {
+ typedef typename T::proto_derived_expr expr_; // removes the const
+ typedef typename Domain::template result<void(expr_)>::type type;
+ typedef type const reference;
+
+ /// INTERNAL ONLY
+ ///
+ template<typename T2>
+ static reference call(T2 &t)
+ {
+ return Domain()(t);
+ }
+ };
+
+ template<typename T>
+ struct as_expr<
+ T
+ , typename T::proto_domain
+ , typename T::proto_is_expr_
+ #ifdef BOOST_PROTO_BROKEN_PTS
+ , void
+ #endif
+ >
+ {
+ typedef typename T::proto_derived_expr type; // removes the const
+ typedef T &reference;
+
+ /// INTERNAL ONLY
+ ///
+ template<typename T2>
+ static reference call(T2 &t)
+ {
+ return t;
+ }
+ };
+
+ /// \brief A metafunction that computes the return type of the \c as_child()
+ /// function.
+ ///
+ /// The <tt>as_child\<\></tt> metafunction turns types into Proto types, if
+ /// they are not already, by making them Proto terminals held by reference.
+ /// Types which are already Proto types are returned by reference.
+ ///
+ /// This specialization is selected when the type is not yet a Proto type.
+ /// The result type <tt>as_child\<T, Domain\>::::type</tt> is
+ /// <tt>boost::result_of\<Domain(expr\< tag::terminal, term\<T &\> \>)\>::::type</tt>.
+ template<
+ typename T
+ , typename Domain BOOST_PROTO_WHEN_BUILDING_DOCS(= default_domain)
+ , typename Void BOOST_PROTO_WHEN_BUILDING_DOCS(= void)
+ #ifdef BOOST_PROTO_BROKEN_PTS
+ , typename Void2 BOOST_PROTO_WHEN_BUILDING_DOCS(= void)
+ #endif
+ >
+ struct as_child
+ {
+ typedef proto::expr<proto::tag::terminal, term<T &> > expr_;
+ typedef typename Domain::template result<void(expr_)>::type type;
+
+ /// INTERNAL ONLY
+ ///
+ template<typename T2>
+ static type call(T2 &t)
+ {
+ return Domain()(expr_::make(t));
+ }
+ };
+
+ /// \brief A metafunction that computes the return type of the \c as_child()
+ /// function.
+ ///
+ /// The <tt>as_child\<\></tt> metafunction turns types into Proto types, if
+ /// they are not already, by making them Proto terminals held by reference.
+ /// Types which are already Proto types are returned by reference.
+ ///
+ /// This specialization is selected when the type is already a Proto type.
+ /// The result type <tt>as_child\<T, Domain\>::::type</tt> is
+ /// <tt>T &</tt>.
+ template<typename T, typename Domain>
+ struct as_child<
+ T
+ , Domain
+ , typename T::proto_is_expr_
+ #ifdef BOOST_PROTO_BROKEN_PTS
+ , typename disable_if<is_same<Domain, typename T::proto_domain> >::type
+ #endif
+ >
+ {
+ // BUGBUG should be able to hold this guy by reference, no?
+ typedef typename Domain::template result<void(T)>::type type;
+
+ /// INTERNAL ONLY
+ ///
+ template<typename T2>
+ static type call(T2 &t)
+ {
+ return Domain()(t);
+ }
+ };
+
+ /// \brief A metafunction that computes the return type of the \c as_child()
+ /// function.
+ ///
+ /// The <tt>as_child\<\></tt> metafunction turns types into Proto types, if
+ /// they are not already, by making them Proto terminals held by reference.
+ /// Types which are already Proto types are returned by reference.
+ ///
+ /// This specialization is selected when the type is already a Proto type.
+ /// The result type <tt>as_child\<T, Domain\>::::type</tt> is
+ /// <tt>T &</tt>.
+ template<typename T>
+ struct as_child<
+ T
+ , typename T::proto_domain
+ , typename T::proto_is_expr_
+ #ifdef BOOST_PROTO_BROKEN_PTS
+ , void
+ #endif
+ >
+ {
+ typedef T &type;
+
+ /// INTERNAL ONLY
+ ///
+ template<typename T2>
+ static T2 &call(T2 &t)
+ {
+ return t;
+ }
+ };
+
+ /// \brief A metafunction that returns the type of the Nth child
+ /// of a Proto expression, where N is an MPL Integral Constant.
+ ///
+ /// <tt>result_of::child\<Expr, N\></tt> is equivalent to
+ /// <tt>result_of::child_c\<Expr, N::value\></tt>.
+ template<typename Expr, typename N BOOST_PROTO_WHEN_BUILDING_DOCS(= mpl::long_<0>) >
+ struct child
+ : child_c<Expr, N::value>
+ {};
+
+ /// \brief A metafunction that returns the type of the value
+ /// of a terminal Proto expression.
+ ///
+ template<typename Expr>
+ struct value : child_c<Expr, 0>
+ {
+ //typedef typename Expr::proto_child0 wrapped_type;
+ //typedef typename unref<wrapped_type>::type type;
+ //typedef typename unref<wrapped_type>::reference reference;
+ //typedef typename unref<wrapped_type>::const_reference const_reference;
+ };
+
+ // TODO left<> and right<> force the instantiation of Expr.
+ // Couldn't we partially specialize them on proto::expr< T, A >
+ // and return A::child0 / A::child1?
+
+ /// \brief A metafunction that returns the type of the left child
+ /// of a binary Proto expression.
+ ///
+ /// <tt>result_of::left\<Expr\></tt> is equivalent to
+ /// <tt>result_of::child_c\<Expr, 0\></tt>.
+ template<typename Expr>
+ struct left : child_c<Expr, 0>
+ {
+ //typedef typename Expr::proto_child0 wrapped_type;
+ //typedef typename unref<wrapped_type>::type type;
+ //typedef typename unref<wrapped_type>::reference reference;
+ //typedef typename unref<wrapped_type>::const_reference const_reference;
+ };
+
+ /// \brief A metafunction that returns the type of the right child
+ /// of a binary Proto expression.
+ ///
+ /// <tt>result_of::right\<Expr\></tt> is equivalent to
+ /// <tt>result_of::child_c\<Expr, 1\></tt>.
+ template<typename Expr>
+ struct right : child_c<Expr, 1>
+ {
+ //typedef typename Expr::proto_child1 wrapped_type;
+ //typedef typename unref<wrapped_type>::type type;
+ //typedef typename unref<wrapped_type>::reference reference;
+ //typedef typename unref<wrapped_type>::const_reference const_reference;
+ };
+
+ } // namespace result_of
+
+ namespace op
+ {
+ /// \brief A metafunction for generating terminal expression types,
+ /// a grammar element for matching terminal expressions, and a
+ /// PrimitiveTransform that returns the current expression unchanged.
+ template<typename T>
+ struct terminal
+ {
+ typedef proto::expr<proto::tag::terminal, term<T> > type;
+ typedef type proto_base_expr;
+
+ template<typename Expr, typename State, typename Data>
+ struct impl : transform_impl<Expr, State, Data>
+ {
+ typedef Expr result_type;
+
+ /// \param expr The current expression
+ /// \pre <tt>matches\<Expr, terminal\<T\> \>::::value</tt> is \c true.
+ /// \return \c expr
+ /// \throw nothrow
+ typename impl::expr_param operator ()(
+ typename impl::expr_param expr
+ , typename impl::state_param
+ , typename impl::data_param
+ ) const
+ {
+ return expr;
+ }
+ };
+
+ /// INTERNAL ONLY
+ typedef proto::tag::terminal proto_tag;
+ /// INTERNAL ONLY
+ typedef T proto_child0;
+ };
+
+ /// \brief A metafunction for generating ternary conditional expression types,
+ /// a grammar element for matching ternary conditional expressions, and a
+ /// PrimitiveTransform that dispatches to the <tt>pass_through\<\></tt>
+ /// transform.
+ template<typename T, typename U, typename V>
+ struct if_else_
+ {
+ typedef proto::expr<proto::tag::if_else_, list3<T, U, V> > type;
+ typedef type proto_base_expr;
+
+ template<typename Expr, typename State, typename Data>
+ struct impl
+ : pass_through<if_else_>::template impl<Expr, State, Data>
+ {};
+
+ /// INTERNAL ONLY
+ typedef proto::tag::if_else_ proto_tag;
+ /// INTERNAL ONLY
+ typedef T proto_child0;
+ /// INTERNAL ONLY
+ typedef U proto_child1;
+ /// INTERNAL ONLY
+ typedef V proto_child2;
+ };
+
+ /// \brief A metafunction for generating unary expression types with a
+ /// specified tag type,
+ /// a grammar element for matching unary expressions, and a
+ /// PrimitiveTransform that dispatches to the <tt>pass_through\<\></tt>
+ /// transform.
+ ///
+ /// Use <tt>unary_expr\<_, _\></tt> as a grammar element to match any
+ /// unary expression.
+ template<typename Tag, typename T>
+ struct unary_expr
+ {
+ typedef proto::expr<Tag, list1<T> > type;
+ typedef type proto_base_expr;
+
+ template<typename Expr, typename State, typename Data>
+ struct impl
+ : pass_through<unary_expr>::template impl<Expr, State, Data>
+ {};
+
+ /// INTERNAL ONLY
+ typedef Tag proto_tag;
+ /// INTERNAL ONLY
+ typedef T proto_child0;
+ };
+
+ /// \brief A metafunction for generating binary expression types with a
+ /// specified tag type,
+ /// a grammar element for matching binary expressions, and a
+ /// PrimitiveTransform that dispatches to the <tt>pass_through\<\></tt>
+ /// transform.
+ ///
+ /// Use <tt>binary_expr\<_, _, _\></tt> as a grammar element to match any
+ /// binary expression.
+ template<typename Tag, typename T, typename U>
+ struct binary_expr
+ {
+ typedef proto::expr<Tag, list2<T, U> > type;
+ typedef type proto_base_expr;
+
+ template<typename Expr, typename State, typename Data>
+ struct impl
+ : pass_through<binary_expr>::template impl<Expr, State, Data>
+ {};
+
+ /// INTERNAL ONLY
+ typedef Tag proto_tag;
+ /// INTERNAL ONLY
+ typedef T proto_child0;
+ /// INTERNAL ONLY
+ typedef U proto_child1;
+ };
+
+ /// \brief A metafunction for generating unary plus expression types,
+ /// a grammar element for matching unary plus expressions, and a
+ /// PrimitiveTransform that dispatches to the <tt>pass_through\<\></tt>
+ /// transform.
+ template<typename T>
+ struct unary_plus
+ {
+ typedef proto::expr<proto::tag::unary_plus, list1<T> > type;
+ typedef type proto_base_expr;
+
+ template<typename Expr, typename State, typename Data>
+ struct impl
+ : pass_through<unary_plus>::template impl<Expr, State, Data>
+ {};
+
+ /// INTERNAL ONLY
+ typedef proto::tag::unary_plus proto_tag;
+ /// INTERNAL ONLY
+ typedef T proto_child0;
+ };
+
+ /// \brief A metafunction for generating unary minus expression types,
+ /// a grammar element for matching unary minus expressions, and a
+ /// PrimitiveTransform that dispatches to the <tt>pass_through\<\></tt>
+ /// transform.
+ template<typename T>
+ struct negate
+ {
+ typedef proto::expr<proto::tag::negate, list1<T> > type;
+ typedef type proto_base_expr;
+
+ template<typename Expr, typename State, typename Data>
+ struct impl
+ : pass_through<negate>::template impl<Expr, State, Data>
+ {};
+
+ /// INTERNAL ONLY
+ typedef proto::tag::negate proto_tag;
+ /// INTERNAL ONLY
+ typedef T proto_child0;
+ };
+
+ /// \brief A metafunction for generating defereference expression types,
+ /// a grammar element for matching dereference expressions, and a
+ /// PrimitiveTransform that dispatches to the <tt>pass_through\<\></tt>
+ /// transform.
+ template<typename T>
+ struct dereference
+ {
+ typedef proto::expr<proto::tag::dereference, list1<T> > type;
+ typedef type proto_base_expr;
+
+ template<typename Expr, typename State, typename Data>
+ struct impl
+ : pass_through<dereference>::template impl<Expr, State, Data>
+ {};
+
+ /// INTERNAL ONLY
+ typedef proto::tag::dereference proto_tag;
+ /// INTERNAL ONLY
+ typedef T proto_child0;
+ };
+
+ /// \brief A metafunction for generating complement expression types,
+ /// a grammar element for matching complement expressions, and a
+ /// PrimitiveTransform that dispatches to the <tt>pass_through\<\></tt>
+ /// transform.
+ template<typename T>
+ struct complement
+ {
+ typedef proto::expr<proto::tag::complement, list1<T> > type;
+ typedef type proto_base_expr;
+
+ template<typename Expr, typename State, typename Data>
+ struct impl
+ : pass_through<complement>::template impl<Expr, State, Data>
+ {};
+
+ /// INTERNAL ONLY
+ typedef proto::tag::complement proto_tag;
+ /// INTERNAL ONLY
+ typedef T proto_child0;
+ };
+
+ /// \brief A metafunction for generating address_of expression types,
+ /// a grammar element for matching address_of expressions, and a
+ /// PrimitiveTransform that dispatches to the <tt>pass_through\<\></tt>
+ /// transform.
+ template<typename T>
+ struct address_of
+ {
+ typedef proto::expr<proto::tag::address_of, list1<T> > type;
+ typedef type proto_base_expr;
+
+ template<typename Expr, typename State, typename Data>
+ struct impl
+ : pass_through<address_of>::template impl<Expr, State, Data>
+ {};
+
+ /// INTERNAL ONLY
+ typedef proto::tag::address_of proto_tag;
+ /// INTERNAL ONLY
+ typedef T proto_child0;
+ };
+
+ /// \brief A metafunction for generating logical_not expression types,
+ /// a grammar element for matching logical_not expressions, and a
+ /// PrimitiveTransform that dispatches to the <tt>pass_through\<\></tt>
+ /// transform.
+ template<typename T>
+ struct logical_not
+ {
+ typedef proto::expr<proto::tag::logical_not, list1<T> > type;
+ typedef type proto_base_expr;
+
+ template<typename Expr, typename State, typename Data>
+ struct impl
+ : pass_through<logical_not>::template impl<Expr, State, Data>
+ {};
+
+ /// INTERNAL ONLY
+ typedef proto::tag::logical_not proto_tag;
+ /// INTERNAL ONLY
+ typedef T proto_child0;
+ };
+
+ /// \brief A metafunction for generating pre-increment expression types,
+ /// a grammar element for matching pre-increment expressions, and a
+ /// PrimitiveTransform that dispatches to the <tt>pass_through\<\></tt>
+ /// transform.
+ template<typename T>
+ struct pre_inc
+ {
+ typedef proto::expr<proto::tag::pre_inc, list1<T> > type;
+ typedef type proto_base_expr;
+
+ template<typename Expr, typename State, typename Data>
+ struct impl
+ : pass_through<pre_inc>::template impl<Expr, State, Data>
+ {};
+
+ /// INTERNAL ONLY
+ typedef proto::tag::pre_inc proto_tag;
+ /// INTERNAL ONLY
+ typedef T proto_child0;
+ };
+
+ /// \brief A metafunction for generating pre-decrement expression types,
+ /// a grammar element for matching pre-decrement expressions, and a
+ /// PrimitiveTransform that dispatches to the <tt>pass_through\<\></tt>
+ /// transform.
+ template<typename T>
+ struct pre_dec
+ {
+ typedef proto::expr<proto::tag::pre_dec, list1<T> > type;
+ typedef type proto_base_expr;
+
+ template<typename Expr, typename State, typename Data>
+ struct impl
+ : pass_through<pre_dec>::template impl<Expr, State, Data>
+ {};
+
+ /// INTERNAL ONLY
+ typedef proto::tag::pre_dec proto_tag;
+ /// INTERNAL ONLY
+ typedef T proto_child0;
+ };
+
+ /// \brief A metafunction for generating post-increment expression types,
+ /// a grammar element for matching post-increment expressions, and a
+ /// PrimitiveTransform that dispatches to the <tt>pass_through\<\></tt>
+ /// transform.
+ template<typename T>
+ struct post_inc
+ {
+ typedef proto::expr<proto::tag::post_inc, list1<T> > type;
+ typedef type proto_base_expr;
+
+ template<typename Expr, typename State, typename Data>
+ struct impl
+ : pass_through<post_inc>::template impl<Expr, State, Data>
+ {};
+
+ /// INTERNAL ONLY
+ typedef proto::tag::post_inc proto_tag;
+ /// INTERNAL ONLY
+ typedef T proto_child0;
+ };
+
+ /// \brief A metafunction for generating post-decrement expression types,
+ /// a grammar element for matching post-decrement expressions, and a
+ /// PrimitiveTransform that dispatches to the <tt>pass_through\<\></tt>
+ /// transform.
+ template<typename T>
+ struct post_dec
+ {
+ typedef proto::expr<proto::tag::post_dec, list1<T> > type;
+ typedef type proto_base_expr;
+
+ template<typename Expr, typename State, typename Data>
+ struct impl
+ : pass_through<post_dec>::template impl<Expr, State, Data>
+ {};
+
+ /// INTERNAL ONLY
+ typedef proto::tag::post_dec proto_tag;
+ /// INTERNAL ONLY
+ typedef T proto_child0;
+ };
+
+ /// \brief A metafunction for generating left-shift expression types,
+ /// a grammar element for matching left-shift expressions, and a
+ /// PrimitiveTransform that dispatches to the <tt>pass_through\<\></tt>
+ /// transform.
+ template<typename T, typename U>
+ struct shift_left
+ {
+ typedef proto::expr<proto::tag::shift_left, list2<T, U> > type;
+ typedef type proto_base_expr;
+
+ template<typename Expr, typename State, typename Data>
+ struct impl
+ : pass_through<shift_left>::template impl<Expr, State, Data>
+ {};
+
+ /// INTERNAL ONLY
+ typedef proto::tag::shift_left proto_tag;
+ /// INTERNAL ONLY
+ typedef T proto_child0;
+ /// INTERNAL ONLY
+ typedef U proto_child1;
+ };
+
+ /// \brief A metafunction for generating right-shift expression types,
+ /// a grammar element for matching right-shift expressions, and a
+ /// PrimitiveTransform that dispatches to the <tt>pass_through\<\></tt>
+ /// transform.
+ template<typename T, typename U>
+ struct shift_right
+ {
+ typedef proto::expr<proto::tag::shift_right, list2<T, U> > type;
+ typedef type proto_base_expr;
+
+ template<typename Expr, typename State, typename Data>
+ struct impl
+ : pass_through<shift_right>::template impl<Expr, State, Data>
+ {};
+
+ /// INTERNAL ONLY
+ typedef proto::tag::shift_right proto_tag;
+ /// INTERNAL ONLY
+ typedef T proto_child0;
+ /// INTERNAL ONLY
+ typedef U proto_child1;
+ };
+
+ /// \brief A metafunction for generating multiplies expression types,
+ /// a grammar element for matching multiplies expressions, and a
+ /// PrimitiveTransform that dispatches to the <tt>pass_through\<\></tt>
+ /// transform.
+ template<typename T, typename U>
+ struct multiplies
+ {
+ typedef proto::expr<proto::tag::multiplies, list2<T, U> > type;
+ typedef type proto_base_expr;
+
+ template<typename Expr, typename State, typename Data>
+ struct impl
+ : pass_through<multiplies>::template impl<Expr, State, Data>
+ {};
+
+ /// INTERNAL ONLY
+ typedef proto::tag::multiplies proto_tag;
+ /// INTERNAL ONLY
+ typedef T proto_child0;
+ /// INTERNAL ONLY
+ typedef U proto_child1;
+ };
+
+ /// \brief A metafunction for generating divides expression types,
+ /// a grammar element for matching divides expressions, and a
+ /// PrimitiveTransform that dispatches to the <tt>pass_through\<\></tt>
+ /// transform.
+ template<typename T, typename U>
+ struct divides
+ {
+ typedef proto::expr<proto::tag::divides, list2<T, U> > type;
+ typedef type proto_base_expr;
+
+ template<typename Expr, typename State, typename Data>
+ struct impl
+ : pass_through<divides>::template impl<Expr, State, Data>
+ {};
+
+ /// INTERNAL ONLY
+ typedef proto::tag::divides proto_tag;
+ /// INTERNAL ONLY
+ typedef T proto_child0;
+ /// INTERNAL ONLY
+ typedef U proto_child1;
+ };
+
+ /// \brief A metafunction for generating modulus expression types,
+ /// a grammar element for matching modulus expressions, and a
+ /// PrimitiveTransform that dispatches to the <tt>pass_through\<\></tt>
+ /// transform.
+ template<typename T, typename U>
+ struct modulus
+ {
+ typedef proto::expr<proto::tag::modulus, list2<T, U> > type;
+ typedef type proto_base_expr;
+
+ template<typename Expr, typename State, typename Data>
+ struct impl
+ : pass_through<modulus>::template impl<Expr, State, Data>
+ {};
+
+ /// INTERNAL ONLY
+ typedef proto::tag::modulus proto_tag;
+ /// INTERNAL ONLY
+ typedef T proto_child0;
+ /// INTERNAL ONLY
+ typedef U proto_child1;
+ };
+
+ /// \brief A metafunction for generating binary plus expression types,
+ /// a grammar element for matching binary plus expressions, and a
+ /// PrimitiveTransform that dispatches to the <tt>pass_through\<\></tt>
+ /// transform.
+ template<typename T, typename U>
+ struct plus
+ {
+ typedef proto::expr<proto::tag::plus, list2<T, U> > type;
+ typedef type proto_base_expr;
+
+ template<typename Expr, typename State, typename Data>
+ struct impl
+ : pass_through<plus>::template impl<Expr, State, Data>
+ {};
+
+ /// INTERNAL ONLY
+ typedef proto::tag::plus proto_tag;
+ /// INTERNAL ONLY
+ typedef T proto_child0;
+ /// INTERNAL ONLY
+ typedef U proto_child1;
+ };
+
+ /// \brief A metafunction for generating binary minus expression types,
+ /// a grammar element for matching binary minus expressions, and a
+ /// PrimitiveTransform that dispatches to the <tt>pass_through\<\></tt>
+ /// transform.
+ template<typename T, typename U>
+ struct minus
+ {
+ typedef proto::expr<proto::tag::minus, list2<T, U> > type;
+ typedef type proto_base_expr;
+
+ template<typename Expr, typename State, typename Data>
+ struct impl
+ : pass_through<minus>::template impl<Expr, State, Data>
+ {};
+
+ /// INTERNAL ONLY
+ typedef proto::tag::minus proto_tag;
+ /// INTERNAL ONLY
+ typedef T proto_child0;
+ /// INTERNAL ONLY
+ typedef U proto_child1;
+ };
+
+ /// \brief A metafunction for generating less expression types,
+ /// a grammar element for matching less expressions, and a
+ /// PrimitiveTransform that dispatches to the <tt>pass_through\<\></tt>
+ /// transform.
+ template<typename T, typename U>
+ struct less
+ {
+ typedef proto::expr<proto::tag::less, list2<T, U> > type;
+ typedef type proto_base_expr;
+
+ template<typename Expr, typename State, typename Data>
+ struct impl
+ : pass_through<less>::template impl<Expr, State, Data>
+ {};
+
+ /// INTERNAL ONLY
+ typedef proto::tag::less proto_tag;
+ /// INTERNAL ONLY
+ typedef T proto_child0;
+ /// INTERNAL ONLY
+ typedef U proto_child1;
+ };
+
+ /// \brief A metafunction for generating greater expression types,
+ /// a grammar element for matching greater expressions, and a
+ /// PrimitiveTransform that dispatches to the <tt>pass_through\<\></tt>
+ /// transform.
+ template<typename T, typename U>
+ struct greater
+ {
+ typedef proto::expr<proto::tag::greater, list2<T, U> > type;
+ typedef type proto_base_expr;
+
+ template<typename Expr, typename State, typename Data>
+ struct impl
+ : pass_through<greater>::template impl<Expr, State, Data>
+ {};
+
+ /// INTERNAL ONLY
+ typedef proto::tag::greater proto_tag;
+ /// INTERNAL ONLY
+ typedef T proto_child0;
+ /// INTERNAL ONLY
+ typedef U proto_child1;
+ };
+
+ /// \brief A metafunction for generating less-or-equal expression types,
+ /// a grammar element for matching less-or-equal expressions, and a
+ /// PrimitiveTransform that dispatches to the <tt>pass_through\<\></tt>
+ /// transform.
+ template<typename T, typename U>
+ struct less_equal
+ {
+ typedef proto::expr<proto::tag::less_equal, list2<T, U> > type;
+ typedef type proto_base_expr;
+
+ template<typename Expr, typename State, typename Data>
+ struct impl
+ : pass_through<less_equal>::template impl<Expr, State, Data>
+ {};
+
+ /// INTERNAL ONLY
+ typedef proto::tag::less_equal proto_tag;
+ /// INTERNAL ONLY
+ typedef T proto_child0;
+ /// INTERNAL ONLY
+ typedef U proto_child1;
+ };
+
+ /// \brief A metafunction for generating greater-or-equal expression types,
+ /// a grammar element for matching greater-or-equal expressions, and a
+ /// PrimitiveTransform that dispatches to the <tt>pass_through\<\></tt>
+ /// transform.
+ template<typename T, typename U>
+ struct greater_equal
+ {
+ typedef proto::expr<proto::tag::greater_equal, list2<T, U> > type;
+ typedef type proto_base_expr;
+
+ template<typename Expr, typename State, typename Data>
+ struct impl
+ : pass_through<greater_equal>::template impl<Expr, State, Data>
+ {};
+
+ /// INTERNAL ONLY
+ typedef proto::tag::greater_equal proto_tag;
+ /// INTERNAL ONLY
+ typedef T proto_child0;
+ /// INTERNAL ONLY
+ typedef U proto_child1;
+ };
+
+ /// \brief A metafunction for generating equal-to expression types,
+ /// a grammar element for matching equal-to expressions, and a
+ /// PrimitiveTransform that dispatches to the <tt>pass_through\<\></tt>
+ /// transform.
+ template<typename T, typename U>
+ struct equal_to
+ {
+ typedef proto::expr<proto::tag::equal_to, list2<T, U> > type;
+ typedef type proto_base_expr;
+
+ template<typename Expr, typename State, typename Data>
+ struct impl
+ : pass_through<equal_to>::template impl<Expr, State, Data>
+ {};
+
+ /// INTERNAL ONLY
+ typedef proto::tag::equal_to proto_tag;
+ /// INTERNAL ONLY
+ typedef T proto_child0;
+ /// INTERNAL ONLY
+ typedef U proto_child1;
+ };
+
+ /// \brief A metafunction for generating not-equal-to expression types,
+ /// a grammar element for matching not-equal-to expressions, and a
+ /// PrimitiveTransform that dispatches to the <tt>pass_through\<\></tt>
+ /// transform.
+ template<typename T, typename U>
+ struct not_equal_to
+ {
+ typedef proto::expr<proto::tag::not_equal_to, list2<T, U> > type;
+ typedef type proto_base_expr;
+
+ template<typename Expr, typename State, typename Data>
+ struct impl
+ : pass_through<not_equal_to>::template impl<Expr, State, Data>
+ {};
+
+ /// INTERNAL ONLY
+ typedef proto::tag::not_equal_to proto_tag;
+ /// INTERNAL ONLY
+ typedef T proto_child0;
+ /// INTERNAL ONLY
+ typedef U proto_child1;
+ };
+
+ /// \brief A metafunction for generating logical-or expression types,
+ /// a grammar element for matching logical-or expressions, and a
+ /// PrimitiveTransform that dispatches to the <tt>pass_through\<\></tt>
+ /// transform.
+ template<typename T, typename U>
+ struct logical_or
+ {
+ typedef proto::expr<proto::tag::logical_or, list2<T, U> > type;
+ typedef type proto_base_expr;
+
+ template<typename Expr, typename State, typename Data>
+ struct impl
+ : pass_through<logical_or>::template impl<Expr, State, Data>
+ {};
+
+ /// INTERNAL ONLY
+ typedef proto::tag::logical_or proto_tag;
+ /// INTERNAL ONLY
+ typedef T proto_child0;
+ /// INTERNAL ONLY
+ typedef U proto_child1;
+ };
+
+ /// \brief A metafunction for generating logical-and expression types,
+ /// a grammar element for matching logical-and expressions, and a
+ /// PrimitiveTransform that dispatches to the <tt>pass_through\<\></tt>
+ /// transform.
+ template<typename T, typename U>
+ struct logical_and
+ {
+ typedef proto::expr<proto::tag::logical_and, list2<T, U> > type;
+ typedef type proto_base_expr;
+
+ template<typename Expr, typename State, typename Data>
+ struct impl
+ : pass_through<logical_and>::template impl<Expr, State, Data>
+ {};
+
+ /// INTERNAL ONLY
+ typedef proto::tag::logical_and proto_tag;
+ /// INTERNAL ONLY
+ typedef T proto_child0;
+ /// INTERNAL ONLY
+ typedef U proto_child1;
+ };
+
+ /// \brief A metafunction for generating bitwise-and expression types,
+ /// a grammar element for matching bitwise-and expressions, and a
+ /// PrimitiveTransform that dispatches to the <tt>pass_through\<\></tt>
+ /// transform.
+ template<typename T, typename U>
+ struct bitwise_and
+ {
+ typedef proto::expr<proto::tag::bitwise_and, list2<T, U> > type;
+ typedef type proto_base_expr;
+
+ template<typename Expr, typename State, typename Data>
+ struct impl
+ : pass_through<bitwise_and>::template impl<Expr, State, Data>
+ {};
+
+ /// INTERNAL ONLY
+ typedef proto::tag::bitwise_and proto_tag;
+ /// INTERNAL ONLY
+ typedef T proto_child0;
+ /// INTERNAL ONLY
+ typedef U proto_child1;
+ };
+
+ /// \brief A metafunction for generating bitwise-or expression types,
+ /// a grammar element for matching bitwise-or expressions, and a
+ /// PrimitiveTransform that dispatches to the <tt>pass_through\<\></tt>
+ /// transform.
+ template<typename T, typename U>
+ struct bitwise_or
+ {
+ typedef proto::expr<proto::tag::bitwise_or, list2<T, U> > type;
+ typedef type proto_base_expr;
+
+ template<typename Expr, typename State, typename Data>
+ struct impl
+ : pass_through<bitwise_or>::template impl<Expr, State, Data>
+ {};
+
+ /// INTERNAL ONLY
+ typedef proto::tag::bitwise_or proto_tag;
+ /// INTERNAL ONLY
+ typedef T proto_child0;
+ /// INTERNAL ONLY
+ typedef U proto_child1;
+ };
+
+ /// \brief A metafunction for generating bitwise-xor expression types,
+ /// a grammar element for matching bitwise-xor expressions, and a
+ /// PrimitiveTransform that dispatches to the <tt>pass_through\<\></tt>
+ /// transform.
+ template<typename T, typename U>
+ struct bitwise_xor
+ {
+ typedef proto::expr<proto::tag::bitwise_xor, list2<T, U> > type;
+ typedef type proto_base_expr;
+
+ template<typename Expr, typename State, typename Data>
+ struct impl
+ : pass_through<bitwise_xor>::template impl<Expr, State, Data>
+ {};
+
+ /// INTERNAL ONLY
+ typedef proto::tag::bitwise_xor proto_tag;
+ /// INTERNAL ONLY
+ typedef T proto_child0;
+ /// INTERNAL ONLY
+ typedef U proto_child1;
+ };
+
+ /// \brief A metafunction for generating comma expression types,
+ /// a grammar element for matching comma expressions, and a
+ /// PrimitiveTransform that dispatches to the <tt>pass_through\<\></tt>
+ /// transform.
+ template<typename T, typename U>
+ struct comma
+ {
+ typedef proto::expr<proto::tag::comma, list2<T, U> > type;
+ typedef type proto_base_expr;
+
+ template<typename Expr, typename State, typename Data>
+ struct impl
+ : pass_through<comma>::template impl<Expr, State, Data>
+ {};
+
+ /// INTERNAL ONLY
+ typedef proto::tag::comma proto_tag;
+ /// INTERNAL ONLY
+ typedef T proto_child0;
+ /// INTERNAL ONLY
+ typedef U proto_child1;
+ };
+
+ template<typename T, typename U>
+ struct mem_ptr
+ {
+ typedef proto::expr<proto::tag::mem_ptr, list2<T, U> > type;
+ typedef type proto_base_expr;
+
+ template<typename Expr, typename State, typename Data>
+ struct impl
+ : pass_through<mem_ptr>::template impl<Expr, State, Data>
+ {};
+
+ /// INTERNAL ONLY
+ typedef proto::tag::mem_ptr proto_tag;
+ /// INTERNAL ONLY
+ typedef T proto_child0;
+ /// INTERNAL ONLY
+ typedef U proto_child1;
+ };
+
+ /// \brief A metafunction for generating assignment expression types,
+ /// a grammar element for matching assignment expressions, and a
+ /// PrimitiveTransform that dispatches to the <tt>pass_through\<\></tt>
+ /// transform.
+ template<typename T, typename U>
+ struct assign
+ {
+ typedef proto::expr<proto::tag::assign, list2<T, U> > type;
+ typedef type proto_base_expr;
+
+ template<typename Expr, typename State, typename Data>
+ struct impl
+ : pass_through<assign>::template impl<Expr, State, Data>
+ {};
+
+ /// INTERNAL ONLY
+ typedef proto::tag::assign proto_tag;
+ /// INTERNAL ONLY
+ typedef T proto_child0;
+ /// INTERNAL ONLY
+ typedef U proto_child1;
+ };
+
+ /// \brief A metafunction for generating left-shift-assign expression types,
+ /// a grammar element for matching left-shift-assign expressions, and a
+ /// PrimitiveTransform that dispatches to the <tt>pass_through\<\></tt>
+ /// transform.
+ template<typename T, typename U>
+ struct shift_left_assign
+ {
+ typedef proto::expr<proto::tag::shift_left_assign, list2<T, U> > type;
+ typedef type proto_base_expr;
+
+ template<typename Expr, typename State, typename Data>
+ struct impl
+ : pass_through<shift_left_assign>::template impl<Expr, State, Data>
+ {};
+
+ /// INTERNAL ONLY
+ typedef proto::tag::shift_left_assign proto_tag;
+ /// INTERNAL ONLY
+ typedef T proto_child0;
+ /// INTERNAL ONLY
+ typedef U proto_child1;
+ };
+
+ /// \brief A metafunction for generating right-shift-assign expression types,
+ /// a grammar element for matching right-shift-assign expressions, and a
+ /// PrimitiveTransform that dispatches to the <tt>pass_through\<\></tt>
+ /// transform.
+ template<typename T, typename U>
+ struct shift_right_assign
+ {
+ typedef proto::expr<proto::tag::shift_right_assign, list2<T, U> > type;
+ typedef type proto_base_expr;
+
+ template<typename Expr, typename State, typename Data>
+ struct impl
+ : pass_through<shift_right_assign>::template impl<Expr, State, Data>
+ {};
+
+ /// INTERNAL ONLY
+ typedef proto::tag::shift_right_assign proto_tag;
+ /// INTERNAL ONLY
+ typedef T proto_child0;
+ /// INTERNAL ONLY
+ typedef U proto_child1;
+ };
+
+ /// \brief A metafunction for generating multiplies-assign expression types,
+ /// a grammar element for matching multiplies-assign expressions, and a
+ /// PrimitiveTransform that dispatches to the <tt>pass_through\<\></tt>
+ /// transform.
+ template<typename T, typename U>
+ struct multiplies_assign
+ {
+ typedef proto::expr<proto::tag::multiplies_assign, list2<T, U> > type;
+ typedef type proto_base_expr;
+
+ template<typename Expr, typename State, typename Data>
+ struct impl
+ : pass_through<multiplies_assign>::template impl<Expr, State, Data>
+ {};
+
+ /// INTERNAL ONLY
+ typedef proto::tag::multiplies_assign proto_tag;
+ /// INTERNAL ONLY
+ typedef T proto_child0;
+ /// INTERNAL ONLY
+ typedef U proto_child1;
+ };
+
+ /// \brief A metafunction for generating divides-assign expression types,
+ /// a grammar element for matching divides-assign expressions, and a
+ /// PrimitiveTransform that dispatches to the <tt>pass_through\<\></tt>
+ /// transform.
+ template<typename T, typename U>
+ struct divides_assign
+ {
+ typedef proto::expr<proto::tag::divides_assign, list2<T, U> > type;
+ typedef type proto_base_expr;
+
+ template<typename Expr, typename State, typename Data>
+ struct impl
+ : pass_through<divides_assign>::template impl<Expr, State, Data>
+ {};
+
+ /// INTERNAL ONLY
+ typedef proto::tag::divides_assign proto_tag;
+ /// INTERNAL ONLY
+ typedef T proto_child0;
+ /// INTERNAL ONLY
+ typedef U proto_child1;
+ };
+
+ /// \brief A metafunction for generating modulus-assign expression types,
+ /// a grammar element for matching modulus-assign expressions, and a
+ /// PrimitiveTransform that dispatches to the <tt>pass_through\<\></tt>
+ /// transform.
+ template<typename T, typename U>
+ struct modulus_assign
+ {
+ typedef proto::expr<proto::tag::modulus_assign, list2<T, U> > type;
+ typedef type proto_base_expr;
+
+ template<typename Expr, typename State, typename Data>
+ struct impl
+ : pass_through<modulus_assign>::template impl<Expr, State, Data>
+ {};
+
+ /// INTERNAL ONLY
+ typedef proto::tag::modulus_assign proto_tag;
+ /// INTERNAL ONLY
+ typedef T proto_child0;
+ /// INTERNAL ONLY
+ typedef U proto_child1;
+ };
+
+ /// \brief A metafunction for generating plus-assign expression types,
+ /// a grammar element for matching plus-assign expressions, and a
+ /// PrimitiveTransform that dispatches to the <tt>pass_through\<\></tt>
+ /// transform.
+ template<typename T, typename U>
+ struct plus_assign
+ {
+ typedef proto::expr<proto::tag::plus_assign, list2<T, U> > type;
+ typedef type proto_base_expr;
+
+ template<typename Expr, typename State, typename Data>
+ struct impl
+ : pass_through<plus_assign>::template impl<Expr, State, Data>
+ {};
+
+ /// INTERNAL ONLY
+ typedef proto::tag::plus_assign proto_tag;
+ /// INTERNAL ONLY
+ typedef T proto_child0;
+ /// INTERNAL ONLY
+ typedef U proto_child1;
+ };
+
+ /// \brief A metafunction for generating minus-assign expression types,
+ /// a grammar element for matching minus-assign expressions, and a
+ /// PrimitiveTransform that dispatches to the <tt>pass_through\<\></tt>
+ /// transform.
+ template<typename T, typename U>
+ struct minus_assign
+ {
+ typedef proto::expr<proto::tag::minus_assign, list2<T, U> > type;
+ typedef type proto_base_expr;
+
+ template<typename Expr, typename State, typename Data>
+ struct impl
+ : pass_through<minus_assign>::template impl<Expr, State, Data>
+ {};
+
+ /// INTERNAL ONLY
+ typedef proto::tag::minus_assign proto_tag;
+ /// INTERNAL ONLY
+ typedef T proto_child0;
+ /// INTERNAL ONLY
+ typedef U proto_child1;
+ };
+
+ /// \brief A metafunction for generating bitwise-and-assign expression types,
+ /// a grammar element for matching bitwise-and-assign expressions, and a
+ /// PrimitiveTransform that dispatches to the <tt>pass_through\<\></tt>
+ /// transform.
+ template<typename T, typename U>
+ struct bitwise_and_assign
+ {
+ typedef proto::expr<proto::tag::bitwise_and_assign, list2<T, U> > type;
+ typedef type proto_base_expr;
+
+ template<typename Expr, typename State, typename Data>
+ struct impl
+ : pass_through<bitwise_and_assign>::template impl<Expr, State, Data>
+ {};
+
+ /// INTERNAL ONLY
+ typedef proto::tag::bitwise_and_assign proto_tag;
+ /// INTERNAL ONLY
+ typedef T proto_child0;
+ /// INTERNAL ONLY
+ typedef U proto_child1;
+ };
+
+ /// \brief A metafunction for generating bitwise-or-assign expression types,
+ /// a grammar element for matching bitwise-or-assign expressions, and a
+ /// PrimitiveTransform that dispatches to the <tt>pass_through\<\></tt>
+ /// transform.
+ template<typename T, typename U>
+ struct bitwise_or_assign
+ {
+ typedef proto::expr<proto::tag::bitwise_or_assign, list2<T, U> > type;
+ typedef type proto_base_expr;
+
+ template<typename Expr, typename State, typename Data>
+ struct impl
+ : pass_through<bitwise_or_assign>::template impl<Expr, State, Data>
+ {};
+
+ /// INTERNAL ONLY
+ typedef proto::tag::bitwise_or_assign proto_tag;
+ /// INTERNAL ONLY
+ typedef T proto_child0;
+ /// INTERNAL ONLY
+ typedef U proto_child1;
+ };
+
+ /// \brief A metafunction for generating bitwise-xor-assign expression types,
+ /// a grammar element for matching bitwise-xor-assign expressions, and a
+ /// PrimitiveTransform that dispatches to the <tt>pass_through\<\></tt>
+ /// transform.
+ template<typename T, typename U>
+ struct bitwise_xor_assign
+ {
+ typedef proto::expr<proto::tag::bitwise_xor_assign, list2<T, U> > type;
+ typedef type proto_base_expr;
+
+ template<typename Expr, typename State, typename Data>
+ struct impl
+ : pass_through<bitwise_xor_assign>::template impl<Expr, State, Data>
+ {};
+
+ /// INTERNAL ONLY
+ typedef proto::tag::bitwise_xor_assign proto_tag;
+ /// INTERNAL ONLY
+ typedef T proto_child0;
+ /// INTERNAL ONLY
+ typedef U proto_child1;
+ };
+
+ /// \brief A metafunction for generating subscript expression types,
+ /// a grammar element for matching subscript expressions, and a
+ /// PrimitiveTransform that dispatches to the <tt>pass_through\<\></tt>
+ /// transform.
+ template<typename T, typename U>
+ struct subscript
+ {
+ typedef proto::expr<proto::tag::subscript, list2<T, U> > type;
+ typedef type proto_base_expr;
+
+ template<typename Expr, typename State, typename Data>
+ struct impl
+ : pass_through<subscript>::template impl<Expr, State, Data>
+ {};
+
+ /// INTERNAL ONLY
+ typedef proto::tag::subscript proto_tag;
+ /// INTERNAL ONLY
+ typedef T proto_child0;
+ /// INTERNAL ONLY
+ typedef U proto_child1;
+ };
+
+ } // namespace op
+
+ #define BOOST_PROTO_CHILD(Z, N, DATA) \
+ /** INTERNAL ONLY */ \
+ typedef BOOST_PP_CAT(DATA, N) BOOST_PP_CAT(proto_child, N); \
+ /**/
+
+ #define BOOST_PROTO_IMPLICIT_ARG(Z, N, DATA) \
+ BOOST_PP_CAT(DATA, N) &BOOST_PP_CAT(a, N); \
+ /**/
+
+ #define BOOST_PP_ITERATION_PARAMS_1 (3, (0, BOOST_PROTO_MAX_ARITY, <boost/proto/traits.hpp>))
+ #include BOOST_PP_ITERATE()
+
+ #undef BOOST_PROTO_CHILD
+ #undef BOOST_PROTO_IMPLICIT_ARG
+
+ namespace functor
+ {
+ /// \brief A callable PolymorphicFunctionObject that is
+ /// equivalent to the \c as_expr() function.
+ template<typename Domain BOOST_PROTO_WHEN_BUILDING_DOCS(= default_domain)>
+ struct as_expr
+ {
+ BOOST_PROTO_CALLABLE()
+
+ template<typename Sig>
+ struct result;
+
+ template<typename This, typename T>
+ struct result<This(T)>
+ {
+ typedef typename remove_reference<T>::type unref_type;
+ typedef typename result_of::as_expr<unref_type, Domain>::type type;
+ };
+
+ /// \brief Wrap an object in a Proto terminal if it isn't a
+ /// Proto expression already.
+ /// \param t The object to wrap.
+ /// \return <tt>proto::as_expr\<Domain\>(t)</tt>
+ template<typename T>
+ typename result_of::as_expr<T, Domain>::reference
+ operator ()(T &t) const
+ {
+ return result_of::as_expr<T, Domain>::call(t);
+ }
+
+ /// \overload
+ ///
+ template<typename T>
+ typename result_of::as_expr<T const, Domain>::reference
+ operator ()(T const &t) const
+ {
+ return result_of::as_expr<T const, Domain>::call(t);
+ }
+
+ #if BOOST_WORKAROUND(BOOST_MSVC, == 1310)
+ template<typename T, std::size_t N_>
+ typename result_of::as_expr<T[N_], Domain>::reference
+ operator ()(T (&t)[N_]) const
+ {
+ return result_of::as_expr<T[N_], Domain>::call(t);
+ }
+
+ template<typename T, std::size_t N_>
+ typename result_of::as_expr<T const[N_], Domain>::reference
+ operator ()(T const (&t)[N_]) const
+ {
+ return result_of::as_expr<T const[N_], Domain>::call(t);
+ }
+ #endif
+ };
+
+ /// \brief A callable PolymorphicFunctionObject that is
+ /// equivalent to the \c as_child() function.
+ template<typename Domain BOOST_PROTO_WHEN_BUILDING_DOCS(= default_domain)>
+ struct as_child
+ {
+ BOOST_PROTO_CALLABLE()
+
+ template<typename Sig>
+ struct result;
+
+ template<typename This, typename T>
+ struct result<This(T)>
+ {
+ typedef typename remove_reference<T>::type unref_type;
+ typedef typename result_of::as_child<unref_type, Domain>::type type;
+ };
+
+ /// \brief Wrap an object in a Proto terminal if it isn't a
+ /// Proto expression already.
+ /// \param t The object to wrap.
+ /// \return <tt>proto::as_child\<Domain\>(t)</tt>
+ template<typename T>
+ typename result_of::as_child<T, Domain>::type
+ operator ()(T &t) const
+ {
+ return result_of::as_child<T, Domain>::call(t);
+ }
+
+ /// \overload
+ ///
+ template<typename T>
+ typename result_of::as_child<T const, Domain>::type
+ operator ()(T const &t) const
+ {
+ return result_of::as_child<T const, Domain>::call(t);
+ }
+ };
+
+ /// \brief A callable PolymorphicFunctionObject that is
+ /// equivalent to the \c child_c() function.
+ template<long N>
+ struct child_c
+ {
+ BOOST_PROTO_CALLABLE()
+
+ template<typename Sig>
+ struct result;
+
+ template<typename This, typename Expr>
+ struct result<This(Expr)>
+ {
+ typedef typename result_of::child_c<Expr, N>::type type;
+ };
+
+ /// \brief Return the Nth child of the given expression.
+ /// \param expr The expression node.
+ /// \pre <tt>is_expr\<Expr\>::::value</tt> is \c true
+ /// \pre <tt>N == 0 || N \< Expr::proto_arity::value</tt>
+ /// \return <tt>proto::child_c\<N\>(expr)</tt>
+ /// \throw nothrow
+ template<typename Expr>
+ typename result_of::child_c<Expr &, N>::type
+ operator ()(Expr &expr) const
+ {
+ return result_of::child_c<Expr &, N>::call(expr);
+ }
+
+ /// \overload
+ ///
+ template<typename Expr>
+ typename result_of::child_c<Expr const &, N>::type
+ operator ()(Expr const &expr) const
+ {
+ return result_of::child_c<Expr const &, N>::call(expr);
+ }
+ };
+
+ /// \brief A callable PolymorphicFunctionObject that is
+ /// equivalent to the \c child() function.
+ ///
+ /// A callable PolymorphicFunctionObject that is
+ /// equivalent to the \c child() function. \c N is required
+ /// to be an MPL Integral Constant.
+ template<typename N BOOST_PROTO_WHEN_BUILDING_DOCS(= mpl::long_<0>) >
+ struct child
+ {
+ BOOST_PROTO_CALLABLE()
+
+ template<typename Sig>
+ struct result;
+
+ template<typename This, typename Expr>
+ struct result<This(Expr)>
+ {
+ typedef typename result_of::child<Expr, N>::type type;
+ };
+
+ /// \brief Return the Nth child of the given expression.
+ /// \param expr The expression node.
+ /// \pre <tt>is_expr\<Expr\>::::value</tt> is \c true
+ /// \pre <tt>N::value == 0 || N::value \< Expr::proto_arity::value</tt>
+ /// \return <tt>proto::child\<N\>(expr)</tt>
+ /// \throw nothrow
+ template<typename Expr>
+ typename result_of::child<Expr &, N>::type
+ operator ()(Expr &expr) const
+ {
+ return result_of::child<Expr &, N>::call(expr);
+ }
+
+ /// \overload
+ ///
+ template<typename Expr>
+ typename result_of::child<Expr const &, N>::type
+ operator ()(Expr const &expr) const
+ {
+ return result_of::child<Expr const &, N>::call(expr);
+ }
+ };
+
+ /// \brief A callable PolymorphicFunctionObject that is
+ /// equivalent to the \c value() function.
+ struct value
+ {
+ BOOST_PROTO_CALLABLE()
+
+ template<typename Sig>
+ struct result;
+
+ template<typename This, typename Expr>
+ struct result<This(Expr)>
+ {
+ typedef typename result_of::value<Expr>::type type;
+ };
+
+ /// \brief Return the value of the given terminal expression.
+ /// \param expr The terminal expression node.
+ /// \pre <tt>is_expr\<Expr\>::::value</tt> is \c true
+ /// \pre <tt>0 == Expr::proto_arity::value</tt>
+ /// \pre <tt>Expr::proto_tag</tt> is <tt>tag::terminal</tt>
+ /// \return <tt>proto::value(expr)</tt>
+ /// \throw nothrow
+ template<typename Expr>
+ typename result_of::value<Expr &>::type
+ operator ()(Expr &expr) const
+ {
+ return expr.proto_base().child0;
+ }
+
+ /// \overload
+ ///
+ template<typename Expr>
+ typename result_of::value<Expr const &>::type
+ operator ()(Expr const &expr) const
+ {
+ return expr.proto_base().child0;
+ }
+ };
+
+ /// \brief A callable PolymorphicFunctionObject that is
+ /// equivalent to the \c left() function.
+ struct left
+ {
+ BOOST_PROTO_CALLABLE()
+
+ template<typename Sig>
+ struct result;
+
+ template<typename This, typename Expr>
+ struct result<This(Expr)>
+ {
+ typedef typename result_of::left<Expr>::type type;
+ };
+
+ /// \brief Return the left child of the given binary expression.
+ /// \param expr The expression node.
+ /// \pre <tt>is_expr\<Expr\>::::value</tt> is \c true
+ /// \pre <tt>2 == Expr::proto_arity::value</tt>
+ /// \return <tt>proto::left(expr)</tt>
+ /// \throw nothrow
+ template<typename Expr>
+ typename result_of::left<Expr &>::type
+ operator ()(Expr &expr) const
+ {
+ return expr.proto_base().child0;
+ }
+
+ /// \overload
+ ///
+ template<typename Expr>
+ typename result_of::left<Expr const &>::type
+ operator ()(Expr const &expr) const
+ {
+ return expr.proto_base().child0;
+ }
+ };
+
+ /// \brief A callable PolymorphicFunctionObject that is
+ /// equivalent to the \c right() function.
+ struct right
+ {
+ BOOST_PROTO_CALLABLE()
+
+ template<typename Sig>
+ struct result;
+
+ template<typename This, typename Expr>
+ struct result<This(Expr)>
+ {
+ typedef typename result_of::right<Expr>::type type;
+ };
+
+ /// \brief Return the right child of the given binary expression.
+ /// \param expr The expression node.
+ /// \pre <tt>is_expr\<Expr\>::::value</tt> is \c true
+ /// \pre <tt>2 == Expr::proto_arity::value</tt>
+ /// \return <tt>proto::right(expr)</tt>
+ /// \throw nothrow
+ template<typename Expr>
+ typename result_of::right<Expr &>::type
+ operator ()(Expr &expr) const
+ {
+ return expr.proto_base().child1;
+ }
+
+ template<typename Expr>
+ typename result_of::right<Expr const &>::type
+ operator ()(Expr const &expr) const
+ {
+ return expr.proto_base().child1;
+ }
+ };
+
+ }
+
+ /// \brief A function that wraps non-Proto expression types in Proto
+ /// terminals and leaves Proto expression types alone.
+ ///
+ /// The <tt>as_expr()</tt> function turns objects into Proto terminals if
+ /// they are not Proto expression types already. Non-Proto types are
+ /// held by value, if possible. Types which are already Proto types are
+ /// left alone and returned by reference.
+ ///
+ /// This function can be called either with an explicitly specified
+ /// \c Domain parameter (i.e., <tt>as_expr\<Domain\>(t)</tt>), or
+ /// without (i.e., <tt>as_expr(t)</tt>). If no domain is
+ /// specified, \c default_domain is assumed.
+ ///
+ /// If <tt>is_expr\<T\>::::value</tt> is \c true, then the argument is
+ /// returned unmodified, by reference. Otherwise, the argument is wrapped
+ /// in a Proto terminal expression node according to the following rules.
+ /// If \c T is a function type, let \c A be <tt>T &</tt>. Otherwise, let
+ /// \c A be the type \c T stripped of cv-qualifiers. Then, \c as_expr()
+ /// returns <tt>Domain()(terminal\<A\>::::type::make(t))</tt>.
+ ///
+ /// \param t The object to wrap.
+ template<typename T>
+ typename result_of::as_expr<T>::reference
+ as_expr(T &t BOOST_PROTO_DISABLE_IF_IS_CONST(T))
+ {
+ return result_of::as_expr<T>::call(t);
+ }
+
+ /// \overload
+ ///
+ template<typename T>
+ typename result_of::as_expr<T const>::reference
+ as_expr(T const &t)
+ {
+ return result_of::as_expr<T const>::call(t);
+ }
+
+ /// \overload
+ ///
+ template<typename Domain, typename T>
+ typename result_of::as_expr<T, Domain>::reference
+ as_expr(T &t BOOST_PROTO_DISABLE_IF_IS_CONST(T))
+ {
+ return result_of::as_expr<T, Domain>::call(t);
+ }
+
+ /// \overload
+ ///
+ template<typename Domain, typename T>
+ typename result_of::as_expr<T const, Domain>::reference
+ as_expr(T const &t)
+ {
+ return result_of::as_expr<T const, Domain>::call(t);
+ }
+
+ /// \brief A function that wraps non-Proto expression types in Proto
+ /// terminals (by reference) and returns Proto expression types by
+ /// reference
+ ///
+ /// The <tt>as_child()</tt> function turns objects into Proto terminals if
+ /// they are not Proto expression types already. Non-Proto types are
+ /// held by reference. Types which are already Proto types are simply
+ /// returned as-is.
+ ///
+ /// This function can be called either with an explicitly specified
+ /// \c Domain parameter (i.e., <tt>as_child\<Domain\>(t)</tt>), or
+ /// without (i.e., <tt>as_child(t)</tt>). If no domain is
+ /// specified, \c default_domain is assumed.
+ ///
+ /// If <tt>is_expr\<T\>::::value</tt> is \c true, then the argument is
+ /// returned as-is. Otherwise, \c as_child() returns
+ /// <tt>Domain()(terminal\<T &\>::::type::make(t))</tt>.
+ ///
+ /// \param t The object to wrap.
+ template<typename T>
+ typename result_of::as_child<T>::type
+ as_child(T &t BOOST_PROTO_DISABLE_IF_IS_CONST(T))
+ {
+ return result_of::as_child<T>::call(t);
+ }
+
+ /// \overload
+ ///
+ template<typename T>
+ typename result_of::as_child<T const>::type
+ as_child(T const &t)
+ {
+ return result_of::as_child<T const>::call(t);
+ }
+
+ /// \overload
+ ///
+ template<typename Domain, typename T>
+ typename result_of::as_child<T, Domain>::type
+ as_child(T &t BOOST_PROTO_DISABLE_IF_IS_CONST(T))
+ {
+ return result_of::as_child<T, Domain>::call(t);
+ }
+
+ /// \overload
+ ///
+ template<typename Domain, typename T>
+ typename result_of::as_child<T const, Domain>::type
+ as_child(T const &t)
+ {
+ return result_of::as_child<T const, Domain>::call(t);
+ }
+
+ /// \brief Return the Nth child of the specified Proto expression.
+ ///
+ /// Return the Nth child of the specified Proto expression. If
+ /// \c N is not specified, as in \c child(expr), then \c N is assumed
+ /// to be <tt>mpl::long_\<0\></tt>. The child is returned by
+ /// reference. If the expression is holding the child in a
+ /// <tt>ref_\<\></tt> wrapper, it is unwrapped before it is returned.
+ ///
+ /// \param expr The Proto expression.
+ /// \pre <tt>is_expr\<Expr\>::::value</tt> is \c true.
+ /// \pre \c N is an MPL Integral Constant.
+ /// \pre <tt>N::value == 0 || N::value \< Expr::proto_arity::value</tt>
+ /// \throw nothrow
+ /// \return A reference to the Nth child
+ template<typename N, typename Expr>
+ typename result_of::child<Expr &, N>::type
+ child(Expr &expr BOOST_PROTO_DISABLE_IF_IS_CONST(Expr))
+ {
+ return result_of::child<Expr &, N>::call(expr);
+ }
+
+ /// \overload
+ ///
+ template<typename N, typename Expr>
+ typename result_of::child<Expr const &, N>::type
+ child(Expr const &expr)
+ {
+ return result_of::child<Expr const &, N>::call(expr);
+ }
+
+ /// \overload
+ ///
+ template<typename Expr2>
+ typename result_of::unref<typename Expr2::proto_base_expr::proto_child0>::reference
+ child(Expr2 &expr2 BOOST_PROTO_DISABLE_IF_IS_CONST(Expr2))
+ {
+ return expr2.proto_base().child0;
+ }
+
+ /// \overload
+ ///
+ template<typename Expr2>
+ typename result_of::unref<typename Expr2::proto_base_expr::proto_child0>::const_reference
+ child(Expr2 const &expr2)
+ {
+ return expr2.proto_base().child0;
+ }
+
+ /// \brief Return the Nth child of the specified Proto expression.
+ ///
+ /// Return the Nth child of the specified Proto expression. The child
+ /// is returned by reference. If the expression is holding the child in
+ /// a <tt>ref_\<\></tt> wrapper, it is unwrapped before it is returned.
+ ///
+ /// \param expr The Proto expression.
+ /// \pre <tt>is_expr\<Expr\>::::value</tt> is \c true.
+ /// \pre <tt>N == 0 || N \< Expr::proto_arity::value</tt>
+ /// \throw nothrow
+ /// \return A reference to the Nth child
+ template<long N, typename Expr>
+ typename result_of::child_c<Expr &, N>::type
+ child_c(Expr &expr BOOST_PROTO_DISABLE_IF_IS_CONST(Expr))
+ {
+ return result_of::child_c<Expr &, N>::call(expr);
+ }
+
+ /// \overload
+ ///
+ template<long N, typename Expr>
+ typename result_of::child_c<Expr const &, N>::type
+ child_c(Expr const &expr)
+ {
+ return result_of::child_c<Expr const &, N>::call(expr);
+ }
+
+ /// \brief Return the value stored within the specified Proto
+ /// terminal expression.
+ ///
+ /// Return the the value stored within the specified Proto
+ /// terminal expression. The value is returned by
+ /// reference.
+ ///
+ /// \param expr The Proto terminal expression.
+ /// \pre \c Expr::proto_tag is \c tag::terminal.
+ /// \pre <tt>N::value == 0</tt>
+ /// \throw nothrow
+ /// \return A reference to the terminal's value
+ template<typename Expr>
+ typename result_of::value<Expr &>::type
+ value(Expr &expr BOOST_PROTO_DISABLE_IF_IS_CONST(Expr))
+ {
+ return expr.proto_base().child0;
+ }
+
+ /// \overload
+ ///
+ template<typename Expr>
+ typename result_of::value<Expr const &>::type
+ value(Expr const &expr)
+ {
+ return expr.proto_base().child0;
+ }
+
+ /// \brief Return the left child of the specified binary Proto
+ /// expression.
+ ///
+ /// Return the left child of the specified binary Proto expression. The
+ /// child is returned by reference.
+ ///
+ /// \param expr The Proto expression.
+ /// \pre <tt>is_expr\<Expr\>::::value</tt> is \c true.
+ /// \pre <tt>2 == Expr::proto_arity::value</tt>
+ /// \throw nothrow
+ /// \return A reference to the left child
+ template<typename Expr>
+ typename result_of::left<Expr &>::type
+ left(Expr &expr BOOST_PROTO_DISABLE_IF_IS_CONST(Expr))
+ {
+ return expr.proto_base().child0;
+ }
+
+ /// \overload
+ ///
+ template<typename Expr>
+ typename result_of::left<Expr const &>::type
+ left(Expr const &expr)
+ {
+ return expr.proto_base().child0;
+ }
+
+ /// \brief Return the right child of the specified binary Proto
+ /// expression.
+ ///
+ /// Return the right child of the specified binary Proto expression. The
+ /// child is returned by reference.
+ ///
+ /// \param expr The Proto expression.
+ /// \pre <tt>is_expr\<Expr\>::::value</tt> is \c true.
+ /// \pre <tt>2 == Expr::proto_arity::value</tt>
+ /// \throw nothrow
+ /// \return A reference to the right child
+ template<typename Expr>
+ typename result_of::right<Expr &>::type
+ right(Expr &expr BOOST_PROTO_DISABLE_IF_IS_CONST(Expr))
+ {
+ return expr.proto_base().child1;
+ }
+
+ /// \overload
+ ///
+ template<typename Expr>
+ typename result_of::right<Expr const &>::type
+ right(Expr const &expr)
+ {
+ return expr.proto_base().child1;
+ }
+
+ /// INTERNAL ONLY
+ ///
+ template<typename Domain>
+ struct is_callable<functor::as_expr<Domain> >
+ : mpl::true_
+ {};
+
+ /// INTERNAL ONLY
+ ///
+ template<typename Domain>
+ struct is_callable<functor::as_child<Domain> >
+ : mpl::true_
+ {};
+
+ /// INTERNAL ONLY
+ ///
+ template<long N>
+ struct is_callable<functor::child_c<N> >
+ : mpl::true_
+ {};
+
+ /// INTERNAL ONLY
+ ///
+ template<typename N>
+ struct is_callable<functor::child<N> >
+ : mpl::true_
+ {};
+
+ }}
+
+ #if BOOST_WORKAROUND( BOOST_MSVC, >= 1400 )
+ #pragma warning(pop)
+ #endif
+
+ #endif
+
+#else // PP_IS_ITERATING
+
+ #define N BOOST_PP_ITERATION()
+ #if N > 0
+ namespace op
+ {
+ /// \brief A metafunction for generating function-call expression types,
+ /// a grammar element for matching function-call expressions, and a
+ /// PrimitiveTransform that dispatches to the <tt>pass_through\<\></tt>
+ /// transform.
+ template<BOOST_PP_ENUM_PARAMS(N, typename A)>
+ struct function<
+ BOOST_PP_ENUM_PARAMS(N, A)
+ BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PP_SUB(BOOST_PROTO_MAX_ARITY, N), void BOOST_PP_INTERCEPT), void
+ >
+ {
+ typedef proto::expr<proto::tag::function, BOOST_PP_CAT(list, N)<BOOST_PP_ENUM_PARAMS(N, A)> > type;
+ typedef type proto_base_expr;
+
+ template<typename Expr, typename State, typename Data>
+ struct impl
+ : pass_through<function>::template impl<Expr, State, Data>
+ {};
+
+ /// INTERNAL ONLY
+ typedef proto::tag::function proto_tag;
+ BOOST_PP_REPEAT(N, BOOST_PROTO_CHILD, A)
+ BOOST_PP_REPEAT_FROM_TO(
+ N
+ , BOOST_PROTO_MAX_ARITY
+ , BOOST_PROTO_CHILD
+ , detail::if_vararg<BOOST_PP_CAT(A, BOOST_PP_DEC(N))> BOOST_PP_INTERCEPT
+ )
+ };
+
+ /// \brief A metafunction for generating n-ary expression types with a
+ /// specified tag type,
+ /// a grammar element for matching n-ary expressions, and a
+ /// PrimitiveTransform that dispatches to the <tt>pass_through\<\></tt>
+ /// transform.
+ ///
+ /// Use <tt>nary_expr\<_, vararg\<_\> \></tt> as a grammar element to match any
+ /// n-ary expression; that is, any non-terminal.
+ template<typename Tag BOOST_PP_ENUM_TRAILING_PARAMS(N, typename A)>
+ struct nary_expr<
+ Tag
+ BOOST_PP_ENUM_TRAILING_PARAMS(N, A)
+ BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PP_SUB(BOOST_PROTO_MAX_ARITY, N), void BOOST_PP_INTERCEPT), void
+ >
+ {
+ typedef proto::expr<Tag, BOOST_PP_CAT(list, N)<BOOST_PP_ENUM_PARAMS(N, A)> > type;
+ typedef type proto_base_expr;
+
+ template<typename Expr, typename State, typename Data>
+ struct impl
+ : pass_through<nary_expr>::template impl<Expr, State, Data>
+ {};
+
+ /// INTERNAL ONLY
+ typedef Tag proto_tag;
+ BOOST_PP_REPEAT(N, BOOST_PROTO_CHILD, A)
+ BOOST_PP_REPEAT_FROM_TO(
+ N
+ , BOOST_PROTO_MAX_ARITY
+ , BOOST_PROTO_CHILD
+ , detail::if_vararg<BOOST_PP_CAT(A, BOOST_PP_DEC(N))> BOOST_PP_INTERCEPT
+ )
+ };
+
+ } // namespace op
+
+ namespace detail
+ {
+ template<BOOST_PP_ENUM_PARAMS(N, typename A)>
+ struct BOOST_PP_CAT(implicit_expr_, N)
+ {
+ BOOST_PP_REPEAT(N, BOOST_PROTO_IMPLICIT_ARG, A)
+
+ template<typename Tag, typename Args, long Arity>
+ operator proto::expr<Tag, Args, Arity> () const
+ {
+ proto::expr<Tag, Args, Arity> that = {BOOST_PP_ENUM_PARAMS(N, a)};
+ return that;
+ }
+ };
+
+ template<
+ template<BOOST_PP_ENUM_PARAMS(N, typename BOOST_PP_INTERCEPT)> class T
+ , BOOST_PP_ENUM_PARAMS(N, typename A)
+ >
+ struct is_callable_<T<BOOST_PP_ENUM_PARAMS(N, A)> BOOST_MPL_AUX_LAMBDA_ARITY_PARAM(N)>
+ : is_same<BOOST_PP_CAT(A, BOOST_PP_DEC(N)), callable>
+ {};
+ }
+
+ /// INTERNAL ONLY
+ template<BOOST_PP_ENUM_PARAMS(N, typename A)>
+ detail::BOOST_PP_CAT(implicit_expr_, N)<BOOST_PP_ENUM_PARAMS(N, A)>
+ implicit_expr(BOOST_PP_ENUM_BINARY_PARAMS(N, A, &a))
+ {
+ detail::BOOST_PP_CAT(implicit_expr_, N)<BOOST_PP_ENUM_PARAMS(N, A)> that
+ = {BOOST_PP_ENUM_PARAMS(N, a)};
+ return that;
+ }
+
+ #endif
+
+ namespace result_of
+ {
+ /// \brief A metafunction that returns the type of the Nth child
+ /// of a Proto expression.
+ ///
+ /// A metafunction that returns the type of the Nth child
+ /// of a Proto expression. \c N must be 0 or less than
+ /// \c Expr::proto_arity::value.
+ template<typename Expr>
+ struct child_c<Expr, N>
+ {
+ typedef typename Expr::BOOST_PP_CAT(proto_child, N) wrapped_type;
+ typedef typename unref<wrapped_type>::type type;
+ };
+
+ template<typename Expr>
+ struct child_c<Expr &, N>
+ {
+ typedef typename Expr::BOOST_PP_CAT(proto_child, N) wrapped_type;
+ typedef typename unref<wrapped_type>::reference type;
+
+ /// INTERNAL ONLY
+ static type call(Expr &expr)
+ {
+ return expr.proto_base().BOOST_PP_CAT(child, N);
+ }
+ };
+
+ template<typename Expr>
+ struct child_c<Expr const &, N>
+ {
+ typedef typename Expr::BOOST_PP_CAT(proto_child, N) wrapped_type;
+ typedef typename unref<wrapped_type>::const_reference type;
+
+ /// INTERNAL ONLY
+ static type call(Expr const &expr)
+ {
+ return expr.proto_base().BOOST_PP_CAT(child, N);
+ }
+ };
+
+
+ // /// The raw type of the Nth child as it is stored within
+ // /// \c Expr. This may be a value, a reference, or a Proto
+ // /// <tt>ref_\<\></tt> wrapper.
+ // typedef typename Expr::BOOST_PP_CAT(proto_child, N) wrapped_type;
+
+ // /// The "value" type of the child, suitable for return by value,
+ // /// computed as follows:
+ // /// \li <tt>ref_\<T const\></tt> becomes <tt>T</tt>
+ // /// \li <tt>ref_\<T\></tt> becomes <tt>T</tt>
+ // /// \li <tt>T const(&)[N]</tt> becomes <tt>T const(&)[N]</tt>
+ // /// \li <tt>T[N]</tt> becomes <tt>T(&)[N]</tt>
+ // /// \li <tt>T(&)[N]</tt> becomes <tt>T(&)[N]</tt>
+ // /// \li <tt>R(&)(A0,...)</tt> becomes <tt>R(&)(A0,...)</tt>
+ // /// \li <tt>T const &</tt> becomes <tt>T</tt>
+ // /// \li <tt>T &</tt> becomes <tt>T</tt>
+ // /// \li <tt>T</tt> becomes <tt>T</tt>
+ // typedef typename unref<wrapped_type>::type type;
+
+ // /// The "reference" type of the child, suitable for return by
+ // /// reference, computed as follows:
+ // /// \li <tt>ref_\<T const\></tt> becomes <tt>T const &</tt>
+ // /// \li <tt>ref_\<T\></tt> becomes <tt>T &</tt>
+ // /// \li <tt>T const(&)[N]</tt> becomes <tt>T const(&)[N]</tt>
+ // /// \li <tt>T[N]</tt> becomes <tt>T(&)[N]</tt>
+ // /// \li <tt>T(&)[N]</tt> becomes <tt>T(&)[N]</tt>
+ // /// \li <tt>R(&)(A0,...)</tt> becomes <tt>R(&)(A0,...)</tt>
+ // /// \li <tt>T const &</tt> becomes <tt>T const &</tt>
+ // /// \li <tt>T &</tt> becomes <tt>T &</tt>
+ // /// \li <tt>T</tt> becomes <tt>T &</tt>
+ // typedef typename unref<wrapped_type>::reference reference;
+
+ // /// The "const reference" type of the child, suitable for return by
+ // /// const reference, computed as follows:
+ // /// \li <tt>ref_\<T const\></tt> becomes <tt>T const &</tt>
+ // /// \li <tt>ref_\<T\></tt> becomes <tt>T &</tt>
+ // /// \li <tt>T const(&)[N]</tt> becomes <tt>T const(&)[N]</tt>
+ // /// \li <tt>T[N]</tt> becomes <tt>T const(&)[N]</tt>
+ // /// \li <tt>T(&)[N]</tt> becomes <tt>T(&)[N]</tt>
+ // /// \li <tt>R(&)(A0,...)</tt> becomes <tt>R(&)(A0,...)</tt>
+ // /// \li <tt>T const &</tt> becomes <tt>T const &</tt>
+ // /// \li <tt>T &</tt> becomes <tt>T &</tt>
+ // /// \li <tt>T</tt> becomes <tt>T const &</tt>
+ // typedef typename unref<wrapped_type>::const_reference const_reference;
+
+ // /// INTERNAL ONLY
+ // ///
+ // static reference call(typename Expr::proto_derived_expr &expr)
+ // {
+ // return proto::unref(expr.proto_base().BOOST_PP_CAT(child, N));
+ // }
+
+ // /// INTERNAL ONLY
+ // ///
+ // static const_reference call(typename Expr::proto_derived_expr const &expr)
+ // {
+ // return proto::unref(expr.proto_base().BOOST_PP_CAT(child, N));
+ // }
+ //};
+ }
+
+ #undef N
+
+#endif

Added: branches/proto/v4/boost/proto/transform.hpp
==============================================================================
--- (empty file)
+++ branches/proto/v4/boost/proto/transform.hpp 2008-04-06 02:19:35 EDT (Sun, 06 Apr 2008)
@@ -0,0 +1,23 @@
+///////////////////////////////////////////////////////////////////////////////
+/// \file transform.hpp
+/// Includes all the transforms in the transform/ sub-directory.
+//
+// Copyright 2008 Eric Niebler. Distributed under the Boost
+// Software License, Version 1.0. (See accompanying file
+// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_PROTO_TRANSFORM_HPP_EAN_06_23_2007
+#define BOOST_PROTO_TRANSFORM_HPP_EAN_06_23_2007
+
+#include <boost/proto/detail/prefix.hpp> // must be first include
+#include <boost/proto/transform/arg.hpp>
+#include <boost/proto/transform/lazy.hpp>
+#include <boost/proto/transform/call.hpp>
+#include <boost/proto/transform/fold.hpp>
+#include <boost/proto/transform/fold_tree.hpp>
+#include <boost/proto/transform/make.hpp>
+#include <boost/proto/transform/pass_through.hpp>
+#include <boost/proto/transform/when.hpp>
+#include <boost/proto/detail/suffix.hpp> // must be last include
+
+#endif

Added: branches/proto/v4/boost/proto/transform/arg.hpp
==============================================================================
--- (empty file)
+++ branches/proto/v4/boost/proto/transform/arg.hpp 2008-04-06 02:19:35 EDT (Sun, 06 Apr 2008)
@@ -0,0 +1,191 @@
+///////////////////////////////////////////////////////////////////////////////
+/// \file arg.hpp
+/// Contains definition of the argN transforms.
+//
+// Copyright 2008 Eric Niebler. Distributed under the Boost
+// Software License, Version 1.0. (See accompanying file
+// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_PROTO_TRANSFORM_ARG_HPP_EAN_11_01_2007
+#define BOOST_PROTO_TRANSFORM_ARG_HPP_EAN_11_01_2007
+
+#include <boost/proto/detail/prefix.hpp>
+#include <boost/proto/proto_fwd.hpp>
+#include <boost/proto/traits.hpp>
+#include <boost/proto/transform/impl.hpp>
+#include <boost/proto/detail/suffix.hpp>
+
+namespace boost { namespace proto
+{
+
+ /// \brief A PrimitiveTransform that returns the current expression
+ /// unmodified
+ struct _expr : transform<_expr>
+ {
+ template<typename Expr, typename State, typename Data>
+ struct impl : transform_impl<Expr, State, Data>
+ {
+ typedef Expr result_type;
+
+ /// \param expr An expression
+ /// \return \c expr
+ /// \throw nothrow
+ typename impl::expr_param operator()(
+ typename impl::expr_param expr
+ , typename impl::state_param
+ , typename impl::data_param
+ ) const
+ {
+ return expr;
+ }
+ };
+ };
+
+ /// \brief A PrimitiveTransform that returns the current state
+ /// unmodified
+ struct _state : transform<_state>
+ {
+ template<typename Expr, typename State, typename Data>
+ struct impl : transform_impl<Expr, State, Data>
+ {
+ typedef State result_type;
+
+ /// \param state The current state.
+ /// \return \c state
+ /// \throw nothrow
+ typename impl::state_param operator ()(
+ typename impl::expr_param
+ , typename impl::state_param state
+ , typename impl::data_param
+ ) const
+ {
+ return state;
+ }
+ };
+ };
+
+ /// \brief A PrimitiveTransform that returns the current data
+ /// unmodified
+ struct _data : transform<_data>
+ {
+ template<typename Expr, typename State, typename Data>
+ struct impl : transform_impl<Expr, State, Data>
+ {
+ typedef Data result_type;
+
+ /// \param state The current data.
+ /// \return \c data
+ /// \throw nothrow
+ typename impl::data_param operator ()(
+ typename impl::expr_param
+ , typename impl::state_param
+ , typename impl::data_param data
+ ) const
+ {
+ return data;
+ }
+ };
+ };
+
+ /// \brief A PrimitiveTransform that returns I-th child of the current
+ /// expression.
+ template<int I>
+ struct _child_c : transform<_child_c<I> >
+ {
+ template<typename Expr, typename State, typename Data>
+ struct impl : transform_impl<Expr, State, Data>
+ {
+ typedef
+ typename result_of::child_c<Expr, I>::type
+ result_type;
+
+ /// \param expr The current expression.
+ /// \return <tt>proto::child_c\<I\>(expr)</tt>
+ /// \throw nothrow
+ typename result_of::child_c<typename impl::expr_param, I>::type
+ operator ()(
+ typename impl::expr_param expr
+ , typename impl::state_param
+ , typename impl::data_param
+ ) const
+ {
+ return proto::child_c<I>(expr);
+ }
+ };
+ };
+
+ /// \brief A unary CallableTransform that wraps its argument
+ /// in a \c boost::reference_wrapper\<\>.
+ struct _ref : callable
+ {
+ template<typename Sig>
+ struct result;
+
+ template<typename This, typename T>
+ struct result<This(T)>
+ {
+ typedef boost::reference_wrapper<T const> const type;
+ };
+
+ template<typename This, typename T>
+ struct result<This(T &)>
+ {
+ typedef boost::reference_wrapper<T> const type;
+ };
+
+ /// \param t The object to wrap
+ /// \return <tt>boost::ref(t)</tt>
+ /// \throw nothrow
+ template<typename T>
+ boost::reference_wrapper<T> const operator ()(T &t) const
+ {
+ return boost::reference_wrapper<T>(t);
+ }
+
+ /// \overload
+ ///
+ template<typename T>
+ boost::reference_wrapper<T const> const operator ()(T const &t) const
+ {
+ return boost::reference_wrapper<T const>(t);
+ }
+ };
+
+ /// INTERNAL ONLY
+ ///
+ template<>
+ struct is_callable<_expr>
+ : mpl::true_
+ {};
+
+ /// INTERNAL ONLY
+ ///
+ template<>
+ struct is_callable<_state>
+ : mpl::true_
+ {};
+
+ /// INTERNAL ONLY
+ ///
+ template<>
+ struct is_callable<_data>
+ : mpl::true_
+ {};
+
+ /// INTERNAL ONLY
+ ///
+ template<int I>
+ struct is_callable<_child_c<I> >
+ : mpl::true_
+ {};
+
+ /// INTERNAL ONLY
+ ///
+ template<>
+ struct is_callable<_ref>
+ : mpl::true_
+ {};
+
+}}
+
+#endif

Added: branches/proto/v4/boost/proto/transform/call.hpp
==============================================================================
--- (empty file)
+++ branches/proto/v4/boost/proto/transform/call.hpp 2008-04-06 02:19:35 EDT (Sun, 06 Apr 2008)
@@ -0,0 +1,421 @@
+#ifndef BOOST_PP_IS_ITERATING
+ ///////////////////////////////////////////////////////////////////////////////
+ /// \file call.hpp
+ /// Contains definition of the call<> transform.
+ //
+ // Copyright 2008 Eric Niebler. Distributed under the Boost
+ // Software License, Version 1.0. (See accompanying file
+ // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+ #ifndef BOOST_PROTO_TRANSFORM_CALL_HPP_EAN_11_02_2007
+ #define BOOST_PROTO_TRANSFORM_CALL_HPP_EAN_11_02_2007
+
+ #include <boost/proto/detail/prefix.hpp>
+ #include <boost/preprocessor/cat.hpp>
+ #include <boost/preprocessor/facilities/intercept.hpp>
+ #include <boost/preprocessor/iteration/iterate.hpp>
+ #include <boost/preprocessor/repetition/enum.hpp>
+ #include <boost/preprocessor/repetition/repeat.hpp>
+ #include <boost/preprocessor/repetition/enum_params.hpp>
+ #include <boost/preprocessor/repetition/enum_binary_params.hpp>
+ #include <boost/preprocessor/repetition/enum_trailing_params.hpp>
+ #include <boost/ref.hpp>
+ #include <boost/utility/result_of.hpp>
+ #include <boost/proto/proto_fwd.hpp>
+ #include <boost/proto/traits.hpp>
+ #include <boost/proto/transform/impl.hpp>
+ #include <boost/proto/detail/dont_care.hpp>
+ #include <boost/proto/detail/as_lvalue.hpp>
+ #include <boost/proto/detail/suffix.hpp>
+
+ #define UNCVREF BOOST_PROTO_UNCVREF
+
+ namespace boost { namespace proto
+ {
+ /// \brief Wrap \c PrimitiveTransform so that <tt>when\<\></tt> knows
+ /// it is callable. Requires that the parameter is actually a
+ /// PrimitiveTransform.
+ ///
+ /// This form of <tt>call\<\></tt> is useful for annotating an
+ /// arbitrary PrimitiveTransform as callable when using it with
+ /// <tt>when\<\></tt>. Consider the following transform, which
+ /// is parameterized with another transform.
+ ///
+ /// \code
+ /// template<typename Grammar>
+ /// struct Foo
+ /// : when<
+ /// unary_plus<Grammar>
+ /// , Grammar(_child) // May or may not work.
+ /// >
+ /// {};
+ /// \endcode
+ ///
+ /// The problem with the above is that <tt>when\<\></tt> may or
+ /// may not recognize \c Grammar as callable, depending on how
+ /// \c Grammar is implemented. (See <tt>is_callable\<\></tt> for
+ /// a discussion of this issue.) You can guard against
+ /// the issue by wrapping \c Grammar in <tt>call\<\></tt>, such
+ /// as:
+ ///
+ /// \code
+ /// template<typename Grammar>
+ /// struct Foo
+ /// : when<
+ /// unary_plus<Grammar>
+ /// , call<Grammar>(_child) // OK, this works
+ /// >
+ /// {};
+ /// \endcode
+ ///
+ /// The above could also have been written as:
+ ///
+ /// \code
+ /// template<typename Grammar>
+ /// struct Foo
+ /// : when<
+ /// unary_plus<Grammar>
+ /// , call<Grammar(_child)> // OK, this works, too
+ /// >
+ /// {};
+ /// \endcode
+ template<typename PrimitiveTransform>
+ struct call : PrimitiveTransform
+ {
+ };
+
+ /// \brief Either call the PolymorphicFunctionObject with 0
+ /// arguments, or invoke the PrimitiveTransform with 3
+ /// arguments.
+ template<typename Fun>
+ struct call<Fun()> : transform<call<Fun()> >
+ {
+ /// INTERNAL ONLY
+ template<typename Expr, typename State, typename Data, bool B>
+ struct impl2
+ : transform_impl<Expr, State, Data>
+ {
+ typedef typename boost::result_of<Fun()>::type result_type;
+
+ result_type operator()(
+ typename impl2::expr_param
+ , typename impl2::state_param
+ , typename impl2::data_param
+ ) const
+ {
+ return Fun()();
+ }
+ };
+
+ /// INTERNAL ONLY
+ template<typename Expr, typename State, typename Data>
+ struct impl2<Expr, State, Data, true>
+ : Fun::template impl<Expr, State, Data>
+ {};
+
+ /// Either call the PolymorphicFunctionObject \c Fun with 0 arguments; or
+ /// invoke the PrimitiveTransform \c Fun with 3 arguments: the current
+ /// expression, state, and data.
+ ///
+ /// If \c Fun is a nullary PolymorphicFunctionObject, return <tt>Fun()()</tt>.
+ /// Otherwise, return <tt>Fun()(expr, state, data)</tt>.
+ ///
+ /// \param expr The current expression
+ /// \param state The current state
+ /// \param data An arbitrary data
+
+ /// If \c Fun is a nullary PolymorphicFunctionObject, \c type is a typedef
+ /// for <tt>boost::result_of\<Fun()\>::::type</tt>. Otherwise, it is
+ /// a typedef for <tt>boost::result_of\<Fun(Expr, State, Data)\>::::type</tt>.
+ template<typename Expr, typename State, typename Data>
+ struct impl
+ : impl2<Expr, State, Data, is_transform<Fun>::value>
+ {};
+ };
+
+ /// \brief Either call the PolymorphicFunctionObject with 1
+ /// argument, or invoke the PrimitiveTransform with 3
+ /// arguments.
+ template<typename Fun, typename A0>
+ struct call<Fun(A0)> : transform<call<Fun(A0)> >
+ {
+ template<typename Expr, typename State, typename Data, bool B>
+ struct impl2
+ : transform_impl<Expr, State, Data>
+ {
+ typedef typename when<_, A0>::template impl<Expr, State, Data>::result_type a0;
+ typedef typename boost::result_of<Fun(UNCVREF(a0))>::type result_type;
+ result_type operator ()(
+ typename impl2::expr_param expr
+ , typename impl2::state_param state
+ , typename impl2::data_param data
+ ) const
+ {
+ return Fun()(
+ typename when<_, A0>
+ ::template impl<Expr, State, Data>()(expr, state, data)
+ );
+ }
+ };
+
+ template<typename Expr, typename State, typename Data>
+ struct impl2<Expr, State, Data, true>
+ : transform_impl<Expr, State, Data>
+ {
+ typedef typename when<_, A0>::template impl<Expr, State, Data>::result_type a0;
+ typedef typename Fun::template impl<a0, State, Data>::result_type result_type;
+ result_type operator ()(
+ typename impl2::expr_param expr
+ , typename impl2::state_param state
+ , typename impl2::data_param data
+ ) const
+ {
+ return typename Fun::template impl<a0, State, Data>()(
+ typename when<_, A0>::template impl<Expr, State, Data>()(expr, state, data)
+ , state
+ , data
+ );
+ }
+ };
+ /// Let \c x be <tt>when\<_, A0\>()(expr, state, data)</tt> and \c X
+ /// be the type of \c x.
+ /// If \c Fun is a unary PolymorphicFunctionObject that accepts \c x,
+ /// then \c type is a typedef for <tt>boost::result_of\<Fun(X)\>::::type</tt>.
+ /// Otherwise, it is a typedef for <tt>boost::result_of\<Fun(X, State, Data)\>::::type</tt>.
+
+ /// Either call the PolymorphicFunctionObject with 1 argument:
+ /// the result of applying the \c A0 transform; or
+ /// invoke the PrimitiveTransform with 3 arguments:
+ /// result of applying the \c A0 transform, the state, and the
+ /// data.
+ ///
+ /// Let \c x be <tt>when\<_, A0\>()(expr, state, data)</tt>.
+ /// If \c Fun is a unary PolymorphicFunctionObject that accepts \c x,
+ /// then return <tt>Fun()(x)</tt>. Otherwise, return
+ /// <tt>Fun()(x, state, data)</tt>.
+ ///
+ /// \param expr The current expression
+ /// \param state The current state
+ /// \param data An arbitrary data
+ template<typename Expr, typename State, typename Data>
+ struct impl
+ : impl2<Expr, State, Data, is_transform<Fun>::value>
+ {};
+ };
+
+ /// \brief Either call the PolymorphicFunctionObject with 2
+ /// arguments, or invoke the PrimitiveTransform with 3
+ /// arguments.
+ template<typename Fun, typename A0, typename A1>
+ struct call<Fun(A0, A1)> : transform<call<Fun(A0, A1)> >
+ {
+ template<typename Expr, typename State, typename Data, bool B>
+ struct impl2
+ : transform_impl<Expr, State, Data>
+ {
+ typedef typename when<_, A0>::template impl<Expr, State, Data>::result_type a0;
+ typedef typename when<_, A1>::template impl<Expr, State, Data>::result_type a1;
+ typedef typename boost::result_of<Fun(UNCVREF(a0), UNCVREF(a1))>::type result_type;
+ result_type operator ()(
+ typename impl2::expr_param expr
+ , typename impl2::state_param state
+ , typename impl2::data_param data
+ ) const
+ {
+ return Fun()(
+ typename when<_, A0>::template impl<Expr, State, Data>()(expr, state, data)
+ , typename when<_, A1>::template impl<Expr, State, Data>()(expr, state, data)
+ );
+ }
+ };
+
+ template<typename Expr, typename State, typename Data>
+ struct impl2<Expr, State, Data, true>
+ : transform_impl<Expr, State, Data>
+ {
+ typedef typename when<_, A0>::template impl<Expr, State, Data>::result_type a0;
+ typedef typename when<_, A1>::template impl<Expr, State, Data>::result_type a1;
+ typedef typename Fun::template impl<a0, a1, Data>::result_type result_type;
+ result_type operator ()(
+ typename impl2::expr_param expr
+ , typename impl2::state_param state
+ , typename impl2::data_param data
+ ) const
+ {
+ return typename Fun::template impl<a0, a1, Data>()(
+ typename when<_, A0>::template impl<Expr, State, Data>()(expr, state, data)
+ , typename when<_, A1>::template impl<Expr, State, Data>()(expr, state, data)
+ , data
+ );
+ }
+ };
+
+ /// Let \c x be <tt>when\<_, A0\>()(expr, state, data)</tt> and \c X
+ /// be the type of \c x.
+ /// Let \c y be <tt>when\<_, A1\>()(expr, state, data)</tt> and \c Y
+ /// be the type of \c y.
+ /// If \c Fun is a binary PolymorphicFunction object that accepts \c x
+ /// and \c y, then \c type is a typedef for
+ /// <tt>boost::result_of\<Fun(X, Y)\>::::type</tt>. Otherwise, it is
+ /// a typedef for <tt>boost::result_of\<Fun(X, Y, Data)\>::::type</tt>.
+
+ /// Either call the PolymorphicFunctionObject with 2 arguments:
+ /// the result of applying the \c A0 transform, and the
+ /// result of applying the \c A1 transform; or invoke the
+ /// PrimitiveTransform with 3 arguments: the result of applying
+ /// the \c A0 transform, the result of applying the \c A1
+ /// transform, and the data.
+ ///
+ /// Let \c x be <tt>when\<_, A0\>()(expr, state, data)</tt>.
+ /// Let \c y be <tt>when\<_, A1\>()(expr, state, data)</tt>.
+ /// If \c Fun is a binary PolymorphicFunction object that accepts \c x
+ /// and \c y, return <tt>Fun()(x, y)</tt>. Otherwise, return
+ /// <tt>Fun()(x, y, data)</tt>.
+ ///
+ /// \param expr The current expression
+ /// \param state The current state
+ /// \param data An arbitrary data
+ template<typename Expr, typename State, typename Data>
+ struct impl
+ : impl2<Expr, State, Data, is_transform<Fun>::value>
+ {};
+ };
+
+ /// \brief Call the PolymorphicFunctionObject or the
+ /// PrimitiveTransform with the current expression, state
+ /// and data, transformed according to \c A0, \c A1, and
+ /// \c A2, respectively.
+ template<typename Fun, typename A0, typename A1, typename A2>
+ struct call<Fun(A0, A1, A2)> : transform<call<Fun(A0, A1, A2)> >
+ {
+ template<typename Expr, typename State, typename Data, bool B>
+ struct impl2
+ : transform_impl<Expr, State, Data>
+ {
+ typedef typename when<_, A0>::template impl<Expr, State, Data>::result_type a0;
+ typedef typename when<_, A1>::template impl<Expr, State, Data>::result_type a1;
+ typedef typename when<_, A2>::template impl<Expr, State, Data>::result_type a2;
+ typedef typename boost::result_of<Fun(UNCVREF(a0), UNCVREF(a1), UNCVREF(a2))>::type result_type;
+ result_type operator ()(
+ typename impl2::expr_param expr
+ , typename impl2::state_param state
+ , typename impl2::data_param data
+ ) const
+ {
+ return Fun()(
+ typename when<_, A0>::template impl<Expr, State, Data>()(expr, state, data)
+ , typename when<_, A1>::template impl<Expr, State, Data>()(expr, state, data)
+ , typename when<_, A2>::template impl<Expr, State, Data>()(expr, state, data)
+ );
+ }
+ };
+
+ template<typename Expr, typename State, typename Data>
+ struct impl2<Expr, State, Data, true>
+ : transform_impl<Expr, State, Data>
+ {
+ typedef typename when<_, A0>::template impl<Expr, State, Data>::result_type a0;
+ typedef typename when<_, A1>::template impl<Expr, State, Data>::result_type a1;
+ typedef typename when<_, A2>::template impl<Expr, State, Data>::result_type a2;
+ typedef typename Fun::template impl<a0, a1, a2>::result_type result_type;
+ result_type operator ()(
+ typename impl2::expr_param expr
+ , typename impl2::state_param state
+ , typename impl2::data_param data
+ ) const
+ {
+ return typename Fun::template impl<a0, a1, a2>()(
+ typename when<_, A0>::template impl<Expr, State, Data>()(expr, state, data)
+ , typename when<_, A1>::template impl<Expr, State, Data>()(expr, state, data)
+ , typename when<_, A2>::template impl<Expr, State, Data>()(expr, state, data)
+ );
+ }
+ };
+
+ /// Let \c x be <tt>when\<_, A0\>()(expr, state, data)</tt>.
+ /// Let \c y be <tt>when\<_, A1\>()(expr, state, data)</tt>.
+ /// Let \c z be <tt>when\<_, A2\>()(expr, state, data)</tt>.
+ /// Return <tt>Fun()(x, y, z)</tt>.
+ ///
+ /// \param expr The current expression
+ /// \param state The current state
+ /// \param data An arbitrary data
+
+ template<typename Expr, typename State, typename Data>
+ struct impl
+ : impl2<Expr, State, Data, is_transform<Fun>::value>
+ {};
+ };
+
+ #if BOOST_PROTO_MAX_ARITY > 3
+ #define BOOST_PP_ITERATION_PARAMS_1 (3, (4, BOOST_PROTO_MAX_ARITY, <boost/proto/transform/call.hpp>))
+ #include BOOST_PP_ITERATE()
+ #endif
+
+ /// INTERNAL ONLY
+ ///
+ template<typename Fun>
+ struct is_callable<call<Fun> >
+ : mpl::true_
+ {};
+
+ }} // namespace boost::proto
+
+ #undef UNCVREF
+
+ #endif
+
+#else
+
+ #define N BOOST_PP_ITERATION()
+
+ /// \brief Call the PolymorphicFunctionObject \c Fun with the
+ /// current expression, state and data, transformed according
+ /// to \c A0 through \c AN.
+ template<typename Fun BOOST_PP_ENUM_TRAILING_PARAMS(N, typename A)>
+ struct call<Fun(BOOST_PP_ENUM_PARAMS(N, A))> : transform<call<Fun(BOOST_PP_ENUM_PARAMS(N, A))> >
+ {
+ template<typename Expr, typename State, typename Data>
+ struct impl : transform_impl<Expr, State, Data>
+ {
+ #define M0(Z, M, DATA) \
+ typedef \
+ typename when<_, BOOST_PP_CAT(A, M)> \
+ ::template impl<Expr, State, Data> \
+ ::result_type \
+ BOOST_PP_CAT(a, M); \
+ /**/
+ BOOST_PP_REPEAT(N, M0, ~)
+ #undef M0
+
+ typedef
+ typename boost::result_of<
+ Fun(BOOST_PP_ENUM_BINARY_PARAMS(N, typename detail::uncvref<a, >::type BOOST_PP_INTERCEPT))
+ >::type
+ result_type;
+
+ /// Let \c ax be <tt>when\<_, Ax\>()(expr, state, data)</tt>
+ /// for each \c x in <tt>[0,N]</tt>.
+ /// Return <tt>Fun()(a0, a1,... aN)</tt>.
+ ///
+ /// \param expr The current expression
+ /// \param state The current state
+ /// \param data An arbitrary data
+ result_type operator ()(
+ typename impl::expr_param expr
+ , typename impl::state_param state
+ , typename impl::data_param data
+ ) const
+ {
+ #define M0(Z, M, DATA) \
+ typename when<_, BOOST_PP_CAT(A, M)> \
+ ::template impl<Expr, State, Data>()(expr, state, data) \
+ return Fun()(BOOST_PP_ENUM(N, M0, ~));
+ #undef M0
+ }
+ };
+ };
+
+ #undef N
+
+#endif

Added: branches/proto/v4/boost/proto/transform/default.hpp
==============================================================================
--- (empty file)
+++ branches/proto/v4/boost/proto/transform/default.hpp 2008-04-06 02:19:35 EDT (Sun, 06 Apr 2008)
@@ -0,0 +1,309 @@
+#ifndef BOOST_PP_IS_ITERATING
+ ///////////////////////////////////////////////////////////////////////////////
+ /// \file default.hpp
+ /// Contains definition of the _default transform, which gives operators their
+ /// usual C++ meanings and uses Boost.Typeof to deduce return types.
+ //
+ // Copyright 2008 Eric Niebler. Distributed under the Boost
+ // Software License, Version 1.0. (See accompanying file
+ // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+ #ifndef BOOST_PROTO_TRANSFORM_DEFAULT_HPP_EAN_04_04_2008
+ #define BOOST_PROTO_TRANSFORM_DEFAULT_HPP_EAN_04_04_2008
+
+ #include <boost/proto/detail/prefix.hpp>
+ #include <boost/preprocessor/iteration/iterate.hpp>
+ #include <boost/preprocessor/repetition/repeat.hpp>
+ #include <boost/preprocessor/repetition/enum_shifted.hpp>
+ #include <boost/preprocessor/repetition/enum_shifted_params.hpp>
+ #include <boost/proto/proto_fwd.hpp>
+ #include <boost/proto/traits.hpp>
+ #include <boost/proto/transform/impl.hpp>
+ #include <boost/proto/transform/arg.hpp>
+ #include <boost/proto/detail/decltype.hpp>
+ #include <boost/proto/detail/suffix.hpp>
+
+ namespace boost { namespace proto
+ {
+ template<typename Grammar>
+ struct _default
+ : transform<_default<Grammar> >
+ {
+ template<typename Expr, typename State, typename Data, typename Tag, long Arity>
+ struct impl2;
+
+ template<typename Expr, typename State, typename Data>
+ struct impl2<Expr, State, Data, tag::terminal, 0>
+ : _value::impl<Expr, State, Data>
+ {};
+
+ #define BOOST_PROTO_UNARY_OP_RESULT(OP, TAG) \
+ template<typename Expr, typename State, typename Data> \
+ struct impl2<Expr, State, Data, TAG, 1> \
+ : transform_impl<Expr, State, Data> \
+ { \
+ private: \
+ typedef typename result_of::child_c<Expr, 0>::type e0; \
+ typedef typename Grammar::template impl<e0, State, Data>::result_type r0; \
+ public: \
+ BOOST_PROTO_DECLTYPE_(OP proto::detail::make<r0>(), result_type) \
+ result_type operator ()( \
+ typename impl2::expr_param expr \
+ , typename impl2::state_param state \
+ , typename impl2::data_param data \
+ ) const \
+ { \
+ typename Grammar::template impl<e0, State, Data> t0; \
+ return OP t0(proto::child_c<0>(expr), state, data); \
+ } \
+ }; \
+ /**/
+
+ #define BOOST_PROTO_BINARY_OP_RESULT(OP, TAG) \
+ template<typename Expr, typename State, typename Data> \
+ struct impl2<Expr, State, Data, TAG, 2> \
+ : transform_impl<Expr, State, Data> \
+ { \
+ private: \
+ typedef typename result_of::child_c<Expr, 0>::type e0; \
+ typedef typename result_of::child_c<Expr, 1>::type e1; \
+ typedef typename Grammar::template impl<e0, State, Data>::result_type r0; \
+ typedef typename Grammar::template impl<e1, State, Data>::result_type r1; \
+ public: \
+ BOOST_PROTO_DECLTYPE_( \
+ proto::detail::make<r0>() OP proto::detail::make<r1>() \
+ , result_type \
+ ) \
+ result_type operator ()( \
+ typename impl2::expr_param expr \
+ , typename impl2::state_param state \
+ , typename impl2::data_param data \
+ ) const \
+ { \
+ typename Grammar::template impl<e0, State, Data> t0; \
+ typename Grammar::template impl<e1, State, Data> t1; \
+ return t0(proto::child_c<0>(expr), state, data) \
+ OP t1(proto::child_c<1>(expr), state, data); \
+ } \
+ }; \
+ /**/
+
+ BOOST_PROTO_UNARY_OP_RESULT(+, tag::unary_plus)
+ BOOST_PROTO_UNARY_OP_RESULT(-, tag::negate)
+ BOOST_PROTO_UNARY_OP_RESULT(*, tag::dereference)
+ BOOST_PROTO_UNARY_OP_RESULT(~, tag::complement)
+ BOOST_PROTO_UNARY_OP_RESULT(&, tag::address_of)
+ BOOST_PROTO_UNARY_OP_RESULT(!, tag::logical_not)
+ BOOST_PROTO_UNARY_OP_RESULT(++, tag::pre_inc)
+ BOOST_PROTO_UNARY_OP_RESULT(--, tag::pre_dec)
+
+ BOOST_PROTO_BINARY_OP_RESULT(<<, tag::shift_left)
+ BOOST_PROTO_BINARY_OP_RESULT(>>, tag::shift_right)
+ BOOST_PROTO_BINARY_OP_RESULT(*, tag::multiplies)
+ BOOST_PROTO_BINARY_OP_RESULT(/, tag::divides)
+ BOOST_PROTO_BINARY_OP_RESULT(%, tag::modulus)
+ BOOST_PROTO_BINARY_OP_RESULT(+, tag::plus)
+ BOOST_PROTO_BINARY_OP_RESULT(-, tag::minus)
+ BOOST_PROTO_BINARY_OP_RESULT(<, tag::less)
+ BOOST_PROTO_BINARY_OP_RESULT(>, tag::greater)
+ BOOST_PROTO_BINARY_OP_RESULT(<=, tag::less_equal)
+ BOOST_PROTO_BINARY_OP_RESULT(>=, tag::greater_equal)
+ BOOST_PROTO_BINARY_OP_RESULT(==, tag::equal_to)
+ BOOST_PROTO_BINARY_OP_RESULT(!=, tag::not_equal_to)
+ BOOST_PROTO_BINARY_OP_RESULT(||, tag::logical_or)
+ BOOST_PROTO_BINARY_OP_RESULT(&&, tag::logical_and)
+ BOOST_PROTO_BINARY_OP_RESULT(&, tag::bitwise_and)
+ BOOST_PROTO_BINARY_OP_RESULT(|, tag::bitwise_or)
+ BOOST_PROTO_BINARY_OP_RESULT(^, tag::bitwise_xor)
+ BOOST_PROTO_BINARY_OP_RESULT(->*, tag::mem_ptr)
+
+ BOOST_PROTO_BINARY_OP_RESULT(=, tag::assign)
+ BOOST_PROTO_BINARY_OP_RESULT(<<=, tag::shift_left_assign)
+ BOOST_PROTO_BINARY_OP_RESULT(>>=, tag::shift_right_assign)
+ BOOST_PROTO_BINARY_OP_RESULT(*=, tag::multiplies_assign)
+ BOOST_PROTO_BINARY_OP_RESULT(/=, tag::divides_assign)
+ BOOST_PROTO_BINARY_OP_RESULT(%=, tag::modulus_assign)
+ BOOST_PROTO_BINARY_OP_RESULT(+=, tag::plus_assign)
+ BOOST_PROTO_BINARY_OP_RESULT(-=, tag::minus_assign)
+ BOOST_PROTO_BINARY_OP_RESULT(&=, tag::bitwise_and_assign)
+ BOOST_PROTO_BINARY_OP_RESULT(|=, tag::bitwise_or_assign)
+ BOOST_PROTO_BINARY_OP_RESULT(^=, tag::bitwise_xor_assign)
+
+ #undef BOOST_PROTO_UNNARY_OP_RESULT
+ #undef BOOST_PROTO_BINARY_OP_RESULT
+
+ template<typename Expr, typename State, typename Data>
+ struct impl2<Expr, State, Data, tag::post_inc, 1>
+ : transform_impl<Expr, State, Data>
+ {
+ private:
+ typedef typename result_of::child_c<Expr, 0>::type e0;
+ typedef typename Grammar::template impl<e0, State, Data>::result_type r0;
+ public:
+ BOOST_PROTO_DECLTYPE_(proto::detail::make<r0>() ++, result_type)
+ result_type operator ()(
+ typename impl2::expr_param expr
+ , typename impl2::state_param state
+ , typename impl2::data_param data
+ ) const
+ {
+ typename Grammar::template impl<e0, State, Data> t0;
+ return t0(proto::child_c<0>(expr), state, data) ++;
+ }
+ };
+
+ template<typename Expr, typename State, typename Data>
+ struct impl2<Expr, State, Data, tag::post_dec, 1>
+ : transform_impl<Expr, State, Data>
+ {
+ private:
+ typedef typename result_of::child_c<Expr, 0>::type e0;
+ typedef typename Grammar::template impl<e0, State, Data>::result_type r0;
+ public:
+ BOOST_PROTO_DECLTYPE_(proto::detail::make<r0>() --, result_type)
+ result_type operator ()(
+ typename impl2::expr_param expr
+ , typename impl2::state_param state
+ , typename impl2::data_param data
+ ) const
+ {
+ typename Grammar::template impl<e0, State, Data> t0;
+ return t0(proto::child_c<0>(expr), state, data) --;
+ }
+ };
+
+ template<typename Expr, typename State, typename Data>
+ struct impl2<Expr, State, Data, tag::subscript, 2>
+ : transform_impl<Expr, State, Data>
+ {
+ private:
+ typedef typename result_of::child_c<Expr, 0>::type e0;
+ typedef typename result_of::child_c<Expr, 1>::type e1;
+ typedef typename Grammar::template impl<e0, State, Data>::result_type r0;
+ typedef typename Grammar::template impl<e1, State, Data>::result_type r1;
+ public:
+ BOOST_PROTO_DECLTYPE_(
+ proto::detail::make<r0>() [ proto::detail::make<r1>() ]
+ , result_type
+ )
+ result_type operator ()(
+ typename impl2::expr_param expr
+ , typename impl2::state_param state
+ , typename impl2::data_param data
+ ) const
+ {
+ typename Grammar::template impl<e0, State, Data> t0;
+ typename Grammar::template impl<e1, State, Data> t1;
+ return t0(proto::child_c<0>(expr), state, data) [
+ t1(proto::child_c<1>(expr), state, data) ];
+ }
+ };
+
+ template<typename Expr, typename State, typename Data>
+ struct impl2<Expr, State, Data, tag::if_else_, 3>
+ : transform_impl<Expr, State, Data>
+ {
+ private:
+ typedef typename result_of::child_c<Expr, 0>::type e0;
+ typedef typename result_of::child_c<Expr, 1>::type e1;
+ typedef typename result_of::child_c<Expr, 2>::type e2;
+ typedef typename Grammar::template impl<e0, State, Data>::result_type r0;
+ typedef typename Grammar::template impl<e1, State, Data>::result_type r1;
+ typedef typename Grammar::template impl<e2, State, Data>::result_type r2;
+ public:
+ BOOST_PROTO_DECLTYPE_(
+ proto::detail::make<r0>()
+ ? proto::detail::make<r1>()
+ : proto::detail::make<r2>();
+ , result_type
+ )
+ result_type operator ()(
+ typename impl2::expr_param expr
+ , typename impl2::state_param state
+ , typename impl2::data_param data
+ ) const
+ {
+ typename Grammar::template impl<e0, State, Data> t0;
+ typename Grammar::template impl<e1, State, Data> t1;
+ typename Grammar::template impl<e2, State, Data> t2;
+ return t0(proto::child_c<0>(expr), state, data)
+ ? t1(proto::child_c<1>(expr), state, data)
+ : t2(proto::child_c<2>(expr), state, data)
+ }
+ };
+
+ #define EVAL_TYPE(Z, N, DATA) \
+ typedef \
+ typename result_of::child_c<DATA, N>::type \
+ BOOST_PP_CAT(e, N); \
+ typedef \
+ typename Grammar::template impl<BOOST_PP_CAT(e, N), State, Data>::result_type \
+ BOOST_PP_CAT(r, N); \
+ /**/
+
+ #define EVAL(Z, N, DATA) \
+ typename Grammar::template impl<BOOST_PP_CAT(e, N), State, Data>()( \
+ proto::child_c<N>(DATA), state, data \
+ ) \
+ /**/
+
+ #define BOOST_PP_ITERATION_PARAMS_1 (3, (1, BOOST_PROTO_MAX_ARITY, <boost/proto/transform/default.hpp>))
+ #include BOOST_PP_ITERATE()
+
+ #undef EVAL_TYPE
+ #undef EVAL
+
+ template<typename Expr, typename State, typename Data>
+ struct impl
+ : impl2<
+ Expr
+ , State
+ , Data
+ , typename transform_impl<Expr, State, Data>::expr::proto_tag
+ , transform_impl<Expr, State, Data>::expr::proto_arity::value
+ >
+ {};
+ };
+
+ template<typename Grammar>
+ struct is_callable<_default<Grammar> >
+ : mpl::true_
+ {};
+
+ }}
+
+ #endif
+
+#else
+
+ #define N BOOST_PP_ITERATION()
+
+ template<typename Expr, typename State, typename Data>
+ struct impl2<Expr, State, Data, tag::function, N>
+ : transform_impl<Expr, State, Data>
+ {
+ BOOST_PP_REPEAT(N, EVAL_TYPE, Expr)
+
+ typedef
+ typename proto::detail::result_of_fixup<e0>::type
+ function_type;
+
+ typedef
+ typename boost::result_of<
+ function_type(BOOST_PP_ENUM_SHIFTED_PARAMS(N, e))
+ >::type
+ result_type;
+
+ result_type operator ()(
+ typename impl2::expr_param expr
+ , typename impl2::state_param state
+ , typename impl2::data_param data
+ ) const
+ {
+ return EVAL(~, 0, expr)(BOOST_PP_ENUM_SHIFTED(N, EVAL, expr));
+ }
+ };
+
+ #undef N
+
+#endif

Added: branches/proto/v4/boost/proto/transform/fold.hpp
==============================================================================
--- (empty file)
+++ branches/proto/v4/boost/proto/transform/fold.hpp 2008-04-06 02:19:35 EDT (Sun, 06 Apr 2008)
@@ -0,0 +1,361 @@
+#ifndef BOOST_PP_IS_ITERATING
+ ///////////////////////////////////////////////////////////////////////////////
+ /// \file fold.hpp
+ /// Contains definition of the fold<> and reverse_fold<> transforms.
+ //
+ // Copyright 2008 Eric Niebler. Distributed under the Boost
+ // Software License, Version 1.0. (See accompanying file
+ // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+ #ifndef BOOST_PROTO_TRANSFORM_FOLD_HPP_EAN_11_04_2007
+ #define BOOST_PROTO_TRANSFORM_FOLD_HPP_EAN_11_04_2007
+
+ #include <boost/proto/detail/prefix.hpp>
+ #include <boost/version.hpp>
+ #include <boost/preprocessor/cat.hpp>
+ #include <boost/preprocessor/iteration/iterate.hpp>
+ #include <boost/preprocessor/arithmetic/inc.hpp>
+ #include <boost/preprocessor/arithmetic/sub.hpp>
+ #include <boost/preprocessor/repetition/repeat.hpp>
+ #if BOOST_VERSION >= 103500
+ #include <boost/fusion/include/fold.hpp>
+ #else
+ #include <boost/spirit/fusion/algorithm/fold.hpp>
+ #endif
+ #include <boost/proto/proto_fwd.hpp>
+ #include <boost/proto/fusion.hpp>
+ #include <boost/proto/traits.hpp>
+ #include <boost/proto/transform/call.hpp>
+ #include <boost/proto/transform/impl.hpp>
+ #include <boost/proto/detail/suffix.hpp>
+
+ namespace boost { namespace proto
+ {
+ namespace detail
+ {
+ template<typename Transform, typename Data>
+ struct as_callable
+ {
+ as_callable(Data v)
+ : v_(v)
+ {}
+
+ template<typename Sig>
+ struct result;
+
+ template<typename This, typename Expr, typename State>
+ struct result<This(Expr, State)>
+ {
+ typedef
+ typename when<_, Transform>::template impl<Expr, State, Data>::result_type
+ type;
+ };
+
+ #if BOOST_VERSION < 103500
+ template<typename Expr, typename State>
+ struct apply
+ : result<void(Expr, State)>
+ {};
+ #endif
+
+ template<typename Expr, typename State>
+ typename when<_, Transform>::template impl<Expr &, State const &, Data>::result_type
+ operator ()(Expr &expr, State const &state) const
+ {
+ return typename when<_, Transform>::template impl<Expr &, State const &, Data>()(expr, state, this->v_);
+ }
+
+ private:
+ Data v_;
+ };
+
+ #if BOOST_VERSION < 103500
+ template<typename Sequence, typename Void = void>
+ struct as_fusion_sequence_type
+ {
+ typedef Sequence const type;
+ };
+
+ template<typename Sequence>
+ Sequence const &as_fusion_sequence(Sequence const &sequence, ...)
+ {
+ return sequence;
+ }
+
+ template<typename Sequence>
+ struct as_fusion_sequence_type<Sequence, typename Sequence::proto_is_expr_>
+ {
+ typedef typename Sequence::proto_base_expr const type;
+ };
+
+ template<typename Sequence>
+ typename Sequence::proto_base_expr const &as_fusion_sequence(Sequence const &sequence, int)
+ {
+ return sequence.proto_base();
+ }
+
+ #define BOOST_PROTO_AS_FUSION_SEQUENCE_TYPE(X) typename detail::as_fusion_sequence_type<X>::type
+ #define BOOST_PROTO_AS_FUSION_SEQUENCE(X) detail::as_fusion_sequence(X, 0)
+ #else
+ #define BOOST_PROTO_AS_FUSION_SEQUENCE_TYPE(X) X
+ #define BOOST_PROTO_AS_FUSION_SEQUENCE(X) X
+ #endif
+
+ template<
+ typename State0
+ , typename Fun
+ , typename Expr
+ , typename State
+ , typename Data
+ , long Arity = remove_reference<Expr>::type::proto_arity::value
+ >
+ struct fold_impl
+ {};
+
+ template<
+ typename State0
+ , typename Fun
+ , typename Expr
+ , typename State
+ , typename Data
+ , long Arity = remove_reference<Expr>::type::proto_arity::value
+ >
+ struct reverse_fold_impl
+ {};
+
+ #define BOOST_PROTO_CHILD_N_TYPE(N)\
+ BOOST_PP_CAT(proto_child, N)\
+ /**/
+
+ #define BOOST_PROTO_FOLD_STATE_TYPE(Z, N, DATA) \
+ typedef \
+ typename when<_, Fun>::template impl< \
+ typename result_of::child_c<Expr, N>::type \
+ , BOOST_PP_CAT(state, N) \
+ , Data \
+ >::result_type \
+ BOOST_PP_CAT(state, BOOST_PP_INC(N)); \
+ /**/
+
+ #define BOOST_PROTO_FOLD_STATE(Z, N, DATA) \
+ BOOST_PP_CAT(state, BOOST_PP_INC(N)) \
+ BOOST_PP_CAT(s, BOOST_PP_INC(N)) \
+ = typename when<_, Fun>::template impl< \
+ typename result_of::child_c<Expr, N>::type \
+ , BOOST_PP_CAT(state, N) \
+ , Data \
+ >()( \
+ proto::child_c<N>(expr) \
+ , BOOST_PP_CAT(s, N) \
+ , data \
+ ); \
+ /**/
+
+ #define BOOST_PROTO_REVERSE_FOLD_STATE_TYPE(Z, N, DATA) \
+ typedef \
+ typename when<_, Fun>::template impl< \
+ typename result_of::child_c< \
+ Expr \
+ , BOOST_PP_SUB(DATA, BOOST_PP_INC(N)) \
+ >::type \
+ , BOOST_PP_CAT(state, BOOST_PP_SUB(DATA, N)) \
+ , Data \
+ >::result_type \
+ BOOST_PP_CAT(state, BOOST_PP_SUB(DATA, BOOST_PP_INC(N))); \
+ /**/
+
+ #define BOOST_PROTO_REVERSE_FOLD_STATE(Z, N, DATA) \
+ BOOST_PP_CAT(state, BOOST_PP_SUB(DATA, BOOST_PP_INC(N))) \
+ BOOST_PP_CAT(s, BOOST_PP_SUB(DATA, BOOST_PP_INC(N))) \
+ = typename when<_, Fun>::template impl< \
+ typename result_of::child_c< \
+ Expr \
+ , BOOST_PP_SUB(DATA, BOOST_PP_INC(N)) \
+ >::type \
+ , BOOST_PP_CAT(state, BOOST_PP_SUB(DATA, N)) \
+ , Data \
+ >()( \
+ proto::child_c<BOOST_PP_SUB(DATA, BOOST_PP_INC(N))>(expr) \
+ , BOOST_PP_CAT(s, BOOST_PP_SUB(DATA, N)) \
+ , data \
+ ); \
+ /**/
+
+ #define BOOST_PP_ITERATION_PARAMS_1 (3, (1, BOOST_PROTO_MAX_ARITY, <boost/proto/transform/fold.hpp>))
+ #include BOOST_PP_ITERATE()
+
+ #undef BOOST_PROTO_REVERSE_FOLD_STATE
+ #undef BOOST_PROTO_REVERSE_FOLD_STATE_TYPE
+ #undef BOOST_PROTO_FOLD_STATE
+ #undef BOOST_PROTO_FOLD_STATE_TYPE
+ #undef BOOST_PROTO_CHILD_N_TYPE
+
+ } // namespace detail
+
+ /// \brief A PrimitiveTransform that invokes the <tt>fusion::fold\<\></tt>
+ /// algorithm to accumulate
+ template<typename Sequence, typename State0, typename Fun>
+ struct fold : transform<fold<Sequence, State0, Fun> >
+ {
+ template<typename Expr, typename State, typename Data>
+ struct impl : transform_impl<Expr, State, Data>
+ {
+ /// \brief A Fusion sequence.
+ typedef
+ typename remove_reference<
+ typename when<_, Sequence>::template impl<Expr, State, Data>::result_type
+ >::type
+ sequence;
+
+ /// \brief An initial state for the fold.
+ typedef
+ typename remove_reference<
+ typename when<_, State0>::template impl<Expr, State, Data>::result_type
+ >::type
+ state0;
+
+ /// \brief <tt>fun(v)(e,s) == when\<_,Fun\>()(e,s,v)</tt>
+ typedef
+ detail::as_callable<Fun, Data>
+ fun;
+
+ typedef
+ typename fusion::BOOST_PROTO_FUSION_RESULT_OF::fold<
+ BOOST_PROTO_AS_FUSION_SEQUENCE_TYPE(sequence)
+ , state0
+ , fun
+ >::type
+ result_type;
+
+ /// Let \c seq be <tt>when\<_, Sequence\>()(expr, state, data)</tt>, let
+ /// \c state0 be <tt>when\<_, State0\>()(expr, state, data)</tt>, and
+ /// let \c fun(data) be an object such that <tt>fun(data)(expr, state)</tt>
+ /// is equivalent to <tt>when\<_, Fun\>()(expr, state, data)</tt>. Then, this
+ /// function returns <tt>fusion::fold(seq, state0, fun(data))</tt>.
+ ///
+ /// \param expr The current expression
+ /// \param state The current state
+ /// \param data An arbitrary data
+ result_type operator ()(
+ typename impl::expr_param expr
+ , typename impl::state_param state
+ , typename impl::data_param data
+ ) const
+ {
+ typename when<_, Sequence>::template impl<Expr, State, Data> sequence;
+ detail::as_callable<Fun, Data> fun(data);
+ return fusion::fold(
+ BOOST_PROTO_AS_FUSION_SEQUENCE(sequence(expr, state, data))
+ , typename when<_, State0>::template impl<Expr, State, Data>()(expr, state, data)
+ , fun
+ );
+ }
+ };
+ };
+
+ /// \brief A PrimitiveTransform that is the same as the
+ /// <tt>fold\<\></tt> transform, except that it folds
+ /// back-to-front instead of front-to-back. It uses
+ /// the \c _reverse callable PolymorphicFunctionObject
+ /// to create a <tt>fusion::reverse_view\<\></tt> of the
+ /// sequence before invoking <tt>fusion::fold\<\></tt>.
+ template<typename Sequence, typename State0, typename Fun>
+ struct reverse_fold
+ : fold<call<_reverse(Sequence)>, State0, Fun>
+ {};
+
+ // This specialization is only for improved compile-time performance
+ // in the commom case when the Sequence transform is \c proto::_.
+ //
+ /// INTERNAL ONLY
+ ///
+ template<typename State0, typename Fun>
+ struct fold<_, State0, Fun> : transform<fold<_, State0, Fun> >
+ {
+ template<typename Expr, typename State, typename Data>
+ struct impl
+ : detail::fold_impl<State0, Fun, Expr, State, Data>
+ {};
+ };
+
+ // This specialization is only for improved compile-time performance
+ // in the commom case when the Sequence transform is \c proto::_.
+ //
+ /// INTERNAL ONLY
+ ///
+ template<typename State0, typename Fun>
+ struct reverse_fold<_, State0, Fun> : transform<reverse_fold<_, State0, Fun> >
+ {
+ template<typename Expr, typename State, typename Data>
+ struct impl
+ : detail::reverse_fold_impl<State0, Fun, Expr, State, Data>
+ {};
+ };
+
+ /// INTERNAL ONLY
+ ///
+ template<typename Sequence, typename State, typename Fun>
+ struct is_callable<fold<Sequence, State, Fun> >
+ : mpl::true_
+ {};
+
+ /// INTERNAL ONLY
+ ///
+ template<typename Sequence, typename State, typename Fun>
+ struct is_callable<reverse_fold<Sequence, State, Fun> >
+ : mpl::true_
+ {};
+
+ }}
+
+ #endif
+
+#else
+
+ #define N BOOST_PP_ITERATION()
+
+ template<typename State0, typename Fun, typename Expr, typename State, typename Data>
+ struct fold_impl<State0, Fun, Expr, State, Data, N>
+ : transform_impl<Expr, State, Data>
+ {
+ typedef typename when<_, State0>::template impl<Expr, State, Data>::result_type state0;
+ BOOST_PP_REPEAT(N, BOOST_PROTO_FOLD_STATE_TYPE, N)
+ typedef BOOST_PP_CAT(state, N) result_type;
+
+ result_type operator ()(
+ typename fold_impl::expr_param expr
+ , typename fold_impl::state_param state
+ , typename fold_impl::data_param data
+ ) const
+ {
+ state0 s0 =
+ typename when<_, State0>::template impl<Expr, State, Data>()(expr, state, data);
+ BOOST_PP_REPEAT(N, BOOST_PROTO_FOLD_STATE, N)
+ return BOOST_PP_CAT(s, N);
+ }
+ };
+
+ template<typename State0, typename Fun, typename Expr, typename State, typename Data>
+ struct reverse_fold_impl<State0, Fun, Expr, State, Data, N>
+ : transform_impl<Expr, State, Data>
+ {
+ typedef typename when<_, State0>::template impl<Expr, State, Data>::result_type BOOST_PP_CAT(state, N);
+ BOOST_PP_REPEAT(N, BOOST_PROTO_REVERSE_FOLD_STATE_TYPE, N)
+ typedef state0 result_type;
+
+ result_type operator ()(
+ typename reverse_fold_impl::expr_param expr
+ , typename reverse_fold_impl::state_param state
+ , typename reverse_fold_impl::data_param data
+ ) const
+ {
+ BOOST_PP_CAT(state, N) BOOST_PP_CAT(s, N) =
+ typename when<_, State0>::template impl<Expr, State, Data>()(expr, state, data);
+ BOOST_PP_REPEAT(N, BOOST_PROTO_REVERSE_FOLD_STATE, N)
+ return s0;
+ }
+ };
+
+ #undef N
+
+#endif

Added: branches/proto/v4/boost/proto/transform/fold_tree.hpp
==============================================================================
--- (empty file)
+++ branches/proto/v4/boost/proto/transform/fold_tree.hpp 2008-04-06 02:19:35 EDT (Sun, 06 Apr 2008)
@@ -0,0 +1,174 @@
+///////////////////////////////////////////////////////////////////////////////
+/// \file fold_tree.hpp
+/// Contains definition of the fold_tree<> and reverse_fold_tree<> transforms.
+//
+// Copyright 2008 Eric Niebler. Distributed under the Boost
+// Software License, Version 1.0. (See accompanying file
+// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_PROTO_TRANSFORM_FOLD_TREE_HPP_EAN_11_05_2007
+#define BOOST_PROTO_TRANSFORM_FOLD_TREE_HPP_EAN_11_05_2007
+
+#include <boost/proto/detail/prefix.hpp>
+#include <boost/type_traits/is_same.hpp>
+#include <boost/proto/proto_fwd.hpp>
+#include <boost/proto/traits.hpp>
+#include <boost/proto/matches.hpp>
+#include <boost/proto/transform/fold.hpp>
+#include <boost/proto/transform/impl.hpp>
+#include <boost/proto/detail/suffix.hpp>
+
+namespace boost { namespace proto
+{
+ namespace detail
+ {
+ template<typename Tag>
+ struct has_tag : transform<has_tag<Tag> >
+ {
+ template<typename Expr, typename State, typename Data, typename EnableIf = Tag>
+ struct impl
+ : transform_impl<Expr, State, Data>
+ {
+ typedef mpl::false_ result_type;
+ };
+
+ template<typename Expr, typename State, typename Data>
+ struct impl<Expr, State, Data, typename Expr::proto_tag>
+ : transform_impl<Expr, State, Data>
+ {
+ typedef mpl::true_ result_type;
+ };
+
+ template<typename Expr, typename State, typename Data>
+ struct impl<Expr &, State, Data, typename Expr::proto_tag>
+ : transform_impl<Expr &, State, Data>
+ {
+ typedef mpl::true_ result_type;
+ };
+ };
+
+ template<typename Tag, typename Fun>
+ struct fold_tree_
+ : if_<has_tag<Tag>, fold<_, _state, fold_tree_<Tag, Fun> >, Fun>
+ {};
+
+ template<typename Tag, typename Fun>
+ struct reverse_fold_tree_
+ : if_<has_tag<Tag>, reverse_fold<_, _state, reverse_fold_tree_<Tag, Fun> >, Fun>
+ {};
+ }
+
+ /// \brief A PrimitiveTransform that recursively applies the
+ /// <tt>fold\<\></tt> transform to sub-trees that all share a common
+ /// tag type.
+ ///
+ /// <tt>fold_tree\<\></tt> is useful for flattening trees into lists;
+ /// for example, you might use <tt>fold_tree\<\></tt> to flatten an
+ /// expression tree like <tt>a | b | c</tt> into a Fusion list like
+ /// <tt>cons(c, cons(b, cons(a)))</tt>.
+ ///
+ /// <tt>fold_tree\<\></tt> is easily understood in terms of a
+ /// <tt>recurse_if_\<\></tt> helper, defined as follows:
+ ///
+ /// \code
+ /// template<typename Tag, typename Fun>
+ /// struct recurse_if_
+ /// : if_<
+ /// // If the current node has type type "Tag" ...
+ /// is_same<tag_of<_>, Tag>()
+ /// // ... recurse, otherwise ...
+ /// , fold<_, _state, recurse_if_<Tag, Fun> >
+ /// // ... apply the Fun transform.
+ /// , Fun
+ /// >
+ /// {};
+ /// \endcode
+ ///
+ /// With <tt>recurse_if_\<\></tt> as defined above,
+ /// <tt>fold_tree\<Sequence, State0, Fun\>()(expr, state, data)</tt> is
+ /// equivalent to
+ /// <tt>fold<Sequence, State0, recurse_if_<Expr::proto_tag, Fun> >()(expr, state, data).</tt>
+ /// It has the effect of folding a tree front-to-back, recursing into
+ /// child nodes that share a tag type with the parent node.
+ template<typename Sequence, typename State0, typename Fun>
+ struct fold_tree
+ : transform<fold_tree<Sequence, State0, Fun> >
+ {
+ template<typename Expr, typename State, typename Data>
+ struct impl
+ : fold<
+ Sequence
+ , State0
+ , detail::fold_tree_<
+ typename remove_reference<Expr>::type::proto_tag
+ , Fun
+ >
+ >::template impl<Expr, State, Data>
+ {};
+ };
+
+ /// \brief A PrimitiveTransform that recursively applies the
+ /// <tt>reverse_fold\<\></tt> transform to sub-trees that all share
+ /// a common tag type.
+ ///
+ /// <tt>reverse_fold_tree\<\></tt> is useful for flattening trees into
+ /// lists; for example, you might use <tt>reverse_fold_tree\<\></tt> to
+ /// flatten an expression tree like <tt>a | b | c</tt> into a Fusion list
+ /// like <tt>cons(a, cons(b, cons(c)))</tt>.
+ ///
+ /// <tt>reverse_fold_tree\<\></tt> is easily understood in terms of a
+ /// <tt>recurse_if_\<\></tt> helper, defined as follows:
+ ///
+ /// \code
+ /// template<typename Tag, typename Fun>
+ /// struct recurse_if_
+ /// : if_<
+ /// // If the current node has type type "Tag" ...
+ /// is_same<tag_of<_>, Tag>()
+ /// // ... recurse, otherwise ...
+ /// , reverse_fold<_, _state, recurse_if_<Tag, Fun> >
+ /// // ... apply the Fun transform.
+ /// , Fun
+ /// >
+ /// {};
+ /// \endcode
+ ///
+ /// With <tt>recurse_if_\<\></tt> as defined above,
+ /// <tt>reverse_fold_tree\<Sequence, State0, Fun\>()(expr, state, data)</tt> is
+ /// equivalent to
+ /// <tt>reverse_fold<Sequence, State0, recurse_if_<Expr::proto_tag, Fun> >()(expr, state, data).</tt>
+ /// It has the effect of folding a tree back-to-front, recursing into
+ /// child nodes that share a tag type with the parent node.
+ template<typename Sequence, typename State0, typename Fun>
+ struct reverse_fold_tree
+ : transform<reverse_fold_tree<Sequence, State0, Fun> >
+ {
+ template<typename Expr, typename State, typename Data>
+ struct impl
+ : reverse_fold<
+ Sequence
+ , State0
+ , detail::reverse_fold_tree_<
+ typename remove_reference<Expr>::type::proto_tag
+ , Fun
+ >
+ >::template impl<Expr, State, Data>
+ {};
+ };
+
+ /// INTERNAL ONLY
+ ///
+ template<typename Sequence, typename State0, typename Fun>
+ struct is_callable<fold_tree<Sequence, State0, Fun> >
+ : mpl::true_
+ {};
+
+ /// INTERNAL ONLY
+ ///
+ template<typename Sequence, typename State0, typename Fun>
+ struct is_callable<reverse_fold_tree<Sequence, State0, Fun> >
+ : mpl::true_
+ {};
+}}
+
+#endif

Added: branches/proto/v4/boost/proto/transform/impl.hpp
==============================================================================
--- (empty file)
+++ branches/proto/v4/boost/proto/transform/impl.hpp 2008-04-06 02:19:35 EDT (Sun, 06 Apr 2008)
@@ -0,0 +1,180 @@
+///////////////////////////////////////////////////////////////////////////////
+/// \file impl.hpp
+/// Contains definition of transform<> and transform_impl<> helpers.
+//
+// Copyright 2008 Eric Niebler. Distributed under the Boost
+// Software License, Version 1.0. (See accompanying file
+// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_PROTO_TRANSFORM_IMPL_HPP_EAN_04_03_2008
+#define BOOST_PROTO_TRANSFORM_IMPL_HPP_EAN_04_03_2008
+
+#include <boost/proto/detail/prefix.hpp>
+#include <boost/proto/proto_fwd.hpp>
+#include <boost/proto/detail/suffix.hpp>
+
+namespace boost { namespace proto
+{
+ template<typename PrimitiveTransform, typename Expr, typename State = int, typename Data = int>
+ struct apply_transform
+ : PrimitiveTransform::template impl<Expr, State, Data>
+ {};
+
+ template<typename PrimitiveTransform>
+ struct transform
+ {
+ typedef PrimitiveTransform transform_type;
+ typedef void proto_is_transform_;
+ BOOST_PROTO_CALLABLE()
+
+ template<typename Sig>
+ struct result;
+
+ template<typename This, typename Expr>
+ struct result<This(Expr)>
+ {
+ typedef typename PrimitiveTransform::template impl<Expr, int, int>::result_type type;
+ };
+
+ template<typename This, typename Expr, typename State>
+ struct result<This(Expr, State)>
+ {
+ typedef typename PrimitiveTransform::template impl<Expr, State, int>::result_type type;
+ };
+
+ template<typename This, typename Expr, typename State, typename Data>
+ struct result<This(Expr, State, Data)>
+ {
+ typedef typename PrimitiveTransform::template impl<Expr, State, Data>::result_type type;
+ };
+
+ template<typename Expr>
+ typename apply_transform<PrimitiveTransform, Expr &>::result_type
+ operator ()(Expr &expr) const
+ {
+ int i = 0;
+ return apply_transform<PrimitiveTransform, Expr &>()(expr, i, i);
+ }
+
+ template<typename Expr, typename State>
+ typename apply_transform<PrimitiveTransform, Expr &, State &>::result_type
+ operator ()(Expr &expr, State &state) const
+ {
+ int i = 0;
+ return apply_transform<PrimitiveTransform, Expr &, State &>()(expr, state, i);
+ }
+
+ template<typename Expr, typename State>
+ typename apply_transform<PrimitiveTransform, Expr &, State const &>::result_type
+ operator ()(Expr &expr, State const &state) const
+ {
+ int i = 0;
+ return apply_transform<PrimitiveTransform, Expr &, State const &>()(expr, state, i);
+ }
+
+ template<typename Expr, typename State, typename Data>
+ typename apply_transform<PrimitiveTransform, Expr &, State &, Data &>::result_type
+ operator ()(Expr &expr, State &state, Data &data) const
+ {
+ return apply_transform<PrimitiveTransform, Expr &, State &, Data &>()(expr, state, data);
+ }
+
+ template<typename Expr, typename State, typename Data>
+ typename apply_transform<PrimitiveTransform, Expr &, State const &, Data &>::result_type
+ operator ()(Expr &expr, State const &state, Data &data) const
+ {
+ return apply_transform<PrimitiveTransform, Expr &, State const &, Data &>()(expr, state, data);
+ }
+ };
+
+ template<typename Expr, typename State, typename Data>
+ struct transform_impl
+ {
+ typedef Expr const expr;
+ typedef Expr const &expr_param;
+ typedef State const state;
+ typedef State const &state_param;
+ typedef Data const data;
+ typedef Data const &data_param;
+ };
+
+ template<typename Expr, typename State, typename Data>
+ struct transform_impl<Expr &, State, Data>
+ {
+ typedef Expr expr;
+ typedef Expr &expr_param;
+ typedef State const state;
+ typedef State const &state_param;
+ typedef Data const data;
+ typedef Data const &data_param;
+ };
+
+ template<typename Expr, typename State, typename Data>
+ struct transform_impl<Expr, State &, Data>
+ {
+ typedef Expr const expr;
+ typedef Expr const &expr_param;
+ typedef State state;
+ typedef State &state_param;
+ typedef Data const data;
+ typedef Data const &data_param;
+ };
+
+ template<typename Expr, typename State, typename Data>
+ struct transform_impl<Expr, State, Data &>
+ {
+ typedef Expr const expr;
+ typedef Expr const &expr_param;
+ typedef State const state;
+ typedef State const &state_param;
+ typedef Data data;
+ typedef Data &data_param;
+ };
+
+ template<typename Expr, typename State, typename Data>
+ struct transform_impl<Expr &, State &, Data>
+ {
+ typedef Expr expr;
+ typedef Expr &expr_param;
+ typedef State state;
+ typedef State &state_param;
+ typedef Data const data;
+ typedef Data const &data_param;
+ };
+
+ template<typename Expr, typename State, typename Data>
+ struct transform_impl<Expr &, State, Data &>
+ {
+ typedef Expr expr;
+ typedef Expr &expr_param;
+ typedef State const state;
+ typedef State const &state_param;
+ typedef Data data;
+ typedef Data &data_param;
+ };
+
+ template<typename Expr, typename State, typename Data>
+ struct transform_impl<Expr, State &, Data &>
+ {
+ typedef Expr const expr;
+ typedef Expr const &expr_param;
+ typedef State state;
+ typedef State &state_param;
+ typedef Data data;
+ typedef Data &data_param;
+ };
+
+ template<typename Expr, typename State, typename Data>
+ struct transform_impl<Expr &, State &, Data &>
+ {
+ typedef Expr expr;
+ typedef Expr &expr_param;
+ typedef State state;
+ typedef State &state_param;
+ typedef Data data;
+ typedef Data &data_param;
+ };
+
+}} // namespace boost::proto
+
+#endif

Added: branches/proto/v4/boost/proto/transform/lazy.hpp
==============================================================================
--- (empty file)
+++ branches/proto/v4/boost/proto/transform/lazy.hpp 2008-04-06 02:19:35 EDT (Sun, 06 Apr 2008)
@@ -0,0 +1,85 @@
+#ifndef BOOST_PP_IS_ITERATING
+ ///////////////////////////////////////////////////////////////////////////////
+ /// \file lazy.hpp
+ /// Contains definition of the lazy<> transform.
+ //
+ // Copyright 2008 Eric Niebler. Distributed under the Boost
+ // Software License, Version 1.0. (See accompanying file
+ // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+ #ifndef BOOST_PROTO_TRANSFORM_LAZY_HPP_EAN_12_02_2007
+ #define BOOST_PROTO_TRANSFORM_LAZY_HPP_EAN_12_02_2007
+
+ #include <boost/proto/detail/prefix.hpp>
+ #include <boost/preprocessor/iteration/iterate.hpp>
+ #include <boost/preprocessor/repetition/enum_params.hpp>
+ #include <boost/preprocessor/repetition/enum_trailing_params.hpp>
+ #include <boost/proto/proto_fwd.hpp>
+ #include <boost/proto/transform/make.hpp>
+ #include <boost/proto/transform/call.hpp>
+ #include <boost/proto/transform/impl.hpp>
+ #include <boost/proto/detail/suffix.hpp>
+
+ namespace boost { namespace proto
+ {
+ /// \brief A PrimitiveTransform that uses <tt>make\<\></tt> to build
+ /// a CallableTransform, and then uses <tt>call\<\></tt> to apply it.
+ ///
+ /// <tt>lazy\<\></tt> is useful as a higher-order transform, when the
+ /// transform to be applied depends on the current state of the
+ /// transformation. The invocation of the <tt>make\<\></tt> transform
+ /// evaluates any nested transforms, and the resulting type is treated
+ /// as a CallableTransform, which is evaluated with <tt>call\<\></tt>.
+ template<typename Object>
+ struct lazy : transform<lazy<Object> >
+ {
+ template<typename Expr, typename State, typename Data>
+ struct impl
+ : call<
+ typename detail::make_<Object, Expr, State, Data>::type
+ >::template impl<Expr, State, Data>
+ {};
+ };
+
+ #define BOOST_PP_ITERATION_PARAMS_1 (3, (0, BOOST_PROTO_MAX_ARITY, <boost/proto/transform/lazy.hpp>))
+ #include BOOST_PP_ITERATE()
+
+ /// INTERNAL ONLY
+ ///
+ template<typename Object>
+ struct is_callable<lazy<Object> >
+ : mpl::true_
+ {};
+
+ }}
+
+ #endif
+
+#else
+
+ #define N BOOST_PP_ITERATION()
+
+ /// \brief A PrimitiveTransform that uses <tt>make\<\></tt> to build
+ /// a CallableTransform, and then uses <tt>call\<\></tt> to apply it.
+ ///
+ /// <tt>lazy\<\></tt> is useful as a higher-order transform, when the
+ /// transform to be applied depends on the current state of the
+ /// transformation. The invocation of the <tt>make\<\></tt> transform
+ /// evaluates any nested transforms, and the resulting type is treated
+ /// as a CallableTransform, which is evaluated with <tt>call\<\></tt>.
+ template<typename Object BOOST_PP_ENUM_TRAILING_PARAMS(N, typename A)>
+ struct lazy<Object(BOOST_PP_ENUM_PARAMS(N, A))>
+ : transform<lazy<Object(BOOST_PP_ENUM_PARAMS(N, A))> >
+ {
+ template<typename Expr, typename State, typename Data>
+ struct impl
+ : call<
+ typename detail::make_<Object, Expr, State, Data>::type
+ (BOOST_PP_ENUM_PARAMS(N, A))
+ >::template impl<Expr, State, Data>
+ {};
+ };
+
+ #undef N
+
+#endif

Added: branches/proto/v4/boost/proto/transform/make.hpp
==============================================================================
--- (empty file)
+++ branches/proto/v4/boost/proto/transform/make.hpp 2008-04-06 02:19:35 EDT (Sun, 06 Apr 2008)
@@ -0,0 +1,383 @@
+#ifndef BOOST_PP_IS_ITERATING
+ ///////////////////////////////////////////////////////////////////////////////
+ /// \file make.hpp
+ /// Contains definition of the make<> transform.
+ //
+ // Copyright 2008 Eric Niebler. Distributed under the Boost
+ // Software License, Version 1.0. (See accompanying file
+ // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+ #ifndef BOOST_PROTO_TRANSFORM_MAKE_HPP_EAN_12_02_2007
+ #define BOOST_PROTO_TRANSFORM_MAKE_HPP_EAN_12_02_2007
+
+ #include <boost/proto/detail/prefix.hpp>
+ #include <boost/detail/workaround.hpp>
+ #include <boost/preprocessor/repetition/enum.hpp>
+ #include <boost/preprocessor/repetition/enum_params.hpp>
+ #include <boost/preprocessor/repetition/enum_trailing_params.hpp>
+ #include <boost/preprocessor/repetition/enum_binary_params.hpp>
+ #include <boost/preprocessor/repetition/enum_params_with_a_default.hpp>
+ #include <boost/preprocessor/repetition/repeat_from_to.hpp>
+ #include <boost/preprocessor/facilities/intercept.hpp>
+ #include <boost/preprocessor/cat.hpp>
+ #include <boost/preprocessor/iteration/iterate.hpp>
+ #include <boost/preprocessor/selection/max.hpp>
+ #include <boost/preprocessor/arithmetic/inc.hpp>
+ #include <boost/mpl/aux_/has_type.hpp>
+ #include <boost/mpl/aux_/template_arity.hpp>
+ #include <boost/mpl/aux_/lambda_arity_param.hpp>
+ #include <boost/utility/result_of.hpp>
+ #include <boost/type_traits/remove_const.hpp>
+ #include <boost/type_traits/remove_reference.hpp>
+ #include <boost/proto/proto_fwd.hpp>
+ #include <boost/proto/traits.hpp>
+ #include <boost/proto/args.hpp>
+ #include <boost/proto/transform/impl.hpp>
+ #include <boost/proto/detail/as_lvalue.hpp>
+ #include <boost/proto/detail/ignore_unused.hpp>
+ #include <boost/proto/detail/suffix.hpp>
+
+ namespace boost { namespace proto
+ {
+ namespace detail
+ {
+ template<BOOST_PP_ENUM_PARAMS_WITH_A_DEFAULT(BOOST_PROTO_MAX_ARITY, typename A, void)>
+ struct typelist
+ {
+ typedef void type;
+ };
+
+ template<typename T, bool HasType = mpl::aux::has_type<T>::value>
+ struct nested_type
+ {
+ typedef typename T::type type;
+ };
+
+ template<typename T>
+ struct nested_type<T, false>
+ {
+ typedef T type;
+ };
+
+ template<typename T, typename Args, typename Void = void>
+ struct nested_type_if
+ : nested_type<T>
+ {};
+
+ template<typename R, typename Expr, typename State, typename Data
+ , bool IsTransform = is_callable<R>::value
+ >
+ struct make_if_;
+
+ template<typename R, typename Expr, typename State, typename Data
+ BOOST_MPL_AUX_LAMBDA_ARITY_PARAM(long Arity = mpl::aux::template_arity<R>::value)
+ >
+ struct make_
+ {
+ typedef R type;
+ typedef void not_applied_;
+ };
+
+ template<typename R, typename Expr, typename State, typename Data>
+ struct make_if_<R, Expr, State, Data, false>
+ : make_<R, Expr, State, Data>
+ {};
+
+ #if BOOST_WORKAROUND(__GNUC__, == 3)
+ // work around GCC bug
+ template<typename Tag, typename Args, long N, typename Expr, typename State, typename Data>
+ struct make_if_<proto::expr<Tag, Args, N>, Expr, State, Data, false>
+ {
+ typedef proto::expr<Tag, Args, N> type;
+ typedef void not_applied_;
+ };
+ #endif
+
+ // TODO could optimize this if R is a transform
+ template<typename R, typename Expr, typename State, typename Data>
+ struct make_if_<R, Expr, State, Data, true>
+ : remove_const<typename remove_reference<
+ typename boost::result_of<R(Expr, State, Data)>::type
+ >::type>
+ {};
+
+ template<typename Type, bool IsAggregate = is_aggregate<Type>::value>
+ struct construct_
+ {
+ typedef Type result_type;
+
+ Type operator ()() const
+ {
+ return Type();
+ }
+
+ #define TMP(Z, N, DATA) \
+ template<BOOST_PP_ENUM_PARAMS_Z(Z, N, typename A)> \
+ Type operator ()(BOOST_PP_ENUM_BINARY_PARAMS_Z(Z, N, A, &a)) const \
+ { \
+ return Type(BOOST_PP_ENUM_PARAMS_Z(Z, N, a)); \
+ }
+ BOOST_PP_REPEAT_FROM_TO(1, BOOST_PP_INC(BOOST_PROTO_MAX_ARITY), TMP, ~)
+ #undef TMP
+ };
+
+ template<typename Type>
+ struct construct_<Type, true>
+ {
+ typedef Type result_type;
+
+ Type operator ()() const
+ {
+ return Type();
+ }
+
+ #define TMP(Z, N, DATA) \
+ template<BOOST_PP_ENUM_PARAMS_Z(Z, N, typename A)> \
+ Type operator ()(BOOST_PP_ENUM_BINARY_PARAMS_Z(Z, N, A, &a)) const \
+ { \
+ Type that = {BOOST_PP_ENUM_PARAMS_Z(Z, N, a)}; \
+ return that; \
+ }
+ BOOST_PP_REPEAT_FROM_TO(1, BOOST_PP_INC(BOOST_PROTO_MAX_ARITY), TMP, ~)
+ #undef TMP
+ };
+
+ #define TMP(Z, N, DATA) \
+ template<typename Type BOOST_PP_ENUM_TRAILING_PARAMS_Z(Z, N, typename A)> \
+ Type construct(BOOST_PP_ENUM_BINARY_PARAMS_Z(Z, N, A, &a)) \
+ { \
+ return construct_<Type>()(BOOST_PP_ENUM_PARAMS_Z(Z, N, a)); \
+ }
+ BOOST_PP_REPEAT(BOOST_PROTO_MAX_ARITY, TMP, ~)
+ #undef TMP
+ }
+
+ /// \brief A PrimitiveTransform which computes a type by evaluating any
+ /// nested transforms and then constructs an object of that type.
+ ///
+ /// The <tt>make\<\></tt> transform checks to see if \c Object is a template.
+ /// If it is, the template type is disassembled to find nested transforms.
+ /// Proto considers the following types to represent transforms:
+ ///
+ /// \li Function types
+ /// \li Function pointer types
+ /// \li Types for which <tt>proto::is_callable\< type \>::::value</tt> is \c true
+ ///
+ /// <tt>make\<T\<X0,X1,...\> \>::::result\<void(Expr, State, Data)\>::::type</tt>
+ /// is evaluated as follows. For each \c X in <tt>X0,X1,...</tt>, do:
+ ///
+ /// \li If \c X is a template like <tt>U\<Y0,Y1,...\></tt>, then let <tt>X'</tt>
+ /// be <tt>make\<U\<Y0,Y1,...\> \>::::result\<void(Expr, State, Data)\>::::type</tt>
+ /// (which evaluates this procedure recursively). Note whether any
+ /// substitutions took place during this operation.
+ /// \li Otherwise, if \c X is a transform, then let <tt>X'</tt> be
+ /// <tt>when\<_, X\>::::result\<void(Expr, State, Data)\>::::type</tt>.
+ /// Note that a substitution took place.
+ /// \li Otherwise, let <tt>X'</tt> be \c X, and note that no substitution
+ /// took place.
+ /// \li If any substitutions took place in any of the above steps and
+ /// <tt>T\<X0',X1',...\></tt> has a nested <tt>::type</tt> typedef,
+ /// the result type is <tt>T\<X0',X1',...\>::::type</tt>.
+ /// \li Otherwise, the result type is <tt>T\<X0',X1',...\></tt>.
+ ///
+ /// Note that <tt>when\<\></tt> is implemented in terms of <tt>call\<\></tt>
+ /// and <tt>make\<\></tt>, so the above procedure is evaluated recursively.
+ template<typename Object>
+ struct make : transform<make<Object> >
+ {
+ template<typename Expr, typename State, typename Data>
+ struct impl : transform_impl<Expr, State, Data>
+ {
+ typedef typename detail::make_if_<Object, Expr, State, Data>::type result_type;
+
+ /// \return <tt>result_type()</tt>
+ result_type operator ()(
+ typename impl::expr_param
+ , typename impl::state_param
+ , typename impl::data_param
+ ) const
+ {
+ return result_type();
+ }
+ };
+ };
+
+ #define BOOST_PP_ITERATION_PARAMS_1 (3, (0, BOOST_PROTO_MAX_ARITY, <boost/proto/transform/make.hpp>))
+ #include BOOST_PP_ITERATE()
+
+ /// INTERNAL ONLY
+ ///
+ template<typename Object>
+ struct is_callable<make<Object> >
+ : mpl::true_
+ {};
+
+ }}
+
+ #endif
+
+#else
+
+ #define N BOOST_PP_ITERATION()
+
+ namespace detail
+ {
+ #if N > 0
+ template<typename T BOOST_PP_ENUM_TRAILING_PARAMS(N, typename A)>
+ struct nested_type_if<
+ T
+ , typelist<BOOST_PP_ENUM_PARAMS(N, A)>
+ , typename typelist<
+ BOOST_PP_ENUM_BINARY_PARAMS(N, typename A, ::not_applied_ BOOST_PP_INTERCEPT)
+ >::type
+ >
+ {
+ typedef T type;
+ typedef void not_applied_;
+ };
+
+ template<
+ template<BOOST_PP_ENUM_PARAMS(N, typename BOOST_PP_INTERCEPT)> class R
+ BOOST_PP_ENUM_TRAILING_PARAMS(N, typename A)
+ , typename Expr, typename State, typename Data
+ >
+ struct make_<R<BOOST_PP_ENUM_PARAMS(N, A)>, Expr, State, Data
+ BOOST_MPL_AUX_LAMBDA_ARITY_PARAM(N)
+ >
+ : nested_type_if<
+ #define TMP0(Z, M, DATA) make_if_<BOOST_PP_CAT(A, M), Expr, State, Data>
+ #define TMP1(Z, M, DATA) typename TMP0(Z, M, DATA) ::type
+ R<BOOST_PP_ENUM(N, TMP1, ~)>
+ , typelist<BOOST_PP_ENUM(N, TMP0, ~) >
+ #undef TMP0
+ #undef TMP1
+ >
+ {};
+ #endif
+
+ template<
+ typename R
+ BOOST_PP_ENUM_TRAILING_PARAMS(N, typename A)
+ , typename Expr, typename State, typename Data
+ >
+ struct make_if_<R(BOOST_PP_ENUM_PARAMS(N, A)), Expr, State, Data, false>
+ {
+ typedef
+ typename remove_const<
+ typename remove_reference<
+ typename when<_, R(BOOST_PP_ENUM_PARAMS(N, A))>
+ ::template impl<Expr, State, Data>::result_type
+ >::type
+ >::type
+ type;
+ };
+
+ template<
+ typename R
+ BOOST_PP_ENUM_TRAILING_PARAMS(N, typename A)
+ , typename Expr, typename State, typename Data
+ >
+ struct make_if_<R(*)(BOOST_PP_ENUM_PARAMS(N, A)), Expr, State, Data, false>
+ {
+ typedef
+ typename remove_const<
+ typename remove_reference<
+ typename when<_, R(BOOST_PP_ENUM_PARAMS(N, A))>
+ ::template impl<Expr, State, Data>::result_type
+ >::type
+ >::type
+ type;
+ };
+
+ template<typename T, typename A>
+ struct construct_<proto::expr<T, A, N>, true>
+ {
+ typedef proto::expr<T, A, N> result_type;
+
+ template<BOOST_PP_ENUM_PARAMS(BOOST_PP_MAX(N, 1), typename A)>
+ result_type operator ()(BOOST_PP_ENUM_BINARY_PARAMS(BOOST_PP_MAX(N, 1), A, &a)) const
+ {
+ return result_type::make(BOOST_PP_ENUM_PARAMS(BOOST_PP_MAX(N, 1), a));
+ }
+ };
+ }
+
+ /// \brief A PrimitiveTransform which computes a type by evaluating any
+ /// nested transforms and then constructs an object of that type with the
+ /// current expression, state and data, transformed according
+ /// to \c A0 through \c AN.
+ template<typename Object BOOST_PP_ENUM_TRAILING_PARAMS(N, typename A)>
+ struct make<Object(BOOST_PP_ENUM_PARAMS(N, A))>
+ : transform<make<Object(BOOST_PP_ENUM_PARAMS(N, A))> >
+ {
+ template<typename Expr, typename State, typename Data>
+ struct impl : transform_impl<Expr, State, Data>
+ {
+ /// \brief <tt>make\<Object\>::::result\<void(Expr, State, Data)\>::::type</tt>
+ typedef typename detail::make_if_<Object, Expr, State, Data>::type result_type;
+ //typedef typename detail::make_<Object, Expr, State, Data>::type result_type;
+
+ /// Let \c ax be <tt>when\<_, Ax\>()(expr, state, data)</tt>
+ /// for each \c x in <tt>[0,N]</tt>.
+ /// Let \c T be <tt>result\<void(Expr, State, Data)\>::::type</tt>.
+ /// Return <tt>T(a0, a1,... aN)</tt>.
+ ///
+ /// \param expr The current expression
+ /// \param state The current state
+ /// \param data An arbitrary data
+ result_type operator ()(
+ typename impl::expr_param expr
+ , typename impl::state_param state
+ , typename impl::data_param data
+ ) const
+ {
+ proto::detail::ignore_unused(expr);
+ proto::detail::ignore_unused(state);
+ proto::detail::ignore_unused(data);
+ return detail::construct<result_type>(
+ #define TMP(Z, M, DATA) \
+ detail::as_lvalue( \
+ typename when<_, BOOST_PP_CAT(A, M)> \
+ ::template impl<Expr, State, Data>()(expr, state, data) \
+ )
+ BOOST_PP_ENUM(N, TMP, DATA)
+ #undef TMP
+ );
+ }
+ };
+ };
+
+ #if BOOST_WORKAROUND(__GNUC__, == 3)
+ // work around GCC bug
+ template<typename Tag, typename Args, long Arity BOOST_PP_ENUM_TRAILING_PARAMS(N, typename A)>
+ struct make<proto::expr<Tag, Args, Arity>(BOOST_PP_ENUM_PARAMS(N, A))>
+ : transform<make<proto::expr<Tag, Args, Arity>(BOOST_PP_ENUM_PARAMS(N, A))> >
+ {
+ template<typename Expr, typename State, typename Data>
+ struct impl : transform_impl<Expr, State, Data>
+ {
+ typedef proto::expr<Tag, Args, Arity> result_type;
+
+ result_type operator ()(
+ typename impl::expr_param expr
+ , typename impl::state_param state
+ , typename impl::data_param data
+ ) const
+ {
+ return proto::expr<Tag, Args, Arity>::make(
+ #define TMP(Z, M, DATA) \
+ detail::as_lvalue( \
+ typename when<_, BOOST_PP_CAT(A, M)> \
+ ::template impl<Expr, State, Data>()(expr, state, data) \
+ )
+ BOOST_PP_ENUM(N, TMP, DATA)
+ #undef TMP
+ );
+ }
+ };
+ };
+ #endif
+
+ #undef N
+
+#endif

Added: branches/proto/v4/boost/proto/transform/pass_through.hpp
==============================================================================
--- (empty file)
+++ branches/proto/v4/boost/proto/transform/pass_through.hpp 2008-04-06 02:19:35 EDT (Sun, 06 Apr 2008)
@@ -0,0 +1,191 @@
+#ifndef BOOST_PP_IS_ITERATING
+ ///////////////////////////////////////////////////////////////////////////////
+ /// \file pass_through.hpp
+ ///
+ /// Definition of the pass_through transform, which is the default transform
+ /// of all of the expression generator metafunctions such as unary_plus<>, plus<>
+ /// and nary_expr<>.
+ //
+ // Copyright 2008 Eric Niebler. Distributed under the Boost
+ // Software License, Version 1.0. (See accompanying file
+ // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+ #ifndef BOOST_PROTO_TRANSFORM_PASS_THROUGH_HPP_EAN_12_26_2006
+ #define BOOST_PROTO_TRANSFORM_PASS_THROUGH_HPP_EAN_12_26_2006
+
+ #include <boost/proto/detail/prefix.hpp>
+ #include <boost/preprocessor/cat.hpp>
+ #include <boost/preprocessor/repetition/enum.hpp>
+ #include <boost/preprocessor/iteration/iterate.hpp>
+ #include <boost/mpl/bool.hpp>
+ #include <boost/type_traits/remove_reference.hpp>
+ #include <boost/proto/proto_fwd.hpp>
+ #include <boost/proto/args.hpp>
+ #include <boost/proto/transform/impl.hpp>
+ #include <boost/proto/detail/suffix.hpp>
+
+ namespace boost { namespace proto
+ {
+ namespace detail
+ {
+ template<
+ typename Grammar
+ , typename Expr
+ , typename State
+ , typename Data
+ , long Arity = remove_reference<Expr>::type::proto_arity::value
+ >
+ struct pass_through_impl
+ {};
+
+ #define BOOST_PROTO_DEFINE_TRANSFORM_TYPE(Z, N, DATA) \
+ typename Grammar::BOOST_PP_CAT(proto_child, N)::template impl< \
+ typename result_of::child_c<Expr, N>::type \
+ , State \
+ , Data \
+ >::result_type
+
+ #define BOOST_PROTO_DEFINE_TRANSFORM(Z, N, DATA) \
+ typename Grammar::BOOST_PP_CAT(proto_child, N)::template impl< \
+ typename result_of::child_c<Expr, N>::type \
+ , State \
+ , Data \
+ >()( \
+ expr.proto_base().BOOST_PP_CAT(child, N), state, data \
+ )
+
+ #define BOOST_PP_ITERATION_PARAMS_1 (3, (1, BOOST_PROTO_MAX_ARITY, <boost/proto/transform/pass_through.hpp>))
+ #include BOOST_PP_ITERATE()
+
+ #undef BOOST_PROTO_DEFINE_TRANSFORM
+ #undef BOOST_PROTO_DEFINE_TRANSFORM_TYPE
+
+ template<typename Grammar, typename Expr, typename State, typename Data>
+ struct pass_through_impl<Grammar, Expr, State, Data, 0>
+ : transform_impl<Expr, State, Data>
+ {
+ typedef Expr result_type;
+
+ /// \param expr An expression
+ /// \return \c expr
+ /// \throw nothrow
+ typename pass_through_impl::expr_param operator()(
+ typename pass_through_impl::expr_param expr
+ , typename pass_through_impl::state_param
+ , typename pass_through_impl::data_param
+ ) const
+ {
+ return expr;
+ }
+ };
+
+ } // namespace detail
+
+ /// \brief A PrimitiveTransform that transforms the child expressions
+ /// of an expression node according to the corresponding children of
+ /// a Grammar.
+ ///
+ /// Given a Grammar such as <tt>plus\<T0, T1\></tt>, an expression type
+ /// that matches the grammar such as <tt>plus\<E0, E1\>::::type</tt>, a
+ /// state \c S and a data \c V, the result of applying the
+ /// <tt>pass_through\<plus\<T0, T1\> \></tt> transform is:
+ ///
+ /// \code
+ /// plus<
+ /// T0::result<void(E0, S, V)>::type
+ /// , T1::result<void(E1, S, V)>::type
+ /// >::type
+ /// \endcode
+ ///
+ /// The above demonstrates how child transforms and child expressions
+ /// are applied pairwise, and how the results are reassembled into a new
+ /// expression node with the same tag type as the original.
+ ///
+ /// The explicit use of <tt>pass_through\<\></tt> is not usually needed,
+ /// since the expression generator metafunctions such as
+ /// <tt>plus\<\></tt> have <tt>pass_through\<\></tt> as their default
+ /// transform. So, for instance, these are equivalent:
+ ///
+ /// \code
+ /// // Within a grammar definition, these are equivalent:
+ /// when< plus<X, Y>, pass_through< plus<X, Y> > >
+ /// when< plus<X, Y>, plus<X, Y> >
+ /// when< plus<X, Y> > // because of when<class X, class Y=X>
+ /// plus<X, Y> // because plus<> is both a
+ /// // grammar and a transform
+ /// \endcode
+ ///
+ /// For example, consider the following transform that promotes all
+ /// \c float terminals in an expression to \c double.
+ ///
+ /// \code
+ /// // This transform finds all float terminals in an expression and promotes
+ /// // them to doubles.
+ /// struct Promote
+ /// : or_<
+ /// when<terminal<float>, terminal<double>::type(_value) >
+ /// // terminal<>'s default transform is a no-op:
+ /// , terminal<_>
+ /// // nary_expr<> has a pass_through<> transform:
+ /// , nary_expr<_, vararg<Promote> >
+ /// >
+ /// {};
+ /// \endcode
+ template<typename Grammar>
+ struct pass_through
+ : transform<pass_through<Grammar> >
+ {
+ template<typename Expr, typename State, typename Data>
+ struct impl
+ : detail::pass_through_impl<Grammar, Expr, State, Data>
+ {};
+ };
+
+ /// INTERNAL ONLY
+ ///
+ template<typename Grammar>
+ struct is_callable<pass_through<Grammar> >
+ : mpl::true_
+ {};
+
+ }} // namespace boost::proto
+
+ #endif
+
+#else
+
+ #define N BOOST_PP_ITERATION()
+
+ template<typename Grammar, typename Expr, typename State, typename Data>
+ struct pass_through_impl<Grammar, Expr, State, Data, N>
+ : transform_impl<Expr, State, Data>
+ {
+ typedef proto::expr<
+ typename remove_reference<Expr>::type::proto_tag
+ , BOOST_PP_CAT(list, N)<
+ BOOST_PP_ENUM(N, BOOST_PROTO_DEFINE_TRANSFORM_TYPE, ~)
+ >
+ > result_type;
+
+ result_type operator ()(
+ typename pass_through_impl::expr_param expr
+ , typename pass_through_impl::state_param state
+ , typename pass_through_impl::data_param data
+ ) const
+ {
+ result_type that = {
+ BOOST_PP_ENUM(N, BOOST_PROTO_DEFINE_TRANSFORM, ~)
+ };
+ #if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1400))
+ // Without this, MSVC complains that "that" is uninitialized,
+ // and it actually triggers a runtime check in debug mode when
+ // built with VC8.
+ &that;
+ #endif
+ return that;
+ }
+ };
+
+ #undef N
+
+#endif

Added: branches/proto/v4/boost/proto/transform/when.hpp
==============================================================================
--- (empty file)
+++ branches/proto/v4/boost/proto/transform/when.hpp 2008-04-06 02:19:35 EDT (Sun, 06 Apr 2008)
@@ -0,0 +1,189 @@
+#ifndef BOOST_PP_IS_ITERATING
+ ///////////////////////////////////////////////////////////////////////////////
+ /// \file when.hpp
+ /// Definition of when transform.
+ //
+ // Copyright 2008 Eric Niebler. Distributed under the Boost
+ // Software License, Version 1.0. (See accompanying file
+ // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+ #ifndef BOOST_PROTO_TRANSFORM_WHEN_HPP_EAN_10_29_2007
+ #define BOOST_PROTO_TRANSFORM_WHEN_HPP_EAN_10_29_2007
+
+ #include <boost/proto/detail/prefix.hpp>
+ #include <boost/preprocessor/cat.hpp>
+ #include <boost/preprocessor/repetition/enum_params.hpp>
+ #include <boost/preprocessor/repetition/enum_trailing_params.hpp>
+ #include <boost/preprocessor/iteration/iterate.hpp>
+ #include <boost/mpl/if.hpp>
+ #include <boost/proto/proto_fwd.hpp>
+ #include <boost/proto/traits.hpp>
+ #include <boost/proto/transform/call.hpp>
+ #include <boost/proto/transform/make.hpp>
+ #include <boost/proto/transform/impl.hpp>
+ #include <boost/proto/detail/suffix.hpp>
+
+ namespace boost { namespace proto
+ {
+ /// \brief A grammar element and a PrimitiveTransform that associates
+ /// a transform with the grammar.
+ ///
+ /// Use <tt>when\<\></tt> to override a grammar's default transform
+ /// with a custom transform. It is for used when composing larger
+ /// transforms by associating smaller transforms with individual
+ /// rules in your grammar, as in the following transform which
+ /// counts the number of terminals in an expression.
+ ///
+ /// \code
+ /// // Count the terminals in an expression tree.
+ /// // Must be invoked with initial state == mpl::int_<0>().
+ /// struct CountLeaves
+ /// : or_<
+ /// when<terminal<_>, mpl::next<_state>()>
+ /// , otherwise<fold<_, _state, CountLeaves> >
+ /// >
+ /// {};
+ /// \endcode
+ ///
+ /// In <tt>when\<G, T\></tt>, when \c T is a class type it is a
+ /// PrimitiveTransform and the following equivalencies hold:
+ ///
+ /// <tt>when\<G,T\>::::result\<void(E,S,V)\>::::type</tt> is the same as
+ /// <tt>T::result\<void(E,S,V)\>::::type</tt>.
+ ///
+ /// <tt>when\<G,T\>()(e,s,v)</tt> is the same as
+ /// <tt>T()(e,s,v)</tt>.
+ template<typename Grammar, typename PrimitiveTransform BOOST_PROTO_WHEN_BUILDING_DOCS(= Grammar)>
+ struct when
+ : PrimitiveTransform
+ {
+ typedef typename Grammar::proto_base_expr proto_base_expr;
+ };
+
+ /// \brief A specialization that treats function pointer Transforms as
+ /// if they were function type Transforms.
+ ///
+ /// This specialization requires that \c Fun is actually a function type.
+ ///
+ /// This specialization is required for nested transforms such as
+ /// <tt>when\<G, T0(T1(_))\></tt>. In C++, functions that are used as
+ /// parameters to other functions automatically decay to funtion
+ /// pointer types. In other words, the type <tt>T0(T1(_))</tt> is
+ /// indistinguishable from <tt>T0(T1(*)(_))</tt>. This specialization
+ /// is required to handle these nested function pointer type transforms
+ /// properly.
+ template<typename Grammar, typename Fun>
+ struct when<Grammar, Fun *>
+ : when<Grammar, Fun>
+ {};
+
+ /// \brief Syntactic sugar for <tt>when\<_, Fun\></tt>, for use
+ /// in grammars to handle all the cases not yet handled.
+ ///
+ /// Use <tt>otherwise\<T\></tt> in your grammars as a synonym for
+ /// <tt>when\<_, T\></tt> as in the following transform which
+ /// counts the number of terminals in an expression.
+ ///
+ /// \code
+ /// // Count the terminals in an expression tree.
+ /// // Must be invoked with initial state == mpl::int_<0>().
+ /// struct CountLeaves
+ /// : or_<
+ /// when<terminal<_>, mpl::next<_state>()>
+ /// , otherwise<fold<_, _state, CountLeaves> >
+ /// >
+ /// {};
+ /// \endcode
+ template<typename Fun>
+ struct otherwise
+ : when<_, Fun>
+ {};
+
+ #define BOOST_PP_ITERATION_PARAMS_1 (3, (0, BOOST_PROTO_MAX_ARITY, <boost/proto/transform/when.hpp>))
+ #include BOOST_PP_ITERATE()
+
+ }} // namespace boost::proto
+
+ #endif
+
+#else
+
+ #define N BOOST_PP_ITERATION()
+
+ /// \brief A grammar element and a PrimitiveTransform that associates
+ /// a transform with the grammar.
+ ///
+ /// Use <tt>when\<\></tt> to override a grammar's default transform
+ /// with a custom transform. It is for used when composing larger
+ /// transforms by associating smaller transforms with individual
+ /// rules in your grammar, as in the following transform which
+ /// counts the number of terminals in an expression.
+ ///
+ /// \code
+ /// // Count the terminals in an expression tree.
+ /// // Must be invoked with initial state == mpl::int_<0>().
+ /// struct CountLeaves
+ /// : or_<
+ /// when<terminal<_>, mpl::next<_state>()>
+ /// , otherwise<fold<_, _state, CountLeaves> >
+ /// >
+ /// {};
+ /// \endcode
+ ///
+ /// The <tt>when\<G, R(A0,A1,...)\></tt> form accepts either a
+ /// CallableTransform or an ObjectTransform as its second parameter.
+ /// <tt>when\<\></tt> uses <tt>is_callable\<R\>::::value</tt> to
+ /// distinguish between the two, and uses <tt>call\<\></tt> to
+ /// evaluate CallableTransforms and <tt>make\<\></tt> to evaluate
+ /// ObjectTransforms.
+ template<typename Grammar, typename R BOOST_PP_ENUM_TRAILING_PARAMS(N, typename A)>
+ struct when<Grammar, R(BOOST_PP_ENUM_PARAMS(N, A))>
+ : transform<when<Grammar, R(BOOST_PP_ENUM_PARAMS(N, A))> >
+ {
+ typedef typename Grammar::proto_base_expr proto_base_expr;
+
+ // Note: do not evaluate is_callable<R> in this scope.
+ // R may be an incomplete type at this point.
+
+ template<typename Expr, typename State, typename Data>
+ struct impl : transform_impl<Expr, State, Data>
+ {
+ typedef call<R(BOOST_PP_ENUM_PARAMS(N, A))> call_;
+ typedef make<R(BOOST_PP_ENUM_PARAMS(N, A))> make_;
+
+ typedef
+ typename mpl::if_c<
+ // OK to evaluate is_callable<R> here.
+ // R should be compete by now.
+ is_callable<R>::value
+ , call_ // "R" is a function to call
+ , make_ // "R" is an object to construct
+ >::type
+ which;
+
+ typedef typename which::template impl<Expr, State, Data>::result_type result_type;
+
+ /// Evaluate <tt>R(A0,A1,...)</tt> as a transform either with
+ /// <tt>call\<\></tt> or with <tt>make\<\></tt> depending on
+ /// whether <tt>is_callable\<R\>::::value</tt> is \c true or
+ /// \c false.
+ ///
+ /// \param expr The current expression
+ /// \param state The current state
+ /// \param data An arbitrary data
+ /// \pre <tt>matches\<Expr, Grammar\>::::value</tt> is \c true
+ /// \return <tt>result\<void(Expr, State, Data)\>::::impl()(expr, state, data)</tt>
+ result_type operator ()(
+ typename impl::expr_param expr
+ , typename impl::state_param state
+ , typename impl::data_param data
+ ) const
+ {
+ return typename which::template impl<Expr, State, Data>()(expr, state, data);
+ }
+ };
+ };
+
+ #undef N
+
+#endif

Modified: branches/proto/v4/boost/xpressive/basic_regex.hpp
==============================================================================
--- branches/proto/v4/boost/xpressive/basic_regex.hpp (original)
+++ branches/proto/v4/boost/xpressive/basic_regex.hpp 2008-04-06 02:19:35 EDT (Sun, 06 Apr 2008)
@@ -24,7 +24,7 @@
 // Doxygen can't handle proto :-(
 #ifndef BOOST_XPRESSIVE_DOXYGEN_INVOKED
 # include <boost/xpressive/detail/static/grammar.hpp>
-# include <boost/xpressive/proto/extends.hpp>
+# include <boost/proto/extends.hpp>
 #endif
 
 #if BOOST_XPRESSIVE_HAS_MS_STACK_GUARD
@@ -77,7 +77,7 @@
     /// \return *this
     basic_regex<BidiIter> &operator =(basic_regex<BidiIter> const &that)
     {
- proto::arg(*this) = proto::arg(that);
+ proto::value(*this) = proto::value(that);
         return *this;
     }
 
@@ -115,14 +115,14 @@
     ///
     std::size_t mark_count() const
     {
- return proto::arg(*this) ? proto::arg(*this)->mark_count_ : 0;
+ return proto::value(*this) ? proto::value(*this)->mark_count_ : 0;
     }
 
     /// Returns a token which uniquely identifies this regular expression.
     ///
     regex_id_type regex_id() const
     {
- return proto::arg(*this) ? proto::arg(*this)->xpr_.get() : 0;
+ return proto::value(*this) ? proto::value(*this)->xpr_.get() : 0;
     }
 
     /// Swaps the contents of this basic_regex object with another.
@@ -137,7 +137,7 @@
     /// \throw nothrow
     void swap(basic_regex<BidiIter> &that) // throw()
     {
- proto::arg(*this).swap(proto::arg(that));
+ proto::value(*this).swap(proto::value(that));
     }
 
     /// Factory method for building a regex object from a range of characters.
@@ -207,7 +207,7 @@
         bool success = false, stack_error = false;
         __try
         {
- success = proto::arg(*this)->xpr_->match(state);
+ success = proto::value(*this)->xpr_->match(state);
         }
         __except(_exception_code() == 0xC00000FDUL)
         {
@@ -217,7 +217,7 @@
         detail::ensure(!stack_error, regex_constants::error_stack, "Regex stack space exhausted");
         return success;
         #else
- return proto::arg(*this)->xpr_->match(state);
+ return proto::value(*this)->xpr_->match(state);
         #endif
     }
 
@@ -225,7 +225,7 @@
     /// INTERNAL ONLY
     bool invalid_() const
     {
- return !proto::arg(*this) || !proto::arg(*this)->xpr_;
+ return !proto::value(*this) || !proto::value(*this)->xpr_;
     }
 
     // Compiles valid static regexes into a state machine.
@@ -233,7 +233,7 @@
     template<typename Expr>
     void compile_(Expr const &expr, mpl::true_)
     {
- detail::static_compile(expr, proto::arg(*this).get());
+ detail::static_compile(expr, proto::value(*this).get());
     }
 
     // No-op for invalid static regexes.

Modified: branches/proto/v4/boost/xpressive/detail/core/access.hpp
==============================================================================
--- branches/proto/v4/boost/xpressive/detail/core/access.hpp (original)
+++ branches/proto/v4/boost/xpressive/detail/core/access.hpp 2008-04-06 02:19:35 EDT (Sun, 06 Apr 2008)
@@ -32,7 +32,7 @@
 
     static std::size_t get_hidden_mark_count(basic_regex<BidiIter> const &rex)
     {
- return proto::arg(rex)->hidden_mark_count_;
+ return proto::value(rex)->hidden_mark_count_;
     }
 
     static bool invalid(basic_regex<BidiIter> const &rex)
@@ -48,7 +48,7 @@
     static shared_ptr<detail::regex_impl<BidiIter> > const &
     get_regex_impl(basic_regex<BidiIter> const &rex)
     {
- return proto::arg(rex).get();
+ return proto::value(rex).get();
     }
 
     static void init_sub_match_vector

Modified: branches/proto/v4/boost/xpressive/detail/core/matcher/action_matcher.hpp
==============================================================================
--- branches/proto/v4/boost/xpressive/detail/core/matcher/action_matcher.hpp (original)
+++ branches/proto/v4/boost/xpressive/detail/core/matcher/action_matcher.hpp 2008-04-06 02:19:35 EDT (Sun, 06 Apr 2008)
@@ -28,12 +28,12 @@
 #include <boost/xpressive/detail/core/quant_style.hpp>
 #include <boost/xpressive/detail/core/action.hpp>
 #include <boost/xpressive/detail/core/state.hpp>
-#include <boost/xpressive/proto/proto.hpp>
-#include <boost/xpressive/proto/context.hpp>
+#include <boost/proto/core.hpp>
+#include <boost/proto/context.hpp>
 #include <boost/xpressive/match_results.hpp> // for type_info_less
 #include <boost/xpressive/detail/static/transforms/as_action.hpp> // for 'read_attr'
 #if BOOST_VERSION >= 103500
-# include <boost/xpressive/proto/fusion.hpp>
+# include <boost/proto/fusion.hpp>
 # include <boost/fusion/include/transform_view.hpp>
 # include <boost/fusion/include/invoke.hpp>
 # include <boost/fusion/include/push_front.hpp>
@@ -57,11 +57,9 @@
 
     template<typename Expr, long N>
     struct child_
- : remove_reference<typename mpl::if_<
- is_const<Expr>
- , typename proto::result_of::arg_c<Expr, N>::const_reference
- , typename proto::result_of::arg_c<Expr, N>::reference
- >::type>
+ : remove_reference<
+ typename proto::result_of::child_c<Expr &, N>::type
+ >
     {};
 
     ///////////////////////////////////////////////////////////////////////////////
@@ -75,8 +73,8 @@
         typedef typename child_<Expr, 1>::type right_type;
 
         typedef
- typename proto::result_of::arg<
- typename proto::result_of::arg_c<right_type, 0>::type
+ typename proto::result_of::value<
+ typename proto::result_of::child_c<right_type, 0>::type
>::type
         function_type;
 
@@ -97,7 +95,7 @@
         result_type operator()(Expr &expr, Context &ctx) const
         {
             return fusion::invoke<function_type>(
- proto::arg(proto::arg_c<0>(proto::right(expr)))
+ proto::value(proto::child_c<0>(proto::right(expr)))
               , evaluated_args(
                     fusion::push_front(fusion::pop_front(proto::right(expr)), boost::ref(proto::left(expr)))
                   , proto::eval_fun<Context>(ctx)
@@ -117,7 +115,7 @@
         typedef typename child_<Expr, 1>::type right_type;
 
         typedef
- typename proto::result_of::arg<right_type>::type
+ typename proto::result_of::value<right_type>::type
         function_type;
 
         typedef typename boost::result_of<
@@ -126,7 +124,7 @@
 
         result_type operator()(Expr &expr, Context &ctx) const
         {
- return proto::arg(proto::right(expr))(
+ return proto::value(proto::right(expr))(
                 proto::eval(proto::left(expr), ctx)
             );
         }
@@ -165,7 +163,7 @@
             typedef Arg &result_type;
             result_type operator()(Expr &expr, action_context const &) const
             {
- return proto::arg(expr).get();
+ return proto::value(expr).get();
             }
         };
 
@@ -175,7 +173,7 @@
             typedef Arg const &result_type;
             result_type operator()(Expr &expr, action_context const &) const
             {
- return proto::arg(expr);
+ return proto::value(expr);
             }
         };
 
@@ -185,7 +183,7 @@
             typedef typename action_arg<Type, Int>::reference result_type;
             result_type operator()(Expr &expr, action_context const &ctx) const
             {
- action_args_type::const_iterator where_ = ctx.args().find(&typeid(proto::arg(expr)));
+ action_args_type::const_iterator where_ = ctx.args().find(&typeid(proto::value(expr)));
                 if(where_ == ctx.args().end())
                 {
                     boost::throw_exception(
@@ -195,7 +193,7 @@
                         )
                     );
                 }
- return proto::arg(expr).cast(where_->second);
+ return proto::value(expr).cast(where_->second);
             }
         };
 
@@ -207,7 +205,7 @@
 
         template<typename Expr>
         struct eval<Expr, proto::tag::terminal>
- : eval_terminal<Expr, typename proto::result_of::arg<Expr>::type>
+ : eval_terminal<Expr, typename proto::result_of::value<Expr>::type>
         {};
 
         // Evaluate attributes like a1|42
@@ -215,9 +213,9 @@
         struct eval<Expr, attr_with_default_tag>
         {
             typedef
- typename proto::result_of::arg<
+ typename proto::result_of::value<
                     typename proto::result_of::left<
- typename proto::result_of::arg<
+ typename proto::result_of::child<
                             Expr
>::type
>::type
@@ -228,9 +226,9 @@
 
             result_type operator ()(Expr const &expr, action_context const &ctx) const
             {
- return proto::arg(proto::left(proto::arg(expr))).t_
- ? *proto::arg(proto::left(proto::arg(expr))).t_
- : proto::eval(proto::right(proto::arg(expr)), ctx);
+ return proto::value(proto::left(proto::child(expr))).t_
+ ? *proto::value(proto::left(proto::child(expr))).t_
+ : proto::eval(proto::right(proto::child(expr)), ctx);
             }
         };
 
@@ -271,49 +269,50 @@
     ///////////////////////////////////////////////////////////////////////////////
     // subreg_transform
     //
- struct subreg_transform : proto::callable
+ struct subreg_transform : proto::transform<subreg_transform>
     {
- template<typename Sig> struct result {};
-
- template<typename This, typename Expr, typename State, typename Visitor>
- struct result<This(Expr, State, Visitor)>
+ template<typename Expr, typename State, typename Data>
+ struct impl : proto::transform_impl<Expr, State, Data>
         {
- typedef State unref_state;
- typedef typename proto::terminal<sub_match<typename unref_state::iterator> >::type type;
- };
+ typedef typename impl::state state_type;
 
- template<typename Expr, typename State, typename Visitor>
- typename result<void(Expr, State, Visitor)>::type
- operator ()(Expr const &, State const &state, Visitor &visitor) const
- {
- sub_match<typename State::iterator> const &sub = state.sub_matches_[ visitor ];
- return proto::as_expr(sub);
- }
+ typedef
+ typename proto::terminal<sub_match<typename state_type::iterator> >::type
+ result_type;
+
+ result_type operator ()(
+ typename impl::expr_param expr
+ , typename impl::state_param state
+ , typename impl::data_param data
+ ) const
+ {
+ return result_type::make(state.sub_matches_[ data ]);
+ }
+ };
     };
 
     ///////////////////////////////////////////////////////////////////////////////
     // mark_transform
     //
- struct mark_transform : proto::callable
+ struct mark_transform : proto::transform<mark_transform>
     {
- template<typename Sig> struct result {};
-
- template<typename This, typename Expr, typename State, typename Visitor>
- struct result<This(Expr, State, Visitor)>
+ template<typename Expr, typename State, typename Data>
+ struct impl : proto::transform_impl<Expr, State, Data>
         {
- typedef State unref_state;
+ typedef typename impl::state state_type;
             typedef
- typename proto::terminal<sub_match<typename unref_state::iterator> >::type
- type;
- };
+ typename proto::terminal<sub_match<typename state_type::iterator> >::type
+ result_type;
 
- template<typename Expr, typename State, typename Visitor>
- typename result<void(Expr, State, Visitor)>::type
- operator ()(Expr const &expr, State const &state, Visitor &) const
- {
- sub_match<typename State::iterator> const &sub = state.sub_matches_[ proto::arg(expr).mark_number_ ];
- return proto::as_expr(sub);
- }
+ result_type operator ()(
+ typename impl::expr_param expr
+ , typename impl::state_param state
+ , typename impl::data_param
+ ) const
+ {
+ return result_type::make(state.sub_matches_[ proto::value(expr).mark_number_ ]);
+ }
+ };
     };
 
     ///////////////////////////////////////////////////////////////////////////////
@@ -341,83 +340,89 @@
     ///////////////////////////////////////////////////////////////////////////////
     // attr_transform
     //
- struct attr_transform : proto::callable
+ struct attr_transform : proto::transform<attr_transform>
     {
- template<typename Sig> struct result {};
-
- template<typename This, typename Expr, typename State, typename Visitor>
- struct result<This(Expr, State, Visitor)>
+ template<typename Expr, typename State, typename Data>
+ struct impl : proto::transform_impl<Expr, State, Data>
         {
+ typedef typename impl::expr expr_type;
+
             typedef
- typename proto::result_of::as_expr<
- opt<typename Expr::proto_arg0::matcher_type::value_type::second_type>
- >::type
- type;
- };
+ typename expr_type::proto_child0::matcher_type::value_type::second_type
+ attr_type;
+
+ typedef
+ typename proto::terminal<opt<attr_type> >::type
+ result_type;
 
- template<typename Expr, typename State, typename Visitor>
- typename result<void(Expr, State, Visitor)>::type
- operator ()(Expr const &, State const &state, Visitor &) const
- {
- typedef typename Expr::proto_arg0::matcher_type::value_type::second_type attr_type;
- int slot = typename Expr::proto_arg0::nbr_type();
- attr_type const *attr = static_cast<attr_type const *>(state.attr_context_.attr_slots_[slot-1]);
- return proto::as_expr(opt<attr_type>(attr));
- }
+ result_type operator ()(
+ typename impl::expr_param
+ , typename impl::state_param state
+ , typename impl::data_param
+ ) const
+ {
+ int slot = typename expr_type::proto_child0::nbr_type();
+ attr_type const *attr = static_cast<attr_type const *>(state.attr_context_.attr_slots_[slot-1]);
+ return result_type::make(opt<attr_type>(attr));
+ }
+ };
     };
 
     ///////////////////////////////////////////////////////////////////////////////
     // attr_with_default_transform
     //
     template<typename Grammar, typename Callable = proto::callable>
- struct attr_with_default_transform : proto::callable
+ struct attr_with_default_transform : proto::transform<attr_with_default_transform<Grammar, Callable> >
     {
- template<typename Sig> struct result {};
-
- template<typename This, typename Expr, typename State, typename Visitor>
- struct result<This(Expr, State, Visitor)>
+ template<typename Expr, typename State, typename Data>
+ struct impl : proto::transform_impl<Expr, State, Data>
         {
             typedef
                 typename proto::unary_expr<
                     attr_with_default_tag
- , typename Grammar::template result<void(Expr, State, Visitor)>::type
+ , typename Grammar::template impl<Expr, State, Data>::result_type
>::type
- type;
- };
+ result_type;
 
- template<typename Expr, typename State, typename Visitor>
- typename result<void(Expr, State, Visitor)>::type
- operator ()(Expr const &expr, State const &state, Visitor &visitor) const
- {
- typename result<void(Expr, State, Visitor)>::type that = {
- Grammar()(expr, state, visitor)
- };
- return that;
- }
+ result_type operator ()(
+ typename impl::expr_param expr
+ , typename impl::state_param state
+ , typename impl::data_param data
+ ) const
+ {
+ result_type that = {
+ typename Grammar::template impl<Expr, State, Data>()(expr, state, data)
+ };
+ return that;
+ }
+ };
     };
 
     ///////////////////////////////////////////////////////////////////////////////
     // by_ref_transform
     //
- struct by_ref_transform : proto::callable
+ struct by_ref_transform : proto::transform<by_ref_transform>
     {
- template<typename Sig> struct result {};
-
- template<typename This, typename Expr, typename State, typename Visitor>
- struct result<This(Expr, State, Visitor)>
+ template<typename Expr, typename State, typename Data>
+ struct impl : proto::transform_impl<Expr, State, Data>
         {
             typedef
- typename proto::terminal<typename proto::result_of::arg<Expr>::const_reference>::type
- type;
- };
+ typename proto::result_of::value<typename impl::expr_param>::type
+ reference;
 
- template<typename Expr, typename State, typename Visitor>
- typename result<void(Expr, State, Visitor)>::type
- operator ()(Expr const &expr, State const &, Visitor &) const
- {
- typedef typename result<void(Expr, State, Visitor)>::type that_type;
- return that_type::make(proto::arg(expr));
- }
+ typedef
+ typename proto::terminal<reference>::type
+ result_type;
+
+ result_type operator ()(
+ typename impl::expr_param expr
+ , typename impl::state_param state
+ , typename impl::data_param data
+ ) const
+ {
+ return result_type::make(proto::value(expr));
+ }
+ };
     };
 
     ///////////////////////////////////////////////////////////////////////////////
@@ -457,9 +462,15 @@
         bool match(match_state<BidiIter> &state, Next const &next) const
         {
             // Bind the arguments
- int sub = this->sub_; // BUGBUG this is a hack
- typedef typename BindActionArgs::template result<void(Actor, match_state<BidiIter>, int)>::type action_type;
- action<action_type> actor(BindActionArgs()(this->actor_, state, sub));
+ typedef
+ typename BindActionArgs::template impl<
+ Actor const &
+ , match_state<BidiIter> &
+ , int const &
+ >::result_type
+ action_type;
+
+ action<action_type> actor(BindActionArgs()(this->actor_, state, this->sub_));
 
             // Put the action in the action list
             actionable const **action_list_tail = state.action_list_tail_;

Modified: branches/proto/v4/boost/xpressive/detail/core/matcher/end_matcher.hpp
==============================================================================
--- branches/proto/v4/boost/xpressive/detail/core/matcher/end_matcher.hpp (original)
+++ branches/proto/v4/boost/xpressive/detail/core/matcher/end_matcher.hpp 2008-04-06 02:19:35 EDT (Sun, 06 Apr 2008)
@@ -88,7 +88,7 @@
             {
                 actor->execute(state.action_args_);
             }
-
+
             return true;
         }
     };

Modified: branches/proto/v4/boost/xpressive/detail/core/matcher/predicate_matcher.hpp
==============================================================================
--- branches/proto/v4/boost/xpressive/detail/core/matcher/predicate_matcher.hpp (original)
+++ branches/proto/v4/boost/xpressive/detail/core/matcher/predicate_matcher.hpp 2008-04-06 02:19:35 EDT (Sun, 06 Apr 2008)
@@ -19,7 +19,7 @@
 #include <boost/xpressive/detail/core/quant_style.hpp>
 #include <boost/xpressive/detail/core/matcher/action_matcher.hpp>
 #include <boost/xpressive/detail/core/state.hpp>
-#include <boost/xpressive/proto/proto.hpp>
+#include <boost/proto/core.hpp>
 
 namespace boost { namespace xpressive { namespace detail
 {
@@ -46,7 +46,7 @@
             typedef Arg &result_type;
             result_type operator()(Expr &expr, predicate_context const &) const
             {
- return proto::arg(expr).get();
+ return proto::value(expr).get();
             }
         };
 
@@ -66,7 +66,7 @@
             typedef sub_match<BidiIter> const &result_type;
             result_type operator()(Expr &expr, predicate_context const &ctx) const
             {
- return ctx.sub_matches_[proto::arg(expr).mark_number_];
+ return ctx.sub_matches_[proto::value(expr).mark_number_];
             }
         };
 
@@ -78,7 +78,7 @@
 
         template<typename Expr>
         struct eval<Expr, proto::tag::terminal>
- : eval_terminal<Expr, typename proto::result_of::arg<Expr>::type>
+ : eval_terminal<Expr, typename proto::result_of::value<Expr>::type>
         {};
 
         #if BOOST_VERSION >= 103500
@@ -131,14 +131,14 @@
         bool match_(match_state<BidiIter> &state, Next const &next, mpl::true_) const
         {
             sub_match<BidiIter> const &sub = state.sub_match(this->sub_);
- return proto::arg(proto::arg_c<1>(this->predicate_))(sub) && next.match(state);
+ return proto::value(proto::child_c<1>(this->predicate_))(sub) && next.match(state);
         }
 
         template<typename BidiIter, typename Next>
         bool match_(match_state<BidiIter> &state, Next const &next, mpl::false_) const
         {
             predicate_context<BidiIter> ctx(this->sub_, state.sub_matches_);
- return proto::eval(proto::arg_c<1>(this->predicate_), ctx) && next.match(state);
+ return proto::eval(proto::child_c<1>(this->predicate_), ctx) && next.match(state);
         }
     };
 

Modified: branches/proto/v4/boost/xpressive/detail/detail_fwd.hpp
==============================================================================
--- branches/proto/v4/boost/xpressive/detail/detail_fwd.hpp (original)
+++ branches/proto/v4/boost/xpressive/detail/detail_fwd.hpp 2008-04-06 02:19:35 EDT (Sun, 06 Apr 2008)
@@ -39,7 +39,7 @@
     struct type_info_less;
 
     typedef std::map<std::type_info const *, void *, type_info_less> action_args_type;
-
+
     struct action_context;
 
     template<typename BidiIter>
@@ -405,13 +405,15 @@
     using proto::otherwise;
     using proto::switch_;
     using proto::make;
- using proto::_arg;
+ using proto::_child;
+ using proto::_value;
     using proto::_left;
     using proto::_right;
     using proto::not_;
     using proto::_state;
- using proto::_visitor;
+ using proto::_data;
     using proto::callable;
+ using proto::transform;
     using proto::fold;
     using proto::reverse_fold;
     using proto::fold_tree;
@@ -421,7 +423,7 @@
     using proto::bitwise_or;
     using proto::logical_not;
     using proto::dereference;
- using proto::posit;
+ using proto::unary_plus;
     using proto::negate;
     using proto::complement;
     using proto::comma;

Modified: branches/proto/v4/boost/xpressive/detail/static/compile.hpp
==============================================================================
--- branches/proto/v4/boost/xpressive/detail/static/compile.hpp (original)
+++ branches/proto/v4/boost/xpressive/detail/static/compile.hpp 2008-04-06 02:19:35 EDT (Sun, 06 Apr 2008)
@@ -15,7 +15,7 @@
 
 #include <boost/mpl/bool.hpp>
 #include <boost/iterator/iterator_traits.hpp>
-#include <boost/xpressive/proto/proto.hpp>
+#include <boost/proto/core.hpp>
 #include <boost/xpressive/regex_traits.hpp>
 #include <boost/xpressive/detail/core/regex_impl.hpp>
 #include <boost/xpressive/detail/core/linker.hpp>
@@ -39,9 +39,14 @@
         impl->traits_ = new traits_holder<Traits>(traits);
 
         // "compile" the regex and wrap it in an xpression_adaptor.
- xpression_visitor<BidiIter, mpl::false_, Traits> visitor(traits, impl);
+ typedef xpression_visitor<BidiIter, mpl::false_, Traits> visitor_type;
+ visitor_type visitor(traits, impl);
         intrusive_ptr<matchable_ex<BidiIter> const> adxpr = make_adaptor<matchable_ex<BidiIter> >(
- Grammar<char_type>()(xpr, end_xpression(), visitor)
+ typename Grammar<char_type>::template impl<Xpr const &, end_xpression, visitor_type &>()(
+ xpr
+ , end_xpression()
+ , visitor
+ )
         );
 
         // Link and optimize the regex
@@ -81,9 +86,9 @@
     static_compile_impl1(Xpr const &xpr, shared_ptr<regex_impl<BidiIter> > const &impl)
     {
         // use specified traits
- typedef typename proto::result_of::arg<typename proto::result_of::left<Xpr>::type>::type::locale_type locale_type;
+ typedef typename proto::result_of::value<typename proto::result_of::left<Xpr>::type>::type::locale_type locale_type;
         typedef typename regex_traits_type<locale_type, BidiIter>::type traits_type;
- static_compile_impl2(proto::right(xpr), impl, traits_type(proto::arg(proto::left(xpr)).getloc()));
+ static_compile_impl2(proto::right(xpr), impl, traits_type(proto::value(proto::left(xpr)).getloc()));
     }
 
     ///////////////////////////////////////////////////////////////////////////////

Modified: branches/proto/v4/boost/xpressive/detail/static/grammar.hpp
==============================================================================
--- branches/proto/v4/boost/xpressive/detail/static/grammar.hpp (original)
+++ branches/proto/v4/boost/xpressive/detail/static/grammar.hpp 2008-04-06 02:19:35 EDT (Sun, 06 Apr 2008)
@@ -16,7 +16,7 @@
 #include <boost/mpl/if.hpp>
 #include <boost/mpl/bool.hpp>
 #include <boost/mpl/assert.hpp>
-#include <boost/xpressive/proto/proto.hpp>
+#include <boost/proto/core.hpp>
 #include <boost/xpressive/detail/static/is_pure.hpp>
 #include <boost/xpressive/detail/static/transforms/as_matcher.hpp>
 #include <boost/xpressive/detail/static/transforms/as_alternate.hpp>
@@ -75,7 +75,7 @@
         template<typename Char, typename Gram, typename Greedy>
         struct as_repeat
           : if_<
- make<detail::use_simple_repeat<_arg, Char> >
+ make<detail::use_simple_repeat<_child, Char> >
               , as_simple_quantifier<Gram, Greedy>
               , as_default_quantifier<Greedy>
>
@@ -97,8 +97,8 @@
             {};
 
             template<typename Dummy>
- struct case_<tag::posit, Dummy>
- : posit<Gram>
+ struct case_<tag::unary_plus, Dummy>
+ : unary_plus<Gram>
             {};
 
             template<typename Dummy>
@@ -210,7 +210,7 @@
             struct case_<optional_tag<Greedy> , Dummy>
               : when<
                     unary_expr<optional_tag<Greedy>, Gram>
- , in_sequence<call<as_optional<Gram, Greedy>(_arg)> >
+ , in_sequence<call<as_optional<Gram, Greedy>(_child)> >
>
             {};
 
@@ -223,9 +223,9 @@
             {};
 
             template<typename Dummy>
- struct case_<tag::posit, Dummy>
+ struct case_<tag::unary_plus, Dummy>
               : when<
- posit<Gram>
+ unary_plus<Gram>
                   , call<Gram(as_repeat<Char, Gram, mpl::true_>)>
>
             {};
@@ -250,7 +250,7 @@
             struct case_<tag::negate, Dummy>
               : when<
                     negate<switch_<NonGreedyRepeatCases<Gram> > >
- , call<Gram(call<as_repeat<Char, Gram, mpl::false_>(_arg)>)>
+ , call<Gram(call<as_repeat<Char, Gram, mpl::false_>(_child)>)>
>
             {};
 
@@ -258,7 +258,7 @@
             struct case_<tag::complement, Dummy>
               : when<
                     complement<switch_<InvertibleCases<Char, Gram> > >
- , in_sequence<call<as_inverse(call<switch_<InvertibleCases<Char, Gram> >(_arg)>)> >
+ , in_sequence<call<as_inverse(call<switch_<InvertibleCases<Char, Gram> >(_child)>)> >
>
             {};
 

Modified: branches/proto/v4/boost/xpressive/detail/static/is_pure.hpp
==============================================================================
--- branches/proto/v4/boost/xpressive/detail/static/is_pure.hpp (original)
+++ branches/proto/v4/boost/xpressive/detail/static/is_pure.hpp 2008-04-06 02:19:35 EDT (Sun, 06 Apr 2008)
@@ -63,14 +63,14 @@
 
     template<typename Expr, typename Char>
     struct use_simple_repeat_<Expr, Char, proto::tag::terminal>
- : use_simple_repeat_terminal<typename proto::result_of::arg<Expr>::type, Char>
+ : use_simple_repeat_terminal<typename proto::result_of::value<Expr>::type, Char>
     {};
 
     template<typename Expr, typename Char>
     struct use_simple_repeat_<Expr, Char, proto::tag::shift_right>
       : mpl::and_<
- use_simple_repeat_<typename Expr::proto_arg0::proto_base_expr, Char>
- , use_simple_repeat_<typename Expr::proto_arg1::proto_base_expr, Char>
+ use_simple_repeat_<typename Expr::proto_child_ref0::proto_base_expr, Char>
+ , use_simple_repeat_<typename Expr::proto_child_ref1::proto_base_expr, Char>
>
     {};
 
@@ -78,8 +78,8 @@
     struct use_simple_repeat_<Expr, Char, proto::tag::bitwise_or>
       : mpl::and_<
             mpl::not_equal_to<unknown_width, width_of<Expr, Char> >
- , use_simple_repeat_<typename Expr::proto_arg0::proto_base_expr, Char>
- , use_simple_repeat_<typename Expr::proto_arg1::proto_base_expr, Char>
+ , use_simple_repeat_<typename Expr::proto_child_ref0::proto_base_expr, Char>
+ , use_simple_repeat_<typename Expr::proto_child_ref1::proto_base_expr, Char>
>
     {};
 
@@ -105,12 +105,16 @@
     // either (s1 = ...) or (a1 = ...) or (set = ...)
     template<typename Expr, typename Char>
     struct use_simple_repeat_<Expr, Char, proto::tag::assign>
- : use_simple_repeat_assign<typename proto::result_of::arg<typename Expr::proto_arg0::proto_base_expr>::type>
+ : use_simple_repeat_assign<
+ typename proto::result_of::value<
+ typename Expr::proto_child_ref0::proto_base_expr
+ >::type
+ >
     {};
 
     template<typename Expr, typename Char>
     struct use_simple_repeat_<Expr, Char, modifier_tag>
- : use_simple_repeat_<typename Expr::proto_arg1::proto_base_expr, Char>
+ : use_simple_repeat_<typename Expr::proto_child_ref1::proto_base_expr, Char>
     {};
 
     template<typename Expr, typename Char>
@@ -131,7 +135,7 @@
     // when complementing a set or an assertion, the purity is that of the set (true) or the assertion
     template<typename Expr, typename Char>
     struct use_simple_repeat_<Expr, Char, proto::tag::complement>
- : use_simple_repeat_<typename Expr::proto_arg0::proto_base_expr, Char>
+ : use_simple_repeat_<typename Expr::proto_child_ref0::proto_base_expr, Char>
     {};
 
     // The comma is used in list-initialized sets, which are pure
@@ -154,12 +158,12 @@
 
     template<typename Expr, typename Char>
     struct use_simple_repeat_<Expr, Char, proto::tag::subscript>
- : use_simple_repeat_subscript<Expr, Char, typename Expr::proto_arg0::proto_base_expr>
+ : use_simple_repeat_subscript<Expr, Char, typename Expr::proto_child_ref0::proto_base_expr>
     {};
 
     // Quantified expressions are variable-width and cannot use the simple quantifier
     template<typename Expr, typename Char>
- struct use_simple_repeat_<Expr, Char, proto::tag::posit>
+ struct use_simple_repeat_<Expr, Char, proto::tag::unary_plus>
       : mpl::false_
     {};
 
@@ -180,12 +184,12 @@
 
     template<typename Expr, typename Char, uint_t Count>
     struct use_simple_repeat_<Expr, Char, generic_quant_tag<Count, Count> >
- : use_simple_repeat_<typename Expr::proto_arg0::proto_base_expr, Char>
+ : use_simple_repeat_<typename Expr::proto_child_ref0::proto_base_expr, Char>
     {};
 
     template<typename Expr, typename Char>
     struct use_simple_repeat_<Expr, Char, proto::tag::negate>
- : use_simple_repeat_<typename Expr::proto_arg0::proto_base_expr, Char>
+ : use_simple_repeat_<typename Expr::proto_child_ref0::proto_base_expr, Char>
     {};
 
     ///////////////////////////////////////////////////////////////////////////////

Modified: branches/proto/v4/boost/xpressive/detail/static/modifier.hpp
==============================================================================
--- branches/proto/v4/boost/xpressive/detail/static/modifier.hpp (original)
+++ branches/proto/v4/boost/xpressive/detail/static/modifier.hpp 2008-04-06 02:19:35 EDT (Sun, 06 Apr 2008)
@@ -17,7 +17,7 @@
 #endif
 
 #include <boost/xpressive/detail/detail_fwd.hpp>
-#include <boost/xpressive/proto/traits.hpp>
+#include <boost/proto/traits.hpp>
 #include <boost/xpressive/regex_constants.hpp>
 
 namespace boost { namespace xpressive { namespace detail
@@ -36,7 +36,7 @@
             typedef typename proto::binary_expr<
                 modifier_tag
               , typename proto::terminal<Modifier>::type
- , typename proto::result_of::as_arg<Expr const>::type
+ , typename proto::result_of::as_child<Expr const>::type
>::type type;
         };
 
@@ -44,7 +44,7 @@
         typename apply<Expr>::type const
         operator ()(Expr const &expr) const
         {
- typename apply<Expr>::type that = {{this->mod_}, proto::as_arg(expr)};
+ typename apply<Expr>::type that = {{this->mod_}, proto::as_child(expr)};
             return that;
         }
 

Modified: branches/proto/v4/boost/xpressive/detail/static/placeholders.hpp
==============================================================================
--- branches/proto/v4/boost/xpressive/detail/static/placeholders.hpp (original)
+++ branches/proto/v4/boost/xpressive/detail/static/placeholders.hpp 2008-04-06 02:19:35 EDT (Sun, 06 Apr 2008)
@@ -108,6 +108,7 @@
     BOOST_XPR_QUANT_STYLE(quant_variable_width, unknown_width::value, false)
 
     typedef Nbr nbr_type;
+ static Nbr nbr() { return Nbr(); }
 };
 
 }}} // namespace boost::xpressive::detail

Modified: branches/proto/v4/boost/xpressive/detail/static/static.hpp
==============================================================================
--- branches/proto/v4/boost/xpressive/detail/static/static.hpp (original)
+++ branches/proto/v4/boost/xpressive/detail/static/static.hpp 2008-04-06 02:19:35 EDT (Sun, 06 Apr 2008)
@@ -251,7 +251,7 @@
 //
 inline int get_mark_number(basic_mark_tag const &mark)
 {
- return proto::arg(mark).mark_number_;
+ return proto::value(mark).mark_number_;
 }
 
 }}} // namespace boost::xpressive::detail

Modified: branches/proto/v4/boost/xpressive/detail/static/transforms/as_action.hpp
==============================================================================
--- branches/proto/v4/boost/xpressive/detail/static/transforms/as_action.hpp (original)
+++ branches/proto/v4/boost/xpressive/detail/static/transforms/as_action.hpp 2008-04-06 02:19:35 EDT (Sun, 06 Apr 2008)
@@ -23,8 +23,8 @@
 #include <boost/xpressive/detail/core/matcher/attr_end_matcher.hpp>
 #include <boost/xpressive/detail/static/static.hpp>
 #include <boost/xpressive/detail/static/transforms/as_quantifier.hpp>
-#include <boost/xpressive/proto/proto.hpp>
-#include <boost/xpressive/proto/transform.hpp>
+#include <boost/proto/core.hpp>
+#include <boost/proto/transform.hpp>
 
 namespace boost { namespace xpressive { namespace detail
 {
@@ -37,6 +37,7 @@
     {
         typedef Nbr nbr_type;
         typedef Matcher matcher_type;
+ static Nbr nbr() { return Nbr(); }
     };
 
 }}}
@@ -52,7 +53,7 @@
             // Ignore nested actions, because attributes are scoped
             when< subscript<_, _>, _state >
           , when< terminal<_>, _state >
- , when< proto::assign<terminal<detail::attribute_placeholder<Nbr> >, _>, call<_arg(_right)> >
+ , when< proto::assign<terminal<detail::attribute_placeholder<Nbr> >, _>, call<_value(_right)> >
           , otherwise< fold<_, _state, FindAttr<Nbr> > >
>
     {};
@@ -62,59 +63,35 @@
     // For patterns like (a1 = RHS)[ref(i) = a1], transform to
     // (a1 = RHS)[ref(i) = read_attr<1, RHS>] so that when reading the attribute
     // we know what type is stored in the attribute slot.
- struct as_read_attr : proto::callable
+ struct as_read_attr : proto::transform<as_read_attr>
     {
- template<typename Sig> struct result {};
-
- template<typename This, typename Expr, typename State, typename Visitor>
- struct result<This(Expr, State, Visitor)>
+ template<typename Expr, typename State, typename Data>
+ struct impl : proto::transform_impl<Expr, State, Data>
         {
+ typedef typename impl::expr expr_type;
+ typedef
+ typename FindAttr<typename expr_type::proto_child0::nbr_type>::template impl<
+ State
+ , mpl::void_
+ , int
+ >::result_type
+ attr_type;
+
             typedef
- typename proto::result_of::as_expr<
+ typename proto::terminal<
                     detail::read_attr<
- typename Expr::proto_arg0::nbr_type
- , typename FindAttr<typename Expr::proto_arg0::nbr_type>::template result<void(
- State
- , mpl::void_
- , int
- )>::type
+ typename expr_type::proto_child0::nbr_type
+ , BOOST_PROTO_UNCVREF(attr_type)
>
>::type
- type;
- };
+ result_type;
 
- template<typename Expr, typename State, typename Visitor>
- typename result<void(Expr, State, Visitor)>::type
- operator ()(Expr const &, State const &, Visitor &) const
- {
- typename result<void(Expr, State, Visitor)>::type that = {{}};
- return that;
- }
- };
-
- ///////////////////////////////////////////////////////////////////////////////
- // by_value
- // Store all terminals within an action by value to avoid dangling references.
- struct by_value : proto::callable
- {
- template<typename Sig> struct result {};
-
- template<typename This, typename Expr, typename State, typename Visitor>
- struct result<This(Expr, State, Visitor)>
- {
- typedef
- typename proto::result_of::as_expr<
- typename proto::result_of::arg<Expr>::type
- >::type
- type;
+ result_type operator ()(proto::ignore, proto::ignore, proto::ignore) const
+ {
+ result_type that = {{}};
+ return that;
+ }
         };
-
- template<typename Expr, typename State, typename Visitor>
- typename result<void(Expr, State, Visitor)>::type
- operator ()(Expr const &expr, State const &, Visitor &) const
- {
- return proto::as_expr(proto::arg(expr));
- }
     };
 
     ///////////////////////////////////////////////////////////////////////////////
@@ -124,7 +101,7 @@
     struct DeepCopy
       : or_<
             when< terminal<detail::attribute_placeholder<_> >, as_read_attr>
- , when< terminal<_>, by_value >
+ , when< terminal<_>, proto::_deep_copy(_)>
           , otherwise< nary_expr<_, vararg<DeepCopy> > >
>
     {};
@@ -132,14 +109,13 @@
     ///////////////////////////////////////////////////////////////////////////////
     // attr_nbr
     // For an attribute placeholder, return the attribute's slot number.
- struct attr_nbr : proto::callable
+ struct attr_nbr : proto::transform<attr_nbr>
     {
- template<typename Sig> struct result {};
-
- template<typename This, typename Expr, typename State, typename Visitor>
- struct result<This(Expr, State, Visitor)>
+ template<typename Expr, typename State, typename Data>
+ struct impl : proto::transform_impl<Expr, State, Data>
         {
- typedef typename Expr::proto_arg0::nbr_type::type type;
+ typedef typename impl::expr expr_type;
+ typedef typename expr_type::proto_child0::nbr_type::type result_type;
         };
     };
 
@@ -161,80 +137,91 @@
     ///////////////////////////////////////////////////////////////////////////////
     // max_attr
     // Take the maximum of the current attr slot number and the state.
- struct max_attr : proto::callable
+ struct max_attr : proto::transform<max_attr>
     {
- template<typename Sig> struct result {};
-
- template<typename This, typename Expr, typename State, typename Visitor>
- struct result<This(Expr, State, Visitor)>
+ template<typename Expr, typename State, typename Data>
+ struct impl : proto::transform_impl<Expr, State, Data>
         {
- typedef typename mpl::max<State, typename MaxAttr::template result<void(Expr, State, Visitor)>::type >::type type;
+ typedef
+ typename mpl::max<
+ typename impl::state
+ , typename MaxAttr::template impl<Expr, State, Data>::result_type
+ >::type
+ result_type;
         };
     };
 
     ///////////////////////////////////////////////////////////////////////////////
     // as_attr_matcher
     // turn a1=matcher into attr_matcher<Matcher>(1)
- struct as_attr_matcher : proto::callable
+ struct as_attr_matcher : proto::transform<as_attr_matcher>
     {
- template<typename Sig> struct result {};
-
- template<typename This, typename Expr, typename State, typename Visitor>
- struct result<This(Expr, State, Visitor)>
+ template<typename Expr, typename State, typename Data>
+ struct impl : proto::transform_impl<Expr, State, Data>
         {
+ typedef typename impl::expr expr_type;
+ typedef typename impl::data data_type;
             typedef
                 detail::attr_matcher<
- typename proto::result_of::arg<typename Expr::proto_arg1>::type
- , typename Visitor::traits_type
- , typename Visitor::icase_type
+ typename proto::result_of::value<typename expr_type::proto_child1>::type
+ , typename data_type::traits_type
+ , typename data_type::icase_type
>
- type;
+ result_type;
+
+ result_type operator ()(
+ typename impl::expr_param expr
+ , typename impl::state_param
+ , typename impl::data_param data
+ ) const
+ {
+ return result_type(
+ proto::value(proto::left(expr)).nbr()
+ , proto::value(proto::right(expr))
+ , data.traits()
+ );
+ }
         };
-
- template<typename Expr, typename State, typename Visitor>
- typename result<void(Expr, State, Visitor)>::type
- operator ()(Expr const &expr, State const &, Visitor &visitor) const
- {
- return typename result<void(Expr, State, Visitor)>::type(
- Expr::proto_arg0::proto_base_expr::proto_arg0::nbr_type::value
- , proto::arg(proto::right(expr))
- , visitor.traits()
- );
- }
     };
 
     ///////////////////////////////////////////////////////////////////////////////
     // add_attrs
     // Wrap an expression in attr_begin_matcher/attr_end_matcher pair
- struct add_attrs : proto::callable
+ struct add_attrs : proto::transform<add_attrs>
     {
- template<typename Sig> struct result {};
-
- template<typename This, typename Expr, typename State, typename Visitor>
- struct result<This(Expr, State, Visitor)>
+ template<typename Expr, typename State, typename Data>
+ struct impl : proto::transform_impl<Expr, State, Data>
         {
             typedef
+ detail::attr_begin_matcher<
+ typename MaxAttr::template impl<Expr, mpl::int_<0>, int>::result_type
+ >
+ begin_type;
+
+ typedef typename impl::expr expr_type;
+
+ typedef
                 typename shift_right<
- typename terminal<
- detail::attr_begin_matcher<typename MaxAttr::template result<void(Expr, mpl::int_<0>, int)>::type >
- >::type
+ typename terminal<begin_type>::type
                   , typename shift_right<
                         Expr
                       , terminal<detail::attr_end_matcher>::type
>::type
>::type
- type;
- };
+ result_type;
 
- template<typename Expr, typename State, typename Visitor>
- typename result<void(Expr, State, Visitor)>::type
- operator ()(Expr const &expr, State const &, Visitor &) const
- {
- detail::attr_begin_matcher<typename MaxAttr::template result<void(Expr, mpl::int_<0>, int)>::type > begin;
- detail::attr_end_matcher end;
- typename result<void(Expr, State, Visitor)>::type that = {{begin}, {expr, {end}}};
- return that;
- }
+ result_type operator ()(
+ typename impl::expr_param expr
+ , typename impl::state_param
+ , typename impl::data_param
+ ) const
+ {
+ begin_type begin;
+ detail::attr_end_matcher end;
+ result_type that = {{begin}, {expr, {end}}};
+ return that;
+ }
+ };
     };
 
     ///////////////////////////////////////////////////////////////////////////////
@@ -255,19 +242,20 @@
     // If A and B use attributes, wrap the above expression in
     // a attr_begin_matcher<Count> / attr_end_matcher pair, where Count is
     // the number of attribute slots used by the pattern/action.
- struct as_action : proto::callable
+ struct as_action : proto::transform<as_action>
     {
- template<typename Sig> struct result {};
-
- template<typename This, typename Expr, typename State, typename Visitor>
- struct result<This(Expr, State, Visitor)>
+ template<typename Expr, typename State, typename Data>
+ struct impl : proto::transform_impl<Expr, State, Data>
         {
             typedef typename proto::result_of::left<Expr>::type expr_type;
             typedef typename proto::result_of::right<Expr>::type action_type;
- typedef typename DeepCopy::template result<void(action_type, expr_type, int)>::type action_copy_type;
 
             typedef
- typename InsertMark::template result<void(expr_type, State, Visitor)>::type
+ typename DeepCopy::impl<action_type, expr_type, int>::result_type
+ action_copy_type;
+
+ typedef
+ typename InsertMark::impl<expr_type, State, Data>::result_type
             marked_expr_type;
 
             typedef
@@ -286,35 +274,35 @@
             no_attr_type;
 
             typedef
- typename InsertAttrs::template result<void(no_attr_type, State, Visitor)>::type
- type;
- };
+ typename InsertAttrs::impl<no_attr_type, State, Data>::result_type
+ result_type;
 
- template<typename Expr, typename State, typename Visitor>
- typename result<void(Expr, State, Visitor)>::type
- operator ()(Expr const &expr, State const &state, Visitor &visitor) const
- {
- typedef result<void(Expr, State, Visitor)> apply_type;
- typedef typename apply_type::matcher_type matcher_type;
-
- int dummy = 0;
- typename apply_type::marked_expr_type marked_expr =
- InsertMark()(proto::left(expr), state, visitor);
-
- typename apply_type::no_attr_type that =
+ result_type operator ()(
+ typename impl::expr_param expr
+ , typename impl::state_param state
+ , typename impl::data_param data
+ ) const
             {
- marked_expr
- , {
- matcher_type
- (
- DeepCopy()(proto::right(expr), proto::left(expr), dummy)
- , proto::arg(proto::left(marked_expr)).mark_number_
- )
- }
- };
-
- return InsertAttrs()(that, state, visitor);
- }
+ int dummy = 0;
+ marked_expr_type marked_expr =
+ InsertMark::impl<expr_type, State, Data>()(proto::left(expr), state, data);
+
+ no_attr_type that = {
+ marked_expr
+ , {
+ matcher_type(
+ DeepCopy::impl<action_type, expr_type, int>()(
+ proto::right(expr)
+ , proto::left(expr)
+ , dummy
+ )
+ , proto::value(proto::left(marked_expr)).mark_number_
+ )
+ }
+ };
+ return InsertAttrs::impl<no_attr_type, State, Data>()(that, state, data);
+ }
+ };
     };
 
 }}}

Modified: branches/proto/v4/boost/xpressive/detail/static/transforms/as_alternate.hpp
==============================================================================
--- branches/proto/v4/boost/xpressive/detail/static/transforms/as_alternate.hpp (original)
+++ branches/proto/v4/boost/xpressive/detail/static/transforms/as_alternate.hpp 2008-04-06 02:19:35 EDT (Sun, 06 Apr 2008)
@@ -16,7 +16,7 @@
 #include <boost/config.hpp>
 #include <boost/mpl/assert.hpp>
 #include <boost/type_traits/is_same.hpp>
-#include <boost/xpressive/proto/proto.hpp>
+#include <boost/proto/core.hpp>
 #include <boost/xpressive/detail/detail_fwd.hpp>
 #include <boost/xpressive/detail/static/static.hpp>
 #include <boost/xpressive/detail/core/matcher/alternate_matcher.hpp>
@@ -61,57 +61,69 @@
     {
         ///////////////////////////////////////////////////////////////////////////////
         // in_alternate_list
- template<typename Grammar>
- struct in_alternate_list : proto::callable
+ template<typename Grammar, typename Callable = proto::callable>
+ struct in_alternate_list : proto::transform<in_alternate_list<Grammar, Callable> >
         {
- template<typename Sig> struct result {};
-
- template<typename This, typename Expr, typename State, typename Visitor>
- struct result<This(Expr, State, Visitor)>
+ template<typename Expr, typename State, typename Data>
+ struct impl : proto::transform_impl<Expr, State, Data>
             {
- typedef detail::alternates_list<
- typename Grammar::template result<void(Expr, detail::alternate_end_xpression, Visitor)>::type
- , State
- > type;
+ typedef
+ detail::alternates_list<
+ typename Grammar::template impl<
+ Expr
+ , detail::alternate_end_xpression
+ , Data
+ >::result_type
+ , State
+ >
+ result_type;
+
+ result_type operator ()(
+ typename impl::expr_param expr
+ , typename impl::state_param state
+ , typename impl::data_param data
+ ) const
+ {
+ return result_type(
+ typename Grammar::template impl<Expr, detail::alternate_end_xpression, Data>()(
+ expr
+ , detail::alternate_end_xpression()
+ , data
+ )
+ , state
+ );
+ }
             };
-
- template<typename Expr, typename State, typename Visitor>
- typename result<void(Expr, State, Visitor)>::type
- operator ()(Expr const &expr, State const &state, Visitor &visitor) const
- {
- return typename result<void(Expr, State, Visitor)>::type(
- Grammar()(expr, detail::alternate_end_xpression(), visitor)
- , state
- );
- }
         };
 
         ///////////////////////////////////////////////////////////////////////////////
         // as_alternate_matcher
- template<typename Grammar>
- struct as_alternate_matcher : proto::callable
+ template<typename Grammar, typename Callable = proto::callable>
+ struct as_alternate_matcher : proto::transform<as_alternate_matcher<Grammar, Callable> >
         {
- template<typename Sig> struct result {};
-
- template<typename This, typename Expr, typename State, typename Visitor>
- struct result<This(Expr, State, Visitor)>
+ template<typename Expr, typename State, typename Data>
+ struct impl : proto::transform_impl<Expr, State, Data>
             {
- typedef detail::alternate_matcher<
- typename Grammar::template result<void(Expr, State, Visitor)>::type
- , typename Visitor::traits_type
- > type;
+ typedef typename impl::data data_type;
+ typedef
+ detail::alternate_matcher<
+ typename Grammar::template impl<Expr, State, Data>::result_type
+ , typename data_type::traits_type
+ >
+ result_type;
+
+ result_type operator ()(
+ typename impl::expr_param expr
+ , typename impl::state_param state
+ , typename impl::data_param data
+ ) const
+ {
+ return result_type(
+ typename Grammar::template impl<Expr, State, Data>()(expr, state, data)
+ );
+ }
             };
-
- template<typename Expr, typename State, typename Visitor>
- typename result<void(Expr, State, Visitor)>::type
- operator ()(Expr const &expr, State const &state, Visitor &visitor) const
- {
- return typename result<void(Expr, State, Visitor)>::type(
- Grammar()(expr, state, visitor)
- );
- }
         };
-
     }
 
 }}

Modified: branches/proto/v4/boost/xpressive/detail/static/transforms/as_independent.hpp
==============================================================================
--- branches/proto/v4/boost/xpressive/detail/static/transforms/as_independent.hpp (original)
+++ branches/proto/v4/boost/xpressive/detail/static/transforms/as_independent.hpp 2008-04-06 02:19:35 EDT (Sun, 06 Apr 2008)
@@ -16,8 +16,8 @@
 #include <boost/mpl/sizeof.hpp>
 #include <boost/xpressive/detail/detail_fwd.hpp>
 #include <boost/xpressive/detail/static/static.hpp>
-#include <boost/xpressive/proto/proto.hpp>
-#include <boost/xpressive/proto/transform.hpp>
+#include <boost/proto/core.hpp>
+#include <boost/proto/transform.hpp>
 
 namespace boost { namespace xpressive { namespace detail
 {
@@ -92,109 +92,119 @@
>
     {};
 
- template<typename Grammar>
- struct as_lookahead : proto::callable
+ template<typename Grammar, typename Callable = proto::callable>
+ struct as_lookahead : proto::transform<as_lookahead<Grammar, Callable> >
     {
- template<typename Sig> struct result {};
-
- template<typename This, typename Expr, typename State, typename Visitor>
- struct result<This(Expr, State, Visitor)>
+ template<typename Expr, typename State, typename Data>
+ struct impl : proto::transform_impl<Expr, State, Data>
         {
- typedef typename proto::result_of::arg<Expr>::type arg_type;
+ typedef typename proto::result_of::child<Expr>::type arg_type;
             
             typedef
- typename Grammar::template result<void(
- arg_type
- , typename IndependentEndXpression::result<void(arg_type, int, int)>::type
- , Visitor
- )>::type
+ typename IndependentEndXpression::impl<arg_type, int, int>::result_type
+ end_xpr_type;
+
+ typedef
+ typename Grammar::template impl<arg_type, end_xpr_type, Data>::result_type
             xpr_type;
- typedef detail::lookahead_matcher<xpr_type> type;
- };
+
+ typedef
+ detail::lookahead_matcher<xpr_type>
+ result_type;
 
- template<typename Expr, typename State, typename Visitor>
- typename result<void(Expr, State, Visitor)>::type
- operator ()(Expr const &expr, State const &, Visitor &visitor) const
- {
- typedef result<void(Expr, State, Visitor)> result_type;
- int i = 0;
- return typename result_type::type(
- Grammar()(
- proto::arg(expr)
- , IndependentEndXpression()(proto::arg(expr), i, i)
- , visitor
- )
- , false
- );
- }
+ result_type operator ()(
+ typename impl::expr_param expr
+ , typename impl::state_param
+ , typename impl::data_param data
+ ) const
+ {
+ int i = 0;
+ return result_type(
+ typename Grammar::template impl<arg_type, end_xpr_type, Data>()(
+ proto::child(expr)
+ , IndependentEndXpression::impl<arg_type, int, int>()(proto::child(expr), i, i)
+ , data
+ )
+ , false
+ );
+ }
+ };
     };
 
- template<typename Grammar>
- struct as_lookbehind : proto::callable
+ template<typename Grammar, typename Callable = proto::callable>
+ struct as_lookbehind : proto::transform<as_lookbehind<Grammar, Callable> >
     {
- template<typename Sig> struct result {};
-
- template<typename This, typename Expr, typename State, typename Visitor>
- struct result<This(Expr, State, Visitor)>
+ template<typename Expr, typename State, typename Data>
+ struct impl : proto::transform_impl<Expr, State, Data>
         {
- typedef typename proto::result_of::arg<Expr>::type arg_type;
+ typedef typename proto::result_of::child<Expr>::type arg_type;
+
             typedef
- typename Grammar::template result<void(
- arg_type
- , typename IndependentEndXpression::result<void(arg_type, int, int)>::type
- , Visitor
- )>::type
+ typename IndependentEndXpression::impl<arg_type, int, int>::result_type
+ end_xpr_type;
+
+ typedef
+ typename Grammar::template impl<arg_type, end_xpr_type, Data>::result_type
             xpr_type;
- typedef detail::lookbehind_matcher<xpr_type> type;
- };
+
+ typedef
+ detail::lookbehind_matcher<xpr_type>
+ result_type;
 
- template<typename Expr, typename State, typename Visitor>
- typename result<void(Expr, State, Visitor)>::type
- operator ()(Expr const &expr, State const &, Visitor &visitor) const
- {
- typedef typename result<void(Expr, State, Visitor)>::xpr_type xpr_type;
- int i = 0;
- xpr_type const &expr2 = Grammar()(
- proto::arg(expr)
- , IndependentEndXpression()(proto::arg(expr), i, i)
- , visitor
- );
- std::size_t width = expr2.get_width().value();
- return detail::lookbehind_matcher<xpr_type>(expr2, width, false);
- }
+ result_type operator ()(
+ typename impl::expr_param expr
+ , typename impl::state_param
+ , typename impl::data_param data
+ ) const
+ {
+ int i = 0;
+ xpr_type expr2 = typename Grammar::template impl<arg_type, end_xpr_type, Data>()(
+ proto::child(expr)
+ , IndependentEndXpression::impl<arg_type, int, int>()(proto::child(expr), i, i)
+ , data
+ );
+ std::size_t width = expr2.get_width().value();
+ return result_type(expr2, width, false);
+ }
+ };
     };
 
- template<typename Grammar>
- struct as_keeper : proto::callable
+ template<typename Grammar, typename Callable = proto::callable>
+ struct as_keeper : proto::transform<as_keeper<Grammar, Callable> >
     {
- template<typename Sig> struct result {};
-
- template<typename This, typename Expr, typename State, typename Visitor>
- struct result<This(Expr, State, Visitor)>
+ template<typename Expr, typename State, typename Data>
+ struct impl : proto::transform_impl<Expr, State, Data>
         {
- typedef typename proto::result_of::arg<Expr>::type arg_type;
- typedef detail::keeper_matcher<
- typename Grammar::template result<void(
- arg_type
- , typename IndependentEndXpression::result<void(arg_type, int, int)>::type
- , Visitor
- )>::type
- > type;
- };
+ typedef typename proto::result_of::child<Expr>::type arg_type;
+
+ typedef
+ typename IndependentEndXpression::impl<arg_type, int, int>::result_type
+ end_xpr_type;
 
- template<typename Expr, typename State, typename Visitor>
- typename result<void(Expr, State, Visitor)>::type
- operator ()(Expr const &expr, State const &, Visitor &visitor) const
- {
- int i = 0;
- return typename result<void(Expr, State, Visitor)>::type(
- Grammar()(
- proto::arg(expr)
- , IndependentEndXpression()(proto::arg(expr), i, i)
- , visitor
- )
- );
- }
+ typedef
+ typename Grammar::template impl<arg_type, end_xpr_type, Data>::result_type
+ xpr_type;
+
+ typedef
+ detail::keeper_matcher<xpr_type>
+ result_type;
+
+ result_type operator ()(
+ typename impl::expr_param expr
+ , typename impl::state_param
+ , typename impl::data_param data
+ ) const
+ {
+ int i = 0;
+ return result_type(
+ typename Grammar::template impl<arg_type, end_xpr_type, Data>()(
+ proto::child(expr)
+ , IndependentEndXpression::impl<arg_type, int, int>()(proto::child(expr), i, i)
+ , data
+ )
+ );
+ }
+ };
     };
 
 }}}

Modified: branches/proto/v4/boost/xpressive/detail/static/transforms/as_inverse.hpp
==============================================================================
--- branches/proto/v4/boost/xpressive/detail/static/transforms/as_inverse.hpp (original)
+++ branches/proto/v4/boost/xpressive/detail/static/transforms/as_inverse.hpp 2008-04-06 02:19:35 EDT (Sun, 06 Apr 2008)
@@ -17,7 +17,7 @@
 #include <boost/mpl/not.hpp>
 #include <boost/xpressive/detail/detail_fwd.hpp>
 #include <boost/xpressive/detail/static/static.hpp>
-#include <boost/xpressive/proto/proto.hpp>
+#include <boost/proto/core.hpp>
 
 #define UNCV(x) typename remove_const<x>::type
 #define UNREF(x) typename remove_reference<x>::type

Modified: branches/proto/v4/boost/xpressive/detail/static/transforms/as_marker.hpp
==============================================================================
--- branches/proto/v4/boost/xpressive/detail/static/transforms/as_marker.hpp (original)
+++ branches/proto/v4/boost/xpressive/detail/static/transforms/as_marker.hpp 2008-04-06 02:19:35 EDT (Sun, 06 Apr 2008)
@@ -15,7 +15,7 @@
 
 #include <boost/xpressive/detail/detail_fwd.hpp>
 #include <boost/xpressive/detail/static/static.hpp>
-#include <boost/xpressive/proto/proto.hpp>
+#include <boost/proto/core.hpp>
 
 namespace boost { namespace xpressive { namespace grammar_detail
 {
@@ -23,38 +23,36 @@
     ///////////////////////////////////////////////////////////////////////////////
     // as_marker
     // Insert mark tags before and after the expression
- struct as_marker : proto::callable
+ struct as_marker : proto::transform<as_marker>
     {
- template<typename Sig> struct result {};
-
- template<typename This, typename Expr, typename State, typename Visitor>
- struct result<This(Expr, State, Visitor)>
+ template<typename Expr, typename State, typename Data>
+ struct impl : proto::transform_impl<Expr, State, Data>
         {
             typedef
                 typename shift_right<
                     terminal<detail::mark_begin_matcher>::type
                   , typename shift_right<
- typename proto::result_of::right<Expr>::type
+ typename proto::result_of::right<typename impl::expr>::type
                       , terminal<detail::mark_end_matcher>::type
>::type
>::type
- type;
- };
+ result_type;
 
- template<typename Expr, typename State, typename Visitor>
- typename result<void(Expr, State, Visitor)>::type
- operator ()(Expr const &expr, State const &, Visitor &) const
- {
- int mark_nbr = detail::get_mark_number(proto::left(expr));
- detail::mark_begin_matcher begin(mark_nbr);
- detail::mark_end_matcher end(mark_nbr);
-
- typename result<void(Expr, State, Visitor)>::type that
- = {{begin}, {proto::right(expr), {end}}};
- return that;
- }
+ result_type operator ()(
+ typename impl::expr_param expr
+ , typename impl::state_param
+ , typename impl::data_param
+ ) const
+ {
+ int mark_nbr = detail::get_mark_number(proto::left(expr));
+ detail::mark_begin_matcher begin(mark_nbr);
+ detail::mark_end_matcher end(mark_nbr);
+
+ result_type that = {{begin}, {proto::right(expr), {end}}};
+ return that;
+ }
+ };
     };
-
 }}}
 
 #endif

Modified: branches/proto/v4/boost/xpressive/detail/static/transforms/as_matcher.hpp
==============================================================================
--- branches/proto/v4/boost/xpressive/detail/static/transforms/as_matcher.hpp (original)
+++ branches/proto/v4/boost/xpressive/detail/static/transforms/as_matcher.hpp 2008-04-06 02:19:35 EDT (Sun, 06 Apr 2008)
@@ -19,26 +19,28 @@
 
 namespace boost { namespace xpressive { namespace grammar_detail
 {
- struct as_matcher : proto::callable
+ struct as_matcher : proto::transform<as_matcher>
     {
- template<typename Sig> struct result {};
-
- template<typename This, typename Expr, typename State, typename Visitor>
- struct result<This(Expr, State, Visitor)>
+ template<typename Expr, typename State, typename Data>
+ struct impl : proto::transform_impl<Expr, State, Data>
         {
+ typedef typename impl::data data_type;
+
             typedef
- typename Visitor::template apply<
- typename proto::result_of::arg<Expr>::type
+ typename data_type::template apply<
+ typename proto::result_of::value<typename impl::expr>::type
>::type
- type;
+ result_type;
+
+ result_type operator ()(
+ typename impl::expr_param expr
+ , typename impl::state_param
+ , typename impl::data_param data
+ ) const
+ {
+ return data.call(proto::value(expr));
+ }
         };
-
- template<typename Expr, typename State, typename Visitor>
- typename result<void(Expr, State, Visitor)>::type
- operator ()(Expr const &expr, State const &, Visitor &visitor) const
- {
- return visitor.call(proto::arg(expr));
- }
     };
 
 }}}

Modified: branches/proto/v4/boost/xpressive/detail/static/transforms/as_modifier.hpp
==============================================================================
--- branches/proto/v4/boost/xpressive/detail/static/transforms/as_modifier.hpp (original)
+++ branches/proto/v4/boost/xpressive/detail/static/transforms/as_modifier.hpp 2008-04-06 02:19:35 EDT (Sun, 06 Apr 2008)
@@ -16,7 +16,7 @@
 #include <boost/mpl/sizeof.hpp>
 #include <boost/xpressive/detail/detail_fwd.hpp>
 #include <boost/xpressive/detail/static/static.hpp>
-#include <boost/xpressive/proto/proto.hpp>
+#include <boost/proto/core.hpp>
 
 #define UNCV(x) typename remove_const<x>::type
 #define UNREF(x) typename remove_reference<x>::type
@@ -36,28 +36,44 @@
 
     ///////////////////////////////////////////////////////////////////////////////
     // as_modifier
- template<typename Grammar>
- struct as_modifier : proto::callable
+ template<typename Grammar, typename Callable = proto::callable>
+ struct as_modifier : proto::transform<as_modifier<Grammar, Callable> >
     {
- template<typename Sig> struct result {};
-
- template<typename This, typename Expr, typename State, typename Visitor>
- struct result<This(Expr, State, Visitor)>
+ template<typename Expr, typename State, typename Data>
+ struct impl : proto::transform_impl<Expr, State, Data>
         {
- typedef typename proto::result_of::arg<typename proto::result_of::left<Expr>::type>::type modifier_type;
- typedef typename modifier_type::BOOST_NESTED_TEMPLATE apply<Visitor>::type visitor_type;
- typedef typename Grammar::template result<void(typename proto::result_of::right<Expr>::type, State, visitor_type)>::type type;
+ typedef
+ typename proto::result_of::value<
+ typename proto::result_of::left<typename impl::expr>::type
+ >::type
+ modifier_type;
+
+ typedef
+ typename modifier_type::template apply<typename impl::data>::type
+ visitor_type;
+
+ typedef
+ typename proto::result_of::right<Expr>::type
+ expr_type;
+
+ typedef
+ typename Grammar::template impl<expr_type, State, visitor_type &>::result_type
+ result_type;
+
+ result_type operator ()(
+ typename impl::expr_param expr
+ , typename impl::state_param state
+ , typename impl::data_param data
+ ) const
+ {
+ visitor_type new_visitor(proto::value(proto::left(expr)).call(data));
+ return typename Grammar::template impl<expr_type, State, visitor_type &>()(
+ proto::right(expr)
+ , state
+ , new_visitor
+ );
+ }
         };
-
- template<typename Expr, typename State, typename Visitor>
- typename result<void(Expr, State, Visitor)>::type
- operator ()(Expr const &expr, State const &state, Visitor &visitor) const
- {
- typedef result<void(Expr, State, Visitor)> result_;
- typedef typename result_::visitor_type new_visitor_type;
- new_visitor_type new_visitor(proto::arg(proto::left(expr)).call(visitor));
- return Grammar()(proto::right(expr), state, new_visitor);
- }
     };
 
 }}}

Modified: branches/proto/v4/boost/xpressive/detail/static/transforms/as_quantifier.hpp
==============================================================================
--- branches/proto/v4/boost/xpressive/detail/static/transforms/as_quantifier.hpp (original)
+++ branches/proto/v4/boost/xpressive/detail/static/transforms/as_quantifier.hpp 2008-04-06 02:19:35 EDT (Sun, 06 Apr 2008)
@@ -17,7 +17,7 @@
 #include <boost/type_traits/is_same.hpp>
 #include <boost/xpressive/detail/detail_fwd.hpp>
 #include <boost/xpressive/detail/static/static.hpp>
-#include <boost/xpressive/proto/proto.hpp>
+#include <boost/proto/core.hpp>
 
 namespace boost { namespace xpressive { namespace detail
 {
@@ -41,7 +41,7 @@
     struct min_type : Tag::min_type {};
 
     template<>
- struct min_type<proto::tag::posit> : mpl::integral_c<uint_t, 1> {};
+ struct min_type<proto::tag::unary_plus> : mpl::integral_c<uint_t, 1> {};
 
     template<>
     struct min_type<proto::tag::dereference> : mpl::integral_c<uint_t, 0> {};
@@ -53,7 +53,7 @@
     struct max_type : Tag::max_type {};
 
     template<>
- struct max_type<proto::tag::posit> : mpl::integral_c<uint_t, UINT_MAX-1> {};
+ struct max_type<proto::tag::unary_plus> : mpl::integral_c<uint_t, UINT_MAX-1> {};
 
     template<>
     struct max_type<proto::tag::dereference> : mpl::integral_c<uint_t, UINT_MAX-1> {};
@@ -63,45 +63,61 @@
 
     ///////////////////////////////////////////////////////////////////////////////
     // as_simple_quantifier
- template<typename Grammar, typename Greedy>
- struct as_simple_quantifier : proto::callable
+ template<typename Grammar, typename Greedy, typename Callable = proto::callable>
+ struct as_simple_quantifier : proto::transform<as_simple_quantifier<Grammar, Greedy, Callable> >
     {
- template<typename Sig> struct result {};
-
- template<typename This, typename Expr, typename State, typename Visitor>
- struct result<This(Expr, State, Visitor)>
+ template<typename Expr, typename State, typename Data>
+ struct impl : proto::transform_impl<Expr, State, Data>
         {
- typedef typename proto::result_of::arg<Expr>::type arg_type;
- typedef typename Grammar::template result<void(arg_type, detail::true_xpression, Visitor)>::type xpr_type;
- typedef detail::simple_repeat_matcher<xpr_type, Greedy> matcher_type;
- typedef typename proto::terminal<matcher_type>::type type;
- };
+ typedef
+ typename proto::result_of::child<Expr>::type
+ arg_type;
+
+ typedef
+ typename Grammar::template impl<arg_type, detail::true_xpression, Data>::result_type
+ xpr_type;
+
+ typedef
+ detail::simple_repeat_matcher<xpr_type, Greedy>
+ matcher_type;
+
+ typedef
+ typename proto::terminal<matcher_type>::type
+ result_type;
 
- template<typename Expr, typename State, typename Visitor>
- typename result<void(Expr, State, Visitor)>::type
- operator ()(Expr const &expr, State const &, Visitor &visitor) const
- {
- typedef result<void(Expr, State, Visitor)> result_;
- typedef typename result_::arg_type arg_type;
- typedef typename result_::xpr_type xpr_type;
- typedef typename result_::matcher_type matcher_type;
- typedef typename Expr::proto_tag tag;
-
- xpr_type const &xpr = Grammar()(proto::arg(expr), detail::true_xpression(), visitor);
- matcher_type matcher(xpr, (uint_t)min_type<tag>(), (uint_t)max_type<tag>(), xpr.get_width().value());
- return proto::terminal<matcher_type>::type::make(matcher);
- }
+ result_type operator ()(
+ typename impl::expr_param expr
+ , typename impl::state_param
+ , typename impl::data_param data
+ ) const
+ {
+ xpr_type xpr = typename Grammar::template impl<arg_type, detail::true_xpression, Data>()(
+ proto::child(expr)
+ , detail::true_xpression()
+ , data
+ );
+
+ typedef typename impl::expr expr_type;
+ matcher_type matcher(
+ xpr
+ , (uint_t)min_type<typename expr_type::proto_tag>::value
+ , (uint_t)max_type<typename expr_type::proto_tag>::value
+ , xpr.get_width().value()
+ );
+
+ return result_type::make(matcher);
+ }
+ };
     };
 
     ///////////////////////////////////////////////////////////////////////////////
     // add_hidden_mark
- struct add_hidden_mark : proto::callable
+ struct add_hidden_mark : proto::transform<add_hidden_mark>
     {
- template<typename Sig> struct result {};
-
- template<typename This, typename Expr, typename State, typename Visitor>
- struct result<This(Expr, State, Visitor)>
+ template<typename Expr, typename State, typename Data>
+ struct impl : proto::transform_impl<Expr, State, Data>
         {
+ typedef typename impl::expr expr_type;
             typedef
                 typename shift_right<
                     terminal<detail::mark_begin_matcher>::type
@@ -110,22 +126,23 @@
                       , terminal<detail::mark_end_matcher>::type
>::type
>::type
- type;
- };
+ result_type;
 
- template<typename Expr, typename State, typename Visitor>
- typename result<void(Expr, State, Visitor)>::type
- operator ()(Expr const &expr, State const &, Visitor &visitor) const
- {
- // we're inserting a hidden mark ... so grab the next hidden mark number.
- int mark_nbr = visitor.get_hidden_mark();
- detail::mark_begin_matcher begin(mark_nbr);
- detail::mark_end_matcher end(mark_nbr);
-
- typename result<void(Expr, State, Visitor)>::type that
- = {{begin}, {expr, {end}}};
- return that;
- }
+ result_type operator ()(
+ typename impl::expr_param expr
+ , typename impl::state_param
+ , typename impl::data_param data
+ ) const
+ {
+ // we're inserting a hidden mark ... so grab the next hidden mark number.
+ int mark_nbr = data.get_hidden_mark();
+ detail::mark_begin_matcher begin(mark_nbr);
+ detail::mark_end_matcher end(mark_nbr);
+
+ result_type that = {{begin}, {expr, {end}}};
+ return that;
+ }
+ };
     };
 
     ///////////////////////////////////////////////////////////////////////////////
@@ -140,15 +157,17 @@
     ///////////////////////////////////////////////////////////////////////////////
     // as_default_quantifier_impl
     template<typename Greedy, uint_t Min, uint_t Max>
- struct as_default_quantifier_impl : proto::callable
+ struct as_default_quantifier_impl : proto::transform<as_default_quantifier_impl<Greedy, Min, Max> >
     {
- template<typename Sig> struct result {};
-
- template<typename This, typename Expr, typename State, typename Visitor>
- struct result<This(Expr, State, Visitor)>
+ template<typename Expr, typename State, typename Data>
+ struct impl : proto::transform_impl<Expr, State, Data>
         {
             typedef
- typename InsertMark::template result<void(typename proto::result_of::arg<Expr>::type, State, Visitor)>::type
+ typename proto::result_of::child<Expr>::type
+ xpr_type;
+
+ typedef
+ typename InsertMark::impl<xpr_type, State, Data>::result_type
             marked_sub_type;
 
             typedef
@@ -159,31 +178,33 @@
                       , typename terminal<detail::repeat_end_matcher<Greedy> >::type
>::type
>::type
- type;
- };
+ result_type;
 
- template<typename Expr, typename State, typename Visitor>
- typename result<void(Expr, State, Visitor)>::type
- operator ()(Expr const &expr, State const &state, Visitor &visitor) const
- {
- // Ensure this sub-expression is book-ended with mark matchers
- typename result<void(Expr, State, Visitor)>::marked_sub_type const &
- marked_sub = InsertMark()(proto::arg(expr), state, visitor);
-
- // Get the mark_number from the begin_mark_matcher
- int mark_number = proto::arg(proto::left(marked_sub)).mark_number_;
- BOOST_ASSERT(0 != mark_number);
-
- uint_t min_ = (uint_t)min_type<typename Expr::proto_tag>();
- uint_t max_ = (uint_t)max_type<typename Expr::proto_tag>();
-
- detail::repeat_begin_matcher begin(mark_number);
- detail::repeat_end_matcher<Greedy> end(mark_number, min_, max_);
-
- typename result<void(Expr, State, Visitor)>::type that
- = {{begin}, {marked_sub, {end}}};
- return that;
- }
+ result_type operator ()(
+ typename impl::expr_param expr
+ , typename impl::state_param state
+ , typename impl::data_param data
+ ) const
+ {
+ // Ensure this sub-expression is book-ended with mark matchers
+ marked_sub_type marked_sub =
+ InsertMark::impl<xpr_type, State, Data>()(proto::child(expr), state, data);
+
+ // Get the mark_number from the begin_mark_matcher
+ int mark_number = proto::value(proto::left(marked_sub)).mark_number_;
+ BOOST_ASSERT(0 != mark_number);
+
+ typedef typename impl::expr expr_type;
+ uint_t min_ = (uint_t)min_type<typename expr_type::proto_tag>();
+ uint_t max_ = (uint_t)max_type<typename expr_type::proto_tag>();
+
+ detail::repeat_begin_matcher begin(mark_number);
+ detail::repeat_end_matcher<Greedy> end(mark_number, min_, max_);
+
+ result_type that = {{begin}, {marked_sub, {end}}};
+ return that;
+ }
+ };
     };
 
     ///////////////////////////////////////////////////////////////////////////////
@@ -194,56 +215,69 @@
 
     ///////////////////////////////////////////////////////////////////////////////
     // as_default_optional
- template<typename Grammar, typename Greedy>
- struct as_default_optional : proto::callable
+ template<typename Grammar, typename Greedy, typename Callable = proto::callable>
+ struct as_default_optional : proto::transform<as_default_optional<Grammar, Greedy, Callable> >
     {
- template<typename Sig> struct result {};
-
- template<typename This, typename Expr, typename State, typename Visitor>
- struct result<This(Expr, State, Visitor)>
+ template<typename Expr, typename State, typename Data>
+ struct impl : proto::transform_impl<Expr, State, Data>
         {
- typedef detail::optional_matcher<
- typename Grammar::template result<void(Expr, detail::alternate_end_xpression, Visitor)>::type
- , Greedy
- > type;
- };
+ typedef
+ detail::alternate_end_xpression
+ end_xpr;
+
+ typedef
+ detail::optional_matcher<
+ typename Grammar::template impl<Expr, end_xpr, Data>::result_type
+ , Greedy
+ >
+ result_type;
 
- template<typename Expr, typename State, typename Visitor>
- typename result<void(Expr, State, Visitor)>::type
- operator ()(Expr const &expr, State const &, Visitor &visitor) const
- {
- return typename result<void(Expr, State, Visitor)>::type(
- Grammar()(expr, detail::alternate_end_xpression(), visitor)
- );
- }
+ result_type operator ()(
+ typename impl::expr_param expr
+ , typename impl::state_param
+ , typename impl::data_param data
+ ) const
+ {
+ return result_type(
+ typename Grammar::template impl<Expr, end_xpr, Data>()(expr, end_xpr(), data)
+ );
+ }
+ };
     };
 
     ///////////////////////////////////////////////////////////////////////////////
     // as_mark_optional
- template<typename Grammar, typename Greedy>
- struct as_mark_optional : proto::callable
+ template<typename Grammar, typename Greedy, typename Callable = proto::callable>
+ struct as_mark_optional : proto::transform<as_mark_optional<Grammar, Greedy, Callable> >
     {
- template<typename Sig> struct result {};
-
- template<typename This, typename Expr, typename State, typename Visitor>
- struct result<This(Expr, State, Visitor)>
+ template<typename Expr, typename State, typename Data>
+ struct impl : proto::transform_impl<Expr, State, Data>
         {
- typedef detail::optional_mark_matcher<
- typename Grammar::template result<void(Expr, detail::alternate_end_xpression, Visitor)>::type
- , Greedy
- > type;
- };
+ typedef
+ detail::alternate_end_xpression
+ end_xpr;
+
+ typedef
+ detail::optional_mark_matcher<
+ typename Grammar::template impl<Expr, end_xpr, Data>::result_type
+ , Greedy
+ >
+ result_type;
 
- template<typename Expr, typename State, typename Visitor>
- typename result<void(Expr, State, Visitor)>::type
- operator ()(Expr const &expr, State const &, Visitor &visitor) const
- {
- int mark_number = proto::arg(proto::left(expr)).mark_number_;
- return typename result<void(Expr, State, Visitor)>::type(
- Grammar()(expr, detail::alternate_end_xpression(), visitor)
- , mark_number
- );
- }
+ result_type operator ()(
+ typename impl::expr_param expr
+ , typename impl::state_param
+ , typename impl::data_param data
+ ) const
+ {
+ int mark_number = proto::value(proto::left(expr)).mark_number_;
+
+ return result_type(
+ typename Grammar::template impl<Expr, end_xpr, Data>()(expr, end_xpr(), data)
+ , mark_number
+ );
+ }
+ };
     };
 
     ///////////////////////////////////////////////////////////////////////////////
@@ -267,24 +301,30 @@
 
     ///////////////////////////////////////////////////////////////////////////////
     // make_optional_
- template<typename Greedy>
- struct make_optional_ : proto::callable
+ template<typename Greedy, typename Callable = proto::callable>
+ struct make_optional_ : proto::transform<make_optional_<Greedy, Callable> >
     {
- template<typename Sig> struct result {};
-
- template<typename This, typename Expr, typename State, typename Visitor>
- struct result<This(Expr, State, Visitor)>
+ template<typename Expr, typename State, typename Data>
+ struct impl : proto::transform_impl<Expr, State, Data>
         {
- typedef typename unary_expr<optional_tag<Greedy>, Expr>::type type;
- };
+ typedef typename impl::expr expr_type;
+ typedef
+ typename unary_expr<
+ optional_tag<Greedy>
+ , Expr
+ >::type
+ result_type;
 
- template<typename Expr, typename State, typename Visitor>
- typename unary_expr<optional_tag<Greedy>, Expr>::type
- operator ()(Expr const &expr, State const &, Visitor &) const
- {
- typename unary_expr<optional_tag<Greedy>, Expr>::type that = {expr};
- return that;
- }
+ result_type operator ()(
+ typename impl::expr_param expr
+ , typename impl::state_param
+ , typename impl::data_param
+ ) const
+ {
+ result_type that = {expr};
+ return that;
+ }
+ };
     };
 
     ///////////////////////////////////////////////////////////////////////////////
@@ -298,40 +338,39 @@
     // as_default_quantifier_impl
     template<typename Greedy>
     struct as_default_quantifier_impl<Greedy, 0, 1>
- : call<make_optional_<Greedy>(_arg)>
+ : call<make_optional_<Greedy>(_child)>
     {};
 
     ///////////////////////////////////////////////////////////////////////////////
     // as_default_quantifier
- template<typename Greedy>
- struct as_default_quantifier : proto::callable
+ template<typename Greedy, typename Callable = proto::callable>
+ struct as_default_quantifier : proto::transform<as_default_quantifier<Greedy, Callable> >
     {
- template<typename Sig> struct result {};
-
- template<typename This, typename Expr, typename State, typename Visitor>
- struct result<This(Expr, State, Visitor)>
+ template<typename Expr, typename State, typename Data>
+ struct impl : proto::transform_impl<Expr, State, Data>
         {
+ typedef typename impl::expr expr_type;
             typedef
                 as_default_quantifier_impl<
                     Greedy
- , min_type<typename Expr::proto_tag>::value
- , max_type<typename Expr::proto_tag>::value
+ , min_type<typename expr_type::proto_tag>::value
+ , max_type<typename expr_type::proto_tag>::value
>
- impl;
+ other;
 
- typedef typename impl::template result<void(Expr, State, Visitor)>::type type;
- };
+ typedef
+ typename other::template impl<Expr, State, Data>::result_type
+ result_type;
 
- template<typename Expr, typename State, typename Visitor>
- typename result<void(Expr, State, Visitor)>::type
- operator ()(Expr const &expr, State const &state, Visitor &visitor) const
- {
- return as_default_quantifier_impl<
- Greedy
- , min_type<typename Expr::proto_tag>::value
- , max_type<typename Expr::proto_tag>::value
- >()(expr, state, visitor);
- }
+ result_type operator ()(
+ typename impl::expr_param expr
+ , typename impl::state_param state
+ , typename impl::data_param data
+ ) const
+ {
+ return typename other::template impl<Expr, State, Data>()(expr, state, data);
+ }
+ };
     };
 
 }}}

Modified: branches/proto/v4/boost/xpressive/detail/static/transforms/as_sequence.hpp
==============================================================================
--- branches/proto/v4/boost/xpressive/detail/static/transforms/as_sequence.hpp (original)
+++ branches/proto/v4/boost/xpressive/detail/static/transforms/as_sequence.hpp 2008-04-06 02:19:35 EDT (Sun, 06 Apr 2008)
@@ -20,29 +20,31 @@
 
 namespace boost { namespace xpressive { namespace grammar_detail
 {
- template<typename Grammar>
- struct in_sequence : proto::callable
+ template<typename Grammar, typename Callable = proto::callable>
+ struct in_sequence : proto::transform<in_sequence<Grammar, Callable> >
     {
- template<typename Sig> struct result {};
-
- template<typename This, typename Expr, typename State, typename Visitor>
- struct result<This(Expr, State, Visitor)>
+ template<typename Expr, typename State, typename Data>
+ struct impl : proto::transform_impl<Expr, State, Data>
         {
- typedef detail::static_xpression<
- typename Grammar::template result<void(Expr, State, Visitor)>::type
- , State
- > type;
- };
+ typedef
+ detail::static_xpression<
+ typename Grammar::template impl<Expr, State, Data>::result_type
+ , State
+ >
+ result_type;
 
- template<typename Expr, typename State, typename Visitor>
- typename result<void(Expr, State, Visitor)>::type
- operator ()(Expr const &expr, State const &state, Visitor &visitor) const
- {
- return typename result<void(Expr, State, Visitor)>::type(
- Grammar()(expr, state, visitor)
- , state
- );
- }
+ result_type operator ()(
+ typename impl::expr_param expr
+ , typename impl::state_param state
+ , typename impl::data_param data
+ ) const
+ {
+ return result_type(
+ typename Grammar::template impl<Expr, State, Data>()(expr, state, data)
+ , state
+ );
+ }
+ };
     };
 
 }}}

Modified: branches/proto/v4/boost/xpressive/detail/static/transforms/as_set.hpp
==============================================================================
--- branches/proto/v4/boost/xpressive/detail/static/transforms/as_set.hpp (original)
+++ branches/proto/v4/boost/xpressive/detail/static/transforms/as_set.hpp 2008-04-06 02:19:35 EDT (Sun, 06 Apr 2008)
@@ -14,7 +14,7 @@
 #endif
 
 #include <boost/mpl/assert.hpp>
-#include <boost/xpressive/proto/proto.hpp>
+#include <boost/proto/core.hpp>
 #include <boost/xpressive/detail/detail_fwd.hpp>
 #include <boost/xpressive/detail/static/static.hpp>
 #include <boost/xpressive/detail/utility/chset/chset.hpp>
@@ -64,52 +64,53 @@
     void fill_list_set(Char *&buffer, Expr const &expr, Traits const &traits)
     {
         fill_list_set(buffer, proto::left(expr), traits);
- *buffer++ = traits.translate(detail::char_cast<Char>(proto::arg(proto::right(expr)), traits));
+ *buffer++ = traits.translate(detail::char_cast<Char>(proto::value(proto::right(expr)), traits));
     }
 
     ///////////////////////////////////////////////////////////////////////////////
     // as_list_set_matcher
- template<typename Char>
- struct as_list_set_matcher
+ template<typename Char, typename Callable = proto::callable>
+ struct as_list_set_matcher : proto::transform<as_list_set_matcher<Char, Callable> >
     {
- template<typename Sig> struct result {};
-
- template<typename This, typename Expr, typename State, typename Visitor>
- struct result<This(Expr, State, Visitor)>
+ template<typename Expr, typename State, typename Data>
+ struct impl : proto::transform_impl<Expr, State, Data>
         {
- typedef detail::set_matcher<
- typename Visitor::traits_type
- , typename ListSet<Char>::template result<void(Expr, State, Visitor)>::type
- > type;
+ typedef typename impl::data data_type;
+ typedef
+ detail::set_matcher<
+ typename data_type::traits_type
+ , typename ListSet<Char>::template impl<Expr, State, Data>::result_type
+ >
+ result_type;
+
+ result_type operator ()(
+ typename impl::expr_param expr
+ , typename impl::state_param
+ , typename impl::data_param data
+ ) const
+ {
+ result_type set;
+ typedef typename impl::data data_type;
+ typename data_type::char_type *buffer = set.set_;
+ fill_list_set(buffer, expr, data.traits());
+ return set;
+ }
         };
-
- template<typename Expr, typename State, typename Visitor>
- typename result<void(Expr, State, Visitor)>::type
- operator ()(Expr const &expr, State const &, Visitor &visitor) const
- {
- detail::set_matcher<
- typename Visitor::traits_type
- , typename ListSet<Char>::template result<void(Expr, State, Visitor)>::type
- > set;
- typename Visitor::char_type *buffer = set.set_;
- fill_list_set(buffer, expr, visitor.traits());
- return set;
- }
     };
 
     ///////////////////////////////////////////////////////////////////////////////
     // merge_charset
     //
- template<typename Grammar, typename CharSet, typename Visitor>
+ template<typename Grammar, typename CharSet, typename Data>
     struct merge_charset
     {
- typedef typename Visitor::traits_type traits_type;
+ typedef typename Data::traits_type traits_type;
         typedef typename CharSet::char_type char_type;
         typedef typename CharSet::icase_type icase_type;
 
- merge_charset(CharSet &charset, Visitor &visitor)
+ merge_charset(CharSet &charset, Data &data)
           : charset_(charset)
- , visitor_(visitor)
+ , visitor_(data)
         {}
 
         template<typename Expr>
@@ -124,7 +125,13 @@
         template<typename Expr, typename Tag>
         void call_(Expr const &expr, Tag) const
         {
- this->set_(Grammar()(expr, detail::end_xpression(), this->visitor_));
+ this->set_(
+ typename Grammar::template impl<Expr const &, detail::end_xpression, Data &>()(
+ expr
+ , detail::end_xpression()
+ , this->visitor_
+ )
+ );
         }
 
         template<typename Expr>
@@ -166,46 +173,50 @@
         }
 
         CharSet &charset_;
- Visitor &visitor_;
+ Data &visitor_;
     };
 
     ///////////////////////////////////////////////////////////////////////////////
     //
- template<typename Grammar>
- struct as_set_matcher : proto::callable
+ template<typename Grammar, typename Callable = proto::callable>
+ struct as_set_matcher : proto::transform<as_set_matcher<Grammar, Callable> >
     {
- template<typename Sig> struct result {};
-
- template<typename This, typename Expr, typename State, typename Visitor>
- struct result<This(Expr, State, Visitor)>
+ template<typename Expr, typename State, typename Data>
+ struct impl : proto::transform_impl<Expr, State, Data>
         {
- typedef typename Visitor::char_type char_type;
+ typedef typename impl::data data_type;
+ typedef typename data_type::char_type char_type;
 
             // if sizeof(char_type)==1, merge everything into a basic_chset
             // BUGBUG this is not optimal.
- typedef typename mpl::if_<
- detail::is_narrow_char<char_type>
- , detail::basic_chset<char_type>
- , detail::compound_charset<typename Visitor::traits_type>
- >::type charset_type;
-
- typedef detail::charset_matcher<
- typename Visitor::traits_type
- , typename Visitor::icase_type
- , charset_type
- > type;
+ typedef
+ typename mpl::if_<
+ detail::is_narrow_char<char_type>
+ , detail::basic_chset<char_type>
+ , detail::compound_charset<typename data_type::traits_type>
+ >::type
+ charset_type;
+
+ typedef
+ detail::charset_matcher<
+ typename data_type::traits_type
+ , typename data_type::icase_type
+ , charset_type
+ >
+ result_type;
+
+ result_type operator ()(
+ typename impl::expr_param expr
+ , typename impl::state_param
+ , typename impl::data_param data
+ ) const
+ {
+ result_type matcher;
+ merge_charset<Grammar, result_type, typename impl::data> merge(matcher, data);
+ merge(expr); // Walks the tree and fills in the charset
+ return matcher;
+ }
         };
-
- template<typename Expr, typename State, typename Visitor>
- typename result<void(Expr, State, Visitor)>::type
- operator ()(Expr const &expr, State const &, Visitor &visitor) const
- {
- typedef typename result<void(Expr, State, Visitor)>::type set_type;
- set_type matcher;
- merge_charset<Grammar, set_type, Visitor> merge(matcher, visitor);
- merge(expr); // Walks the tree and fills in the charset
- return matcher;
- }
     };
 
 }}}

Modified: branches/proto/v4/boost/xpressive/detail/static/visitor.hpp
==============================================================================
--- branches/proto/v4/boost/xpressive/detail/static/visitor.hpp (original)
+++ branches/proto/v4/boost/xpressive/detail/static/visitor.hpp 2008-04-06 02:19:35 EDT (Sun, 06 Apr 2008)
@@ -14,7 +14,6 @@
 #endif
 
 #include <boost/ref.hpp>
-#include <boost/mpl/bind.hpp>
 #include <boost/shared_ptr.hpp>
 #include <boost/xpressive/detail/detail_fwd.hpp>
 #include <boost/xpressive/detail/core/regex_impl.hpp>

Modified: branches/proto/v4/boost/xpressive/detail/static/width_of.hpp
==============================================================================
--- branches/proto/v4/boost/xpressive/detail/static/width_of.hpp (original)
+++ branches/proto/v4/boost/xpressive/detail/static/width_of.hpp 2008-04-06 02:19:35 EDT (Sun, 06 Apr 2008)
@@ -23,10 +23,49 @@
 #include <boost/mpl/equal_to.hpp>
 #include <boost/type_traits/is_same.hpp>
 #include <boost/xpressive/detail/detail_fwd.hpp>
-#include <boost/xpressive/proto/traits.hpp>
+#include <boost/proto/traits.hpp>
 
 namespace boost { namespace xpressive { namespace detail
 {
+ template<typename Expr, typename Char, typename Tag = typename Expr::proto_tag>
+ struct width_of;
+
+ ///////////////////////////////////////////////////////////////////////////////
+ // add_widths
+ //
+ template<std::size_t N, std::size_t M>
+ struct add_widths
+ : mpl::size_t<N + M>
+ {};
+
+ template<std::size_t M>
+ struct add_widths<unknown_width::value, M>
+ : unknown_width
+ {};
+
+ template<std::size_t N>
+ struct add_widths<N, unknown_width::value>
+ : unknown_width
+ {};
+
+ template<>
+ struct add_widths<unknown_width::value, unknown_width::value>
+ : unknown_width
+ {};
+
+ ///////////////////////////////////////////////////////////////////////////////
+ // or_widths
+ //
+ template<std::size_t N, std::size_t M>
+ struct or_widths
+ : unknown_width
+ {};
+
+ template<std::size_t N>
+ struct or_widths<N, N>
+ : mpl::size_t<N>
+ {};
+
     ///////////////////////////////////////////////////////////////////////////////
     // is_char
     //
@@ -86,43 +125,29 @@
     ///////////////////////////////////////////////////////////////////////////////
     // width_of
     //
- template<typename Expr, typename Char, typename Tag = typename Expr::proto_tag>
+ template<typename Expr, typename Char, typename Tag>
     struct width_of
     {};
 
     template<typename Expr, typename Char>
     struct width_of<Expr, Char, proto::tag::terminal>
- : width_of_terminal<typename proto::result_of::arg<Expr>::type, Char>
+ : width_of_terminal<typename proto::result_of::value<Expr>::type, Char>
     {};
 
     template<typename Expr, typename Char>
     struct width_of<Expr, Char, proto::tag::shift_right>
- : mpl::if_<
- mpl::or_<
- mpl::equal_to<unknown_width, width_of<typename Expr::proto_arg0::proto_base_expr, Char> >
- , mpl::equal_to<unknown_width, width_of<typename Expr::proto_arg1::proto_base_expr, Char> >
- >
- , unknown_width
- , mpl::plus<
- width_of<typename Expr::proto_arg0::proto_base_expr, Char>
- , width_of<typename Expr::proto_arg1::proto_base_expr, Char>
- >
- >::type
+ : add_widths<
+ width_of<typename Expr::proto_child_ref0::proto_base_expr, Char>::value
+ , width_of<typename Expr::proto_child_ref1::proto_base_expr, Char>::value
+ >
     {};
 
     template<typename Expr, typename Char>
     struct width_of<Expr, Char, proto::tag::bitwise_or>
- : mpl::if_<
- mpl::or_<
- mpl::equal_to<unknown_width, width_of<typename Expr::proto_arg0::proto_base_expr, Char> >
- , mpl::not_equal_to<
- width_of<typename Expr::proto_arg0::proto_base_expr, Char>
- , width_of<typename Expr::proto_arg1::proto_base_expr, Char>
- >
- >
- , unknown_width
- , width_of<typename Expr::proto_arg0::proto_base_expr, Char>
- >::type
+ : or_widths<
+ width_of<typename Expr::proto_child_ref0::proto_base_expr, Char>::value
+ , width_of<typename Expr::proto_child_ref1::proto_base_expr, Char>::value
+ >
     {};
 
     template<typename Expr, typename Char, typename Left>
@@ -131,7 +156,7 @@
 
     template<typename Expr, typename Char>
     struct width_of_assign<Expr, Char, mark_placeholder>
- : width_of<typename Expr::proto_arg1::proto_base_expr, Char>
+ : width_of<typename Expr::proto_child_ref1::proto_base_expr, Char>
     {};
 
     template<typename Expr, typename Char>
@@ -147,12 +172,18 @@
     // either (s1 = ...) or (a1 = ...) or (set = ...)
     template<typename Expr, typename Char>
     struct width_of<Expr, Char, proto::tag::assign>
- : width_of_assign<Expr, Char, typename proto::result_of::arg<typename Expr::proto_arg0::proto_base_expr>::type>
+ : width_of_assign<
+ Expr
+ , Char
+ , typename proto::result_of::value<
+ typename Expr::proto_child_ref0::proto_base_expr
+ >::type
+ >
     {};
 
     template<typename Expr, typename Char>
     struct width_of<Expr, Char, modifier_tag>
- : width_of<typename Expr::proto_arg1::proto_base_expr, Char>
+ : width_of<typename Expr::proto_child_ref1::proto_base_expr, Char>
     {};
 
     template<typename Expr, typename Char>
@@ -174,11 +205,15 @@
         // If this assert fires, you put something that doesn't require backtracking
         // in a keep(). In that case, the keep() is not necessary and you should just
         // remove it.
- BOOST_MPL_ASSERT_RELATION((width_of<typename Expr::proto_arg0::proto_base_expr, Char>::value), ==, unknown_width::value);
+ BOOST_MPL_ASSERT_RELATION(
+ (width_of<typename Expr::proto_child_ref0::proto_base_expr, Char>::value)
+ , ==
+ , unknown_width::value
+ );
     };
 
     template<typename Expr, typename Char>
- struct width_of<Expr, Char, proto::tag::posit>
+ struct width_of<Expr, Char, proto::tag::unary_plus>
       : unknown_width
     {};
 
@@ -200,10 +235,10 @@
     template<typename Expr, typename Char, uint_t Count>
     struct width_of<Expr, Char, generic_quant_tag<Count, Count> >
       : mpl::if_<
- mpl::equal_to<unknown_width, width_of<typename Expr::proto_arg0::proto_base_expr, Char> >
+ mpl::equal_to<unknown_width, width_of<typename Expr::proto_child_ref0::proto_base_expr, Char> >
           , unknown_width
           , mpl::times<
- width_of<typename Expr::proto_arg0::proto_base_expr, Char>
+ width_of<typename Expr::proto_child_ref0::proto_base_expr, Char>
               , mpl::size_t<Count>
>
>::type
@@ -211,13 +246,13 @@
 
     template<typename Expr, typename Char>
     struct width_of<Expr, Char, proto::tag::negate>
- : width_of<typename Expr::proto_arg0::proto_base_expr, Char>
+ : width_of<typename Expr::proto_child_ref0::proto_base_expr, Char>
     {};
 
     // when complementing a set or an assertion, the width is that of the set (1) or the assertion (0)
     template<typename Expr, typename Char>
     struct width_of<Expr, Char, proto::tag::complement>
- : width_of<typename Expr::proto_arg0::proto_base_expr, Char>
+ : width_of<typename Expr::proto_child_ref0::proto_base_expr, Char>
     {};
 
     // The comma is used in list-initialized sets, and the width of sets are 1
@@ -238,14 +273,19 @@
       : mpl::size_t<1>
     {
         // If Left is "set" then make sure that Right has a width_of 1
- BOOST_MPL_ASSERT_RELATION(1, ==, (width_of<typename Expr::proto_arg1::proto_base_expr, Char>::value));
+ BOOST_MPL_ASSERT_RELATION(
+ 1
+ , ==
+ , (width_of<typename Expr::proto_child_ref1::proto_base_expr, Char>::value));
     };
 
     template<typename Expr, typename Char>
     struct width_of<Expr, Char, proto::tag::subscript>
- : width_of_subscript<Expr, Char, typename Expr::proto_arg0::proto_base_expr>
+ : width_of_subscript<Expr, Char, typename Expr::proto_child_ref0::proto_base_expr>
     {};
 
 }}} // namespace boost::xpressive::detail
 
+#undef UNREF
+
 #endif

Modified: branches/proto/v4/boost/xpressive/match_results.hpp
==============================================================================
--- branches/proto/v4/boost/xpressive/match_results.hpp (original)
+++ branches/proto/v4/boost/xpressive/match_results.hpp 2008-04-06 02:19:35 EDT (Sun, 06 Apr 2008)
@@ -57,8 +57,8 @@
 #include <boost/xpressive/detail/utility/literals.hpp>
 #include <boost/xpressive/detail/utility/algorithm.hpp>
 #include <boost/xpressive/detail/utility/counted_base.hpp>
-#include <boost/xpressive/proto/proto_fwd.hpp>
-#include <boost/xpressive/proto/eval.hpp>
+#include <boost/proto/proto_fwd.hpp>
+#include <boost/proto/eval.hpp>
 
 namespace boost { namespace xpressive { namespace detail
 {
@@ -668,11 +668,11 @@
     {
         typedef typename proto::result_of::left<Arg>::type left_type;
         typedef typename proto::result_of::right<Arg>::type right_type;
- typedef typename proto::result_of::arg<left_type>::type arg_left_type;
- typedef typename proto::result_of::arg<right_type>::type arg_right_type;
+ typedef typename proto::result_of::value<left_type>::type arg_left_type;
+ typedef typename proto::result_of::value<right_type>::type arg_right_type;
         BOOST_MPL_ASSERT((proto::matches<Arg, detail::ActionArgBinding>));
         BOOST_MPL_ASSERT((is_same<typename arg_left_type::type, arg_right_type>));
- this->args_[&typeid(proto::arg(proto::left(arg)))] = &proto::arg(proto::right(arg));
+ this->args_[&typeid(proto::value(proto::left(arg)))] = &proto::value(proto::right(arg));
         return *this;
     }
 

Modified: branches/proto/v4/boost/xpressive/regex_actions.hpp
==============================================================================
--- branches/proto/v4/boost/xpressive/regex_actions.hpp (original)
+++ branches/proto/v4/boost/xpressive/regex_actions.hpp 2008-04-06 02:19:35 EDT (Sun, 06 Apr 2008)
@@ -19,7 +19,6 @@
 #include <boost/mpl/if.hpp>
 #include <boost/mpl/or.hpp>
 #include <boost/mpl/int.hpp>
-#include <boost/noncopyable.hpp>
 #include <boost/lexical_cast.hpp>
 #include <boost/throw_exception.hpp>
 #include <boost/utility/enable_if.hpp>
@@ -41,7 +40,7 @@
 
 // Doxygen can't handle proto :-(
 #ifndef BOOST_XPRESSIVE_DOXYGEN_INVOKED
-# include <boost/xpressive/proto/transform.hpp>
+# include <boost/proto/transform.hpp>
 # include <boost/xpressive/detail/core/matcher/action_matcher.hpp>
 #endif
 
@@ -98,10 +97,10 @@
         {
             typedef int result_type;
 
- template<typename Visitor, typename Expr>
- int operator ()(Visitor &visitor, Expr const &expr) const
+ template<typename Data, typename Expr>
+ int operator ()(Data &data, Expr const &expr) const
             {
- visitor.let(expr);
+ data.let(expr);
                 return 0;
             }
         };
@@ -118,7 +117,7 @@
>
               , proto::function<
                     proto::_state // no-op
- , proto::vararg<proto::call<BindArg(proto::_visitor, proto::_)> >
+ , proto::vararg<proto::call<BindArg(proto::_data, proto::_)> >
>
>
         {};
@@ -130,14 +129,18 @@
         template<typename Expr>
         struct let_
         {
- BOOST_PROTO_EXTENDS(Expr, let_<Expr>, let_domain)
- BOOST_PROTO_EXTENDS_FUNCTION(Expr, let_<Expr>, let_domain)
+ BOOST_PROTO_BASIC_EXTENDS(Expr, let_<Expr>, let_domain)
+ BOOST_PROTO_EXTENDS_FUNCTION()
         };
 
         template<typename Args, typename BidiIter>
         void bind_args(let_<Args> const &args, match_results<BidiIter> &what)
         {
- BindArgs()(args, 0, what);
+ BindArgs::impl<let_<Args> const &, int, match_results<BidiIter> &>()(
+ args
+ , 0
+ , what
+ );
         }
 
         template<typename BidiIter>
@@ -679,12 +682,12 @@
 
         T &get()
         {
- return proto::arg(*this);
+ return proto::value(*this);
         }
 
         T const &get() const
         {
- return proto::arg(*this);
+ return proto::value(*this);
         }
     };
 
@@ -702,27 +705,24 @@
 
         T &get() const
         {
- return proto::arg(*this).get();
+ return proto::value(*this).get();
         }
     };
 
     template<typename T>
     struct local
- : private noncopyable
- , detail::value_wrapper<T>
+ : detail::value_wrapper<T>
       , proto::terminal<reference_wrapper<T> >::type
     {
         typedef typename proto::terminal<reference_wrapper<T> >::type base_type;
 
         local()
- : noncopyable()
- , detail::value_wrapper<T>()
+ : detail::value_wrapper<T>()
           , base_type(base_type::make(boost::ref(detail::value_wrapper<T>::value)))
         {}
 
         explicit local(T const &t)
- : noncopyable()
- , detail::value_wrapper<T>(t)
+ : detail::value_wrapper<T>(t)
           , base_type(base_type::make(boost::ref(detail::value_wrapper<T>::value)))
         {}
 
@@ -730,13 +730,16 @@
 
         T &get()
         {
- return proto::arg(*this);
+ return proto::value(*this);
         }
 
         T const &get() const
         {
- return proto::arg(*this);
+ return proto::value(*this);
         }
+
+ private:
+ local(local const &);
     };
 
     /// as (a.k.a., lexical_cast)
@@ -821,9 +824,6 @@
         typedef typename proto::terminal<detail::action_arg<T, mpl::int_<I> > >::type action_arg_type;
 
         BOOST_PROTO_EXTENDS(action_arg_type, this_type, proto::default_domain)
- BOOST_PROTO_EXTENDS_ASSIGN(action_arg_type, this_type, proto::default_domain)
- BOOST_PROTO_EXTENDS_SUBSCRIPT(action_arg_type, this_type, proto::default_domain)
- BOOST_PROTO_EXTENDS_FUNCTION(action_arg_type, this_type, proto::default_domain)
     };
 
     /// Usage: construct\<Type\>(arg1, arg2)

Modified: branches/proto/v4/boost/xpressive/regex_algorithms.hpp
==============================================================================
--- branches/proto/v4/boost/xpressive/regex_algorithms.hpp (original)
+++ branches/proto/v4/boost/xpressive/regex_algorithms.hpp 2008-04-06 02:19:35 EDT (Sun, 06 Apr 2008)
@@ -51,7 +51,7 @@
 /// \param end The end of the sequence.
 /// \param what The \c match_results struct into which the sub_matches will be written
 /// \param re The regular expression object to use
-/// \param flags Optional match flags, used to control how the expression is matched
+/// \param flags Optional match flags, used to control how the expression is matched
 /// against the sequence. (See \c match_flag_type.)
 /// \return \c true if a match is found, \c false otherwise
 /// \throw \c regex_error on stack exhaustion
@@ -569,7 +569,7 @@
 ///
 /// \pre Type \c BidiIter meets the requirements of a Bidirectional Iterator (24.1.4).
 /// \pre Type \c OutIter meets the requirements of an Output Iterator (24.1.2).
-/// \pre Type \c Formatter models \c ForwardRange, <tt>Callable\<match_results\<BidiIter\> \></tt>,
+/// \pre Type \c Formatter models \c ForwardRange, <tt>Callable\<match_results\<BidiIter\> \></tt>,
 /// <tt>Callable\<match_results\<BidiIter\>, OutIter\></tt>, or
 /// <tt>Callable\<match_results\<BidiIter\>, OutIter, regex_constants::match_flag_type\></tt>;
 /// or else it is a null-terminated format string, or an expression template

Modified: branches/proto/v4/boost/xpressive/regex_primitives.hpp
==============================================================================
--- branches/proto/v4/boost/xpressive/regex_primitives.hpp (original)
+++ branches/proto/v4/boost/xpressive/regex_primitives.hpp 2008-04-06 02:19:35 EDT (Sun, 06 Apr 2008)
@@ -23,8 +23,8 @@
 
 // Doxygen can't handle proto :-(
 #ifndef BOOST_XPRESSIVE_DOXYGEN_INVOKED
-# include <boost/xpressive/proto/proto.hpp>
-# include <boost/xpressive/proto/transform.hpp>
+# include <boost/proto/core.hpp>
+# include <boost/proto/transform.hpp>
 # include <boost/xpressive/detail/core/icase.hpp>
 # include <boost/xpressive/detail/static/compile.hpp>
 # include <boost/xpressive/detail/static/modifier.hpp>
@@ -43,7 +43,7 @@
         mark_tag(int mark_nbr)
         {
             mark_placeholder mark = {mark_nbr};
- proto::arg(*this) = mark;
+ proto::value(*this) = mark;
         }
 
         operator basic_mark_tag const &() const
@@ -89,8 +89,8 @@
     // s1 or -s1
     struct SubMatch
       : proto::or_<
- proto::when<basic_mark_tag, push_back(proto::_visitor, mark_number(proto::_arg)) >
- , proto::when<proto::negate<basic_mark_tag>, push_back(proto::_visitor, minus_one()) >
+ proto::when<basic_mark_tag, push_back(proto::_data, mark_number(proto::_value)) >
+ , proto::when<proto::negate<basic_mark_tag>, push_back(proto::_data, minus_one()) >
>
     {};
 
@@ -116,32 +116,36 @@
     #endif
 
     // replace "Expr" with "keep(*State) >> Expr"
- struct skip_primitives : proto::callable
+ struct skip_primitives : proto::transform<skip_primitives>
     {
- template<typename Sig> struct result {};
-
- template<typename This, typename Expr, typename State, typename Visitor>
- struct result<This(Expr, State, Visitor)>
+ template<typename Expr, typename State, typename Data>
+ struct impl : proto::transform_impl<Expr, State, Data>
         {
+ typedef typename impl::expr expr_type;
+ typedef typename impl::state state_type;
+
             typedef
                 typename proto::shift_right<
                     typename proto::unary_expr<
                         keeper_tag
- , typename proto::dereference<State>::type
+ , typename proto::dereference<
+ typename state_type::proto_derived_expr // remove the const &
+ >::type
>::type
- , Expr
+ , typename expr_type::proto_derived_expr // remove the const &
>::type
- type;
- };
+ result_type;
 
- template<typename Expr, typename State, typename Visitor>
- typename result<void(Expr, State, Visitor)>::type
- operator ()(Expr const &expr, State const &state, Visitor &) const
- {
- typedef typename result<void(Expr, State, Visitor)>::type type;
- type that = {{{state}}, expr};
- return that;
- }
+ result_type operator ()(
+ typename impl::expr_param expr
+ , typename impl::state_param state
+ , typename impl::data_param
+ ) const
+ {
+ result_type that = {{{state}}, expr};
+ return that;
+ }
+ };
     };
 
     struct Primitives
@@ -182,12 +186,16 @@
         struct result<This(Expr)>
         {
             typedef
+ SkipGrammar::impl<
+ typename proto::result_of::as_expr<Expr>::type
+ , skip_type const &
+ , mpl::void_ &
+ >
+ skip_transform;
+
+ typedef
                 typename proto::shift_right<
- typename SkipGrammar::result<void(
- typename proto::result_of::as_expr<Expr>::type
- , skip_type
- , mpl::void_
- )>::type
+ typename skip_transform::result_type
                   , typename proto::dereference<skip_type>::type
>::type
             type;
@@ -198,9 +206,12 @@
         operator ()(Expr const &expr) const
         {
             mpl::void_ ignore;
- typedef typename result<skip_directive(Expr)>::type result_type;
- result_type result = {SkipGrammar()(proto::as_expr(expr), this->skip_, ignore), {skip_}};
- return result;
+ typedef result<skip_directive(Expr)> result_fun;
+ typename result_fun::type that = {
+ typename result_fun::skip_transform()(proto::as_expr(expr), this->skip_, ignore)
+ , {skip_}
+ };
+ return that;
         }
 
     private:
@@ -574,7 +585,7 @@
 #ifdef BOOST_XPRESSIVE_DOXYGEN_INVOKED
 template<typename Literal> detail::unspecified as_xpr(Literal const &literal) { return 0; }
 #else
-proto::functional::as_expr<> const as_xpr = {};
+proto::functor::as_expr<> const as_xpr = {};
 #endif
 
 ///////////////////////////////////////////////////////////////////////////////

Modified: branches/proto/v4/boost/xpressive/xpressive_fwd.hpp
==============================================================================
--- branches/proto/v4/boost/xpressive/xpressive_fwd.hpp (original)
+++ branches/proto/v4/boost/xpressive/xpressive_fwd.hpp 2008-04-06 02:19:35 EDT (Sun, 06 Apr 2008)
@@ -50,8 +50,8 @@
 # endif
 #endif
 
-#include <boost/xpressive/proto/proto_fwd.hpp>
-#include <boost/xpressive/proto/traits.hpp>
+#include <boost/proto/proto_fwd.hpp>
+#include <boost/proto/traits.hpp>
 
 namespace boost { namespace xpressive
 {

Modified: branches/proto/v4/boost/xpressive/xpressive_typeof.hpp
==============================================================================
--- branches/proto/v4/boost/xpressive/xpressive_typeof.hpp (original)
+++ branches/proto/v4/boost/xpressive/xpressive_typeof.hpp 2008-04-06 02:19:35 EDT (Sun, 06 Apr 2008)
@@ -19,7 +19,7 @@
 #ifndef BOOST_NO_STL_LOCALE
 # include <boost/typeof/std/locale.hpp>
 #endif
-#include <boost/xpressive/proto/proto_typeof.hpp>
+#include <boost/proto/proto_typeof.hpp>
 #include <boost/xpressive/detail/detail_fwd.hpp>
 
 #include BOOST_TYPEOF_INCREMENT_REGISTRATION_GROUP()

Added: branches/proto/v4/libs/proto/doc/Jamfile.v2
==============================================================================
--- (empty file)
+++ branches/proto/v4/libs/proto/doc/Jamfile.v2 2008-04-06 02:19:35 EDT (Sun, 06 Apr 2008)
@@ -0,0 +1,109 @@
+# Copyright Eric Niebler 2007. Use, modification, and distribution are
+# subject to the Boost Software License, Version 1.0. (See accompanying
+# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+import path ;
+import doxygen ;
+import quickbook ;
+
+wave-command = [ path.native $(BOOST_ROOT)/dist/bin/wave ] ;
+
+# Generate reference section using Doxygen
+doxygen protodoc
+ :
+ ../../../boost/proto/args.hpp
+ ../../../boost/proto/context.hpp
+ ../../../boost/proto/debug.hpp
+ ../../../boost/proto/deep_copy.hpp
+ ../../../boost/proto/domain.hpp
+ ../../../boost/proto/eval.hpp
+ ../../../boost/proto/expr.hpp
+ ../../../boost/proto/extends.hpp
+ ../../../boost/proto/fusion.hpp
+ ../../../boost/proto/generate.hpp
+ ../../../boost/proto/literal.hpp
+ ../../../boost/proto/make_expr.hpp
+ ../../../boost/proto/matches.hpp
+ ../../../boost/proto/operators.hpp
+ ../../../boost/proto/proto.hpp
+ ../../../boost/proto/proto_fwd.hpp
+# ../../../boost/proto/proto_typeof.hpp
+ ../../../boost/proto/ref.hpp
+ ../../../boost/proto/tags.hpp
+ ../../../boost/proto/traits.hpp
+ ../../../boost/proto/transform.hpp
+ ../../../boost/proto/context/callable.hpp
+ ../../../boost/proto/context/default.hpp
+ ../../../boost/proto/context/null.hpp
+ ../../../boost/proto/transform/arg.hpp
+ ../../../boost/proto/transform/call.hpp
+ ../../../boost/proto/transform/fold.hpp
+ ../../../boost/proto/transform/fold_tree.hpp
+ ../../../boost/proto/transform/lazy.hpp
+ ../../../boost/proto/transform/make.hpp
+ ../../../boost/proto/transform/pass_through.hpp
+ ../../../boost/proto/transform/when.hpp
+ :
+ <doxygen:param>EXTRACT_ALL=YES
+ <doxygen:param>HIDE_UNDOC_MEMBERS=NO
+ # Use Boost.Wave to preprocess Proto's source
+# <doxygen:param>INPUT_FILTER=./wave.sh
+ <doxygen:param>"INPUT_FILTER=\"$(wave-command) -S ../../.. \\
+ -S $(BOOST_ROOT) \\
+ -S \\\"C:\\Program Files\\Microsoft Visual Studio .NET 2003\\vc7\\include\\\" \\
+ -D _WIN32 \\
+ -D BOOST_PROTO_BUILDING_DOCS \\
+ -p 1 \""
+ # This ensures that Wave is actually built before we try to execute it
+ <dependency>$(BOOST_ROOT)/tools/wave/build release
+ ;
+
+xml proto
+ :
+ proto.qbk
+ ;
+
+boostbook standalone
+ :
+ proto
+ :
+ # HTML options first:
+ # Use graphics not text for navigation:
+ <xsl:param>navig.graphics=1
+ # How far down we chunk nested sections, basically all of them:
+ <xsl:param>chunk.section.depth=10
+ # Don't put the first section on the same page as the TOC:
+ <xsl:param>chunk.first.sections=1
+ # How far down sections get TOC's
+ <xsl:param>toc.section.depth=10
+ # Max depth in each TOC:
+ <xsl:param>toc.max.depth=4
+ # How far down we go with TOC's
+ <xsl:param>generate.section.toc.level=10
+ # Set the path to the boost-root so we find our graphics:
+ #<xsl:param>boost.root=$(BOOST_ROOT)
+ # location of the main index file so our links work:
+ #<xsl:param>boost.libraries=$(BOOST_ROOT)/libs/libraries.htm
+
+ # PDF Options:
+ # TOC Generation: this is needed for FOP-0.9 and later:
+ # <xsl:param>fop1.extensions=1
+ <format>pdf:<xsl:param>fop1.extensions=0
+ <format>pdf:<xsl:param>xep.extensions=1
+ # TOC generation: this is needed for FOP 0.2, but must not be set to zero for FOP-0.9!
+ <format>pdf:<xsl:param>fop.extensions=0
+ # No indent on body text:
+ <format>pdf:<xsl:param>body.start.indent=0pt
+ # Margin size:
+ <format>pdf:<xsl:param>page.margin.inner=0.5in
+ # Margin size:
+ <format>pdf:<xsl:param>page.margin.outer=0.5in
+ # Yes, we want graphics for admonishments:
+ <format>pdf:<xsl:param>admon.graphics=1
+ # Set this one for PDF generation *only*:
+ # default png graphics are awful in PDF form,
+ # better use SVG's instead:
+ # <format>pdf:<xsl:param>admon.graphics.extension=".svg"
+
+# <dependency>protodoc
+ ;

Added: branches/proto/v4/libs/proto/doc/acknowledgements.qbk
==============================================================================
--- (empty file)
+++ branches/proto/v4/libs/proto/doc/acknowledgements.qbk 2008-04-06 02:19:35 EDT (Sun, 06 Apr 2008)
@@ -0,0 +1,17 @@
+[/
+ / Copyright (c) 2008 Eric Niebler
+ /
+ / Distributed under the Boost Software License, Version 1.0. (See accompanying
+ / file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+ /]
+
+[section:acknowledgements Appendix D: Acknowledgements]
+
+I'd like to thank Joel de Guzman and Hartmut Kaiser for being willing to take a
+chance on using Proto for their work on Spirit-2 and Karma when Proto was
+little more than a vision. Their requirements and feedback have been
+indespensable.
+
+Thanks also to the developers of _PETE_. I found many good ideas there.
+
+[endsect]

Added: branches/proto/v4/libs/proto/doc/calculator.qbk
==============================================================================
--- (empty file)
+++ branches/proto/v4/libs/proto/doc/calculator.qbk 2008-04-06 02:19:35 EDT (Sun, 06 Apr 2008)
@@ -0,0 +1,176 @@
+[/
+ / Copyright (c) 2008 Eric Niebler
+ /
+ / Distributed under the Boost Software License, Version 1.0. (See accompanying
+ / file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+ /]
+
+[section Hello Calculator]
+
+"Hello, world" is nice, but it doesn't get you very far. Let's use Proto to
+build a Domain Specific Embedded Language for a lazily-evaluated calculator.
+We'll see how to define the terminals in your mini-language, how Proto combines
+the terminals into larger expressions, and how to define an evaluation context
+so that your expressions can do useful work. When we're done, we'll have a
+mini-language that will allow us to declare a lazily-evaluated arithmetic
+expression, such as `(_2 - _1) / _2 * 100`, where `_1` and `_2` are
+placeholders for values to be passed in when the expression is evaluated.
+
+[heading Defining Terminals]
+
+The first order of business is to define the placeholders `_1` and `_2`. For
+that, we'll use the _terminal_ metafunction.
+
+ // Define some placeholder types
+ struct placeholder1 {};
+ struct placeholder2 {};
+
+ // Define the Proto-ified placeholder terminals
+ proto::terminal< placeholder1 >::type const _1 = {{}};
+ proto::terminal< placeholder2 >::type const _2 = {{}};
+
+The initialization may look a little odd at first, but there is a good reason
+for doing things this way. The objects `_1` and `_2` above do not require
+run-time construction -- they are ['statically initialized], which means they
+are essentially initialized at compile time. See the
+[link boost_proto.appendices.rationale.static_initialization Static
+Initialization] section in the [link boost_proto.appendices.rationale Rationale]
+appendix for more information.
+
+[heading Constructing Expression Trees]
+
+Now that we have terminals, we can use Proto's operator overloads to combine
+these terminals into larger expressions. So, for instance, we can immediately
+create the expression `(_2 - _1) / _2 * 100`. This creates an expression tree
+with a node for each operator. The type of the resulting object is large and
+complex, but we are not terribly interested in it.
+
+So far, the object is just a tree representing the expression. It has no
+behavior. In particular, it is not yet a calculator. Below we'll see how
+to make it a calculator by defining an evaluation context.
+
+[heading Defining an Evaluation Context]
+
+No doubt you want your expression templates to actually /do/ something. One
+approach is to define an ['evaluation context]. The context is like a function
+object that associates behaviors with the node types in your expression tree.
+An example should make it clear.
+
+ struct calculator_context
+ : proto::callable_context< calculator_context const >
+ {
+ calculator_context(double d1, double d2)
+ : d1_(d1), d2_(d2)
+ {}
+
+ // Define the result type of the calculator.
+ // (This makes the the calculator_context "callable".)
+ typedef double result_type;
+
+ // Handle the placeholders:
+ double operator()(proto::tag::terminal, placeholder1) const
+ {
+ return this->d1_;
+ }
+
+ double operator()(proto::tag::terminal, placeholder2) const
+ {
+ return this->d2_;
+ }
+
+ // Handle literals:
+ double operator()(proto::tag::terminal, double d) const
+ {
+ return d;
+ }
+
+ // Handle addition:
+ template< typename Left, typename Right >
+ double operator()(proto::tag::plus, Left const &left, Right const &right) const
+ {
+ return proto::eval(left, *this) + proto::eval(right, *this);
+ }
+
+ // Handle subtraction:
+ template< typename Left, typename Right >
+ double operator()(proto::tag::minus, Left const &left, Right const &right) const
+ {
+ return proto::eval(left, *this) - proto::eval(right, *this);
+ }
+
+ // Handle multiplication:
+ template< typename Left, typename Right >
+ double operator()(proto::tag::multiplies, Left const &left, Right const &right) const
+ {
+ return proto::eval(left, *this) * proto::eval(right, *this);
+ }
+
+ // Handle division:
+ template< typename Left, typename Right >
+ double operator()(proto::tag::divides, Left const &left, Right const &right) const
+ {
+ return proto::eval(left, *this) / proto::eval(right, *this);
+ }
+
+ private:
+ double d1_, d2_;
+ };
+
+Notice how the binary arithmetic operations are handled. First the left and
+right operands are evaluated by invoking `proto::eval()`. After the left and
+right children are evaluated, the results are combined using the appropriate
+arithmetic operation.
+
+Now that we have an evaluation context for our calculator, we can use it to
+evaluate our arithmetic expressions, as below:
+
+ // Define a calculator context, where _1 is 45 and _2 is 50
+ calculator_context ctx( 45, 50 );
+
+ // Create an arithmetic expression and immediately evaluate it
+ double d = proto::eval( (_2 - _1) / _2 * 100, ctx );
+
+ // This prints "10"
+ std::cout << d << std::endl;
+
+[heading Default Expression Evaluation]
+
+You might notice that the `calculator_context` has a lot of boilerplate. It
+is fairly common for addition nodes to be handled by evaluating the left and
+right children and then adding the result, for instance. For this purpose,
+Boost.Proto provides the _default_context_, which gives the operators their usual
+meanings, and uses Boost.Typeof to deduce return types. In fact, the
+_callable_context_ from which our `calculator_context` inherits uses
+_default_context_ as a fall-back for any expression types you don't handle
+explicitly. We can use that fact to simplify our `calculator_context`
+considerably:
+
+ struct calculator_context
+ : proto::callable_context< calculator_context const >
+ {
+ calculator_context(double d1, double d2)
+ : d1_(d1), d2_(d2)
+ {}
+
+ // Define the result type of the calculator.
+ // (This makes the the calculator_context "callable".)
+ typedef double result_type;
+
+ // Handle the placeholders:
+ double operator()(proto::tag::terminal, placeholder1) const
+ {
+ return this->d1_;
+ }
+
+ double operator()(proto::tag::terminal, placeholder2) const
+ {
+ return this->d2_;
+ }
+
+ private:
+ double d1_, d2_;
+ };
+
+That's pretty simple!
+
+[endsect]

Added: branches/proto/v4/libs/proto/doc/concepts/CallableTransform.xml
==============================================================================
--- (empty file)
+++ branches/proto/v4/libs/proto/doc/concepts/CallableTransform.xml 2008-04-06 02:19:35 EDT (Sun, 06 Apr 2008)
@@ -0,0 +1,90 @@
+<?xml version="1.0" ?>
+<concept name="CallableTransform" category="utility">
+ <!--
+ Copyright 2008 Eric Niebler
+
+ Distributed under the Boost
+ Software License, Version 1.0. (See accompanying
+ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+ -->
+ <param name="Fn" role="polymorphic-function-object-type" />
+ <param name="Tn" role="transform-type" />
+ <param name="Expr" role="expression-type" />
+ <param name="State" role="state-type" />
+ <param name="Data" role="data-type" />
+
+ <models-sentence>
+ The type <arg num="1" /> must be a model of <conceptname name="PolymorphicFunctionObject"/>.
+ The type <arg num="2" /> must be a model of <conceptname name="Transform"/>.
+ </models-sentence>
+
+ <description>
+ <para>
+ A CallableTransform is a function type or a function
+ pointer type where the return type Fn is a
+ PolymorphicFunctionObject and the arguments are
+ Transforms. is_callable&lt; Fn &gt;::value
+ must be true.
+ </para>
+ </description>
+
+ <notation variables="fn">
+ <sample-value>
+ <type name="Fn" />
+ </sample-value>
+ </notation>
+
+ <notation variables="expr">
+ <sample-value>
+ <type name="Expr" />
+ </sample-value>
+ </notation>
+
+ <notation variables="state">
+ <sample-value>
+ <type name="State" />
+ </sample-value>
+ </notation>
+
+ <notation variables="data">
+ <sample-value>
+ <type name="Data" />
+ </sample-value>
+ </notation>
+
+ <associated-type name="result_type">
+ <get-member-type name="type">
+ <apply-template name="boost::result_of">
+ <type name="Fn(Transform&lt;Tn, Expr, State, Data&gt;::result_type...)"/>
+ </apply-template>
+ </get-member-type>
+ <description>
+ <simpara>The result of applying the CallableTransform.</simpara>
+ </description>
+ </associated-type>
+
+ <valid-expression name="Apply Transform">
+ <apply-function name="when&lt; _, Fn(Tn...)&gt;()">
+ <sample-value>
+ <type name="Expr" />
+ </sample-value>
+ <sample-value>
+ <type name="State" />
+ </sample-value>
+ <sample-value>
+ <type name="Data" />
+ </sample-value>
+ </apply-function>
+ <return-type>
+ <require-same-type testable="yes">
+ <type name="result_type"/>
+ </require-same-type>
+ </return-type>
+ <semantics>Applies the transform.</semantics>
+ </valid-expression>
+
+ <example-model>
+ <type name="boost::proto::transform::arg(boost::proto::transform::left)" />
+ </example-model>
+
+</concept>

Added: branches/proto/v4/libs/proto/doc/concepts/PolymorphicFunctionObject.xml
==============================================================================
--- (empty file)
+++ branches/proto/v4/libs/proto/doc/concepts/PolymorphicFunctionObject.xml 2008-04-06 02:19:35 EDT (Sun, 06 Apr 2008)
@@ -0,0 +1,66 @@
+<?xml version="1.0" ?>
+<concept name="PolymorphicFunctionObject" category="utility">
+ <!--
+ Copyright 2008 Eric Niebler
+
+ Distributed under the Boost
+ Software License, Version 1.0. (See accompanying
+ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+ -->
+ <param name="Fn" role="polymorphic-function-object-type" />
+
+ <models-sentence>
+ The type <arg num="1" /> must be a model of <self/>.
+ </models-sentence>
+
+ <description>
+ <para>
+ A type that can be called and that follows the TR1 ResultOf
+ protocol for return type calculation.
+ </para>
+ </description>
+
+ <notation variables="fn">
+ <sample-value>
+ <type name="Fn" />
+ </sample-value>
+ </notation>
+
+ <notation variables="a0,...an">
+ <sample-value>
+ <type name="A0,...An" />
+ </sample-value>
+ </notation>
+
+ <associated-type name="result_type">
+ <get-member-type name="type">
+ <apply-template name="result_of">
+ <apply-function name="Fn">
+ <type name="A0,...An" />
+ </apply-function>
+ </apply-template>
+ </get-member-type>
+ <description>
+ <simpara>The result of calling the Polymorphic Function Object.</simpara>
+ </description>
+ </associated-type>
+
+ <valid-expression name="Function Call">
+ <apply-function name="fn">
+ <sample-value>
+ <type name="A0,...An" />
+ </sample-value>
+ </apply-function>
+ <return-type>
+ <require-same-type testable="yes">
+ <type name="result_type"/>
+ </require-same-type>
+ </return-type>
+ <semantics>Calls the function object.</semantics>
+ </valid-expression>
+
+ <example-model>
+ <type name="std::plus&lt;int&gt;" />
+ </example-model>
+
+</concept>

Added: branches/proto/v4/libs/proto/doc/concepts/PrimitiveTransform.xml
==============================================================================
--- (empty file)
+++ branches/proto/v4/libs/proto/doc/concepts/PrimitiveTransform.xml 2008-04-06 02:19:35 EDT (Sun, 06 Apr 2008)
@@ -0,0 +1,90 @@
+<?xml version="1.0" ?>
+<concept name="PrimitiveTransform" category="utility">
+ <!--
+ Copyright 2008 Eric Niebler
+
+ Distributed under the Boost
+ Software License, Version 1.0. (See accompanying
+ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+ -->
+ <param name="Fn" role="primitive-transform-type" />
+ <param name="Expr" role="expression-type" />
+ <param name="State" role="state-type" />
+ <param name="Data" role="data-type" />
+
+ <models-sentence>
+ The type <arg num="1" /> must be a model of <self/>.
+ </models-sentence>
+
+ <description>
+ <para>A PrimitiveTransform is class type that
+ has an overloaded function call operator and
+ uses a narrow subset of the TR1.ResultOf protocol
+ for return type calculation. It takes three
+ parameters: expression, state and data.</para>
+ </description>
+
+ <notation variables="fn">
+ <sample-value>
+ <type name="Fn" />
+ </sample-value>
+ </notation>
+
+ <notation variables="expr">
+ <sample-value>
+ <type name="Expr" />
+ </sample-value>
+ </notation>
+
+ <notation variables="state">
+ <sample-value>
+ <type name="State" />
+ </sample-value>
+ </notation>
+
+ <notation variables="data">
+ <sample-value>
+ <type name="Data" />
+ </sample-value>
+ </notation>
+
+ <associated-type name="result_type">
+ <get-member-type name="type">
+ <apply-template name="typename Fn::template result">
+ <apply-function name="Fn">
+ <type name="Expr"/>
+ <type name="State"/>
+ <type name="Data"/>
+ </apply-function>
+ </apply-template>
+ </get-member-type>
+ <description>
+ <simpara>The return type of the overloaded function call operator.</simpara>
+ </description>
+ </associated-type>
+
+ <valid-expression name="Function Call">
+ <apply-function name="fn">
+ <sample-value>
+ <type name="Expr" />
+ </sample-value>
+ <sample-value>
+ <type name="State" />
+ </sample-value>
+ <sample-value>
+ <type name="Data" />
+ </sample-value>
+ </apply-function>
+ <return-type>
+ <require-same-type testable="yes">
+ <type name="result_type"/>
+ </require-same-type>
+ </return-type>
+ <semantics>Applies the transform.</semantics>
+ </valid-expression>
+
+ <example-model>
+ <type name="boost::proto::transform::arg_c&lt; 0 &gt;" />
+ </example-model>
+
+</concept>

Added: branches/proto/v4/libs/proto/doc/concepts/Transform.xml
==============================================================================
--- (empty file)
+++ branches/proto/v4/libs/proto/doc/concepts/Transform.xml 2008-04-06 02:19:35 EDT (Sun, 06 Apr 2008)
@@ -0,0 +1,79 @@
+<?xml version="1.0" ?>
+<concept name="Transform" category="utility">
+ <!--
+ Copyright 2008 Eric Niebler
+
+ Distributed under the Boost
+ Software License, Version 1.0. (See accompanying
+ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+ -->
+ <param name="Tn" role="transform-type" />
+ <param name="Expr" role="expression-type" />
+ <param name="State" role="state-type" />
+ <param name="Data" role="data-type" />
+
+ <models-sentence>
+ The type <arg num="1" /> must be a model of <self/>.
+ </models-sentence>
+
+ <description>
+ <para>
+ A Transform is a PrimitiveTransform, a CallableTransform
+ or an ObjectTransform.
+ </para>
+ </description>
+
+ <notation variables="expr">
+ <sample-value>
+ <type name="Expr" />
+ </sample-value>
+ </notation>
+
+ <notation variables="state">
+ <sample-value>
+ <type name="State" />
+ </sample-value>
+ </notation>
+
+ <notation variables="data">
+ <sample-value>
+ <type name="Data" />
+ </sample-value>
+ </notation>
+
+ <associated-type name="result_type">
+ <get-member-type name="type">
+ <apply-template name="boost::result_of">
+ <type name="when&lt; _, Tn &gt;(Expr, State, Data)"/>
+ </apply-template>
+ </get-member-type>
+ <description>
+ <simpara>The result of applying the Transform.</simpara>
+ </description>
+ </associated-type>
+
+ <valid-expression name="Apply Transform">
+ <apply-function name="when&lt; _, Tn &gt;()">
+ <sample-value>
+ <type name="Expr" />
+ </sample-value>
+ <sample-value>
+ <type name="State" />
+ </sample-value>
+ <sample-value>
+ <type name="Data" />
+ </sample-value>
+ </apply-function>
+ <return-type>
+ <require-same-type testable="yes">
+ <type name="result_type"/>
+ </require-same-type>
+ </return-type>
+ <semantics>Applies the transform.</semantics>
+ </valid-expression>
+
+ <example-model>
+ <type name="boost::proto::transform::arg(boost::proto::transform::left)" />
+ </example-model>
+
+</concept>

Added: branches/proto/v4/libs/proto/doc/construction.qbk
==============================================================================
--- (empty file)
+++ branches/proto/v4/libs/proto/doc/construction.qbk 2008-04-06 02:19:35 EDT (Sun, 06 Apr 2008)
@@ -0,0 +1,1025 @@
+[/
+ / Copyright (c) 2007 Eric Niebler
+ /
+ / Distributed under the Boost Software License, Version 1.0. (See accompanying
+ / file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+ /]
+
+[def __implelemtation_defined__ [~implementation-defined]]
+
+[/=======================================================================================]
+[section:expression_construction Expression Construction: Building Proto Expression Trees]
+[/=======================================================================================]
+
+We've seen some simple examples of how to use Proto, but we haven't really said
+much about what is going on under the hood. How exactly does Proto build and
+process expression trees? Now is the time to find out.
+
+In the calculator example, we defined a placeholder terminal like this:
+
+ // Define a placeholder type
+ struct placeholder1 {};
+
+ // Define the Proto-ified placeholder terminal
+ terminal< placeholder1 >::type const _1 = {{}};
+
+The actual type of `_1` looks like this:
+
+ expr< tag::terminal, term< placeholder1 >, 0 >
+
+The _expr_ template is the most important type in Proto. Although you will
+rarely need to deal with it directly, it's always there behind the scenes
+holding your expression trees together. In fact, _expr_ /is/ the expression
+tree -- branches, leaves and all.
+
+The _expr_ template makes up the nodes in expression trees. The first template
+parameter is the node type; in this case, `proto::tag::terminal`. That means
+that `_1` is a leaf-node in the expression tree. The second template parameter
+is a list of child types. Terminals will always have only one type in the
+type list. The last parameter is the arity of the expression. Terminals have
+arity 0, unary expressions have arity 1, etc.
+
+The _expr_ struct is defined as follows:
+
+ template< typename Tag, typename Args, long Arity = Args::size >
+ struct expr;
+
+ template< typename Tag, typename Args >
+ struct expr< Tag, Args, 1 >
+ {
+ typename Args::child0 child0;
+ // ...
+ };
+
+The _expr_ struct does not define a constructor, or anything else that would
+prevent static initialization. All _expr_ objects are initialized using
+['aggregate initialization], with curly braces. In our example, `_1` is
+initialized with the initializer `{{}}`. The outer braces is the initializer
+for the _expr_ struct, and the inner braces are for the member `_1.child0` which
+is of type `placeholder1`. Note that we use braces to initialize `_1.child0`
+because `placeholder1` is also an aggregate.
+
+[/====================================================]
+[section:operator_overloads Proto's Operator Overloads]
+[/====================================================]
+
+Once we have some Proto terminals, expressions involving those terminals build
+expression trees for us, as if by magic. It's not magic; Proto defines
+overloads for each of C++'s overloadable operators to make it happen. As long
+as one operand is a Proto expression, the result of the operation is a tree
+node representing that operation.[footnote There are a couple of exceptions to
+this. In ["`int x; x = _1`], the assignment isn't a Proto expression, even
+though the right hand operand /is/ a Proto expression. That's just how C++ works.
+The same is also true for the subscript operator and the function call
+operator, as in ["`int *x; x[_1];`] and ["`std::sin(_1);`]. Them's the breaks,
+as they say.]
+
+[note The _expr_ struct lives in the `boost::proto` namespace, as do all of
+Proto's operator overloads. The overloads are found via ADL (Argument-Dependent
+Lookup). That is why expressions must be "tainted" with Proto-ness for Proto to
+be able to build trees out of expressions.]
+
+As a result of Proto's operator overloads, we can say:
+
+ -_1; // OK, build a unary-negate tree node
+ _1 + 42; // OK, build a binary-plus tree node
+
+[endsect]
+
+[/=================================================]
+[section:expression_trees Building Expression Trees]
+[/=================================================]
+
+The `_1` node is an _expr_ type, and new nodes created with this type are
+also _expr_ types. They look like this:
+
+ // typeof( -_1 )
+ expr<
+ tag::negate
+ , list1<
+ ref_< expr< tag::terminal, term< placeholder1 >, 0 > >
+ >
+ , 1
+ >
+
+ // typeof( _1 + 42 )
+ expr<
+ tag::plus
+ , list2<
+ ref_< expr< tag::terminal, term< placeholder1 >, 0 > >
+ , expr< tag::terminal, term< int const & >, 0 >
+ >
+ , 2
+ >
+
+There are a few things to note about these types:
+
+# Terminals have arity 0, unary expressions have arity 1 and binary expressions
+ have arity 2.
+# When one Proto expression is made a child node of another Proto expression,
+ it is wrapped in _ref_, which is a simple reference wrapper. That is, Proto
+ expressions hold their children by reference ['even if they are temporary
+ objects]. This last point becomes important later.
+# Non-Proto expressions, such as the integer literal, are turned into Proto
+ expressions by making them Proto terminals. These terminal expressions
+ are /not/ wrapped in _ref_, but the object itself /is/ held by reference.
+ Notice that the type of the Proto-ified `42` literal is `int const &` -- held
+ by reference.
+
+The types make it clear: everything in a Proto expression tree is held by
+reference. That means that building an expression tree is exceptionally cheap.
+It involves no copying at all.
+
+[note To use Proto effectively, you won't have to bother yourself with the
+actual types that Proto generates. These are details, but you're likely to
+encounter these types in compiler error messages, so it's helpful to be familiar
+with them.]
+
+[endsect]
+
+[/==============================================]
+[section:left_right_arg Accessing Children Nodes]
+[/==============================================]
+
+After assembling an expression into a tree, you'll naturally want to be
+able to do the reverse, and access its children.
+You may even want to be able to iterate over the children with algorithms
+from the Boost.Fusion library. This section shows how.
+
+[heading [^tag_of<>]]
+
+A node in an expression tree is nothing more than a collection of child
+nodes and a tag type. You can access the tag type of any Proto expression type
+`Expr` directly as `typename Expr::proto_tag`, or you can use the _tag_of_
+metafunction, as shown below:
+
+ template<typename Expr>
+ typename proto::result_of::tag_of<Expr>::type
+ get_tag_of(Expr const &)
+ {
+ // Tag types are required to be default-constructible
+ return typename proto::result_of::tag_of<Expr>::type();
+ }
+
+ proto::terminal<int>::type const i = {0};
+
+ // Addition nodes have the "plus" tag type:
+ proto::tag::plus plus_tag = get_tag_of( i + 2 );
+
+[heading [^child_c()]]
+
+Each node in an expression tree corresponds to an operator in an expression,
+and the children correspond to the operands, or arguments of the operator.
+To access them, you can use the _arg_c_ function template, as demonstrated
+below:
+
+ proto::terminal<int>::type i = {0};
+
+ // Get the 0-th operand of an addition operation:
+ proto::terminal<int>::type &ri = proto::child_c<0>( i + 2 );
+
+ // Assert that we got back what we put in:
+ assert( &i == &ri );
+
+You can use the `result_of::child_c<>` metafunction to get the type of the Nth
+child of an expression node. The nested `::type` of the `child_c<>` metafunction
+gives you the type after references and cv-qualifiers have been stripped from
+the child's type.
+
+ template<typename Expr>
+ void test_result_of_arg_c(Expr const &expr)
+ {
+ typedef typename proto::result_of::child_c<Expr, 0>::type type;
+
+ // ::type is a non-cv qualified, non-reference
+ BOOST_MPL_ASSERT((is_same< type, terminal<int>::type>));
+ }
+
+ // ...
+ terminal<int>::type i = {0};
+ test_result_of_arg_c( i + 2 );
+
+Why does the `child_c<>` metafunction strip cv-qualifiers and references? The
+reason is one of practicality. Because expression trees are most typically
+built by holding references to temporary objects, lifetime management of these
+child nodes can be problematic. If `child_c<>::type` were a reference, it
+would be very simple to create dangling references. Avoiding dangling
+references results in tedious and verbose applications of `remove_reference<>`
+and `remove_const<>`. This is especially problematic when building transforms
+that operate on ephemeral constelations of temporary objects. The current
+behavior of the `child_c<>` metafunction makes it much simpler to write correct
+code.
+
+If you would like to know exactly the type of the Nth argument, including
+references and cv-qualifiers, you can use
+`fusion::result_of::value_at<Expr, N>::type`. This way, you can tell whether
+a child is stored by value or by reference. And if you would like to know
+the exact type that _arg_c_ returns, you can use
+`fusion::result_of::at_c<Expr, N>::type`. It will always be a reference type,
+and its cv-qualification depends on the cv-qualification of `Expr` and
+whether the child is stored by reference or not.
+
+[heading [^child()], [^left()], and [^right()]]
+
+Most operators in C++ are unary or binary. For that reason, accessing the
+only operand, or the left and right operands, are very common operations. For
+this reason, Proto provides the _arg_, _left_, and _right_ functions. _arg_
+and _left_ are synonomous with `child_c<0>()`, and _right_ is synonomous with
+`child_c<1>()`.
+
+There are also `result_of::child<>`, `result_of::left<>`, and `result_of::right<>`
+metafunctions that merely forward to their `result_of::child_c<>` counterparts.
+
+[heading Expression Nodes as Fusion Sequences]
+
+Proto expression nodes are valid Fusion random-access sequences of their
+child nodes. That means you can apply Fusion algorithms to them,
+transform them, apply Fusion filters and views to them, and access their
+elements using `fusion::at()`. The things Fusion can do to heterogeneous
+sequences is beyond the scope of this users' guide, but below is a simple
+example. It takes a lazy function invocation like `fun(1,2,3,4)` and uses
+Fusion to print the function arguments in order.
+
+ struct display
+ {
+ template<typename T>
+ void operator()(T const &t) const
+ {
+ std::cout << t << std::endl;
+ }
+ };
+
+ struct fun_t {};
+ terminal<fun_t>::type const fun = {{}};
+
+ // ...
+ fusion::for_each(
+ fusion::transform(
+ // pop_front() removes the "fun" child
+ fusion::pop_front(fun(1,2,3,4))
+ // Extract the ints from the terminal nodes
+ , functor::child<>()
+ )
+ , display()
+ );
+
+The above invocation of `fusion::for_each()` displays the following:
+
+[pre
+1
+2
+3
+4
+]
+
+[heading Flattening Proto Expression Tress]
+
+Imagine a slight variation of the above example where, instead of iterating
+over the arguments of a lazy function invocation, we would like to iterate
+over the terminals in an addition expression:
+
+ terminal<int>::type const _1 = {1};
+
+ // ERROR: this doesn't work! Why?
+ fusion::for_each(
+ fusion::transform(
+ _1 + 2 + 3 + 4
+ , functor::child<>()
+ )
+ , display()
+ );
+
+The reason this doesn't work is because the expression `_1 + 2 + 3 + 4` does
+not describe a flat sequence of terminals --- it describes a binary tree. We
+can treat it as a flat sequence of terminals, however, using Proto's _flatten_
+function. _flatten_ returns a view which makes a tree appear as a flat Fusion
+sequence. If the top-most node has a tag type `T`, then the elements of the
+flattened sequence are the child nodes that do *not* have tag type `T`. This
+process is evaluated recursively. So the above can correctly be written as:
+
+ terminal<int>::type const _1 = {1};
+
+ // OK, iterate over a flattened view
+ fusion::for_each(
+ fusion::transform(
+ proto::flatten(_1 + 2 + 3 + 4)
+ , functor::child<>()
+ )
+ , display()
+ );
+
+The above invocation of `fusion::for_each()` displays the following:
+
+[pre
+1
+2
+3
+4
+]
+
+[endsect]
+
+[/===============================================================]
+[section:tags_and_meta_functions Operator Tags and Meta-Functions]
+[/===============================================================]
+
+The following table lists the overloadable C++ operators, the Proto tag types
+for each, and the name of the Proto meta-function for generating the
+corresponding Proto expression nodes. The meta-functions are also usable as
+grammars for matching such nodes, as well as pass-through transforms, as
+explained in later sections.
+
+[table Operators, Tags and Meta-Functions
+ [[Operator]
+ [Proto Tag]
+ [Proto Meta-Function]]
+
+ [[unary `+`]
+ [`tag::unary_plus`]
+ [`unary_plus<>`]]
+
+ [[unary `-`]
+ [`tag::negate`]
+ [`negate<>`]]
+
+ [[unary `*`]
+ [`tag::dereference`]
+ [`dereference<>`]]
+
+ [[unary `~`]
+ [`tag::complement`]
+ [`complement<>`]]
+
+ [[unary `&`]
+ [`tag::address_of`]
+ [`address_of<>`]]
+
+ [[unary `!`]
+ [`tag::logical_not`]
+ [`logical_not<>`]]
+
+ [[unary prefix `++`]
+ [`tag::pre_inc`]
+ [`pre_inc<>`]]
+
+ [[unary prefix `--`]
+ [`tag::pre_dec`]
+ [`pre_dec<>`]]
+
+ [[unary postfix `++`]
+ [`tag::post_inc`]
+ [`post_inc<>`]]
+
+ [[unary postfix `--`]
+ [`tag::post_dec`]
+ [`post_dec<>`]]
+
+ [[binary `<<`]
+ [`tag::shift_left`]
+ [`shift_left<>`]]
+
+ [[binary `>>`]
+ [`tag::shift_right`]
+ [`shift_right<>`]]
+
+ [[binary `*`]
+ [`tag::multiplies`]
+ [`multiplies<>`]]
+
+ [[binary `/`]
+ [`tag::divides`]
+ [`divides<>`]]
+
+ [[binary `%`]
+ [`tag::modulus`]
+ [`modulus<>`]]
+
+ [[binary `+`]
+ [`tag::plus`]
+ [`plus<>`]]
+
+ [[binary `-`]
+ [`tag::minus`]
+ [`minus<>`]]
+
+ [[binary `<`]
+ [`tag::less`]
+ [`less<>`]]
+
+ [[binary `>`]
+ [`tag::greater`]
+ [`greater<>`]]
+
+ [[binary `<=`]
+ [`tag::less_equal`]
+ [`less_equal<>`]]
+
+ [[binary `>=`]
+ [`tag::greater_equal`]
+ [`greater_equal<>`]]
+
+ [[binary `==`]
+ [`tag::equal_to`]
+ [`equal_to<>`]]
+
+ [[binary `!=`]
+ [`tag::not_equal_to`]
+ [`not_equal_to<>`]]
+
+ [[binary `||`]
+ [`tag::logical_or`]
+ [`logical_or<>`]]
+
+ [[binary `&&`]
+ [`tag::logical_and`]
+ [`logical_and<>`]]
+
+ [[binary `&`]
+ [`tag::bitwise_and`]
+ [`bitwise_and<>`]]
+
+ [[binary `|`]
+ [`tag::bitwise_or`]
+ [`bitwise_or<>`]]
+
+ [[binary `^`]
+ [`tag::bitwise_xor`]
+ [`bitwise_xor<>`]]
+
+ [[binary `,`]
+ [`tag::comma`]
+ [`comma<>`]]
+
+ [[binary `->*`]
+ [`tag::mem_ptr`]
+ [`mem_ptr<>`]]
+
+ [[binary `=`]
+ [`tag::assign`]
+ [`assign<>`]]
+
+ [[binary `<<=`]
+ [`tag::shift_left_assign`]
+ [`shift_left_assign<>`]]
+
+ [[binary `>>=`]
+ [`tag::shift_right_assign`]
+ [`shift_right_assign<>`]]
+
+ [[binary `*=`]
+ [`tag::multiplies_assign`]
+ [`multiplies_assign<>`]]
+
+ [[binary `/=`]
+ [`tag::divides_assign`]
+ [`divides_assign<>`]]
+
+ [[binary `%=`]
+ [`tag::modulus_assign`]
+ [`modulus_assign<>`]]
+
+ [[binary `+=`]
+ [`tag::plus_assign`]
+ [`plus_assign<>`]]
+
+ [[binary `-=`]
+ [`tag::minus_assign`]
+ [`minus_assign<>`]]
+
+ [[binary `&=`]
+ [`tag::bitwise_and_assign`]
+ [`bitwise_and_assign<>`]]
+
+ [[binary `|=`]
+ [`tag::bitwise_or_assign`]
+ [`bitwise_or_assign<>`]]
+
+ [[binary `^=`]
+ [`tag::bitwise_xor_assign`]
+ [`bitwise_xor_assign<>`]]
+
+ [[binary subscript]
+ [`tag::subscript`]
+ [`subscript<>`]]
+
+ [[ternary `?:`]
+ [`tag::if_else_`]
+ [`if_else_<>`]]
+
+ [[n-ary function call]
+ [`tag::function`]
+ [`function<>`]]
+]
+
+[endsect]
+
+[/===========================================================]
+[section:construction_utils Expression Construction Utilities]
+[/===========================================================]
+
+Proto gives you many other ways of creating expression trees besides the operator
+overloads. These are useful for building nodes with custom tag types that don't
+correspond to any C++ operator. They're also useful when writing tree transforms
+that manipulate the structure of the expression tree, as we'll see.
+
+Below are the tools and a brief description of each.
+
+[variablelist
+[ [_make_expr_]
+ [A function that takes a tag type and child nodes and
+ builds a parent node of the requested type.]]
+[ [_unpack_expr_]
+ [A function that does the same as _make_expr_ except
+ the child nodes are specified as a Fusion sequence.]]
+[ [`BOOST_PROTO_DEFINE_VARARG_FUNCTION_TEMPLATE()`]
+ [A macro that generates a number of overloads of a
+ user-specified function template that behaves like
+ _make_expr_.]]
+]
+
+[/====================================================]
+[heading Building Expression Trees With [^make_expr()]]
+[/====================================================]
+
+[:[*Synopsys:]]
+
+ namespace proto
+ {
+ namespace result_of
+ {
+ // Metafunction for calculating the return type
+ // of the make_expr() function
+ template<
+ typename Tag
+ , typename DomainOrArg
+ , typename... A
+ >
+ struct make_expr
+ {
+ typedef __implelemtation_defined__ type;
+ };
+ }
+
+ namespace functor
+ {
+ // A callable function object equivalent of the
+ // make_expr() function.
+ template<typename Tag, typename Domain = default_domain>
+ struct make_expr : callable
+ {
+ template<typename Sig> struct result;
+
+ template<typename This, typename... A>
+ struct result<This(A...)>
+ : result_of::make_expr<Tag, Domain, A...>
+ {};
+
+ template<typename... A>
+ typename result_of::make_expr<Tag, Domain, const A...>::type
+ operator ()(A const &... a) const;
+ };
+ }
+
+ // The make_expr() function
+ template<typename Tag, typename Domain, typename... A>
+ typename result_of::make_expr<Tag, Domain, A...>::type
+ make_expr(A const &... a);
+ }
+
+You can use the _make_expr_ function to build an expression tree node with
+a specified tag type, as follows.
+
+ // Some user-defined tag type
+ struct MyTag {};
+
+ // Construct a node with MyTag tag type, and
+ // two terminals as children.
+ int i = 0;
+ proto::make_expr<MyTag, default_domain>(i, 'a');
+
+You are not required to specify a domain. If you choose not to, `default_domain`
+is assumed. So the above is equivalent to:
+
+ // Construct a node with MyTag tag type, and
+ // two terminals as children.
+ int i = 0;
+ proto::make_expr<MyTag>(i, 'a');
+
+The return type of the above function invocation can be calculated with the
+`result_of::make_expr<>` metafunction.
+
+ // Use result_of::make_expr<> to compute the return type:
+ int i = 0;
+ typedef
+ proto::result_of::make_expr<
+ MyTag
+ , int
+ , char
+ >::type
+ expr_type;
+
+ expr_type expr = proto::make_expr<MyTag>(i, 'a');
+
+ // expr_type is the same as this type:
+ typedef
+ proto::binary_expr<
+ MyTag
+ , proto::terminal<int>::type
+ , proto::terminal<char>::type
+ >::type
+ expr_type2;
+
+ BOOST_MPL_ASSERT((is_same<expr_type2, expr_type>));
+
+Notice that the children, an int and a char, are wrapped in terminal
+nodes and held by value. If you would like an argument to be beld by
+reference in the resulting tree node, you can use `boost::ref()`:
+
+ // One terminal held by reference:
+ int i = 0;
+
+ typedef
+ proto::result_of::make_expr<
+ MyTag
+ , int & // <-- Note reference here
+ , char
+ >::type
+ expr_type;
+
+ expr_type expr = proto::make_expr<MyTag>(boost::ref(i), 'a');
+
+In the return type calculation, we can specify by-ref with
+`int &`, but we need `boost::ref()` in the actual function invocation.
+That's because the _make_expr_ function can't tell from the function
+arguments whether you want to store the arguments by value or by
+reference.
+
+Non-terminals are handled similarly. Given the non-terminal `expr` as
+defined above, we could wrap it in a unary plus node by value or by
+reference as follows:
+
+ // Make "expr" a child node of a new unary plus node, where
+ // "expr" is held by-value:
+ typedef
+ proto::result_of::make_expr<
+ proto::tag::unary_plus
+ , expr_type
+ >::type
+ posit_val_type;
+
+ posit_val_type p1 = proto::make_expr<proto::tag::unary_plus>(expr);
+
+ // Same as above, except "expr" is held by-reference:
+ typedef
+ proto::result_of::make_expr<
+ proto::tag::unary_plus
+ , expr_type & // <-- Note reference here
+ >::type
+ posit_ref_type;
+
+ posit_ref_type p2 = proto::make_expr<proto::tag::unary_plus>(boost::ref(expr));
+
+ // Equivalent to "by-ref" line directly above:
+ posit_ref_type p3 = +expr;
+
+The application of unary `operator+` on the last line is equivalent to
+the by-ref invocation of _make_expr_ because Proto's operator overloads
+always build trees by holding nodes by reference.
+
+If you specify a domain when invoking _make_expr_, then _make_expr_
+will use that domain's generator to wrap the resulting node in a
+domain-specific wrapper. In the example below, expressions within the
+`MyDomain` domain are wrapped in a `MyExpr<>` wrapper.
+
+ template<typename Expr>
+ struct MyExpr;
+
+ struct MyDomain
+ : proto::domain<proto::generator<MyExpr> >
+ {};
+
+ // ...
+
+ // Use result_of::make_expr<> to compute the return type:
+ int i = 0;
+ typedef
+ proto::result_of::make_expr<
+ MyTag
+ , MyDomain // <-- Note second template
+ , int // param can be a domain.
+ , char
+ >::type
+ expr_type;
+
+ // Construct an expression within MyDomain:
+ expr_type expr = proto::make_expr<MyTag, MyDomain>(i, 'a');
+
+ // expr_type is the same as this type:
+ typedef
+ // New node is wrapped in MyExpr<>
+ MyExpr<proto::binary_expr<
+ MyTag
+ // Terminals are also wrapped.
+ , MyExpr<proto::terminal<int>::type>
+ , MyExpr<proto::terminal<char>::type>
+ >::type>
+ expr_type2;
+
+ BOOST_MPL_ASSERT((is_same<expr_type2, expr_type>));
+
+[/======================================================]
+[heading Building Expression Trees With [^unpack_expr()]]
+[/======================================================]
+
+[:[*Synopsys:]]
+
+ namespace proto
+ {
+ namespace result_of
+ {
+ // Metafunction for calculating the return type
+ // of the unpack_expr() function
+ template<
+ typename Tag
+ , typename DomainOrSequence
+ , typename SequenceOrVoid = void
+ >
+ struct unpack_expr
+ {
+ typedef __implelemtation_defined__ type;
+ };
+ }
+
+ namespace functor
+ {
+ // A callable function object equivalent of the
+ // unpack_expr() function.
+ template<typename Tag, typename Domain = default_domain>
+ struct unpack_expr : callable
+ {
+ template<typename Sig> struct result;
+
+ template<typename This, typename Sequence>
+ struct result<This(Sequence)>
+ : result_of::unpack_expr<Tag, Domain, Sequence>
+ {};
+
+ template<typename Sequence>
+ typename result_of::unpack_expr<Tag, Domain, Sequence>::type
+ operator ()(Sequence const &sequence) const;
+ };
+ }
+
+ // The unpack_expr() function
+ template<typename Tag, typename Domain, typename Sequence>
+ typename result_of::unpack_expr<Tag, Domain, Sequence>::type
+ unpack_expr(Sequence const &sequence);
+ }
+
+Once you understand _make_expr_, understanding _unpack_expr_ is
+simple. It behaves exactly the same way, except that rather than
+passing children individually, you pass the children as a Fusion
+sequence. So for instance, the following are equivalent:
+
+ // Build an expression with make_expr():
+ int i = 0;
+ proto::make_expr<Tag>(i, 'a');
+
+ // Build the same expression with unpack_expr():
+ proto::unpack_expr<Tag>(fusion::make_tuple(i, 'a'));
+
+ // Also the same as the above:
+ fusion::tuple<int, char> args(i, 'a');
+ proto::unpack_expr<Tag>(args);
+
+If you would like the arguments to be stored by reference, you can
+use `boost::ref()`, just as with _make_expr_.
+
+ // Hold one argument by reference:
+ int i = 0;
+ proto::unpack_expr<Tag>(fusion::make_tuple(boost::ref(i), 'a'));
+
+ // Also the same as the above:
+ fusion::tuple<int &, char> args(i, 'a');
+ proto::unpack_expr<Tag>(args);
+
+As with _make_expr_, _unpack_expr_ has a corresponding metafunction
+in the `proto::result_of` namespace for calculating its return type, as
+well as a callable function object form in the `proto::functor`
+namespace.
+
+One last interesting point about _unpack_expr_: Proto expression
+nodes are themselves valid Fusion sequences. Here, for instance, is
+a clever way to use _unpack_expr_ to turn a binary plus node into
+a binary minus node:
+
+ // Use unpack_expr() to turn an addition into a subtraction
+ proto::literal<int> i(8), j(42);
+ proto::unpack_expr<proto::tag::minus>( i + j );
+
+The expression `i + j` creates an expression tree which _unpack_expr_
+interprets as a sequence of its children `i` and `j`. The result is a
+new node with the `tag::minus` tag and `i` and `j` as children.
+
+[/=====================================================]
+[heading Generating Custom Expression Factory Functions]
+[/=====================================================]
+
+[:[*Synopsys:]]
+
+ // Generate BOOST_PROTO_MAX_ARITY overloads of a
+ // function template named NAME within a particular
+ // DOMAIN that generates expressions with a given
+ // TAG and optionally has some arguments bound.
+ #define BOOST_PROTO_DEFINE_VARARG_FUNCTION_TEMPLATE( \
+ NAME \
+ , DOMAIN \
+ , TAG \
+ , BOUNDARGS \
+ )
+
+The `proto::functor::make_expr<>` function object makes it very simple
+to create something that behaves like an expression factory function. For
+instance, the following defines a factory named `invert()` that
+"complements" its argument; that is, it builds a new node with type
+`tag::complement` as if Proto's `operator~` had been applied:
+
+ // invert(x) is now a synonym for ~proto::as_expr(x)
+ proto::functor::make_expr<proto::tag::complement> const invert = {};
+
+Such named "operators" are very important for domain-specific embedded
+languages. What's more, when defined as above, the `invert()` factory can
+accept up to `BOOST_PROTO_MAX_ARITY` arguments, although in this case
+that wouldn't be particularly meaningful.
+
+But imagine if you have a custom tag type `foo_tag<>` that is a template.
+You would like to define a `foo()` factory function that itself was a template,
+like this:
+
+ template<typename T, typename A0>
+ typename proto::result_of::make_expr<
+ foo_tag<T>
+ , A0 const &
+ >::type foo(A0 const &a0)
+ {
+ return proto::make_expr<foo_tag<T> >(boost::ref(a0));
+ }
+
+Now, users of your function can invoke it like this: `foo<int>("foo!")`. If
+you want to seamlessly handle up to /N/ argument, you have to write all /N/
+overloads yourself --- `functor::make_expr<>` can't help you. For this
+situation, Proto provides the `BOOST_PROTO_DEFINE_VARARG_FUNCTION_TEMPLATE()`
+macro. You can invoke it as follows:
+
+ // Generate overloads of the foo() function template
+ // like the one above
+ BOOST_PROTO_DEFINE_VARARG_FUNCTION_TEMPLATE( \
+ foo \
+ , proto::default_domain \
+ , (foo_tag)(typename) \
+ , BOOST_PP_SEQ_NIL \
+ )
+
+The first macro parameter specified the name of the function template, `foo`.
+The second parameter is the domain of the resulting expression. The third
+parameter is the tag type, specified as a Boost.Preprocessor sequence. A
+tag template like `foo_tag<typename>` is represented as a PP sequence like
+`(foo_tag)(typename)`. Had `foo_tag<>` been defined instead as
+`template<typename, int> struct foo_tag`, that would be a PP sequence like
+`(foo_tag)(typename)(int)`.
+
+The last macro parammeter, `BOOST_PP_SEQ_NIL`, is used for specifying any
+additional implicit arguments. There are none in this case, so
+`BOOST_PP_SEQ_NIL` is used to represent an empty sequence.
+
+As another example, consider a DSEL like the Boost Lambda Library, for
+which you might want a function named `construct()` for doing deferred
+construction of objects. You might want users to be able to use it like
+this:
+
+ std::vector<S> buffer;
+
+ // Use a lambda to construct S objects using two
+ // sequences as constructor arguments:
+ std::transform(
+ sequence1.begin()
+ , sequence1.end()
+ , sequence2.begin()
+ , std::back_inserter(buffer)
+ , construct<S>(_1, _2) // From a hypothetical lambda DSEL
+ );
+
+How might the `construct()` function be defined? We would like it to return
+a lazy function invocation that, when evaluated with two arguments, causes
+`S` objects to be constructed. Lazy functions in Proto look like this:
+
+ // The type of a Proto lazy function
+ proto::function<
+ TheFunctionToCall
+ , Argument1
+ , Argument2
+ , ...
+ >::type
+
+In the above, `TheFunctionToCall` might be an ordinary function object, so
+let's define a `construct_helper<>` function object that constructs an object.
+
+ template<typename T>
+ struct construct_helper
+ {
+ typedef T result_type; // for TR1 result_of
+
+ T operator()() const { return T(); }
+
+ template<typename A0>
+ T operator()(A0 const &a0) const { return T(a0); }
+
+ // ... other overloads ...
+ };
+
+With such a function object, we can say `construct_helper<S>()(1, 'a')` to
+immediately construct an `S` object using `1` and `'a'` as constructor
+arguments. We want this to be lazy, so we can wrap `construct_helper<S>` in
+a Proto terminal.
+
+ // A lazy S constructor
+ terminal<construct_helper<S> >::type const construct_S = {{}};
+
+ // OK, make a lazy function invocation but don't call it.
+ construct_S(1, 'a');
+
+ // Calls the lazy function and constructs an S
+ proto::default_context ctx;
+ S s = proto::eval( construct_S(1, 'a'), ctx );
+
+We're closer, but this is not the syntax we want. Recall that we want
+users to create objects lazily with `construct<S>(_1, _2)`. We can
+get that syntax with the following:
+
+ // Define the construct() function template that
+ // constructs an object lazily.
+ template<typename T, typename A0, typename A1>
+ typename proto::result_of::make_expr<
+ proto::tag::function
+ , construct_helper<T> const
+ , A0 const &
+ , A1 const &
+ >::type const
+ construct(A0 const &a0, A1 const &a1)
+ {
+ return proto::make_expr<proto::tag::function>(
+ construct_helper<T>()
+ , boost::ref(a0)
+ , boost::ref(a1)
+ );
+ }
+
+Now users can say `construct<S>(_1, _2)` and get the lazy object
+construction they want. (Making it work with `std::transform()`
+takes a little more effort, but that's covered in the
+[link boost_proto.users_guide.examples.lambda Lambda] example.)
+Now we need /N/ overloads to handle up to /N/ arguments. That's a lot
+of boiler plate, so we can use the `BOOST_PROTO_DEFINE_VARARG_FUNCTION_TEMPLATE()`
+macro to simplify our job.
+
+ // Generate BOOST_PROTO_MAX_ARITY-1 overloads of the
+ // construct function template like the one defined above.
+ BOOST_PROTO_DEFINE_VARARG_FUNCTION_TEMPLATE( \
+ construct \
+ , MyLambdaDomain \
+ , (proto::tag::function) \
+ , ((construct_helper)(typename)) \
+ )
+
+What is new in this case is the fourth macro argument, which specifies
+that there is an implicit first argument to `construct()` of type
+`construct_helper<X>`, where `X` is a template parameter of the function.
+The fourth argument to the macro is actually a PP sequence of PP
+sequences. Each sequence describes one implicit argument.
+
+To see `BOOST_PROTO_DEFINE_VARARG_FUNCTION_TEMPLATE()` and `construct()` in
+action, please check out the
+[link boost_proto.users_guide.examples.lambda Lambda] example.
+
+[blurb [*Ugly Macros]
+
+You may find this use of the preprocessor distasteful and decide to
+write out the overloads yourself. That's fine, but there are some good
+reasons to consider the macro.
+
+1) You may not be able to anticipate the maximum number of arguments
+ your users will require. If users decide to increase
+ `BOOST_PROTO_MAX_ARITY`, the macro will automatically generate
+ the additional overloads for you.
+
+2) On compilers that support variadic templates, you'd rather this
+ generated just one variadic function instead of /N/ overloads,
+ but you'd like your code to be portable to compilers that don't
+ support variadic templates. This is possible if you use the macro,
+ but not otherwise. (Proto doesn't yet support variadic templates
+ but it will in the future.)
+]
+
+[endsect]
+
+[endsect]

Added: branches/proto/v4/libs/proto/doc/definitions.qbk
==============================================================================
--- (empty file)
+++ branches/proto/v4/libs/proto/doc/definitions.qbk 2008-04-06 02:19:35 EDT (Sun, 06 Apr 2008)
@@ -0,0 +1,42 @@
+[/
+ / Copyright (c) 2008 Eric Niebler
+ /
+ / Distributed under the Boost Software License, Version 1.0. (See accompanying
+ / file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+ /]
+
+[/==================]
+[section Definitions]
+[/==================]
+
+[variablelist
+ [ [grammar]
+ []]
+ [ [transform]
+ []]
+ [ [polymorphic function object]
+ [A class type with an overloaded function call operator
+ and an nested `result_type` typedef or `result` template
+ for calculating the return type of the function call
+ operator.]]
+ [ [callable transform]
+ [A transform of the form `R(A0,A1,...)` where
+ `is_callable<R>::value` is `true`. `R` is treated as
+ a polymorphic function object and the arguments are
+ treated as transforms that yield the arguments to
+ the function object.] ]
+ [ [object transform]
+ [A transform of the form `R(A0,A1,...)` where
+ `is_callable<R>::value` is `false`. `R` is treated as
+ type type of an object to construct and the arguments
+ are treated as transforms that yield the arguments to
+ the constructor.]]
+ [ [primitive transform]
+ [A polymorphic function object that takes three arguments:
+ a Proto expression, a state and a data. Primitive
+ transforms can be used in grammars without needing to
+ specify arguements. A primitive transform `T` is
+ equivalent to `T(_expr, _state, _data)`.]]
+]
+
+[endsect]

Added: branches/proto/v4/libs/proto/doc/evaluation.qbk
==============================================================================
--- (empty file)
+++ branches/proto/v4/libs/proto/doc/evaluation.qbk 2008-04-06 02:19:35 EDT (Sun, 06 Apr 2008)
@@ -0,0 +1,565 @@
+[/
+ / Copyright (c) 2007 Eric Niebler
+ /
+ / Distributed under the Boost Software License, Version 1.0. (See accompanying
+ / file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+ /]
+
+[section:expression_evaluation Expression Evaluation: Imparting Behaviors Within A Context]
+
+Once you have constructed a Proto expression tree, either by using Proto's
+operator overloads or with _make_expr_ and friends, you probably want to
+actually /do/ something with it. The simplest option is to use `proto::eval()`,
+a generic expression evaluator. To use _eval_, you'll need to define a
+/context/ that tells _eval_ how each node should be evaluated. This section
+goes through the nuts and bolts of using _eval_, defining evaluation contexts,
+and using the contexts that Proto provides.
+
+[note `proto::eval()` is a less powerful but easier-to-use evaluation technique
+than Proto transforms, which are covered later. Although very powerful,
+transforms have a steep learning curve and can be more difficult to debug.
+`proto::eval()` is a rather weak tree traversal algorithm. Dan Marsden has
+been working on a more general and powerful tree traversal library. When it is
+ready, I anticipate that it will eliminate the need for `proto::eval()`.]
+
+[/================================================================]
+[section:proto_eval Evaluating An Expression with [^proto::eval()]]
+[/================================================================]
+
+[:[*Synopsis:]]
+
+ namespace proto
+ {
+ namespace result_of
+ {
+ // A metafunction for calculating the return
+ // type of proto::eval() given certain Expr
+ // and Context types.
+ template<typename Expr, typename Context>
+ struct eval
+ {
+ typedef
+ typename Context::template eval<Expr>::result_type
+ type;
+ };
+ }
+
+ namespace functor
+ {
+ // A callable function object type for evaluating
+ // a Proto expression with a certain context.
+ struct eval : callable
+ {
+ template<typename Sig>
+ struct result;
+
+ template<typename Expr, typename Context>
+ typename proto::result_of::eval<Expr, Context>::type
+ operator ()(Expr &expr, Context &context) const;
+
+ template<typename Expr, typename Context>
+ typename proto::result_of::eval<Expr, Context>::type
+ operator ()(Expr &expr, Context const &context) const;
+ };
+ }
+
+ template<typename Expr, typename Context>
+ typename proto::result_of::eval<Expr, Context>::type
+ eval(Expr &expr, Context &context);
+
+ template<typename Expr, typename Context>
+ typename proto::result_of::eval<Expr, Context>::type
+ eval(Expr &expr, Context const &context);
+ }
+
+Given an expression and an evaluation context, using _eval_ is quite simple.
+Simply pass the expression and the context to _eval_ and it does the rest and
+returns the result. You can use the `eval<>` metafunction in the
+`proto::result_of` namespace to compute the return type of _eval_. The
+following demonstrates a use of _eval_:
+
+ template<typename Expr>
+ typename proto::result_of::eval<Expr const, MyContext>::type
+ MyEvaluate(Expr const &expr)
+ {
+ // Some user-defined context type
+ MyContext ctx;
+
+ // Evaluate an expression with the context
+ return proto::eval(expr, ctx);
+ }
+
+What _eval_ does is also very simple. It defers most of the work to the
+context itself. Here essentially is the implementation of _eval_:
+
+ // eval() dispatches to a nested "eval<>" function
+ // object within the Context:
+ template<typename Expr, typename Context>
+ typename Context::template eval<Expr>::result_type
+ eval(Expr &expr, Context &ctx)
+ {
+ typename Context::template eval<Expr> eval_fun;
+ return eval_fun(expr, ctx);
+ }
+
+Really, _eval_ is nothing more than a thin wrapper that dispatches to the
+appropriate handler within the context class. In the next section, we'll see
+how to implement a context class from scratch.
+
+[endsect]
+
+[/==============================================]
+[section:contexts Defining an Evaluation Context]
+[/==============================================]
+
+As we saw in the previous section, there is really not much to the _eval_
+function. Rather, all the interesting expression evaluation goes on within
+a context class. This sections shows how to implement one from scratch.
+
+All context classes have roughly the following form:
+
+ // A prototypical user-defined context.
+ struct MyContext
+ {
+ // A nested eval<> class template
+ template<
+ typename Expr
+ , typename Tag = typename Expr::proto_tag
+ >
+ struct eval;
+
+ // Handle terminal nodes here...
+ template<typename Expr>
+ struct eval<Expr, proto::tag::terminal>
+ {
+ // Must have a nested result_type typedef.
+ typedef ... result_type;
+
+ // Must have a function call operator that takes
+ // an expression and the context.
+ result_type operator()(Expr &expr, MyContext &ctx) const
+ {
+ return ...;
+ }
+ };
+
+ // ... other specializations of struct eval<> ...
+ };
+
+Context classes are nothing more than a collection of specializations of a
+nested `eval<>` class template. Each specialization handles a different
+expression type.
+
+In the [link boost_proto.users_guide.hello_calculator Hello Calculator]
+section, we saw an example of a user-defined context class for evaluating
+calculator expressions. That context class was implemented with the help
+of Proto's _callable_context_. If we were to implement it from scratch, it
+would look something like this:
+
+ // The calculator_contest from the "Hello Calculator" section,
+ // implemented from scratch.
+ struct calculator_context
+ {
+ // The values for the _1 and _2 placeholders are
+ // passed to the calculator_context constructor.
+ calculator_context(double d1, double d2)
+ : d1_(d1), d2_(d2)
+ {}
+
+ template<
+ typename Expr
+ // defaulted template parameters, so we can
+ // specialize on the expressions that need
+ // special handling.
+ , typename Tag = typename tag_of<Expr>::type
+ , typename Arg0 = typename child_c<Expr, 0>::type
+ >
+ struct eval;
+
+ // Handle placeholder1 terminals here...
+ template<typename Expr>
+ struct eval<Expr, proto::tag::terminal, placeholder1>
+ {
+ typedef double result_type;
+
+ result_type operator()(Expr &, MyContext &ctx) const
+ {
+ // replaces _1 with the value in ctx.d1_
+ return ctx.d1_;
+ }
+ };
+
+ // Handle placeholder2 terminals here...
+ template<typename Expr>
+ struct eval<Expr, proto::tag::terminal, placeholder2>
+ {
+ typedef double result_type;
+
+ result_type operator()(Expr &, MyContext &ctx) const
+ {
+ // replaces _1 with the value in ctx.d2_
+ return ctx.d2_;
+ }
+ };
+
+ // Handle other terminals here...
+ template<typename Expr, typename Arg0>
+ struct eval<Expr, proto::tag::terminal, Arg0>
+ {
+ typedef double result_type;
+
+ result_type operator()(Expr &expr, MyContext &) const
+ {
+ return proto::child(expr);
+ }
+ };
+
+ // Handle addition here...
+ template<typename Expr, typename Arg0>
+ struct eval<Expr, proto::tag::plus, Arg0>
+ {
+ typedef double result_type;
+
+ result_type operator()(Expr &expr, MyContext &ctx) const
+ {
+ return proto::eval(proto::left(expr), ctx)
+ + proto::eval(proto::right(expr), ctx);
+ }
+ };
+
+ // ... other eval<> specializations for other node types ...
+
+ double d1_, d2_;
+ };
+
+Now we can use _eval_ with the context class above to evaluate calculator
+expressions as follows:
+
+ // Evaluate an expression with a calculator_context
+ double d = proto::eval(_1 + _2, calculator_context(5, 6));
+ assert(11 == d);
+
+Defining a context from scratch this way is tedious and verbose, but it gives
+you complete control over how the expression is evaluated. The context class in
+the [link boost_proto.users_guide.hello_calculator Hello Calculator] example
+was much simpler. In the next section we'll see the helper class Proto provides
+to ease the job of implementing context classes.
+
+[endsect]
+
+[/======================================]
+[section:canned_contexts Canned Contexts]
+[/======================================]
+
+Proto provides some ready-made context classes that you can use as-is, or that
+you can use to help while implementing your own contexts. They are:
+
+[variablelist
+ [ [[link boost_proto.users_guide.expression_evaluation.canned_contexts.default_context [^default_context]]]
+ [An evaluation context that assigns the usual C++ meanings to all the
+ operators. For example, addition nodes are handled by evaluating the
+ left and right children and then adding the results. The _default_context_
+ uses Boost.Typeof to deduce the types of the expressions it evaluates.] ]
+ [ [[link boost_proto.users_guide.expression_evaluation.canned_contexts.null_context [^null_context]]]
+ [A simple context that recursively evaluates children but does not combine
+ the results in any way and returns void.] ]
+ [ [[link boost_proto.users_guide.expression_evaluation.canned_contexts.callable_context [^callable_context<>]]]
+ [A helper that simplifies the job of writing context classes. Rather than
+ writing template specializations, with _callable_context_ you write a
+ function object with an overloaded function call operator. Any expressions
+ not handled by an overload are automatically dispatched to a default
+ evaluation context that you can specify.] ]
+]
+
+[/=========================================]
+[section:default_context [^default_context]]
+[/=========================================]
+
+The _default_context_ is an evaluation context that assigns the usual C++
+meanings to all the operators. For example, addition nodes are handled by
+evaluating the left and right children and then adding the results. The
+_default_context_ uses Boost.Typeof to deduce the types of the expressions it
+evaluates.
+
+For example, consider the following "Hello World" example:
+
+ #include <iostream>
+ #include <boost/proto/proto.hpp>
+ #include <boost/proto/context.hpp>
+ #include <boost/typeof/std/ostream.hpp>
+ using namespace boost;
+
+ proto::terminal< std::ostream & >::type cout_ = { std::cout };
+
+ template< typename Expr >
+ void evaluate( Expr const & expr )
+ {
+ // Evaluate the expression with default_context,
+ // to give the operators their C++ meanings:
+ proto::default_context ctx;
+ proto::eval(expr, ctx);
+ }
+
+ int main()
+ {
+ evaluate( cout_ << "hello" << ',' << " world" );
+ return 0;
+ }
+
+This program outputs the following:
+
+[pre
+hello, world
+]
+
+_default_context_ is trivially defined in terms of a `default_eval<>`
+template, as follows:
+
+ // Definition of default_context
+ struct default_context
+ {
+ template<typename Expr>
+ struct eval
+ : default_eval<Expr, default_context const, typename Expr::proto_tag>
+ {};
+ };
+
+There are a bunch of `default_eval<>` specializations, each of which handles
+a different C++ operator. Here, for instance, is the specialization for binary
+addition:
+
+ // A default expression evaluator for binary addition
+ template<typename Expr, typename Context>
+ struct default_eval<Expr, Context, proto::tag::plus>
+ {
+ private:
+ static Expr & s_expr;
+ static Context & s_ctx;
+
+ public:
+ typedef
+ decltype(
+ proto::eval(proto::child_c<0>(s_expr), s_ctx)
+ + proto::eval(proto::child_c<1>(s_expr), s_ctx)
+ )
+ result_type;
+
+ result_type operator ()(Expr &expr, Context &ctx) const
+ {
+ return proto::eval(proto::child_c<0>(expr), ctx)
+ + proto::eval(proto::child_c<1>(expr), ctx);
+ }
+ };
+
+The above code uses `decltype` to calculate the return type of the function
+call operator. `decltype` is a new keyword in the next version of C++ that gets
+the type of any expression. Most compilers do not yet support `decltype`
+directly, so `default_eval<>` uses the Boost.Typeof library to emulate it. On
+some compilers, that may mean that `default_context` either doesn't work or
+that it requires you to register your types with the Boost.Typeof library.
+Check the documentation for Boost.Typeof to see.
+
+[endsect]
+
+[/===================================]
+[section:null_context [^null_context]]
+[/===================================]
+
+The _null_context_ is a simple context that recursively evaluates children
+but does not combine the results in any way and returns void. It is useful
+in conjunction with `callable_context<>`, or when defining your own contexts
+which mutate an expression tree in-place rather than accumulate a result, as
+we'll see below.
+
+_null_context_ is trivially implemented in terms of `null_eval<>` as follows:
+
+ // Definition of null_context
+ struct null_context
+ {
+ template<typename Expr>
+ struct eval
+ : null_eval<Expr, null_context const, Expr::proto_arity::value>
+ {};
+ };
+
+And `null_eval<>` is also trivially implemented. Here, for instance is
+a binary `null_eval<>`:
+
+ // Binary null_eval<>
+ template<typename Expr, typename Context>
+ struct null_eval<Expr, Context, 2>
+ {
+ typedef void result_type;
+
+ void operator()(Expr &expr, Context &ctx) const
+ {
+ proto::eval(proto::child_c<0>(expr), ctx);
+ proto::eval(proto::child_c<1>(expr), ctx);
+ }
+ };
+
+When would such classes be useful? Imagine you have an expression tree with
+integer terminals, and you would like to increment each integer in-place. You
+might define an evaluation context as follows:
+
+ struct increment_ints
+ {
+ // By default, just evaluate all children by defering
+ // to the null_eval<>
+ template<typename Expr, typename Arg = proto::result_of::child<Expr>::type>
+ struct eval
+ : null_eval<Expr, increment_ints const>
+ {};
+
+ // Increment integer terminals
+ template<typename Expr>
+ struct eval<Expr, int>
+ {
+ typedef void result_type;
+
+ void operator()(Expr &expr, increment_ints const &) const
+ {
+ ++proto::child(expr);
+ }
+ };
+ };
+
+In the next section on _callable_context_, we'll see an even simpler way to
+achieve the same thing.
+
+[endsect]
+
+[/=============================================]
+[section:callable_context [^callable_context<>]]
+[/=============================================]
+
+The _callable_context_ is a helper that simplifies the job of writing context
+classes. Rather than writing template specializations, with _callable_context_
+you write a function object with an overloaded function call operator. Any
+expressions not handled by an overload are automatically dispatched to a
+default evaluation context that you can specify.
+
+Rather than an evaluation context in its own right, _callable_context_ is more
+properly thought of as a context adaptor. To use it, you must define your own
+context that inherits from _callable_context_.
+
+In the [link boost_proto.users_guide.expression_evaluation.canned_contexts.null_context [^null_context]]
+section, we saw how to implement an evaluation context that increments all the
+integers within an expression tree. Here is how to do the same thing with the
+_callable_context_:
+
+ // An evaluation context that increments all
+ // integer terminals in-place.
+ struct increment_ints
+ : callable_context<
+ increment_ints const // derived context
+ , null_context const // fall-back context
+ >
+ {
+ typedef void result_type;
+
+ // Handle int terminals here:
+ void operator()(proto::tag::terminal, int &i) const
+ {
+ ++i;
+ }
+ };
+
+With such a context, we can do the following:
+
+ literal<int> i = 0, j = 10;
+ proto::eval( i - j * 3.14, increment_ints() );
+
+ std::cout << "i = " << i.get() << std::endl;
+ std::cout << "j = " << j.get() << std::endl;
+
+This program outputs the following, which shows that the integers `i` and `j`
+have been incremented by `1`:
+
+[pre
+i = 1
+j = 11
+]
+
+In the `increment_ints` context, we didn't have to define any nested `eval<>`
+templates. That's because _callable_context_ implements them for us.
+_callable_context_ takes two template parameters: the derived context and a
+fall-back context. For each node in the expression tree being evaluated,
+_callable_context_ checks to see if there is an overloaded `operator()` in the
+derived context that accepts it. Given some expression `expr` of type `Expr`,
+and a context `ctx`, it attempts to call:
+
+ ctx(
+ typename Expr::proto_tag()
+ , proto::child_c<0>(expr)
+ , proto::child_c<1>(expr)
+ ...
+ );
+
+Using function overloading and metaprogramming tricks, _callable_context_ can
+detect at compile-time whether such a function exists or not. If so, that
+function is called. If not, the current expression is passed to the fall-back
+evaluation context to be processed.
+
+We saw another example of the _callable_context_ when we looked at the simple
+calculator expression evaluator. There, we wanted to customize the evaluation
+of placeholder terminals, and delegate the handling of all other nodes to the
+_default_context_. We did that as follows:
+
+ // An evaluation context for calculator expressions that
+ // explicitly handles placeholder terminals, but defers the
+ // processing of all other nodes to the default_context.
+ struct calculator_context
+ : proto::callable_context< calculator_context const >
+ {
+ calculator_context(double d1, double d2)
+ : d1_(d1), d2_(d2)
+ {}
+
+ // Define the result type of the calculator.
+ typedef double result_type;
+
+ // Handle the placeholders:
+ double operator()(proto::tag::terminal, placeholder1) const
+ {
+ return this->d1_;
+ }
+
+ double operator()(proto::tag::terminal, placeholder2) const
+ {
+ return this->d2_;
+ }
+
+ private:
+ double d1_, d2_;
+ };
+
+In this case, we didn't specify a fall-back context. In that case,
+_callable_context_ uses the _default_context_. With the above
+`calculator_context` and a couple of appropriately defined placeholder
+terminals, we can evaluate calculator expressions, as demonstrated
+below:
+
+ struct placeholder1 {};
+ struct placeholder2 {};
+ terminal<placeholder1>::type const _1 = {{}};
+ terminal<placeholder2>::type const _2 = {{}};
+ // ...
+
+ double j = proto::eval(
+ (_2 - _1) / _2 * 100
+ , calculator_context(4, 5)
+ );
+ std::cout << "j = " << j << std::endl;
+
+The above code displays the following:
+
+[pre
+j = 20
+]
+
+[endsect]
+
+[endsect]
+
+[endsect]

Added: branches/proto/v4/libs/proto/doc/examples.qbk
==============================================================================
--- (empty file)
+++ branches/proto/v4/libs/proto/doc/examples.qbk 2008-04-06 02:19:35 EDT (Sun, 06 Apr 2008)
@@ -0,0 +1,192 @@
+[/
+ / Copyright (c) 2008 Eric Niebler
+ /
+ / Distributed under the Boost Software License, Version 1.0. (See accompanying
+ / file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+ /]
+
+[import ../example/hello.cpp]
+[import ../example/calc1.cpp]
+[import ../example/calc2.cpp]
+[import ../example/calc3.cpp]
+[import ../example/lazy_vector.cpp]
+[import ../example/mixed.cpp]
+[import ../example/rgb.cpp]
+[import ../example/tarray.cpp]
+[import ../example/vec3.cpp]
+[import ../example/vector.cpp]
+[import ../example/map_assign.cpp]
+[import ../example/futures.cpp]
+[import ../example/lambda.cpp]
+
+[/===============]
+[section Examples]
+[/===============]
+
+A code example is worth a thousand words ...
+
+[/=================================================================================]
+[section:hello_world Hello World: Building An Expression Template and Evaluating It]
+[/=================================================================================]
+
+A trivial example which builds and expression template
+and evaluates it.
+
+[HelloWorld]
+
+[endsect]
+
+[/==================================================]
+[section:calc1 Calc1: Defining An Evaluation Context]
+[/==================================================]
+
+A simple example which builds a miniature domain-specific
+embedded language for lazy arithmetic expressions, with
+TR1 bind-style argument placeholders.
+
+[Calc1]
+
+[endsect]
+
+[/============================================================]
+[section:calc2 Calc2: Adding Members Using [^proto::extends<>]]
+[/============================================================]
+
+An extension of the Calc1 example that uses _extends_ to
+make calculator expressions valid function objects that
+can be used with STL algorithms.
+
+[Calc2]
+
+[endsect]
+
+[/===============================================]
+[section:calc3 Calc3: Defining A Simple Transform]
+[/===============================================]
+
+An extension of the Calc2 example that uses a Proto transform
+to calculate the arity of a calculator expression and statically
+assert that the correct number of argument are passed.
+
+[Calc3]
+
+[endsect]
+
+[/==============================================================]
+[section:lazy_vector Lazy Vector: Controlling Operator Overloads]
+[/==============================================================]
+
+This example constructs a mini-library for linear algebra, using
+expression templates to eliminate the need for temporaries when
+adding vectors of numbers.
+
+This example uses a domain with a grammar to prune the set
+of overloaded operators. Only those operators that produce
+valid lazy vector expressions are allowed.
+
+[LazyVector]
+
+[endsect]
+
+[/========================================================]
+[section:rgb RGB: Type Manipulations With Proto Transforms]
+[/========================================================]
+
+This is a simple example of doing arbitrary type manipulations with Proto
+transforms. It takes some expression involving primiary colors and combines
+the colors according to arbitrary rules. It is a port of the RGB example
+from _PETE_.
+
+[RGB]
+
+[endsect]
+
+[/=====================================================]
+[section:tarray TArray: A Simple Linear Algebra Library]
+[/=====================================================]
+
+This example constructs a mini-library for linear algebra, using
+expression templates to eliminate the need for temporaries when
+adding arrays of numbers. It duplicates the TArray example from
+_PETE_.
+
+[TArray]
+
+[endsect]
+
+[/========================================================]
+[section:vec3 Vec3: Computing With Transforms And Contexts]
+[/========================================================]
+
+This is a simple example using `proto::extends<>` to extend a terminal type
+with additional behaviors, and using custom contexts and `proto::eval()` for
+evaluating expressions. It is a port of the Vec3 example from
+_PETE_.
+
+[Vec3]
+
+[endsect]
+
+[/========================================================]
+[section:vector Vector: Adapting A Non-Proto Terminal Type]
+[/========================================================]
+
+This is an example of using `BOOST_PROTO_DEFINE_OPERATORS()` to Proto-ify
+expressions using `std::vector<>`, a non-Proto type. It is a port of the
+Vector example from _PETE_.
+
+[Vector]
+
+[endsect]
+
+[/=============================================================]
+[section:mixed Mixed: Adapting Several Non-Proto Terminal Types]
+[/=============================================================]
+
+This is an example of using `BOOST_PROTO_DEFINE_OPERATORS()` to Proto-ify
+expressions using `std::vector<>` and `std::list<>`, non-Proto types. It is a
+port of the Mixed example from _PETE_.
+
+[Mixed]
+
+[endsect]
+
+[/=======================================================]
+[section:map_assign Map Assign: An Intermediate Transform]
+[/=======================================================]
+
+A demonstration of how to implement `map_list_of()` from the Boost.Assign
+library using Proto. `map_list_assign()` is used to conveniently initialize a
+`std::map<>`. By using Proto, we can avoid any dynamic allocation while
+building the intermediate representation.
+
+[MapAssign]
+
+[endsect]
+
+[/===========================================================]
+[section:future_group Future Group: A More Advanced Transform]
+[/===========================================================]
+
+An advanced example of a Proto transform that implements
+Howard Hinnant's design for /future groups/ that block
+for all or some asynchronous operations to complete and
+returns their results in a tuple of the appropriate type.
+
+[FutureGroup]
+
+[endsect]
+
+[/========================================================]
+[section:lambda Lambda: A Simple Lambda Library with Proto]
+[/========================================================]
+
+This is an advanced example that shows how to implement a simple
+lambda DSEL with Proto, like the Boost.Lambda_library. It uses
+contexts, transforms and expression extension.
+
+[Lambda]
+
+[endsect]
+
+[endsect]

Added: branches/proto/v4/libs/proto/doc/extensibility.qbk
==============================================================================
--- (empty file)
+++ branches/proto/v4/libs/proto/doc/extensibility.qbk 2008-04-06 02:19:35 EDT (Sun, 06 Apr 2008)
@@ -0,0 +1,329 @@
+[/
+ / Copyright (c) 2008 Eric Niebler
+ /
+ / Distributed under the Boost Software License, Version 1.0. (See accompanying
+ / file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+ /]
+
+[section:expression_extension Expression Extension: Giving Expressions Extra Smarts]
+
+In this section, we'll see how to associate Proto expressions with a /domain/,
+how to add members to expressions within a domain, how to control which
+operators are overloaded in a domain, and how to define your own "operators".
+
+[/==============]
+[section Domains]
+[/==============]
+
+In the examples we've seen so far, Proto has been used to construct an
+expression tree that either is evaluated with the help of a /context/ or else
+is transformed into some other object. What if you need something else? Take
+our old friend the calculator example. Perhaps we would like to build a
+calculator expression and immediately use it as a function object to a standard
+algorithm, like this:
+
+ double data[] = {1., 2., 3., 4.};
+
+ // Use the calculator DSEL to square each element ... FAILS! :-(
+ std::transform( data, data + 4, data, _1 * _1 );
+
+This will not compile. The problem is that the object created by the expression
+`_1 * _1` does not meet the `UnaryFunction` requirements of the
+`std::transform()` algorithm. In particular, it doesn't have an `operator()`
+member function that takes a `double` and returns a `double`, like
+`std::transform()` expects. What can we do?
+
+[endsect]
+
+[/==================================================]
+[section:extends The [^extends<>] Expression Wrapper]
+[/==================================================]
+
+The general idea is to add behaviors to the _expr_ type by wrapping it in a
+class template that you define. This wrapper is associated with a domain. Proto
+will build larger expressions out of your wrapper objects, and you will want
+those objects to also be wrapped. You do that by hooking Proto's expression
+generator for your domain.
+
+The first step to giving your calculator expressions extra behaviors is to
+define a calculator domain. All expressions within the calculator domain will
+be imbued with calculator-ness, as we'll see.
+
+ // A type to be used as a domain tag (to be defined below)
+ struct calculator_domain;
+
+We use this domain type when extending the _expr_ type, which we do with the
+_extends_ class template. Here is our expression wrapper, which imbues an
+expression with calculator-ness. It is described below.
+
+ // The calculator<> expression wrapper makes expressions
+ // function objects.
+ template< typename Expr >
+ struct calculator
+ : proto::extends< Expr, calculator< Expr >, calculator_domain >
+ {
+ typedef proto::extends< Expr, calculator< Expr >, calculator_domain > base_type;
+
+ calculator( Expr const &expr = Expr() )
+ : base_type( expr )
+ {}
+
+ // This is usually needed because by default, the compiler-generated
+ // assignment operator hides the extends<>::operator=
+ using base_type::operator =;
+
+ // Hide base_type::operator() by defining our own which
+ // evaluates the calculator expression with a calculator context.
+ typedef double result_type;
+ result_type operator()( double d1 = 0.0, double d2 = 0.0 ) const
+ {
+ calculator_context ctx( d1, d2 );
+ return proto::eval(*this, ctx );
+ }
+ };
+
+We want calculator expressions to be function objects, so we have to define an
+`operator()` that takes and returns `double`s. The `calculator<>` wrapper above
+does that with the help of the _extends_ template. The first template to
+_extends_ parameter is the expression type we are extending. The second is the
+type of the wrapped expression. The third parameter is the domain that this
+wrapper is associated with. A wrapper type like `calculator<>` that inherits
+from _extends_ behaves just like the expression type it has extended, with any
+additional behaviors you choose to give it.
+
+Although not strictly necessary in this case, we bring `extends<>::operator=`
+into scope with a `using` declaration. This is really only necessary if you
+want expressions like `_1 = 3` to create a lazily evaluated assignment.
+_extends_ defines the appropriate `operator=` for you, but the
+compiler-generated `calculator<>::operator=` will hide it unless you make it
+available with the `using` declaration.
+
+Note that in the implementation of `calculator<>::operator()`, we evaluate the
+expression with the `calculator_context` we defined earlier. As we saw before,
+the context is what gives the operators their meaning. In the case of the
+calculator, the context is also what defines the meaning of the placeholder
+terminals.
+
+Now that we have defined the `calculator<>` expression wrapper, we need to
+wrap the placeholders to imbue them with calculator-ness:
+
+ calculator< proto::terminal< placeholder1 >::type > const _1;
+ calculator< proto::terminal< placeholder2 >::type > const _2;
+
+[endsect]
+
+[/============================]
+[section Expression Generators]
+[/============================]
+
+The last thing that remains to be done is to tell Proto that it needs to wrap
+all of our calculator expressions in our `calculator<>` wrapper. We have
+already wrapped the placeholders, but we want /all/ expressions that involve
+the calculator placeholders to be calculators. We can do that by specifying an
+expression generator when we define our `calculator_domain`, as follows:
+
+ // Define the calculator_domain we forward-declared above.
+ // Specify that all expression in this domain should be wrapped
+ // in the calculator<> expression wrapper.
+ struct calculator_domain
+ : proto::domain< proto::generator< calculator > >
+ {};
+
+Proto uses domains to generate expressions. After Proto has calculated a new
+expression type, it checks the domains of the child expressions. They must
+match. Assuming they do, Proto creates the new expression and passes it to
+`Domain::make()` for any additional processing. If we don't specify a
+generator, the new expression gets passed through unchanged. But since we've
+specified a generator above, `calculator_domain::make()` returns `calculator<>`
+objects.
+
+Now we can use calculator expressions as function objects to STL algorithms, as
+follows:
+
+ double data[] = {1., 2., 3., 4.};
+
+ // Use the calculator DSEL to square each element ... WORKS! :-)
+ std::transform( data, data + 4, data, _1 * _1 );
+
+[endsect]
+
+[/==========================================================]
+[section:inhibiting_overloads Controlling Operator Overloads]
+[/==========================================================]
+
+By default, Proto defines every possible operator overload for Proto-ified
+expressions. This makes it simple to bang together a DSEL, and Proto's grammar
+building and checking facilities make it simple to detect and report invalid
+expressions. In some cases, however, the presence of Proto's promiscuous
+overloads can lead to confusion or worse. When that happens, you'll have to
+disable some of Proto's overloaded operators.
+
+As an example, consider a simple linear algebra DSEL that lets you efficiently
+add vectors without creating temporaries. With such a DSEL, we could initialize
+vectors and add them as follows:
+
+ // lazy_vectors with 4 elements each.
+ lazy_vector< double > v1( 4, 1.0 ), v2( 4, 2.0 ), v3( 4, 3.0 );
+
+ // Add two vectors lazily and get the 2nd element.
+ double d1 = ( v2 + v3 )[ 2 ]; // Look ma, no temporaries!
+
+ // Subtract two vectors and add the result to a third vector.
+ v1 += v2 - v3; // Still no temporaries!
+
+Consider the uses of the `operator[]` and `operator+=` in the examples above.
+We want them to do real work instead of creating expression templates. We need
+to imbue our expression templates with linear algebra-ness and then give
+`operator[]` and `operator+=` new domain-specific semantics. As above, we do
+that by defining an appropriate domain-specific expression wrapper.
+
+Here is the code. It is described below.
+
+ struct lazy_vector_domain;
+
+ // Here is an evaluation context that indexes into an algebraic
+ // expression, and combines the result.
+ template<typename Size = std::size_t>
+ struct lazy_subscript_context
+ {
+ lazy_subscript_context(Size subscript)
+ : subscript_(subscript)
+ {}
+
+ // Use default_eval for all the operations ...
+ template<typename Expr, typename Tag = typename Expr::proto_tag>
+ struct eval
+ : proto::default_eval<Expr, lazy_subscript_context>
+ {};
+
+ // ... except for terminals, which we index with our subscript
+ template<typename Expr>
+ struct eval<Expr, proto::tag::terminal>
+ {
+ typedef typename proto::result_of::child<Expr>::type::value_type result_type;
+
+ result_type operator()( Expr const & expr, lazy_subscript_context & ctx ) const
+ {
+ return proto::child( expr )[ ctx.subscript_ ];
+ }
+ };
+
+ Size subscript_;
+ };
+
+ // Here is the domain-specific expression wrapper, which overrides
+ // operator[] to evaluate the expression using the lazy_subscript_context.
+ template<typename Expr>
+ struct lazy_vector_expr
+ : proto::extends<Expr, lazy_vector_expr<Expr>, lazy_vector_domain>
+ {
+ typedef proto::extends<Expr, lazy_vector_expr<Expr>, lazy_vector_domain> base_type;
+
+ lazy_vector_expr( Expr const & expr = Expr() )
+ : base_type( expr )
+ {}
+
+ template< typename Size >
+ typename proto::result_of::eval< Expr, lazy_subscript_context<Size> >::type
+ operator []( Size subscript ) const
+ {
+ lazy_subscript_context<Size> ctx(subscript);
+ return proto::eval(*this, ctx);
+ }
+ };
+
+ // Here is our lazy_vector terminal, implemented in terms of lazy_vector_expr
+ template< typename T >
+ struct lazy_vector
+ : lazy_vector_expr< typename proto::terminal< std::vector<T> >::type >
+ {
+ typedef typename proto::terminal< std::vector<T> >::type expr_type;
+
+ lazy_vector( std::size_t size = 0, T const & value = T() )
+ : lazy_vector_expr<expr_type>( expr_type::make( std::vector<T>( size, value ) ) )
+ {}
+
+ template< typename Expr >
+ lazy_vector &operator += (Expr const & expr)
+ {
+ std::size_t size = proto::child(*this).size();
+ for(std::size_t i = 0; i < size; ++i)
+ {
+ proto::child(*this)[i] += expr[i];
+ }
+ return *this;
+ }
+ };
+
+ struct lazy_vector_domain
+ : proto::domain< proto::generator< lazy_vector_expr > >
+ {};
+
+The `lazy_subscript_context<>` struct is used to evaluate expressions like
+`(v1 + v2)[2]` as if they were written `v1[2] + v2[2]`. The `lazy_vector_expr<>`
+struct is a wrapper for expressions. It defines an `operator[]` which evaluates
+the expression using `lazy_subscript_context<>`. The `lazy_vector<>` struct is
+used for the vector terminals in our expression trees. It is essentially a
+`proto::terminal< std::vector<T> >::type`, with `operator[]` and `operator+=`
+defined to evaluate the expressions. With the above code, we can do the
+following:
+
+ // lazy_vectors with 4 elements each.
+ lazy_vector< double > v1( 4, 1.0 ), v2( 4, 2.0 ), v3( 4, 3.0 );
+
+ // Add two vectors lazily and get the 2nd element.
+ double d1 = ( v2 + v3 )[ 2 ]; // Look ma, no temporaries!
+
+ // Subtract two vectors and add the result to a third vector.
+ v1 += v2 - v3; // Hmm, trouble here.
+
+ // What does this do?
+ (v2 + v3) += v1;
+
+The line `v1 += v2 - v3` is somewhat ambiguous. Clearly we want it to use the
+`lazy_vector<>::operator+=` we defined above, but it could also mean to
+construct an even larger expression template using proto's `operator+=`. At
+least one compiler actually believes the call to be ambiguous! We have to tell
+the compiler which.
+
+And the last line is clearly a bug. It is nonsensical to add two vectors and
+then assign /to/ the result. But strangely, this line of code compiles! And even
+more strangely, it has no effect! It is building an expression template and then
+discarding it. We would like this to be a compile error, instead. We can make
+it an error, and solve the ambiguity problem, by disabling Proto's `operator+=`
+overload, and all the other overloaded operators that don't make sense in our
+domain. To do that, we define the grammar for our domain. Let's say we want to
+allow addition and subtraction of our vector terminals. Our grammar looks like
+this:
+
+ using proto::_;
+
+ struct LazyVectorGrammar
+ : proto::or_<
+ proto::terminal< std::vector<_> >
+ , proto::plus< LazyVectorGrammar, LazyVectorGrammar>
+ , proto::minus< LazyVectorGrammar, LazyVectorGrammar>
+ >
+ {};
+
+Notice that even though the terminals of our DSEL are `lazy_vector<>`'s, they
+will match `terminal< std::vector<_> >` because `lazy_vector<T>` extends
+`terminal< std::vector<T> >::type`. Once we have defined the grammar of our
+DSEL, using it to control the operator overloads in our domain is as simple
+as:
+
+ // Expressions in the lazy_vector_domain must conform to the
+ // LazyVectorGrammar
+ struct lazy_vector_domain
+ : proto::domain<
+ proto::generator< lazy_vector_expr >
+ , LazyVectorGrammar
+ >
+ {};
+
+And that's it! Now, all operators that do not produce valid lazy vector
+expressions are automatically disabled.
+
+[endsect]
+
+[endsect]

Added: branches/proto/v4/libs/proto/doc/grammars.qbk
==============================================================================
--- (empty file)
+++ branches/proto/v4/libs/proto/doc/grammars.qbk 2008-04-06 02:19:35 EDT (Sun, 06 Apr 2008)
@@ -0,0 +1,481 @@
+[/
+ / Copyright (c) 2008 Eric Niebler
+ /
+ / Distributed under the Boost Software License, Version 1.0. (See accompanying
+ / file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+ /]
+
+[/============================================================================]
+[section:expression_introspection Expression Introspection: Defining a Grammar]
+[/============================================================================]
+
+Expression trees can have a very rich and complicated structure. Often, you
+need to know some things about an expression's structure before you can process
+it. This section describes the tools Proto provides for peering inside an
+expression tree and discovering its structure.
+
+[/===============================================]
+[section:patterns Finding Patterns In Expressions]
+[/===============================================]
+
+Imagine your DSEL is a miniature I/O facility, with iostream operations
+that execute lazily. You might want expressions representing input operations
+to be processed by one function, and output operations to be processed by a
+different function. How would you do that?
+
+The answer is to write patterns (a.k.a, /grammars/) that match the structure
+of input and output expressions. Proto provides utilities for defining the
+grammars, and the _matches_ template for checking whether a given expression
+type matches the grammar.
+
+First, let's define some terminals we can use in our lazy I/O expressions:
+
+ terminal< std::istream & >::type cin_ = { std::cin };
+ terminal< std::ostream & >::type cout_ = { std::cout };
+
+Now, we can use `cout_` instead of `std::cout`, and get I/O expression trees
+that we can execute later. To define grammars that match intput and output
+expressions of the form `cin_ >> i` and `cout_ << 1` we do this:
+
+ struct Input
+ : shift_right< terminal< std::istream & >, _ >
+ {};
+
+ struct Output
+ : shift_left< terminal< std::ostream & >, _ >
+ {};
+
+We've seen the template `terminal<>` before, but here we're using it
+without accessing the nested `::type`. When used like this, it is a very simple
+grammar, as are `shift_right<>` and `shift_left<>`. The newcomer
+here is `_` in the `proto` namespace. It is a wildcard that matches anything.
+The `Input` struct is a grammar that matches any right-shift expression that
+has a `std::istream` terminal as its left operand.
+
+We can use these grammars together with the _matches_ template to query at
+compile time whether a given I/O expression type is an input or output
+operation. Consider the following:
+
+ template< typename Expr >
+ void input_output( Expr const & expr )
+ {
+ if( matches< Expr, Input >::value )
+ {
+ std::cout << "Input!\n";
+ }
+
+ if( matches< Expr, Output >::value )
+ {
+ std::cout << "Output!\n";
+ }
+ }
+
+ int main()
+ {
+ int i = 0;
+ input_output( cout_ << 1 );
+ input_output( cin_ >> i );
+
+ return 0;
+ }
+
+This program prints the following:
+
+[pre
+Output!
+Input!
+]
+
+If we wanted to break the `input_output()` function into two functions, one
+that handles input expressions and one for output expressions, we can use
+`boost::enable_if<>`, as follows:
+
+ template< typename Expr >
+ typename enable_if< matches< Expr, Input > >::type
+ input_output( Expr const & expr )
+ {
+ std::cout << "Input!\n";
+ }
+
+ template< typename Expr >
+ typename enable_if< matches< Expr, Output > >::type
+ input_output( Expr const & expr )
+ {
+ std::cout << "Output!\n";
+ }
+
+This works as the previous version did. However, the following does not compile
+at all:
+
+ input_output( cout_ << 1 << 2 ); // oops!
+
+What's wrong? The problem is that this expression does not match our grammar.
+The expression groups as if it were written like `(cout_ << 1) << 2`. It will
+not match the `Output` grammar, which expects the left operand to be a
+terminal, not another left-shift operation. We need to fix the grammar.
+
+We notice that in order to verify an expression as input or output, we'll need
+to recurse down to the bottom-left-most leaf and check that it is a
+`std::istream` or `std::ostream`. When we get to the terminal, we must stop
+recursing. We can express this in our grammar using _or_. Here are the correct
+`Input` and `Output` grammars:
+
+ struct Input
+ : or_<
+ shift_right< terminal< std::istream & >, _ >
+ , shift_right< Input, _ >
+ >
+ {};
+
+ struct Output
+ : or_<
+ shift_left< terminal< std::ostream & >, _ >
+ , shift_left< Output, _ >
+ >
+ {};
+
+This may look a little odd at first. We seem to be defining the `Input` and
+`Output` types in terms of themselves. This is perfectly OK, actually. At
+the point in the grammar that the `Input` and `Output` types are being used,
+they are /incomplete/, but by the time we actually evaluate the grammar with
+_matches_, the types will be complete. These are recursive grammars, and
+rightly so because they must match a recursive data structure!
+
+When the `Output` grammar is evaluated against an expression like
+`cout_ << 1 << 2`, the first alternate of the _or_ is tried first. It will
+fail, because the expression `cout_ << 1 << 2` does not match the grammar
+`shift_left< terminal< std::ostream & >, _ >`. Then the second
+alternate is tried. We match the expression against
+`shift_left< Output, _ >`. The expression is a left-shift, so we try
+the operands. The right operand `2` matches `_` trivially. To see if
+the left operand `cout_ << 1` matches `Output`, we must recursively evaluate
+the `Output` grammar. This time we succeed, because `cout_ << 1` will match
+the first alternate of the _or_. We're done -- the grammar matches
+successfully.
+
+[endsect]
+
+[/===========================================]
+[section Fuzzy and Exact Matches of Terminals]
+[/===========================================]
+
+The terminals in an expression tree could be const or non-const references, or
+they might not be references at all. When writing grammars, you usually don't
+have to worry about it because _matches_ gives you a little wiggle room when
+matching terminals. A grammar such as `proto::terminal<int>` will match a
+terminal of type `int`, `int &`, or `int const &`.
+
+You can explicitly specify that you want to match a reference type. If you do,
+the type must match exactly. For instance, a grammar such as
+`proto::terminal<int &>` will only match an `int &`. It will not match an `int`
+or a `int const &`.
+
+The table below shows how Proto matches terminals. The simple rule is: if you
+want to match only reference types, you must specify the reference in your
+grammar. Otherwise, leave it off and Proto will ignore const and references.
+
+[table proto::matches<> and Reference / CV-Qualification of Terminals
+ [[Terminal] [Grammar] [Matches?]]
+ [[T] [T] [yes]]
+ [[T &] [T] [yes]]
+ [[T const &] [T] [yes]]
+ [[T] [T &] [no]]
+ [[T &] [T &] [yes]]
+ [[T const &] [T &] [no]]
+ [[T] [T const &] [no]]
+ [[T &] [T const &] [no]]
+ [[T const &] [T const &] [yes]]
+]
+
+This begs the question: What if you want to match an `int`, but not an `int &`
+or an `int const &`? For forcing exact matches, Proto provides the _exact_
+template. For instance, `proto::terminal<exact<int> >` would only match an `int`
+held by value.
+
+Proto gives you extra wiggle room when matching array types. Array types match
+themselves or the pointer types they decay to. This is especially useful with
+character arrays. The type returned by `proto::as_expr("hello")` is
+`proto::terminal<char const[6]>::type`. That's a terminal containing a
+a 6-element character array. Naturally, you can match this terminal
+with the grammar `proto::terminal<char const[6]>`, but the grammar
+`proto::terminal<char const *>` will match it as well, as the following
+code fragment illustrates.
+
+ struct CharString
+ : terminal< char const * >
+ {};
+
+ typedef terminal< char const[6] >::type char_array;
+
+ BOOST_MPL_ASSERT(( matches< char_array, CharString > ));
+
+What if we only wanted `CharString` to match terminals of exactly the type
+`char const *`? You can use _exact_ here to turn off the fuzzy matching of
+terminals, as follows:
+
+ struct CharString
+ : terminal< exact< char const * > >
+ {};
+
+ typedef terminal<char const[6]>::type char_array;
+ typedef terminal<char const *>::type char_string;
+
+ BOOST_MPL_ASSERT(( matches< char_string, CharString > ));
+ BOOST_MPL_ASSERT_NOT(( matches< char_array, CharString > ));
+
+Now, `CharString` does not match array types, only character string pointers.
+
+The inverse problem is a little trickier: what if you wanted to match all
+character arrays, but not character pointers? As mentioned above, the
+expression `as_expr("hello")` has the type
+`terminal< char const[ 6 ] >::type`. If you wanted to match character
+arrays of arbitrary size, you could use `proto::N`, which is an array-size
+wildcard. The following grammar would match any string literal:
+`terminal< char const[ proto::N ] >`.
+
+Sometimes you need even more wiggle room when matching terminals. For
+example, maybe you're building a calculator DSEL and you want to allow any
+terminals that are convertible to `double`. For that, Proto provides the
+_convertible_to_ template. You can use it as:
+`proto::terminal<proto::convertible_to<double> >`.
+
+There is one more way you can perform a fuzzy match on terminals. Consider the
+problem of trying to match a `std::complex<>` terminal. You can easily match
+a `std::complex<float>` or a `std::complex<double>`, but how would you match
+any instantiation of `std::complex<>`? You can use `proto::_` here to solve
+this problem. Here is the grammar to match any `std::complex<>` instantiation:
+
+ struct StdComplex
+ : terminal< std::complex< _ > >
+ {};
+
+When given a grammar like this, Proto will deconstruct the grammar and the
+terminal it is being matched against and see if it can match all the
+constituents.
+
+[endsect]
+
+[/====================================================]
+[section:if_and_not [^if_<>], [^and_<>], and [^not_<>]]
+[/====================================================]
+
+We've already seen how to use expression generators like `terminal<>` and
+`shift_right<>` as grammars. We've also seen _or_, which we can use to
+express a set of alternate grammars. There are a few others of interest; in
+particular, _if_, _and_ and _not_.
+
+The _not_ template is the simplest. It takes a grammar as a template parameter
+and logically negates it; `not_<Grammar>` will match any expression that
+`Grammar` does /not/ match.
+
+The _if_ template is used together with a Proto transform that is evaluated
+against expression types to find matches. (Proto transforms will be described
+later.)
+
+The _and_ template is like _or_, except that each argument of the _and_ must
+match in order for the _and_ to match. As an example, consider the definition
+of `CharString` above that uses _exact_. It could have been written without
+_exact_ as follows:
+
+ struct CharString
+ : and_<
+ terminal< _ >
+ , if_< is_same< _value, char const * >() >
+ >
+ {};
+
+This says that a `CharString` must be a terminal, /and/ its argument must be
+the same as `char const *`. Notice the template argument of _if_:
+`is_same< _value, char const * >()`. This is Proto transform that compares the
+value of a terminal to `char const *`.
+
+The _if_ template has a couple of variants. In additon to `if_<Condition>` you
+can also say `if_<Condition, ThenGrammar>` and
+`if_<Condition, ThenGrammar, ElseGrammar>`. These let you select one sub-grammar
+or another based on the `Condition`.
+
+[endsect]
+
+[/==================================]
+[section Matching Vararg Expressions]
+[/==================================]
+
+Not all of C++'s overloadable operators are unary or binary. There is the
+oddball `operator()` -- the function call operator -- which can have any number
+of arguments. Likewise, with Proto you may define your own "operators" that
+could also take more that two arguments. As a result, there may be nodes in
+your Proto expression tree that have an arbitrary number of children (up to
+some predefined maximum). How do you write a grammar to match such a node?
+
+For such cases, Proto provides the _vararg_ class template. Its template
+argument is a grammar, and the _vararg_ will match the grammar zero or more
+times. Consider a Proto lazy function called `fun()` that can take zero or
+more characters as arguments, as follows:
+
+ struct fun_tag {};
+ struct FunTag : terminal< fun_tag > {};
+ FunTag::type const fun = {{}};
+
+ // example usage:
+ fun();
+ fun('a');
+ fun('a', 'b');
+ ...
+
+Below is the grammar that matches all the allowable invocations of `fun()`:
+
+ struct FunCall
+ : function< FunTag, vararg< terminal< char > > >
+ {};
+
+The `FunCall` grammar uses _vararg_ to match zero or more character literals
+as arguments of the `fun()` function.
+
+As another example, can you guess what the following grammar matches?
+
+ struct Foo
+ : or_<
+ terminal< _ >
+ , nary_expr< _, vararg< Foo > >
+ >
+ {};
+
+Here's a hint: the first template parameter to `nary_expr<>` represents the
+node type, and any additional template parameters represent child nodes. The
+answer is that this is a degenerate grammar that matches every possible
+expression tree, from root to leaves.
+
+[endsect]
+
+[/=============================]
+[section Defining DSEL Grammars]
+[/=============================]
+
+We've already seen how to use small grammars to answer simple questions about
+expression trees. Here's a harder question: ["Does this expression conform to the
+grammar of my domain-specific embedded language?] In this section we'll see how
+to use Proto to define a grammar for your DSEL and use it to validate
+expression templates, giving short, readable compile-time errors for invalid
+expressions.
+
+[tip You might be thinking that this is a backwards way of doing things.
+["If Proto let me select which operators to overload, my users wouldn't be able
+to create invalid expressions in the first place, and I wouldn't need a grammar
+at all!] That may be true, but there are reasons for preferring to do things
+this way.
+
+First, it lets you develop your DSEL rapidly -- all the operators are
+there for you already! -- and worry about invalid syntax later.
+
+Second, it
+might be the case that some operators are only allowed in certain contexts
+within your DSEL. This is easy to express with a grammar, and hard to do with
+straight operator overloading.
+
+Third, using a DSEL grammar to flag invalid
+expressions can often yield better errors than manually selecting the
+overloaded operators.
+
+Fourth, the grammar can be used for more than just
+validation. As we'll see later, you can use your grammar to define ['tree
+transformations] that convert expression templates into other more useful
+objects.
+
+If none of the above convinces you, you actually /can/ use Proto to control
+which operators are overloaded within your domain. And to do it, you need to
+define a grammar! We'll see how later.
+]
+
+In a previous section, we used Proto to define a DSEL for a lazily evaluated
+calculator that allowed any combination of placeholders, floating-point
+literals, addition, subtraction, multiplaction, division and grouping. If
+we were to write the grammar for this DSEL in
+[@http://en.wikipedia.org/wiki/Extended_Backus_Naur_Form EBNF], it might look
+like this:
+
+[pre
+group ::= '(' expression ')'
+factor ::= double | placeholder1 | placeholder2 | group
+term ::= factor (('*' factor) | ('/' factor))*
+expression ::= term (('+' term) | ('-' term))*
+]
+
+This captures the syntax, associativity and precedence rules of a calculator.
+Writing the grammar for our calculator DSEL using Proto is /even simpler/.
+Since we are using C++ as the host language, we are bound to the associativity
+and precedence rules for the C++ operators. Our grammar can assume them. Also,
+in C++ grouping is already handled for us with the use of parenthesis, so we
+don't have to code that into our grammar.
+
+Let's begin our grammar for forward-declaring it:
+
+ struct CalculatorGrammar;
+
+It's an incomplete type at this point, but we'll still be able to use it to
+define the rules of our grammar. Let's define grammar rules for the terminals:
+
+ struct Double
+ : terminal< convertible_to< double > >
+ {};
+
+ struct Placeholder1
+ : terminal< placeholder1 >
+ {};
+
+ struct Placeholder2
+ : terminal< placeholder2 >
+ {};
+
+ struct Terminal
+ : or_< Double, Placeholder1, Placeholder2 >
+ {};
+
+Now let's define the rules for addition, subtraction, multiplication and
+division. Here, we can ignore issues of associativity and precedence -- the C++
+compiler will enforce that for us. We only must enforce that the arguments to
+the operators must themselves conform to the `CalculatorGrammar` that we
+forward-declared above.
+
+ struct Plus
+ : plus< CalculatorGrammar, CalculatorGrammar >
+ {};
+
+ struct Minus
+ : minus< CalculatorGrammar, CalculatorGrammar >
+ {};
+
+ struct Multiplies
+ : multiplies< CalculatorGrammar, CalculatorGrammar >
+ {};
+
+ struct Divides
+ : divides< CalculatorGrammar, CalculatorGrammar >
+ {};
+
+Now that we've defined all the parts of the grammar, we can define
+`CalculatorGrammar`:
+
+ struct CalculatorGrammar
+ : or_<
+ Terminal
+ , Plus
+ , Minus
+ , Multiplies
+ , Divides
+ >
+ {};
+
+That's it! Now we can use `CalculatorGrammar` to enforce that an expression
+template conforms to our grammar. We can use _matches_ and `BOOST_MPL_ASSERT()`
+to issue readable compile-time errors for invalid expressions, as below:
+
+ template< typename Expr >
+ void evaluate( Expr const & expr )
+ {
+ BOOST_MPL_ASSERT(( matches< Expr, CalculatorGrammar > ));
+ // ...
+ }
+
+[endsect]
+
+[endsect]

Added: branches/proto/v4/libs/proto/doc/history.qbk
==============================================================================
--- (empty file)
+++ branches/proto/v4/libs/proto/doc/history.qbk 2008-04-06 02:19:35 EDT (Sun, 06 Apr 2008)
@@ -0,0 +1,52 @@
+[/
+ / Copyright (c) 2008 Eric Niebler
+ /
+ / Distributed under the Boost Software License, Version 1.0. (See accompanying
+ / file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+ /]
+
+[section:history Appendix A: History]
+
+[variablelist
+[
+ [January 11, 2008]
+ [Boost.Proto v3 brings separation of grammars and transforms and a
+ "round" lambda syntax for defining transforms in-place.]
+]
+[
+ [April 15, 2007]
+ [Boost.Xpressive is ported from Proto compilers to Proto transforms.
+ Support for old Proto compilers is dropped.]
+]
+[
+ [April 4, 2007]
+ [Preliminary submission of Proto to Boost.]
+]
+[
+ [December 11, 2006]
+ [The idea for transforms that decorate grammar rules is born in a private
+ email discussion with Joel de Guzman and Hartmut Kaiser. The first
+ transforms are committed to CVS 5 days later on December 16.]
+]
+[
+ [November 1, 2006]
+ [The idea for `proto::matches<>` and the whole grammar facility is
+ hatched during a discussion with Hartmut Kaiser on the spirit-devel list.
+ The first version of `proto::matches<>` is checked into CVS 3 days later.
+ Message is [@http://osdir.com/ml/parsers.spirit.devel/2006-11/msg00003.html here].]
+]
+[
+ [October 28, 2006]
+ [Proto is reborn, this time with a uniform expression types that are POD.
+ Announcement is [@http://lists.boost.org/Archives/boost/2006/10/112453.php here].]
+]
+[
+ [April 20, 2005]
+ [Proto is born as a major refactorization of Boost.Xpressive's
+ meta-programming. Proto offers expression types, operator overloads and
+ "compilers", an early formulation of what later became transforms.
+ Announcement is [@http://lists.boost.org/Archives/boost/2005/04/85256.php here].]
+]
+]
+
+[endsect]

Added: branches/proto/v4/libs/proto/doc/implementation.qbk
==============================================================================
--- (empty file)
+++ branches/proto/v4/libs/proto/doc/implementation.qbk 2008-04-06 02:19:35 EDT (Sun, 06 Apr 2008)
@@ -0,0 +1,172 @@
+[/
+ / Copyright (c) 2008 Eric Niebler
+ /
+ / Distributed under the Boost Software License, Version 1.0. (See accompanying
+ / file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+ /]
+
+[section:implementation Appendix C: Implementation Notes]
+
+[section:sfinae Quick-n-Dirty Type Categorization]
+
+Much has already been written about dispatching on type traits using
+SFINAE (Substitution Failure Is Not An Error) techniques in C++. There
+is a Boost library, Boost.Enable_if, to make the technique idiomatic.
+Proto dispatches on type traits extensively, but it doesn't use
+`enable_if<>` very often. Rather, it dispatches based on the presence
+or absence of nested types, often typedefs for void.
+
+Consider the implementation of `is_expr<>`. It could have been written
+as something like this:
+
+ template<typename T>
+ struct is_expr
+ : is_base_and_derived<proto::some_expr_base, T>
+ {};
+
+Rather, it is implemented as this:
+
+ template<typename T, typename Void = void>
+ struct is_expr
+ : mpl::false_
+ {};
+
+ template<typename T>
+ struct is_expr<T, typename T::proto_is_expr_>
+ : mpl::true_
+ {};
+
+This relies on the fact that the specialization will be preferred
+if `T` has a nested `proto_is_expr_` that is a typedef for `void`.
+All Proto expression types have such a nested typedef.
+
+Why does Proto do it this way? The reason is because, after running
+extensive benchmarks while trying to improve compile times, I have
+found that this approach compiles faster. It requires exactly one
+template instantiation. The other approach requires at least 2:
+`is_expr<>` and `is_base_and_derived<>`, plus whatever templates
+`is_base_and_derived<>` may instantiate.
+
+[endsect]
+
+[section:function_arity Detecting the Arity of Function Objects]
+
+In several places, Proto needs to know whether or not a function
+object `Fun` can be called with certain parameters and take a
+fallback action if not. This happens in _callable_context_ and
+in the _call_ transform. How does Proto know? It involves some
+tricky metaprogramming. Here's how.
+
+Another way of framing the question is by trying to implement
+the following `can_be_called<>` Boolean metafunction, which
+checks to see if a function object `Fun` can be called with
+parameters of type `A` and `B`:
+
+ template<typename Fun, typename A, typename B>
+ struct can_be_called;
+
+First, we define the following `dont_care` struct, which has an
+implicit conversion from anything. And not just any implicit
+conversion; it has a ellipsis conversion, which is the worst possible
+conversion for the purposes of overload resolution:
+
+ struct dont_care
+ {
+ dont_care(...);
+ };
+
+We also need some private type known only to us with an overloaded
+comma operator (!), and some functions that detect the presence of
+this type and return types with different sizes, as follows:
+
+ struct private_type
+ {
+ private_type const &operator,(int) const;
+ };
+
+ typedef char yes_type; // sizeof(yes_type) == 1
+ typedef char (&no_type)[2]; // sizeof(no_type) == 2
+
+ template<typename T>
+ no_type is_private_type(T const &);
+
+ yes_type is_private_type(private_type const &);
+
+Next, we implement a binary function object wrapper with a very
+strange conversion operator, whose meaning will become clear later.
+
+ template<typename Fun>
+ struct funwrap2 : Fun
+ {
+ funwrap2();
+ typedef private_type const &(*pointer_to_function)(dont_care, dont_care);
+ operator pointer_to_function() const;
+ };
+
+With all of these bits and pieces, we can implement `can_be_called<>` as
+follows:
+
+ template<typename Fun, typename A, typename B>
+ struct can_be_called
+ {
+ static funwrap2<Fun> &fun;
+ static A &a;
+ static B &b;
+
+ static bool const value = (
+ sizeof(no_type) == sizeof(is_private_type( (fun(a,b), 0) ))
+ );
+
+ typedef mpl::bool_<value> type;
+ };
+
+The idea is to make it so that `fun(a,b)` will always compile by adding
+our own binary function overload, but doing it in such a way that we can
+detect whether our overload was selected or not. And we rig it so that
+our overload is selected if there is really no better option. What follows
+is a description of how `can_be_called<>` works.
+
+We wrap `Fun` in a type that has an implicit conversion to a pointer to
+a binary function. An object `fun` of class type can be invoked as
+`fun(a, b)` if it has such a conversion operator, but since it involves
+a user-defined conversion operator, it is less preferred than an
+overloaded `operator()`, which requires no such conversion.
+
+The function pointer can accept any two arguments by virtue
+of the `dont_care` type. The conversion sequence for each argument is
+guaranteed to be the worst possible conversion sequence: an implicit
+conversion through an ellipsis, and a user-defined conversion to
+`dont_care`. In total, it means that `funwrap2<Fun>()(a, b)` will
+always compile, but it will select our overload only if there really is
+no better option.
+
+If there is a better option --- for example if `Fun` has an overloaded
+function call operator such as `void operator()(A a, B b)` --- then
+`fun(a, b)` will resolve to that one instead. The question now is how
+to detect which function got picked by overload resolution.
+
+Notice how `fun(a, b)` appears in `can_be_called<>`: `(fun(a, b), 0)`.
+Why do we use the comma operator there? The reason is because we are
+using this expression as the argument to a function. If the return type
+of `fun(a, b)` is `void`, it cannot legally be used as an argument to
+a function. The comma operator sidesteps the issue.
+
+This should also make plain the purpose of the overloaded comma operator
+in `private_type`. The return type of the pointer to function is
+`private_type`. If overload resolution selects our overload, then the
+type of `(fun(a, b), 0)` is `private_type`. Otherwise, it is `int`.
+That fact is used to dispatch to either overload of `is_private_type()`,
+which encodes its answer in the size of its return type.
+
+That's how it works with binary functions. Now repeat the above process
+for functions up to some predefined function arity, and you're done.
+
+[endsect]
+
+[section:ppmp_vs_tmp Avoiding Template Instiations With The Preprocessor]
+
+TODO
+
+[endsect]
+
+[endsect]

Added: branches/proto/v4/libs/proto/doc/installation.qbk
==============================================================================
--- (empty file)
+++ branches/proto/v4/libs/proto/doc/installation.qbk 2008-04-06 02:19:35 EDT (Sun, 06 Apr 2008)
@@ -0,0 +1,44 @@
+[/
+ / Copyright (c) 2008 Eric Niebler
+ /
+ / Distributed under the Boost Software License, Version 1.0. (See accompanying
+ / file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+ /]
+
+[section Installing Proto]
+
+[heading Getting Proto]
+
+You can get Proto by downloading [^proto.zip] from
+[@http://www.boost-consulting.com/vault/index.php?directory=Template%20Metaprogramming]
+or by accessing Boost's SVN repository on SourceForge.net. Just go to
+[@http://svn.boost.org/trac/boost/wiki/BoostSubversion]
+and follow the instructions there for anonymous SVN access.
+
+[heading Building with Proto]
+
+Proto is a header-only template library, which means you don't need to alter
+your build scripts or link to any separate lib file to use it. All you need
+to do is `#include <boost/proto/proto.hpp>`. This will include the
+core of Proto. If you want to use any transforms, you must include the
+appropriate header from the [^boost\/proto\/transform\/] directory.
+Likewise for any evaluation contexts, which live in the
+[^boost\/proto\/context\/] directory.
+
+[heading Requirements]
+
+Proto depends on Boost. You must use either Boost version 1.34.1 or the
+version in SVN trunk.
+
+[heading Supported Compilers]
+
+Currently, Boost.Proto is known to work on the following compilers:
+
+* Visual C++ 7.1 and higher
+* GNU C++ 3.4 and higher
+* Intel on Linux 8.1 and higher
+* Intel on Windows 9.1 and higher
+
+[note Please send any questions, comments and bug reports to eric <at> boost-consulting <dot> com.]
+
+[endsect]

Added: branches/proto/v4/libs/proto/doc/preface.qbk
==============================================================================
--- (empty file)
+++ branches/proto/v4/libs/proto/doc/preface.qbk 2008-04-06 02:19:35 EDT (Sun, 06 Apr 2008)
@@ -0,0 +1,74 @@
+[/
+ / Copyright (c) 2008 Eric Niebler
+ /
+ / Distributed under the Boost Software License, Version 1.0. (See accompanying
+ / file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+ /]
+
+[section Preface]
+
+[:["There are more things in heaven and earth, Horatio, than are dreamt of in your philosophy.]]
+[:[*['-- William Shakespeare]]]
+
+[heading Description]
+
+Proto is a framework for building Domain Specific Embedded Languages
+in C++. It provides tools for constructing, type-checking, transforming and
+executing ['expression templates][footnote See
+[@http://www.osl.iu.edu/~tveldhui/papers/Expression-Templates/exprtmpl.html Expression Templates]].
+More specifically, Proto provides:
+
+* An expression tree data structure.
+* Operator overloads for building the tree from an expression.
+* Utilities for defining the grammar to which an expression must conform.
+* An extensible mechanism for immediately executing an expression template.
+* An extensible set of tree transformations to apply to expression trees.
+* A mechanism for giving expressions additional behaviors and members.
+
+[heading Motivation]
+
+Expression Templates are an advanced technique that C++ library developers use
+to define embedded mini-languages that target specific problem domains. The
+technique has been used to create hyper-efficient and easy-to-use libraries
+for linear algebra as well as to define C++ parser generators with a readable
+syntax. But developing such a library involves writing an inordinate amount of
+unreadable and unmaintainable template mumbo-jumbo. Boost.Proto eases the
+development of domain-specific embedded languages (DSELs). Use Proto to define
+the primitives of your mini-language and let Proto handle the operator
+overloading and the construction of the expression parse tree. Immediately
+evaluate the expression tree by passing it a function object. Or transform the
+expression tree by defining the grammar of your mini-language, decorated
+with an assortment of tree transforms provided by Proto or defined by you.
+Then use the grammar to give your users short and readable syntax errors
+for invalid expressions! No more mumbo-jumbo -- an expression template library
+developed with Proto is declarative and readable.
+
+In short, Proto is a DSEL for defining DSELs.
+
+[heading Influences and Related Work]
+
+Proto was initially developed as part of _xpressive_ to simplify the job of
+transforming an expression template into an executable finite state machine
+capable of matching a regular expression. Since then, Proto has found
+application in the redesigned and improved Spirit-2 and the related Karma
+library, currently under development. As a result of these efforts, Proto
+evolved into a generic and abstract grammar and tree transformation
+framework applicable in a wide variety of DSEL scenarios.
+
+The grammar and tree transformation framework is modelled on Spirit's
+grammar and semantic action framework. The expression tree data structure
+is similar to Fusion data structures in many respects, and is interoperable
+with Fusion's iterators and algorithms.
+
+The syntax for the grammar-matching features of `proto::matches<>` is inspired
+by MPL's lambda expressions, and by Aleksey Gurtovoy's
+[@http://lists.boost.org/Archives/boost/2002/11/39718.php "round" lambda] notation.
+
+[heading Further Reading]
+
+A technical paper about an earlier version of Proto was accepted into the
+[@http://lcsd.cs.tamu.edu/2007/ ACM SIGPLAN Symposium on Library-Centric Software Design LCSD'07],
+and can be found at [@http://lcsd.cs.tamu.edu/2007/final/1/1_Paper.pdf]. The
+tree transforms described in that paper differ from what exists today.
+
+[endsect]

Added: branches/proto/v4/libs/proto/doc/propdocs.sh
==============================================================================
--- (empty file)
+++ branches/proto/v4/libs/proto/doc/propdocs.sh 2008-04-06 02:19:35 EDT (Sun, 06 Apr 2008)
@@ -0,0 +1,8 @@
+#!/bin/sh
+
+rm html.tar.gz
+tar -czf html.tar.gz html
+
+scp html.tar.gz eric_niebler_at_[hidden]:/home/groups/b/bo/boost-sandbox/htdocs/libs/proto/doc
+ssh eric_niebler_at_[hidden] 'cd /home/groups/b/bo/boost-sandbox/htdocs/libs/proto/doc; rm -rf html; tar -xzf html.tar.gz'
+

Added: branches/proto/v4/libs/proto/doc/proto.qbk
==============================================================================
--- (empty file)
+++ branches/proto/v4/libs/proto/doc/proto.qbk 2008-04-06 02:19:35 EDT (Sun, 06 Apr 2008)
@@ -0,0 +1,139 @@
+
+[library Boost.Proto
+ [quickbook 1.3]
+ [authors [Niebler, Eric]]
+ [copyright 2008 Eric Niebler]
+ [category template]
+ [id proto]
+ [dirname proto]
+ [purpose
+ Generic expression template, grammar and
+ tree-transformation framework.
+ ]
+ [license
+ Distributed under the Boost Software License, Version 1.0.
+ (See accompanying file LICENSE_1_0.txt or copy at
+ [@http://www.boost.org/LICENSE_1_0.txt])
+ ]
+]
+
+[/
+ / Copyright (c) 2008 Eric Niebler
+ /
+ / Distributed under the Boost Software License, Version 1.0. (See accompanying
+ / file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+ /]
+
+[/ QuickBook Document version 1.3 ]
+
+[/ Images ]
+
+[def __note__ [$images/note.png]]
+[def __alert__ [$images/caution.png]]
+[def __detail__ [$images/note.png]]
+[def __tip__ [$images/tip.png]]
+
+[/ Links ]
+
+[def _PETE_ [@http://www.codesourcery.com/pooma/download.html PETE]]
+[def _spirit_fx_ [@http://spirit.sourceforge.net Spirit Parser Framework]]
+[def _spirit_ [@http://spirit.sourceforge.net Spirit]]
+[def _xpressive_ [@../../../libs/doc/index.html Boost.Xpressive]]
+[def _expr_ [classref boost::proto::expr<Tag,Args,1> `expr<>`]]
+[def _ref_ [classref boost::proto::ref_ `ref_<>`]]
+[def _unref_ [funcref boost::proto::unref `unref()`]]
+[def _deep_copy_ [funcref boost::proto::deep_copy `deep_copy()`]]
+[def _extends_ [classref boost::proto::extends `extends<>`]]
+[def _as_expr_ [funcref boost::proto::as_expr `as_expr()`]]
+[def _as_arg_ [funcref boost::proto::as_child `as_child()`]]
+[def _make_expr_ [funcref boost::proto::make_expr `make_expr()`]]
+[def _unpack_expr_ [funcref boost::proto::unpack_expr `unpack_expr()`]]
+[def _matches_ [classref boost::proto::result_of::matches `matches<>`]]
+[def _or_ [classref boost::proto::control::or_ `or_<>`]]
+[def _and_ [classref boost::proto::control::and_ `and_<>`]]
+[def _if_ [classref boost::proto::control::if_ `if_<>`]]
+[def _not_ [classref boost::proto::control::not_ `not_<>`]]
+[def _exact_ [classref boost::proto::control::exact `exact<>`]]
+[def _convertible_to_ [classref boost::proto::control::convertible_to `convertible_to<>`]]
+[def _is_expr_ [classref boost::proto::result_of::is_expr `is_expr<>`]]
+[def _tag_of_ [classref boost::proto::result_of::tag_of `tag_of<>`]]
+[def _arg_ [funcref boost::proto::child `child()`]]
+[def _arg_c_ [funcref boost::proto::child_c `child_c()`]]
+[def _eval_ [funcref boost::proto::eval `eval()`]]
+[def _left_ [funcref boost::proto::left `left()`]]
+[def _right_ [funcref boost::proto::right `right()`]]
+[def _terminal_ [classref boost::proto::op::terminal `terminal<>`]]
+[def _unary_expr_ [classref boost::proto::op::unary_expr `unary_expr<>`]]
+[def _binary_expr_ [classref boost::proto::op::binary_expr `binary_expr<>`]]
+[def _literal_ [classref boost::proto::utility::literal `literal<>`]]
+[def _lit_ [funcref boost::proto::lit `lit()`]]
+[def _vararg_ [classref boost::proto::control::vararg `vararg<>`]]
+[def _default_context_ [classref boost::proto::context::default_context `default_context`]]
+[def _callable_context_ [classref boost::proto::context::callable_context `callable_context<>`]]
+[def _null_context_ [classref boost::proto::context::null_context `null_context<>`]]
+[def _when_ [classref boost::proto::when `when<>`]]
+[def _call_ [classref boost::proto::call `call<>`]]
+[def _make_ [classref boost::proto::make `make<>`]]
+[def _flatten_ [funcref boost::proto::flatten `flatten()`]]
+
+[include preface.qbk]
+
+[section:users_guide Users' Guide]
+
+This Users' Guide describes how to use Proto to build expression-template
+based Domain-Specific Embedded Langauges. It is broken up in to 5 sections,
+corresponding to the 5 major parts to Proto:
+
+[variablelist
+[[[link boost_proto.users_guide.expression_construction Expression Construction]]
+ [Describes how to use Proto to build expression trees.]]
+[[[link boost_proto.users_guide.expression_evaluation Expression Evaluation]]
+ [Describes the tools Proto provides for making your expression trees do
+ something useful.]]
+[[[link boost_proto.users_guide.expression_introspection Expression Introspection]]
+ [Describes Proto's grammar matching facilities, which make
+ it easy to discover the structure of an expression tree.]]
+[[[link boost_proto.users_guide.expression_transformation Expression Transformation]]
+ [Describes how to write expression transforms that turn an expression tree
+ into some other object.]]
+[[[link boost_proto.users_guide.expression_extension Expression Extension]]
+ [Describes how to extend Proto expressions with additional behaviors and
+ members and how to selectively disable Proto's operator overloads.]]
+]
+
+But before we get started, let's have a look at some very simple Proto examples
+and say a few words about Proto's philosophy.
+
+[include installation.qbk]
+
+[include quick_start.qbk]
+
+[include calculator.qbk]
+
+[include construction.qbk]
+
+[include evaluation.qbk]
+
+[include grammars.qbk]
+
+[include transforms.qbk]
+
+[include extensibility.qbk]
+
+[include examples.qbk]
+
+[endsect]
+
+[xinclude proto.xml]
+
+[section Appendices]
+
+[include history.qbk]
+
+[include rationale.qbk]
+
+[include implementation.qbk]
+
+[include acknowledgements.qbk]
+
+[endsect]

Added: branches/proto/v4/libs/proto/doc/proto.xml
==============================================================================
--- (empty file)
+++ branches/proto/v4/libs/proto/doc/proto.xml 2008-04-06 02:19:35 EDT (Sun, 06 Apr 2008)
@@ -0,0 +1,9 @@
+<?xml version="1.0" standalone="yes"?>
+<library-reference id="reference" xmlns:xi="http://www.w3.org/2001/XInclude">
+ <title>Reference</title>
+ <xi:include href="concepts/CallableTransform.xml"/>
+ <xi:include href="concepts/PrimitiveTransform.xml"/>
+ <xi:include href="concepts/Transform.xml"/>
+ <xi:include href="concepts/PolymorphicFunctionObject.xml"/>
+ <xi:include href="protodoc.xml" xpointer="xpointer(//header)"/>
+</library-reference>

Added: branches/proto/v4/libs/proto/doc/protodoc.xml
==============================================================================
--- (empty file)
+++ branches/proto/v4/libs/proto/doc/protodoc.xml 2008-04-06 02:19:35 EDT (Sun, 06 Apr 2008)
@@ -0,0 +1,3327 @@
+<?xml version="1.0" standalone="yes"?>
+<library-reference><header name="boost/proto/args.hpp"><para>Contains definition of args&lt;&gt; class template. </para><namespace name="boost"><namespace name="proto"><struct name="term"><template>
+ <template-type-parameter name="Arg0"/>
+ </template><purpose>A type sequence, for use as the 2nd parameter to the <computeroutput>expr&lt;&gt;</computeroutput> class template. </purpose><description><para>A type sequence, for use as the 2nd parameter to the <computeroutput>expr&lt;&gt;</computeroutput> class template. The types in the sequence correspond to the children of a node in an expression tree. </para></description><data-member name="arity" specifiers="static"><type>const long</type></data-member><typedef name="child0"><type>Arg0</type></typedef><typedef name="child1"><type>mpl::void_</type></typedef><typedef name="child2"><type>mpl::void_</type></typedef><typedef name="child3"><type>mpl::void_</type></typedef><typedef name="child4"><type>mpl::void_</type></typedef></struct><struct name="list1"><template>
+ <template-type-parameter name="Arg0"/>
+ </template><purpose>A type sequence, for use as the 2nd parameter to the <computeroutput>expr&lt;&gt;</computeroutput> class template. </purpose><description><para>A type sequence, for use as the 2nd parameter to the <computeroutput>expr&lt;&gt;</computeroutput> class template. The types in the sequence correspond to the children of a node in an expression tree. </para></description><data-member name="arity" specifiers="static"><type>const long</type></data-member><typedef name="child0"><type>Arg0</type></typedef><typedef name="child1"><type>mpl::void_</type></typedef><typedef name="child2"><type>mpl::void_</type></typedef><typedef name="child3"><type>mpl::void_</type></typedef><typedef name="child4"><type>mpl::void_</type></typedef></struct><struct name="list2"><template>
+ <template-type-parameter name="Arg0"/>
+ <template-type-parameter name="Arg1"/>
+ </template><purpose>A type sequence, for use as the 2nd parameter to the <computeroutput>expr&lt;&gt;</computeroutput> class template. </purpose><description><para>A type sequence, for use as the 2nd parameter to the <computeroutput>expr&lt;&gt;</computeroutput> class template. The types in the sequence correspond to the children of a node in an expression tree. </para></description><data-member name="arity" specifiers="static"><type>const long</type></data-member><typedef name="child0"><type>Arg0</type></typedef><typedef name="child1"><type>Arg1</type></typedef><typedef name="child2"><type>mpl::void_</type></typedef><typedef name="child3"><type>mpl::void_</type></typedef><typedef name="child4"><type>mpl::void_</type></typedef></struct><struct name="list3"><template>
+ <template-type-parameter name="Arg0"/>
+ <template-type-parameter name="Arg1"/>
+ <template-type-parameter name="Arg2"/>
+ </template><purpose>A type sequence, for use as the 2nd parameter to the <computeroutput>expr&lt;&gt;</computeroutput> class template. </purpose><description><para>A type sequence, for use as the 2nd parameter to the <computeroutput>expr&lt;&gt;</computeroutput> class template. The types in the sequence correspond to the children of a node in an expression tree. </para></description><data-member name="arity" specifiers="static"><type>const long</type></data-member><typedef name="child0"><type>Arg0</type></typedef><typedef name="child1"><type>Arg1</type></typedef><typedef name="child2"><type>Arg2</type></typedef><typedef name="child3"><type>mpl::void_</type></typedef><typedef name="child4"><type>mpl::void_</type></typedef></struct><struct name="list4"><template>
+ <template-type-parameter name="Arg0"/>
+ <template-type-parameter name="Arg1"/>
+ <template-type-parameter name="Arg2"/>
+ <template-type-parameter name="Arg3"/>
+ </template><purpose>A type sequence, for use as the 2nd parameter to the <computeroutput>expr&lt;&gt;</computeroutput> class template. </purpose><description><para>A type sequence, for use as the 2nd parameter to the <computeroutput>expr&lt;&gt;</computeroutput> class template. The types in the sequence correspond to the children of a node in an expression tree. </para></description><data-member name="arity" specifiers="static"><type>const long</type></data-member><typedef name="child0"><type>Arg0</type></typedef><typedef name="child1"><type>Arg1</type></typedef><typedef name="child2"><type>Arg2</type></typedef><typedef name="child3"><type>Arg3</type></typedef><typedef name="child4"><type>mpl::void_</type></typedef></struct><struct name="list5"><template>
+ <template-type-parameter name="Arg0"/>
+ <template-type-parameter name="Arg1"/>
+ <template-type-parameter name="Arg2"/>
+ <template-type-parameter name="Arg3"/>
+ <template-type-parameter name="Arg4"/>
+ </template><purpose>A type sequence, for use as the 2nd parameter to the <computeroutput>expr&lt;&gt;</computeroutput> class template. </purpose><description><para>A type sequence, for use as the 2nd parameter to the <computeroutput>expr&lt;&gt;</computeroutput> class template. The types in the sequence correspond to the children of a node in an expression tree. </para></description><data-member name="arity" specifiers="static"><type>const long</type></data-member><typedef name="child0"><type>Arg0</type></typedef><typedef name="child1"><type>Arg1</type></typedef><typedef name="child2"><type>Arg2</type></typedef><typedef name="child3"><type>Arg3</type></typedef><typedef name="child4"><type>Arg4</type></typedef></struct></namespace></namespace></header><header name="boost/proto/context.hpp"><para>Includes all the context classes in the context/ sub-directory. </para></header><header name="boost/proto/context/callable.hpp"><para>Definintion of callable_context&lt;&gt;, an evaluation context for proto::eval
() that explodes each node and calls the derived context type with the expressions constituents. If the derived context doesn't have an overload that handles this node, fall back to some other context. </para><namespace name="boost"><namespace name="proto"><namespace name="context"><struct name="callable_eval"><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="Context"/>
+ <template-nontype-parameter name="Arity"><type>long</type><default>Expr::proto_arity::value</default></template-nontype-parameter>
+ </template><purpose>A BinaryFunction that accepts a Proto expression and a callable context and calls the context with the expression tag and children as arguments, effectively fanning the expression out. </purpose><description><para><computeroutput>callable_eval&lt;&gt;</computeroutput> requires that <computeroutput>Context</computeroutput> is a PolymorphicFunctionObject that can be invoked with <computeroutput>Expr's</computeroutput> tag and children as expressions, as follows:</para><para><programlisting> context(Expr::proto_tag(), child_c&lt;0&gt;(expr), child_c&lt;1&gt;(expr), ...)
+</programlisting> </para></description></struct><struct name="callable_context"><template>
+ <template-type-parameter name="Context"/>
+ <template-type-parameter name="DefaultCtx"><default>default_context</default></template-type-parameter>
+ </template><purpose>An evaluation context adaptor that makes authoring a context a simple matter of writing function overloads, rather then writing template specializations. </purpose><description><para><computeroutput>callable_context&lt;&gt;</computeroutput> is a base class that implements the context protocol by passing fanned-out expression nodes to the derived context, making it easy to customize the handling of expression types by writing function overloads. Only those expression types needing special handling require explicit handling. All others are dispatched to a user-specified default context, <computeroutput>DefaultCtx</computeroutput>.</para><para><computeroutput>callable_context&lt;&gt;</computeroutput> is defined simply as:</para><para><programlisting> template&lt;typename Context, typename DefaultCtx = default_context&gt;
+ struct callable_context
+ {
+ template&lt;typename Expr, typename ThisContext = Context&gt;
+ struct eval
+ : mpl::if_&lt;
+ is_expr_handled_&lt;Expr, Context&gt; // For exposition
+ , callable_eval&lt;Expr, ThisContext&gt;
+ , typename DefaultCtx::template eval&lt;Expr, Context&gt;
+ &gt;::type
+ {};
+ };
+</programlisting></para><para>The Boolean metafunction <computeroutput>is_expr_handled_&lt;&gt;</computeroutput> uses metaprogramming tricks to determine whether <computeroutput>Context</computeroutput> has an overloaded function call operator that accepts the fanned-out constituents of an expression of type <computeroutput>Expr</computeroutput>. If so, the handling of the expression is dispatched to <computeroutput>callable_eval&lt;&gt;</computeroutput>. If not, it is dispatched to the user-specified <computeroutput>DefaultCtx</computeroutput>.</para><para>Below is an example of how to use <computeroutput>callable_context&lt;&gt;</computeroutput>:</para><para><programlisting> // An evaluation context that increments all
+ // integer terminals in-place.
+ struct increment_ints
+ : callable_context&lt;
+ increment_ints const // derived context
+ , null_context const // fall-back context
+ &gt;
+ {
+ typedef void result_type;
+
+ // Handle int terminals here:
+ void operator()(proto::tag::terminal, int &amp;i) const
+ {
+ ++i;
+ }
+ };
+</programlisting></para><para>With <computeroutput>increment_ints</computeroutput>, we can do the following:</para><para><programlisting> literal&lt;int&gt; i = 0, j = 10;
+ proto::eval( i - j * 3.14, increment_ints() );
+
+ assert( i.get() == 1 &amp;&amp; j.get() == 11 );
+</programlisting> </para></description><struct name="eval"><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="ThisContext"><default>Context</default></template-type-parameter>
+ </template><description><para>A BinaryFunction that accepts an <computeroutput>Expr</computeroutput> and a <computeroutput>Context</computeroutput>, and either fans out the expression and passes it to the context, or else hands off the expression to <computeroutput>DefaultCtx</computeroutput>.</para><para>If <computeroutput>Context</computeroutput> is a PolymorphicFunctionObject such that it can be invoked with the tag and children of <computeroutput>Expr</computeroutput>, as <computeroutput>ctx(Expr::proto_tag(), child_c&lt;0&gt;(expr), child_c&lt;1&gt;(expr)...)</computeroutput>, then <computeroutput>eval&lt;Expr, ThisContext&gt;</computeroutput> inherits from <computeroutput>callable_eval&lt;Expr, ThisContext&gt;</computeroutput>. Otherwise, <computeroutput>eval&lt;Expr, ThisContext&gt;</computeroutput> inherits from <computeroutput>DefaultCtx::eval&lt;Expr, Context&gt;</computeroutput>. </para></description></struct></struct><struct-specialization name="callable_eval"><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="Context"/>
+ </template><specialization><template-arg>Expr</template-arg><template-arg>Context</template-arg><template-arg>0</template-arg></specialization><purpose>A BinaryFunction that accepts a Proto expression and a callable context and calls the context with the expression tag and children as arguments, effectively fanning the expression out. </purpose><description><para><computeroutput>callable_eval&lt;&gt;</computeroutput> requires that <computeroutput>Context</computeroutput> is a PolymorphicFunctionObject that can be invoked with <computeroutput>Expr's</computeroutput> tag and children as expressions, as follows:</para><para><programlisting> context(Expr::proto_tag(), child_c\&lt;0\&gt;(expr), child_c\&lt;1\&gt;(expr), ...)
+</programlisting> </para></description><typedef name="child0"><type>proto::result_of::child_c&lt; Expr, 0 &gt;::const_reference</type></typedef><typedef name="result_type"><type>boost::result_of&lt; Context(typename Expr::proto_tag, child0)&gt;::type</type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type>result_type</type><parameter name="expr"><paramtype>Expr &amp;</paramtype><description><para>The current expression </para></description></parameter><parameter name="context"><paramtype>Context &amp;</paramtype><description><para>The callable evaluation context </para></description></parameter><description><para>
+
+</para></description><returns><para><computeroutput>context(Expr::proto_tag(), child_c&lt;0&gt;(expr), child_c&lt;1&gt;(expr), ...)</computeroutput> </para></returns></method></method-group></struct-specialization><struct-specialization name="callable_eval"><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="Context"/>
+ </template><specialization><template-arg>Expr</template-arg><template-arg>Context</template-arg><template-arg>1</template-arg></specialization><purpose>A BinaryFunction that accepts a Proto expression and a callable context and calls the context with the expression tag and children as arguments, effectively fanning the expression out. </purpose><description><para><computeroutput>callable_eval&lt;&gt;</computeroutput> requires that <computeroutput>Context</computeroutput> is a PolymorphicFunctionObject that can be invoked with <computeroutput>Expr's</computeroutput> tag and children as expressions, as follows:</para><para><programlisting> context(Expr::proto_tag(), child_c\&lt;0\&gt;(expr), child_c\&lt;1\&gt;(expr), ...)
+</programlisting> </para></description><typedef name="child0"><type>proto::result_of::child_c&lt; Expr, 0 &gt;::const_reference</type></typedef><typedef name="result_type"><type>boost::result_of&lt; Context(typename Expr::proto_tag, child0)&gt;::type</type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type>result_type</type><parameter name="expr"><paramtype>Expr &amp;</paramtype><description><para>The current expression </para></description></parameter><parameter name="context"><paramtype>Context &amp;</paramtype><description><para>The callable evaluation context </para></description></parameter><description><para>
+
+</para></description><returns><para><computeroutput>context(Expr::proto_tag(), child_c&lt;0&gt;(expr), child_c&lt;1&gt;(expr), ...)</computeroutput> </para></returns></method></method-group></struct-specialization><struct-specialization name="callable_eval"><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="Context"/>
+ </template><specialization><template-arg>Expr</template-arg><template-arg>Context</template-arg><template-arg>2</template-arg></specialization><purpose>A BinaryFunction that accepts a Proto expression and a callable context and calls the context with the expression tag and children as arguments, effectively fanning the expression out. </purpose><description><para><computeroutput>callable_eval&lt;&gt;</computeroutput> requires that <computeroutput>Context</computeroutput> is a PolymorphicFunctionObject that can be invoked with <computeroutput>Expr's</computeroutput> tag and children as expressions, as follows:</para><para><programlisting> context(Expr::proto_tag(), child_c\&lt;0\&gt;(expr), child_c\&lt;1\&gt;(expr), ...)
+</programlisting> </para></description><typedef name="child0"><type>proto::result_of::child_c&lt; Expr, 0 &gt;::const_reference</type></typedef><typedef name="child1"><type>proto::result_of::child_c&lt; Expr, 1 &gt;::const_reference</type></typedef><typedef name="result_type"><type>boost::result_of&lt; Context(typename Expr::proto_tag, child0, child1)&gt;::type</type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type>result_type</type><parameter name="expr"><paramtype>Expr &amp;</paramtype><description><para>The current expression </para></description></parameter><parameter name="context"><paramtype>Context &amp;</paramtype><description><para>The callable evaluation context </para></description></parameter><description><para>
+
+</para></description><returns><para><computeroutput>context(Expr::proto_tag(), child_c&lt;0&gt;(expr), child_c&lt;1&gt;(expr), ...)</computeroutput> </para></returns></method></method-group></struct-specialization><struct-specialization name="callable_eval"><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="Context"/>
+ </template><specialization><template-arg>Expr</template-arg><template-arg>Context</template-arg><template-arg>3</template-arg></specialization><purpose>A BinaryFunction that accepts a Proto expression and a callable context and calls the context with the expression tag and children as arguments, effectively fanning the expression out. </purpose><description><para><computeroutput>callable_eval&lt;&gt;</computeroutput> requires that <computeroutput>Context</computeroutput> is a PolymorphicFunctionObject that can be invoked with <computeroutput>Expr's</computeroutput> tag and children as expressions, as follows:</para><para><programlisting> context(Expr::proto_tag(), child_c\&lt;0\&gt;(expr), child_c\&lt;1\&gt;(expr), ...)
+</programlisting> </para></description><typedef name="child0"><type>proto::result_of::child_c&lt; Expr, 0 &gt;::const_reference</type></typedef><typedef name="child1"><type>proto::result_of::child_c&lt; Expr, 1 &gt;::const_reference</type></typedef><typedef name="child2"><type>proto::result_of::child_c&lt; Expr, 2 &gt;::const_reference</type></typedef><typedef name="result_type"><type>boost::result_of&lt; Context(typename Expr::proto_tag, child0, child1, child2)&gt;::type</type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type>result_type</type><parameter name="expr"><paramtype>Expr &amp;</paramtype><description><para>The current expression </para></description></parameter><parameter name="context"><paramtype>Context &amp;</paramtype><description><para>The callable evaluation context </para></description></parameter><description><para>
+
+</para></description><returns><para><computeroutput>context(Expr::proto_tag(), child_c&lt;0&gt;(expr), child_c&lt;1&gt;(expr), ...)</computeroutput> </para></returns></method></method-group></struct-specialization><struct-specialization name="callable_eval"><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="Context"/>
+ </template><specialization><template-arg>Expr</template-arg><template-arg>Context</template-arg><template-arg>4</template-arg></specialization><purpose>A BinaryFunction that accepts a Proto expression and a callable context and calls the context with the expression tag and children as arguments, effectively fanning the expression out. </purpose><description><para><computeroutput>callable_eval&lt;&gt;</computeroutput> requires that <computeroutput>Context</computeroutput> is a PolymorphicFunctionObject that can be invoked with <computeroutput>Expr's</computeroutput> tag and children as expressions, as follows:</para><para><programlisting> context(Expr::proto_tag(), child_c\&lt;0\&gt;(expr), child_c\&lt;1\&gt;(expr), ...)
+</programlisting> </para></description><typedef name="child0"><type>proto::result_of::child_c&lt; Expr, 0 &gt;::const_reference</type></typedef><typedef name="child1"><type>proto::result_of::child_c&lt; Expr, 1 &gt;::const_reference</type></typedef><typedef name="child2"><type>proto::result_of::child_c&lt; Expr, 2 &gt;::const_reference</type></typedef><typedef name="child3"><type>proto::result_of::child_c&lt; Expr, 3 &gt;::const_reference</type></typedef><typedef name="result_type"><type>boost::result_of&lt; Context(typename Expr::proto_tag, child0, child1, child2, child3)&gt;::type</type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type>result_type</type><parameter name="expr"><paramtype>Expr &amp;</paramtype><description><para>The current expression </para></description></parameter><parameter name="context"><paramtype>Context &amp;</paramtype><description><para>The callable evaluation context </para></description></parameter><description><para>
+
+</para></description><returns><para><computeroutput>context(Expr::proto_tag(), child_c&lt;0&gt;(expr), child_c&lt;1&gt;(expr), ...)</computeroutput> </para></returns></method></method-group></struct-specialization><struct-specialization name="callable_eval"><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="Context"/>
+ </template><specialization><template-arg>Expr</template-arg><template-arg>Context</template-arg><template-arg>5</template-arg></specialization><purpose>A BinaryFunction that accepts a Proto expression and a callable context and calls the context with the expression tag and children as arguments, effectively fanning the expression out. </purpose><description><para><computeroutput>callable_eval&lt;&gt;</computeroutput> requires that <computeroutput>Context</computeroutput> is a PolymorphicFunctionObject that can be invoked with <computeroutput>Expr's</computeroutput> tag and children as expressions, as follows:</para><para><programlisting> context(Expr::proto_tag(), child_c\&lt;0\&gt;(expr), child_c\&lt;1\&gt;(expr), ...)
+</programlisting> </para></description><typedef name="child0"><type>proto::result_of::child_c&lt; Expr, 0 &gt;::const_reference</type></typedef><typedef name="child1"><type>proto::result_of::child_c&lt; Expr, 1 &gt;::const_reference</type></typedef><typedef name="child2"><type>proto::result_of::child_c&lt; Expr, 2 &gt;::const_reference</type></typedef><typedef name="child3"><type>proto::result_of::child_c&lt; Expr, 3 &gt;::const_reference</type></typedef><typedef name="child4"><type>proto::result_of::child_c&lt; Expr, 4 &gt;::const_reference</type></typedef><typedef name="result_type"><type>boost::result_of&lt; Context(typename Expr::proto_tag, child0, child1, child2, child3, child4)&gt;::type</type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type>result_type</type><parameter name="expr"><paramtype>Expr &amp;</paramtype><description><para>The current expression </para></description></parameter><parameter name="context"><paramtype>Context &amp;</paramtype><des
cription><para>The callable evaluation context </para></description></parameter><description><para>
+
+</para></description><returns><para><computeroutput>context(Expr::proto_tag(), child_c&lt;0&gt;(expr), child_c&lt;1&gt;(expr), ...)</computeroutput> </para></returns></method></method-group></struct-specialization></namespace></namespace></namespace></header><header name="boost/proto/context/default.hpp"><para>Definintion of default_context, a default evaluation context for proto::eval() that uses Boost.Typeof to deduce return types of the built-in operators. </para><namespace name="boost"><namespace name="proto"><namespace name="context"><struct name="default_eval"><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="Context"/>
+ <template-type-parameter name="Tag"><default>typename Expr::proto_tag</default></template-type-parameter>
+ <template-nontype-parameter name="Arity"><type>long</type><default>Expr::proto_arity::value</default></template-nontype-parameter>
+ </template></struct><struct-specialization name="default_eval"><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="Context"/>
+ </template><specialization><template-arg>Expr</template-arg><template-arg>Context</template-arg><template-arg>proto::tag::unary_plus</template-arg><template-arg>1</template-arg></specialization><typedef name="result_type"><type><emphasis>unspecified</emphasis></type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type>result_type</type><parameter name="expr"><paramtype>Expr &amp;</paramtype></parameter><parameter name="ctx"><paramtype>Context &amp;</paramtype></parameter></method></method-group></struct-specialization><struct-specialization name="default_eval"><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="Context"/>
+ </template><specialization><template-arg>Expr</template-arg><template-arg>Context</template-arg><template-arg>proto::tag::negate</template-arg><template-arg>1</template-arg></specialization><typedef name="result_type"><type><emphasis>unspecified</emphasis></type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type>result_type</type><parameter name="expr"><paramtype>Expr &amp;</paramtype></parameter><parameter name="ctx"><paramtype>Context &amp;</paramtype></parameter></method></method-group></struct-specialization><struct-specialization name="default_eval"><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="Context"/>
+ </template><specialization><template-arg>Expr</template-arg><template-arg>Context</template-arg><template-arg>proto::tag::dereference</template-arg><template-arg>1</template-arg></specialization><typedef name="result_type"><type><emphasis>unspecified</emphasis></type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type>result_type</type><parameter name="expr"><paramtype>Expr &amp;</paramtype></parameter><parameter name="ctx"><paramtype>Context &amp;</paramtype></parameter></method></method-group></struct-specialization><struct-specialization name="default_eval"><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="Context"/>
+ </template><specialization><template-arg>Expr</template-arg><template-arg>Context</template-arg><template-arg>proto::tag::complement</template-arg><template-arg>1</template-arg></specialization><typedef name="result_type"><type><emphasis>unspecified</emphasis></type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type>result_type</type><parameter name="expr"><paramtype>Expr &amp;</paramtype></parameter><parameter name="ctx"><paramtype>Context &amp;</paramtype></parameter></method></method-group></struct-specialization><struct-specialization name="default_eval"><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="Context"/>
+ </template><specialization><template-arg>Expr</template-arg><template-arg>Context</template-arg><template-arg>proto::tag::address_of</template-arg><template-arg>1</template-arg></specialization><typedef name="result_type"><type><emphasis>unspecified</emphasis></type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type>result_type</type><parameter name="expr"><paramtype>Expr &amp;</paramtype></parameter><parameter name="ctx"><paramtype>Context &amp;</paramtype></parameter></method></method-group></struct-specialization><struct-specialization name="default_eval"><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="Context"/>
+ </template><specialization><template-arg>Expr</template-arg><template-arg>Context</template-arg><template-arg>proto::tag::logical_not</template-arg><template-arg>1</template-arg></specialization><typedef name="result_type"><type><emphasis>unspecified</emphasis></type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type>result_type</type><parameter name="expr"><paramtype>Expr &amp;</paramtype></parameter><parameter name="ctx"><paramtype>Context &amp;</paramtype></parameter></method></method-group></struct-specialization><struct-specialization name="default_eval"><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="Context"/>
+ </template><specialization><template-arg>Expr</template-arg><template-arg>Context</template-arg><template-arg>proto::tag::pre_inc</template-arg><template-arg>1</template-arg></specialization><typedef name="result_type"><type><emphasis>unspecified</emphasis></type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type>result_type</type><parameter name="expr"><paramtype>Expr &amp;</paramtype></parameter><parameter name="ctx"><paramtype>Context &amp;</paramtype></parameter></method></method-group></struct-specialization><struct-specialization name="default_eval"><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="Context"/>
+ </template><specialization><template-arg>Expr</template-arg><template-arg>Context</template-arg><template-arg>proto::tag::pre_dec</template-arg><template-arg>1</template-arg></specialization><typedef name="result_type"><type><emphasis>unspecified</emphasis></type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type>result_type</type><parameter name="expr"><paramtype>Expr &amp;</paramtype></parameter><parameter name="ctx"><paramtype>Context &amp;</paramtype></parameter></method></method-group></struct-specialization><struct-specialization name="default_eval"><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="Context"/>
+ </template><specialization><template-arg>Expr</template-arg><template-arg>Context</template-arg><template-arg>proto::tag::shift_left</template-arg><template-arg>2</template-arg></specialization><typedef name="result_type"><type><emphasis>unspecified</emphasis></type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type>result_type</type><parameter name="expr"><paramtype>Expr &amp;</paramtype></parameter><parameter name="ctx"><paramtype>Context &amp;</paramtype></parameter></method></method-group></struct-specialization><struct-specialization name="default_eval"><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="Context"/>
+ </template><specialization><template-arg>Expr</template-arg><template-arg>Context</template-arg><template-arg>proto::tag::shift_right</template-arg><template-arg>2</template-arg></specialization><typedef name="result_type"><type><emphasis>unspecified</emphasis></type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type>result_type</type><parameter name="expr"><paramtype>Expr &amp;</paramtype></parameter><parameter name="ctx"><paramtype>Context &amp;</paramtype></parameter></method></method-group></struct-specialization><struct-specialization name="default_eval"><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="Context"/>
+ </template><specialization><template-arg>Expr</template-arg><template-arg>Context</template-arg><template-arg>proto::tag::multiplies</template-arg><template-arg>2</template-arg></specialization><typedef name="result_type"><type><emphasis>unspecified</emphasis></type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type>result_type</type><parameter name="expr"><paramtype>Expr &amp;</paramtype></parameter><parameter name="ctx"><paramtype>Context &amp;</paramtype></parameter></method></method-group></struct-specialization><struct-specialization name="default_eval"><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="Context"/>
+ </template><specialization><template-arg>Expr</template-arg><template-arg>Context</template-arg><template-arg>proto::tag::divides</template-arg><template-arg>2</template-arg></specialization><typedef name="result_type"><type><emphasis>unspecified</emphasis></type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type>result_type</type><parameter name="expr"><paramtype>Expr &amp;</paramtype></parameter><parameter name="ctx"><paramtype>Context &amp;</paramtype></parameter></method></method-group></struct-specialization><struct-specialization name="default_eval"><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="Context"/>
+ </template><specialization><template-arg>Expr</template-arg><template-arg>Context</template-arg><template-arg>proto::tag::modulus</template-arg><template-arg>2</template-arg></specialization><typedef name="result_type"><type><emphasis>unspecified</emphasis></type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type>result_type</type><parameter name="expr"><paramtype>Expr &amp;</paramtype></parameter><parameter name="ctx"><paramtype>Context &amp;</paramtype></parameter></method></method-group></struct-specialization><struct-specialization name="default_eval"><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="Context"/>
+ </template><specialization><template-arg>Expr</template-arg><template-arg>Context</template-arg><template-arg>proto::tag::plus</template-arg><template-arg>2</template-arg></specialization><typedef name="result_type"><type><emphasis>unspecified</emphasis></type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type>result_type</type><parameter name="expr"><paramtype>Expr &amp;</paramtype></parameter><parameter name="ctx"><paramtype>Context &amp;</paramtype></parameter></method></method-group></struct-specialization><struct-specialization name="default_eval"><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="Context"/>
+ </template><specialization><template-arg>Expr</template-arg><template-arg>Context</template-arg><template-arg>proto::tag::minus</template-arg><template-arg>2</template-arg></specialization><typedef name="result_type"><type><emphasis>unspecified</emphasis></type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type>result_type</type><parameter name="expr"><paramtype>Expr &amp;</paramtype></parameter><parameter name="ctx"><paramtype>Context &amp;</paramtype></parameter></method></method-group></struct-specialization><struct-specialization name="default_eval"><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="Context"/>
+ </template><specialization><template-arg>Expr</template-arg><template-arg>Context</template-arg><template-arg>proto::tag::less</template-arg><template-arg>2</template-arg></specialization><typedef name="result_type"><type><emphasis>unspecified</emphasis></type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type>result_type</type><parameter name="expr"><paramtype>Expr &amp;</paramtype></parameter><parameter name="ctx"><paramtype>Context &amp;</paramtype></parameter></method></method-group></struct-specialization><struct-specialization name="default_eval"><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="Context"/>
+ </template><specialization><template-arg>Expr</template-arg><template-arg>Context</template-arg><template-arg>proto::tag::greater</template-arg><template-arg>2</template-arg></specialization><typedef name="result_type"><type><emphasis>unspecified</emphasis></type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type>result_type</type><parameter name="expr"><paramtype>Expr &amp;</paramtype></parameter><parameter name="ctx"><paramtype>Context &amp;</paramtype></parameter></method></method-group></struct-specialization><struct-specialization name="default_eval"><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="Context"/>
+ </template><specialization><template-arg>Expr</template-arg><template-arg>Context</template-arg><template-arg>proto::tag::less_equal</template-arg><template-arg>2</template-arg></specialization><typedef name="result_type"><type><emphasis>unspecified</emphasis></type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type>result_type</type><parameter name="expr"><paramtype>Expr &amp;</paramtype></parameter><parameter name="ctx"><paramtype>Context &amp;</paramtype></parameter></method></method-group></struct-specialization><struct-specialization name="default_eval"><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="Context"/>
+ </template><specialization><template-arg>Expr</template-arg><template-arg>Context</template-arg><template-arg>proto::tag::greater_equal</template-arg><template-arg>2</template-arg></specialization><typedef name="result_type"><type><emphasis>unspecified</emphasis></type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type>result_type</type><parameter name="expr"><paramtype>Expr &amp;</paramtype></parameter><parameter name="ctx"><paramtype>Context &amp;</paramtype></parameter></method></method-group></struct-specialization><struct-specialization name="default_eval"><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="Context"/>
+ </template><specialization><template-arg>Expr</template-arg><template-arg>Context</template-arg><template-arg>proto::tag::equal_to</template-arg><template-arg>2</template-arg></specialization><typedef name="result_type"><type><emphasis>unspecified</emphasis></type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type>result_type</type><parameter name="expr"><paramtype>Expr &amp;</paramtype></parameter><parameter name="ctx"><paramtype>Context &amp;</paramtype></parameter></method></method-group></struct-specialization><struct-specialization name="default_eval"><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="Context"/>
+ </template><specialization><template-arg>Expr</template-arg><template-arg>Context</template-arg><template-arg>proto::tag::not_equal_to</template-arg><template-arg>2</template-arg></specialization><typedef name="result_type"><type><emphasis>unspecified</emphasis></type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type>result_type</type><parameter name="expr"><paramtype>Expr &amp;</paramtype></parameter><parameter name="ctx"><paramtype>Context &amp;</paramtype></parameter></method></method-group></struct-specialization><struct-specialization name="default_eval"><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="Context"/>
+ </template><specialization><template-arg>Expr</template-arg><template-arg>Context</template-arg><template-arg>proto::tag::logical_or</template-arg><template-arg>2</template-arg></specialization><typedef name="result_type"><type><emphasis>unspecified</emphasis></type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type>result_type</type><parameter name="expr"><paramtype>Expr &amp;</paramtype></parameter><parameter name="ctx"><paramtype>Context &amp;</paramtype></parameter></method></method-group></struct-specialization><struct-specialization name="default_eval"><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="Context"/>
+ </template><specialization><template-arg>Expr</template-arg><template-arg>Context</template-arg><template-arg>proto::tag::logical_and</template-arg><template-arg>2</template-arg></specialization><typedef name="result_type"><type><emphasis>unspecified</emphasis></type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type>result_type</type><parameter name="expr"><paramtype>Expr &amp;</paramtype></parameter><parameter name="ctx"><paramtype>Context &amp;</paramtype></parameter></method></method-group></struct-specialization><struct-specialization name="default_eval"><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="Context"/>
+ </template><specialization><template-arg>Expr</template-arg><template-arg>Context</template-arg><template-arg>proto::tag::bitwise_and</template-arg><template-arg>2</template-arg></specialization><typedef name="result_type"><type><emphasis>unspecified</emphasis></type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type>result_type</type><parameter name="expr"><paramtype>Expr &amp;</paramtype></parameter><parameter name="ctx"><paramtype>Context &amp;</paramtype></parameter></method></method-group></struct-specialization><struct-specialization name="default_eval"><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="Context"/>
+ </template><specialization><template-arg>Expr</template-arg><template-arg>Context</template-arg><template-arg>proto::tag::bitwise_or</template-arg><template-arg>2</template-arg></specialization><typedef name="result_type"><type><emphasis>unspecified</emphasis></type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type>result_type</type><parameter name="expr"><paramtype>Expr &amp;</paramtype></parameter><parameter name="ctx"><paramtype>Context &amp;</paramtype></parameter></method></method-group></struct-specialization><struct-specialization name="default_eval"><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="Context"/>
+ </template><specialization><template-arg>Expr</template-arg><template-arg>Context</template-arg><template-arg>proto::tag::bitwise_xor</template-arg><template-arg>2</template-arg></specialization><typedef name="result_type"><type><emphasis>unspecified</emphasis></type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type>result_type</type><parameter name="expr"><paramtype>Expr &amp;</paramtype></parameter><parameter name="ctx"><paramtype>Context &amp;</paramtype></parameter></method></method-group></struct-specialization><struct-specialization name="default_eval"><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="Context"/>
+ </template><specialization><template-arg>Expr</template-arg><template-arg>Context</template-arg><template-arg>proto::tag::mem_ptr</template-arg><template-arg>2</template-arg></specialization><typedef name="result_type"><type><emphasis>unspecified</emphasis></type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type>result_type</type><parameter name="expr"><paramtype>Expr &amp;</paramtype></parameter><parameter name="ctx"><paramtype>Context &amp;</paramtype></parameter></method></method-group></struct-specialization><struct-specialization name="default_eval"><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="Context"/>
+ </template><specialization><template-arg>Expr</template-arg><template-arg>Context</template-arg><template-arg>proto::tag::assign</template-arg><template-arg>2</template-arg></specialization><typedef name="result_type"><type><emphasis>unspecified</emphasis></type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type>result_type</type><parameter name="expr"><paramtype>Expr &amp;</paramtype></parameter><parameter name="ctx"><paramtype>Context &amp;</paramtype></parameter></method></method-group></struct-specialization><struct-specialization name="default_eval"><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="Context"/>
+ </template><specialization><template-arg>Expr</template-arg><template-arg>Context</template-arg><template-arg>proto::tag::shift_left_assign</template-arg><template-arg>2</template-arg></specialization><typedef name="result_type"><type><emphasis>unspecified</emphasis></type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type>result_type</type><parameter name="expr"><paramtype>Expr &amp;</paramtype></parameter><parameter name="ctx"><paramtype>Context &amp;</paramtype></parameter></method></method-group></struct-specialization><struct-specialization name="default_eval"><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="Context"/>
+ </template><specialization><template-arg>Expr</template-arg><template-arg>Context</template-arg><template-arg>proto::tag::shift_right_assign</template-arg><template-arg>2</template-arg></specialization><typedef name="result_type"><type><emphasis>unspecified</emphasis></type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type>result_type</type><parameter name="expr"><paramtype>Expr &amp;</paramtype></parameter><parameter name="ctx"><paramtype>Context &amp;</paramtype></parameter></method></method-group></struct-specialization><struct-specialization name="default_eval"><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="Context"/>
+ </template><specialization><template-arg>Expr</template-arg><template-arg>Context</template-arg><template-arg>proto::tag::multiplies_assign</template-arg><template-arg>2</template-arg></specialization><typedef name="result_type"><type><emphasis>unspecified</emphasis></type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type>result_type</type><parameter name="expr"><paramtype>Expr &amp;</paramtype></parameter><parameter name="ctx"><paramtype>Context &amp;</paramtype></parameter></method></method-group></struct-specialization><struct-specialization name="default_eval"><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="Context"/>
+ </template><specialization><template-arg>Expr</template-arg><template-arg>Context</template-arg><template-arg>proto::tag::divides_assign</template-arg><template-arg>2</template-arg></specialization><typedef name="result_type"><type><emphasis>unspecified</emphasis></type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type>result_type</type><parameter name="expr"><paramtype>Expr &amp;</paramtype></parameter><parameter name="ctx"><paramtype>Context &amp;</paramtype></parameter></method></method-group></struct-specialization><struct-specialization name="default_eval"><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="Context"/>
+ </template><specialization><template-arg>Expr</template-arg><template-arg>Context</template-arg><template-arg>proto::tag::modulus_assign</template-arg><template-arg>2</template-arg></specialization><typedef name="result_type"><type><emphasis>unspecified</emphasis></type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type>result_type</type><parameter name="expr"><paramtype>Expr &amp;</paramtype></parameter><parameter name="ctx"><paramtype>Context &amp;</paramtype></parameter></method></method-group></struct-specialization><struct-specialization name="default_eval"><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="Context"/>
+ </template><specialization><template-arg>Expr</template-arg><template-arg>Context</template-arg><template-arg>proto::tag::plus_assign</template-arg><template-arg>2</template-arg></specialization><typedef name="result_type"><type><emphasis>unspecified</emphasis></type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type>result_type</type><parameter name="expr"><paramtype>Expr &amp;</paramtype></parameter><parameter name="ctx"><paramtype>Context &amp;</paramtype></parameter></method></method-group></struct-specialization><struct-specialization name="default_eval"><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="Context"/>
+ </template><specialization><template-arg>Expr</template-arg><template-arg>Context</template-arg><template-arg>proto::tag::minus_assign</template-arg><template-arg>2</template-arg></specialization><typedef name="result_type"><type><emphasis>unspecified</emphasis></type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type>result_type</type><parameter name="expr"><paramtype>Expr &amp;</paramtype></parameter><parameter name="ctx"><paramtype>Context &amp;</paramtype></parameter></method></method-group></struct-specialization><struct-specialization name="default_eval"><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="Context"/>
+ </template><specialization><template-arg>Expr</template-arg><template-arg>Context</template-arg><template-arg>proto::tag::bitwise_and_assign</template-arg><template-arg>2</template-arg></specialization><typedef name="result_type"><type><emphasis>unspecified</emphasis></type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type>result_type</type><parameter name="expr"><paramtype>Expr &amp;</paramtype></parameter><parameter name="ctx"><paramtype>Context &amp;</paramtype></parameter></method></method-group></struct-specialization><struct-specialization name="default_eval"><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="Context"/>
+ </template><specialization><template-arg>Expr</template-arg><template-arg>Context</template-arg><template-arg>proto::tag::bitwise_or_assign</template-arg><template-arg>2</template-arg></specialization><typedef name="result_type"><type><emphasis>unspecified</emphasis></type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type>result_type</type><parameter name="expr"><paramtype>Expr &amp;</paramtype></parameter><parameter name="ctx"><paramtype>Context &amp;</paramtype></parameter></method></method-group></struct-specialization><struct-specialization name="default_eval"><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="Context"/>
+ </template><specialization><template-arg>Expr</template-arg><template-arg>Context</template-arg><template-arg>proto::tag::bitwise_xor_assign</template-arg><template-arg>2</template-arg></specialization><typedef name="result_type"><type><emphasis>unspecified</emphasis></type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type>result_type</type><parameter name="expr"><paramtype>Expr &amp;</paramtype></parameter><parameter name="ctx"><paramtype>Context &amp;</paramtype></parameter></method></method-group></struct-specialization><struct-specialization name="default_eval"><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="Context"/>
+ </template><specialization><template-arg>Expr</template-arg><template-arg>Context</template-arg><template-arg>proto::tag::terminal</template-arg><template-arg>0</template-arg></specialization><typedef name="result_type"><type>mpl::if_&lt; is_const&lt; Expr &gt;, typename <classname>proto::result_of::value</classname>&lt; Expr &gt;::const_reference, typename <classname>proto::result_of::value</classname>&lt; Expr &gt;::reference &gt;::type</type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type>result_type</type><parameter name="expr"><paramtype>Expr &amp;</paramtype></parameter><parameter name=""><paramtype>Context &amp;</paramtype></parameter></method></method-group></struct-specialization><struct-specialization name="default_eval"><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="Context"/>
+ </template><specialization><template-arg>Expr</template-arg><template-arg>Context</template-arg><template-arg>proto::tag::post_inc</template-arg><template-arg>1</template-arg></specialization><typedef name="result_type"><type><emphasis>unspecified</emphasis></type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type>result_type</type><parameter name="expr"><paramtype>Expr &amp;</paramtype></parameter><parameter name="ctx"><paramtype>Context &amp;</paramtype></parameter></method></method-group></struct-specialization><struct-specialization name="default_eval"><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="Context"/>
+ </template><specialization><template-arg>Expr</template-arg><template-arg>Context</template-arg><template-arg>proto::tag::post_dec</template-arg><template-arg>1</template-arg></specialization><typedef name="result_type"><type><emphasis>unspecified</emphasis></type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type>result_type</type><parameter name="expr"><paramtype>Expr &amp;</paramtype></parameter><parameter name="ctx"><paramtype>Context &amp;</paramtype></parameter></method></method-group></struct-specialization><struct-specialization name="default_eval"><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="Context"/>
+ </template><specialization><template-arg>Expr</template-arg><template-arg>Context</template-arg><template-arg>proto::tag::subscript</template-arg><template-arg>2</template-arg></specialization><typedef name="result_type"><type><emphasis>unspecified</emphasis></type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type>result_type</type><parameter name="expr"><paramtype>Expr &amp;</paramtype></parameter><parameter name="ctx"><paramtype>Context &amp;</paramtype></parameter></method></method-group></struct-specialization><struct-specialization name="default_eval"><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="Context"/>
+ </template><specialization><template-arg>Expr</template-arg><template-arg>Context</template-arg><template-arg>proto::tag::if_else_</template-arg><template-arg>3</template-arg></specialization><typedef name="result_type"><type><emphasis>unspecified</emphasis></type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type>result_type</type><parameter name="expr"><paramtype>Expr &amp;</paramtype></parameter><parameter name="ctx"><paramtype>Context &amp;</paramtype></parameter></method></method-group></struct-specialization><struct-specialization name="default_eval"><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="Context"/>
+ </template><specialization><template-arg>Expr</template-arg><template-arg>Context</template-arg><template-arg>proto::tag::comma</template-arg><template-arg>2</template-arg></specialization><typedef name="result_type"><type><emphasis>unspecified</emphasis></type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type>result_type</type><parameter name="expr"><paramtype>Expr &amp;</paramtype></parameter><parameter name="ctx"><paramtype>Context &amp;</paramtype></parameter></method></method-group></struct-specialization><struct-specialization name="default_eval"><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="Context"/>
+ </template><specialization><template-arg>Expr</template-arg><template-arg>Context</template-arg><template-arg>proto::tag::function</template-arg><template-arg>0</template-arg></specialization><typedef name="function_type"><type><emphasis>unspecified</emphasis></type></typedef><typedef name="result_type"><type>boost::result_of&lt; function_type()&gt;::type</type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type>result_type</type><parameter name="expr"><paramtype>Expr &amp;</paramtype></parameter><parameter name="context"><paramtype>Context &amp;</paramtype></parameter></method></method-group></struct-specialization><struct-specialization name="default_eval"><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="Context"/>
+ </template><specialization><template-arg>Expr</template-arg><template-arg>Context</template-arg><template-arg>proto::tag::function</template-arg><template-arg>1</template-arg></specialization><typedef name="function_type"><type><emphasis>unspecified</emphasis></type></typedef><typedef name="result_type"><type>boost::result_of&lt; function_type()&gt;::type</type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type>result_type</type><parameter name="expr"><paramtype>Expr &amp;</paramtype></parameter><parameter name="context"><paramtype>Context &amp;</paramtype></parameter></method></method-group></struct-specialization><struct-specialization name="default_eval"><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="Context"/>
+ </template><specialization><template-arg>Expr</template-arg><template-arg>Context</template-arg><template-arg>proto::tag::function</template-arg><template-arg>2</template-arg></specialization><typedef name="function_type"><type><emphasis>unspecified</emphasis></type></typedef><typedef name="result_type"><type>boost::result_of&lt; function_type(typename <classname>proto::result_of::eval</classname>&lt; typename remove_reference&lt; typename proto::result_of::child_c&lt; Expr, 1 &gt;::type &gt;::type, Context &gt;::type)&gt;::type</type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type>result_type</type><parameter name="expr"><paramtype>Expr &amp;</paramtype></parameter><parameter name="context"><paramtype>Context &amp;</paramtype></parameter></method></method-group></struct-specialization><struct-specialization name="default_eval"><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="Context"/>
+ </template><specialization><template-arg>Expr</template-arg><template-arg>Context</template-arg><template-arg>proto::tag::function</template-arg><template-arg>3</template-arg></specialization><typedef name="function_type"><type><emphasis>unspecified</emphasis></type></typedef><typedef name="result_type"><type>boost::result_of&lt; function_type(typename <classname>proto::result_of::eval</classname>&lt; typename remove_reference&lt; typename proto::result_of::child_c&lt; Expr, 1 &gt;::type &gt;::type, Context &gt;::type, typename <classname>proto::result_of::eval</classname>&lt; typename remove_reference&lt; typename proto::result_of::child_c&lt; Expr, 2 &gt;::type &gt;::type, Context &gt;::type)&gt;::type</type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type>result_type</type><parameter name="expr"><paramtype>Expr &amp;</paramtype></parameter><parameter name="context"><paramtype>Context &amp;</paramtype></parameter></method></method-group></struct-special
ization><struct-specialization name="default_eval"><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="Context"/>
+ </template><specialization><template-arg>Expr</template-arg><template-arg>Context</template-arg><template-arg>proto::tag::function</template-arg><template-arg>4</template-arg></specialization><typedef name="function_type"><type><emphasis>unspecified</emphasis></type></typedef><typedef name="result_type"><type>boost::result_of&lt; function_type(typename <classname>proto::result_of::eval</classname>&lt; typename remove_reference&lt; typename proto::result_of::child_c&lt; Expr, 1 &gt;::type &gt;::type, Context &gt;::type, typename <classname>proto::result_of::eval</classname>&lt; typename remove_reference&lt; typename proto::result_of::child_c&lt; Expr, 2 &gt;::type &gt;::type, Context &gt;::type, typename <classname>proto::result_of::eval</classname>&lt; typename remove_reference&lt; typename proto::result_of::child_c&lt; Expr, 3 &gt;::type &gt;::type, Context &gt;::type)&gt;::type</type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type>result_type</type><pa
rameter name="expr"><paramtype>Expr &amp;</paramtype></parameter><parameter name="context"><paramtype>Context &amp;</paramtype></parameter></method></method-group></struct-specialization><struct-specialization name="default_eval"><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="Context"/>
+ </template><specialization><template-arg>Expr</template-arg><template-arg>Context</template-arg><template-arg>proto::tag::function</template-arg><template-arg>5</template-arg></specialization><typedef name="function_type"><type><emphasis>unspecified</emphasis></type></typedef><typedef name="result_type"><type>boost::result_of&lt; function_type(typename <classname>proto::result_of::eval</classname>&lt; typename remove_reference&lt; typename proto::result_of::child_c&lt; Expr, 1 &gt;::type &gt;::type, Context &gt;::type, typename <classname>proto::result_of::eval</classname>&lt; typename remove_reference&lt; typename proto::result_of::child_c&lt; Expr, 2 &gt;::type &gt;::type, Context &gt;::type, typename <classname>proto::result_of::eval</classname>&lt; typename remove_reference&lt; typename proto::result_of::child_c&lt; Expr, 3 &gt;::type &gt;::type, Context &gt;::type, typename <classname>proto::result_of::eval</classname>&lt; typename remove_reference&lt; typename proto::result_of::child_c&lt; Expr, 4
 &gt;::type &gt;::type, Context &gt;::type)&gt;::type</type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type>result_type</type><parameter name="expr"><paramtype>Expr &amp;</paramtype></parameter><parameter name="context"><paramtype>Context &amp;</paramtype></parameter></method></method-group></struct-specialization><struct name="default_context"><description><para>default_context </para></description><struct name="eval"><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="ThisContext"><default>default_context const</default></template-type-parameter>
+ </template><inherit access="public">boost::proto::context::default_eval&lt; Expr, ThisContext &gt;</inherit><description><para>default_context::eval </para></description></struct></struct></namespace></namespace></namespace></header><header name="boost/proto/context/null.hpp"><para>Definintion of null_context&lt;&gt;, an evaluation context for proto::eval() that simply evaluates each child expression, doesn't combine the results at all, and returns void. </para><namespace name="boost"><namespace name="proto"><namespace name="context"><struct name="null_eval"><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="Context"/>
+ <template-nontype-parameter name="Arity"><type>long</type><default>Expr::proto_arity::value</default></template-nontype-parameter>
+ </template></struct><struct-specialization name="null_eval"><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="Context"/>
+ </template><specialization><template-arg>Expr</template-arg><template-arg>Context</template-arg><template-arg>0</template-arg></specialization><typedef name="result_type"><type>void</type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type>void</type><parameter name=""><paramtype>Expr &amp;</paramtype></parameter><parameter name=""><paramtype>Context &amp;</paramtype></parameter></method></method-group></struct-specialization><struct-specialization name="null_eval"><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="Context"/>
+ </template><specialization><template-arg>Expr</template-arg><template-arg>Context</template-arg><template-arg>1</template-arg></specialization><typedef name="result_type"><type>void</type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type>void</type><parameter name="expr"><paramtype>Expr &amp;</paramtype></parameter><parameter name="ctx"><paramtype>Context &amp;</paramtype></parameter></method></method-group></struct-specialization><struct-specialization name="null_eval"><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="Context"/>
+ </template><specialization><template-arg>Expr</template-arg><template-arg>Context</template-arg><template-arg>2</template-arg></specialization><typedef name="result_type"><type>void</type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type>void</type><parameter name="expr"><paramtype>Expr &amp;</paramtype></parameter><parameter name="ctx"><paramtype>Context &amp;</paramtype></parameter></method></method-group></struct-specialization><struct-specialization name="null_eval"><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="Context"/>
+ </template><specialization><template-arg>Expr</template-arg><template-arg>Context</template-arg><template-arg>3</template-arg></specialization><typedef name="result_type"><type>void</type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type>void</type><parameter name="expr"><paramtype>Expr &amp;</paramtype></parameter><parameter name="ctx"><paramtype>Context &amp;</paramtype></parameter></method></method-group></struct-specialization><struct-specialization name="null_eval"><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="Context"/>
+ </template><specialization><template-arg>Expr</template-arg><template-arg>Context</template-arg><template-arg>4</template-arg></specialization><typedef name="result_type"><type>void</type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type>void</type><parameter name="expr"><paramtype>Expr &amp;</paramtype></parameter><parameter name="ctx"><paramtype>Context &amp;</paramtype></parameter></method></method-group></struct-specialization><struct-specialization name="null_eval"><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="Context"/>
+ </template><specialization><template-arg>Expr</template-arg><template-arg>Context</template-arg><template-arg>5</template-arg></specialization><typedef name="result_type"><type>void</type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type>void</type><parameter name="expr"><paramtype>Expr &amp;</paramtype></parameter><parameter name="ctx"><paramtype>Context &amp;</paramtype></parameter></method></method-group></struct-specialization><struct name="null_context"><description><para>null_context </para></description><struct name="eval"><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="ThisContext"><default>null_context const</default></template-type-parameter>
+ </template><inherit access="public">boost::proto::context::null_eval&lt; Expr, ThisContext &gt;</inherit><description><para>null_context::eval </para></description></struct></struct></namespace></namespace></namespace></header><header name="boost/proto/debug.hpp"><para>Utilities for debugging Proto expression trees </para><namespace name="boost"><namespace name="proto"><namespace name="functor"><struct name="display_expr"><purpose>Pretty-print a Proto expression tree. </purpose><description><para>A PolymorphicFunctionObject which accepts a Proto expression tree and pretty-prints it to an <computeroutput>ostream</computeroutput> for debugging purposes. </para></description><typedef name="result_type"><type>void</type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type>void</type><template>
+ <template-type-parameter name="Args"/>
+ </template><parameter name="expr"><paramtype>proto::expr&lt; <classname>tag::terminal</classname>, Args, 0 &gt; const &amp;</paramtype></parameter><purpose>Pretty-print the current node in a Proto expression tree. </purpose></method><method name="operator()" cv="const"><type>void</type><template>
+ <template-type-parameter name="Tag"/>
+ <template-type-parameter name="Args"/>
+ </template><parameter name="expr"><paramtype>proto::expr&lt; Tag, Args, 1 &gt; const &amp;</paramtype></parameter></method><method name="operator()" cv="const"><type>void</type><template>
+ <template-type-parameter name="Tag"/>
+ <template-type-parameter name="Args"/>
+ </template><parameter name="expr"><paramtype>proto::expr&lt; Tag, Args, 2 &gt; const &amp;</paramtype></parameter></method><method name="operator()" cv="const"><type>void</type><template>
+ <template-type-parameter name="Tag"/>
+ <template-type-parameter name="Args"/>
+ </template><parameter name="expr"><paramtype>proto::expr&lt; Tag, Args, 3 &gt; const &amp;</paramtype></parameter></method><method name="operator()" cv="const"><type>void</type><template>
+ <template-type-parameter name="Tag"/>
+ <template-type-parameter name="Args"/>
+ </template><parameter name="expr"><paramtype>proto::expr&lt; Tag, Args, 4 &gt; const &amp;</paramtype></parameter></method><method name="operator()" cv="const"><type>void</type><template>
+ <template-type-parameter name="Tag"/>
+ <template-type-parameter name="Args"/>
+ </template><parameter name="expr"><paramtype>proto::expr&lt; Tag, Args, 5 &gt; const &amp;</paramtype></parameter></method><method name="operator()" cv="const"><type>void</type><template>
+ <template-type-parameter name="T"/>
+ </template><parameter name="t"><paramtype>T const &amp;</paramtype></parameter><description><para>This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts. </para></description></method></method-group><constructor><parameter name="sout"><paramtype>std::ostream &amp;</paramtype><default>std::cout</default><description><para>The <computeroutput>ostream</computeroutput> to which the expression tree will be written. </para></description></parameter><parameter name="depth"><paramtype>int</paramtype><default>0</default><description><para>The starting indentation depth for this node. Children nodes will be displayed at a starting depth of <computeroutput>depth+4</computeroutput>. </para></description></parameter><description><para>
+</para></description></constructor><method-group name="private member functions"/><copy-assignment><parameter name=""><paramtype><classname>display_expr</classname> const &amp;</paramtype></parameter></copy-assignment></struct></namespace><namespace name="tag"><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::unary_plus</classname></paramtype></parameter></function><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::negate</classname></paramtype></parameter></function><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::dereference</classname></paramtype></parameter></function><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::complement</classname></paramtype></parameter></function><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::address_of</classname
></paramtype></parameter></function><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::logical_not</classname></paramtype></parameter></function><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::pre_inc</classname></paramtype></parameter></function><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::pre_dec</classname></paramtype></parameter></function><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::post_inc</classname></paramtype></parameter></function><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::post_dec</classname></paramtype></parameter></function><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::shift_left</classname></paramtype></parameter></function><function name="proto_tag_name"><typ
e>char const *</type><parameter name=""><paramtype><classname>tag::shift_right</classname></paramtype></parameter></function><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::multiplies</classname></paramtype></parameter></function><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::divides</classname></paramtype></parameter></function><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::modulus</classname></paramtype></parameter></function><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::plus</classname></paramtype></parameter></function><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::minus</classname></paramtype></parameter></function><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::less</classn
ame></paramtype></parameter></function><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::greater</classname></paramtype></parameter></function><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::less_equal</classname></paramtype></parameter></function><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::greater_equal</classname></paramtype></parameter></function><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::equal_to</classname></paramtype></parameter></function><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::not_equal_to</classname></paramtype></parameter></function><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::logical_or</classname></paramtype></parameter></function><function name="proto_ta
g_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::logical_and</classname></paramtype></parameter></function><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::bitwise_and</classname></paramtype></parameter></function><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::bitwise_or</classname></paramtype></parameter></function><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::bitwise_xor</classname></paramtype></parameter></function><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::comma</classname></paramtype></parameter></function><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::mem_ptr</classname></paramtype></parameter></function><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><clas
sname>tag::assign</classname></paramtype></parameter></function><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::shift_left_assign</classname></paramtype></parameter></function><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::shift_right_assign</classname></paramtype></parameter></function><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::multiplies_assign</classname></paramtype></parameter></function><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::divides_assign</classname></paramtype></parameter></function><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::modulus_assign</classname></paramtype></parameter></function><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::plus_assign</classname></p
aramtype></parameter></function><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::minus_assign</classname></paramtype></parameter></function><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::bitwise_and_assign</classname></paramtype></parameter></function><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::bitwise_or_assign</classname></paramtype></parameter></function><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::bitwise_xor_assign</classname></paramtype></parameter></function><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::subscript</classname></paramtype></parameter></function><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::if_else_</classname></paramtype></parameter></function><function
 name="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::function</classname></paramtype></parameter></function></namespace><overloaded-function name="display_expr"><signature><type>void</type><template>
+ <template-type-parameter name="Expr"/>
+ </template><parameter name="expr"><paramtype>Expr const &amp;</paramtype><description><para>The Proto expression tree to pretty-print </para></description></parameter><parameter name="sout"><paramtype>std::ostream &amp;</paramtype><description><para>The <computeroutput>ostream</computeroutput> to which the output should be written. If not specified, defaults to <computeroutput>std::cout</computeroutput>. </para></description></parameter></signature><signature><type>void</type><template>
+ <template-type-parameter name="Expr"/>
+ </template><parameter name="expr"><paramtype>Expr const &amp;</paramtype></parameter></signature><purpose>Pretty-print a Proto expression tree. </purpose><description><para>
+
+</para></description><notes><para>Equivalent to <computeroutput>functor::display_expr(0, sout)(expr)</computeroutput> </para></notes></overloaded-function></namespace></namespace></header><header name="boost/proto/deep_copy.hpp"><para>Replace all nodes stored by reference by nodes stored by value. </para><namespace name="boost"><namespace name="proto"><namespace name="functor"><struct name="deep_copy"><purpose>A PolymorphicFunctionObject type for deep-copying Proto expression trees. </purpose><description><para>A PolymorphicFunctionObject type for deep-copying Proto expression trees. When a tree is deep-copied, all internal nodes and most terminals held by reference are instead held by value.</para><para>
+</para></description><struct-specialization name="result"><template>
+ <template-type-parameter name="This"/>
+ <template-type-parameter name="Expr"/>
+ </template><specialization><template-arg>This(Expr)</template-arg></specialization><typedef name="type"><type><classname>result_of::deep_copy</classname>&lt; typename boost::remove_const&lt; typename boost::remove_reference&lt; Expr &gt;::type &gt;::type &gt;::type</type></typedef></struct-specialization><typedef name="proto_is_callable_"><type>void</type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type><classname>result_of::deep_copy</classname>&lt; Expr &gt;::type</type><template>
+ <template-type-parameter name="Expr"/>
+ </template><parameter name="expr"><paramtype>Expr const &amp;</paramtype></parameter><purpose>Deep-copies a Proto expression tree, turning all nodes and terminals held by reference into ones held by value. </purpose></method></method-group></struct></namespace><namespace name="result_of"><struct name="deep_copy"><template>
+ <template-type-parameter name="Expr"/>
+ </template><purpose>A metafunction for calculating the return type of <computeroutput>proto::deep_copy()</computeroutput>. </purpose><description><para>A metafunction for calculating the return type of <computeroutput>proto::deep_copy()</computeroutput>. The type parameter <computeroutput>Expr</computeroutput> should be the type of a Proto expression tree. It should not be a reference type, nor should it be cv-qualified. </para></description><typedef name="type"><type><emphasis>unspecified</emphasis></type></typedef></struct></namespace><function name="deep_copy"><type><classname>proto::result_of::deep_copy</classname>&lt; Expr &gt;::type</type><template>
+ <template-type-parameter name="Expr"/>
+ </template><parameter name="expr"><paramtype>Expr const &amp;</paramtype></parameter><purpose>A function for deep-copying Proto expression trees. </purpose><description><para>A function for deep-copying Proto expression trees. When a tree is deep-copied, all internal nodes and most terminals held by reference are instead held by value.</para><para>
+<para>proto::functor::deep_copy. </para>
+</para></description><notes><para>Terminals of reference-to-array type and of reference-to-function type are left unchanged.</para></notes></function></namespace></namespace></header><header name="boost/proto/domain.hpp"><para>Contains definition of domain&lt;&gt; class template and helpers for defining domains with a generator and a grammar for controlling operator overloading. </para><namespace name="boost"><namespace name="proto"><struct name="domain"><template>
+ <template-type-parameter name="Generator"><default>default_generator</default></template-type-parameter>
+ <template-type-parameter name="Grammar"><default>proto::_</default></template-type-parameter>
+ </template><purpose>For use in defining domain tags to be used with <computeroutput>proto::extends&lt;&gt;</computeroutput>. A Domain associates an expression type with a Generator, and optionally a Grammar. </purpose><description><para>The Generator determines how new expressions in the domain are constructed. Typically, a generator wraps all new expressions in a wrapper that imparts domain-specific behaviors to expressions within its domain. (See <computeroutput>proto::extends&lt;&gt;</computeroutput>.)</para><para>The Grammar determines whether a given expression is valid within the domain, and automatically disables any operator overloads which would cause an invalid expression to be created. By default, the Grammar parameter defaults to the wildcard, <computeroutput>proto::_</computeroutput>, which makes all expressions valid within the domain.</para><para>Example: <programlisting> template&lt;typename Expr&gt;
+ struct MyExpr;
+
+ struct MyGrammar
+ : or_&lt; terminal&lt;_&gt;, plus&lt;MyGrammar, MyGrammar&gt; &gt;
+ {};
+
+ // Define MyDomain, in which all expressions are
+ // wrapped in MyExpr&lt;&gt; and only expressions that
+ // conform to MyGrammar are allowed.
+ struct MyDomain
+ : domain&lt;generator&lt;MyExpr&gt;, MyGrammar&gt;
+ {};
+
+ // Use MyDomain to define MyExpr
+ template&lt;typename Expr&gt;
+ struct MyExpr
+ : extends&lt;Expr, MyExpr&lt;Expr&gt;, MyDomain&gt;
+ {
+ // ...
+ };
+</programlisting> </para></description><typedef name="proto_grammar"><type>Grammar</type></typedef><typedef name="proto_is_domain_"><type>void</type></typedef></struct><struct name="default_domain"><inherit access="public">boost::proto::domain&lt; Generator, Grammar &gt;</inherit><purpose>The domain expressions have by default, if <computeroutput>proto::extends&lt;&gt;</computeroutput> has not been used to associate a domain with an expression. </purpose></struct><struct name="deduce_domain"><inherit access="public">boost::proto::domain&lt; Generator, Grammar &gt;</inherit><purpose>A pseudo-domain for use in functions and metafunctions that require a domain parameter. It indicates that the domain of the parent node should be inferred from the domains of the child nodes. </purpose><description><para>
+</para></description></struct><namespace name="result_of"><struct name="is_domain"><template>
+ <template-type-parameter name="T"/>
+ <template-type-parameter name="Void"><default>void</default></template-type-parameter>
+ </template><inherit access="public">boost::mpl::false_</inherit><description><para>A metafunction that returns <computeroutput>mpl::true_</computeroutput> if the type <computeroutput>T</computeroutput> is the type of a Proto domain; <computeroutput>mpl::false_</computeroutput> otherwise. If <computeroutput>T</computeroutput> inherits from <computeroutput>proto::domain&lt;&gt;</computeroutput>, <computeroutput>is_domain&lt;T&gt;</computeroutput> is <computeroutput>mpl::true_</computeroutput>. </para></description></struct><struct name="domain_of"><template>
+ <template-type-parameter name="T"/>
+ <template-type-parameter name="Void"><default>void</default></template-type-parameter>
+ </template><description><para>A metafunction that returns the domain of a given type. If <computeroutput>T</computeroutput> is a Proto expression type, it returns that expression's associated domain. If not, it returns <computeroutput>proto::default_domain</computeroutput>. </para></description><typedef name="type"><type><classname>default_domain</classname></type></typedef></struct></namespace></namespace></namespace></header><header name="boost/proto/eval.hpp"><para>Contains the eval() expression evaluator. </para><namespace name="boost"><namespace name="proto"><namespace name="functor"><struct name="eval"><purpose>A PolymorphicFunctionObject type for evaluating a given Proto expression with a given context. </purpose><struct-specialization name="result"><template>
+ <template-type-parameter name="This"/>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="Context"/>
+ </template><specialization><template-arg>This(Expr</template-arg><template-arg>Context)</template-arg></specialization><typedef name="type"><type><classname>proto::result_of::eval</classname>&lt; typename remove_reference&lt; Expr &gt;::type, typename remove_reference&lt; Context &gt;::type &gt;::type</type></typedef></struct-specialization><typedef name="proto_is_callable_"><type>void</type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type><classname>proto::result_of::eval</classname>&lt; Expr, Context &gt;::type</type><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="Context"/>
+ </template><parameter name="expr"><paramtype>Expr &amp;</paramtype><description><para>The Proto expression to evaluate </para></description></parameter><parameter name="context"><paramtype>Context &amp;</paramtype><description><para>The context in which the expression should be evaluated. </para></description></parameter><purpose>Evaluate a given Proto expression with a given context. </purpose><description><para>
+
+</para></description><returns><para><computeroutput>typename Context::template eval&lt;Expr&gt;()(expr, context)</computeroutput> </para></returns></method><method name="operator()" cv="const"><type><classname>proto::result_of::eval</classname>&lt; Expr, Context &gt;::type</type><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="Context"/>
+ </template><parameter name="expr"><paramtype>Expr &amp;</paramtype></parameter><parameter name="context"><paramtype>Context const &amp;</paramtype></parameter><description><para>This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts. </para></description></method></method-group></struct></namespace><namespace name="result_of"><struct name="eval"><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="Context"/>
+ </template><purpose>A metafunction for calculating the return type of <computeroutput>proto::eval()</computeroutput> given a certain <computeroutput>Expr</computeroutput> and <computeroutput>Context</computeroutput> types. </purpose><description><para>
+</para></description><typedef name="type"><type>Context::template <classname>eval</classname>&lt; Expr &gt;::result_type</type></typedef></struct></namespace><overloaded-function name="eval"><signature><type><classname>proto::result_of::eval</classname>&lt; Expr, Context &gt;::type</type><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="Context"/>
+ </template><parameter name="expr"><paramtype>Expr &amp;</paramtype><description><para>The Proto expression to evaluate </para></description></parameter><parameter name="context"><paramtype>Context &amp;</paramtype><description><para>The context in which the expression should be evaluated. </para></description></parameter></signature><signature><type><classname>proto::result_of::eval</classname>&lt; Expr, Context &gt;::type</type><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="Context"/>
+ </template><parameter name="expr"><paramtype>Expr &amp;</paramtype></parameter><parameter name="context"><paramtype>Context const &amp;</paramtype></parameter></signature><purpose>Evaluate a given Proto expression with a given context. </purpose><description><para>
+
+</para></description><returns><para><computeroutput>typename Context::template eval&lt;Expr&gt;()(expr, context)</computeroutput> </para></returns></overloaded-function></namespace></namespace></header><header name="boost/proto/expr.hpp"><para>Contains definition of expr&lt;&gt; class template. </para><namespace name="boost"><namespace name="proto"><struct-specialization name="expr"><template>
+ <template-type-parameter name="Tag"/>
+ <template-type-parameter name="Args"/>
+ </template><specialization><template-arg>Tag</template-arg><template-arg>Args</template-arg><template-arg>0</template-arg></specialization><purpose>Representation of a node in an expression tree. </purpose><description><para><computeroutput>proto::expr&lt;&gt;</computeroutput> is a node in an expression template tree. It is a container for its child sub-trees. It also serves as the terminal nodes of the tree.</para><para><computeroutput>Tag</computeroutput> is type that represents the operation encoded by this expression. It is typically one of the structs in the <computeroutput>boost::proto::tag</computeroutput> namespace, but it doesn't have to be. If the <computeroutput>Tag</computeroutput> type is <computeroutput>boost::proto::tag::terminal</computeroutput> then this <computeroutput>expr&lt;&gt;</computeroutput> type represents a leaf in the expression tree.</para><para><computeroutput>Args</computeroutput> is a type list representing the type of the children of this expression. It is an instantiati
on of one of <computeroutput>proto::list1&lt;&gt;</computeroutput>, <computeroutput>proto::list2&lt;&gt;</computeroutput>, etc. The child types must all themselves be either <computeroutput>expr&lt;&gt;</computeroutput> or <computeroutput>proto::ref_&lt;proto::expr&lt;&gt;&gt;</computeroutput>, unless the <computeroutput>Tag</computeroutput> type is <computeroutput>boost::proto::tag::terminal</computeroutput>, in which case <computeroutput>Args</computeroutput> must be <computeroutput>proto::term&lt;T&gt;</computeroutput>, where <computeroutput>T</computeroutput> can be any type.</para><para><computeroutput>proto::expr&lt;&gt;</computeroutput> is a valid Fusion random-access sequence, where the elements of the sequence are the child expressions. </para></description><struct name="result"><template>
+ <template-type-parameter name="Sig"/>
+ </template><description><para>Encodes the return type of <computeroutput>expr&lt;&gt;operator()</computeroutput>, for use with <computeroutput>boost::result_of&lt;&gt;</computeroutput> </para></description><typedef name="type"><type>result_of::funop&lt; Sig, expr, <classname>default_domain</classname> &gt;::type</type></typedef></struct><typedef name="proto_tag"><type>Tag</type></typedef><typedef name="proto_arity"><type>mpl::long_&lt; 0 &gt;</type></typedef><typedef name="proto_base_expr"><type>expr</type></typedef><typedef name="proto_args"><type>Args</type></typedef><typedef name="proto_domain"><type><classname>default_domain</classname></type></typedef><typedef name="fusion_tag"><type>proto::tag::proto_expr</type></typedef><typedef name="proto_is_expr_"><type>void</type></typedef><typedef name="proto_derived_expr"><type>expr</type></typedef><typedef name="proto_child0"><type>Args::child0</type></typedef><typedef name="proto_child1"><type>void</type></typedef><typedef name="proto_child2"><type>void</
type></typedef><typedef name="proto_child3"><type>void</type></typedef><typedef name="proto_child4"><type>void</type></typedef><data-member name="child0"><type>proto_child0</type></data-member><method-group name="public member functions"><method name="proto_base" cv="const"><type>expr const &amp;</type><description><para>
+</para></description><returns><para>*this </para></returns></method><method name="proto_base" cv=""><type>expr &amp;</type><description><para>This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts. </para></description></method><method name="operator[]" cv="const"><type>proto::expr&lt; <classname>proto::tag::subscript</classname>, <classname>list2</classname>&lt; <classname>ref_</classname>&lt; expr const &gt;, typename <classname>result_of::as_child</classname>&lt; A &gt;::type &gt; &gt; const</type><template>
+ <template-type-parameter name="A"/>
+ </template><parameter name="a"><paramtype>A &amp;</paramtype><description><para>The rhs. </para></description></parameter><description><para>Subscript</para><para>
+
+</para></description><returns><para>A new <computeroutput>expr&lt;&gt;</computeroutput> node representing <computeroutput>*this</computeroutput> subscripted with <computeroutput>a</computeroutput>. </para></returns></method><method name="operator[]" cv="const"><type>proto::expr&lt; <classname>proto::tag::subscript</classname>, <classname>list2</classname>&lt; <classname>ref_</classname>&lt; expr const &gt;, typename <classname>result_of::as_child</classname>&lt; A const &gt;::type &gt; &gt; const</type><template>
+ <template-type-parameter name="A"/>
+ </template><parameter name="a"><paramtype>A const &amp;</paramtype></parameter><description><para>This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts. </para></description></method><method name="operator[]" cv=""><type>proto::expr&lt; <classname>proto::tag::subscript</classname>, <classname>list2</classname>&lt; <classname>ref_</classname>&lt; expr &gt;, typename <classname>result_of::as_child</classname>&lt; A &gt;::type &gt; &gt; const</type><template>
+ <template-type-parameter name="A"/>
+ </template><parameter name="a"><paramtype>A &amp;</paramtype></parameter><description><para>This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts. </para></description></method><method name="operator[]" cv=""><type>proto::expr&lt; <classname>proto::tag::subscript</classname>, <classname>list2</classname>&lt; <classname>ref_</classname>&lt; expr &gt;, typename <classname>result_of::as_child</classname>&lt; A const &gt;::type &gt; &gt; const</type><template>
+ <template-type-parameter name="A"/>
+ </template><parameter name="a"><paramtype>A const &amp;</paramtype></parameter><description><para>This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts. </para></description></method><method name="operator()" cv="const"><type>proto::expr&lt; <classname>proto::tag::function</classname>, <classname>list1</classname>&lt; <classname>ref_</classname>&lt; expr const &gt; &gt; &gt; const</type><description><para>Function call</para><para>
+</para></description><returns><para>A new <computeroutput>expr&lt;&gt;</computeroutput> node representing the function invocation of <computeroutput/>(*this)(). </para></returns></method><method name="operator()" cv=""><type>proto::expr&lt; <classname>proto::tag::function</classname>, <classname>list1</classname>&lt; <classname>ref_</classname>&lt; expr &gt; &gt; &gt; const</type><description><para>This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts. </para></description></method><method name="operator()" cv="const"><type><classname>result_of::funop1</classname>&lt; expr const, <classname>default_domain</classname>, const A0 &gt;::type const</type><template>
+ <template-type-parameter name="A0"/>
+ </template><parameter name="a0"><paramtype>A0 const &amp;</paramtype></parameter><description><para>This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts. </para></description></method><method name="operator()" cv="const"><type><classname>result_of::funop2</classname>&lt; expr const, <classname>default_domain</classname>, const A0, const A1 &gt;::type const</type><template>
+ <template-type-parameter name="A0"/>
+ <template-type-parameter name="A1"/>
+ </template><parameter name="a0"><paramtype>A0 const &amp;</paramtype></parameter><parameter name="a1"><paramtype>A1 const &amp;</paramtype></parameter><description><para>This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts. </para></description></method><method name="operator()" cv="const"><type><classname>result_of::funop3</classname>&lt; expr const, <classname>default_domain</classname>, const A0, const A1, const A2 &gt;::type const</type><template>
+ <template-type-parameter name="A0"/>
+ <template-type-parameter name="A1"/>
+ <template-type-parameter name="A2"/>
+ </template><parameter name="a0"><paramtype>A0 const &amp;</paramtype></parameter><parameter name="a1"><paramtype>A1 const &amp;</paramtype></parameter><parameter name="a2"><paramtype>A2 const &amp;</paramtype></parameter><description><para>This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts. </para></description></method><method name="operator()" cv="const"><type><classname>result_of::funop4</classname>&lt; expr const, <classname>default_domain</classname>, const A0, const A1, const A2, const A3 &gt;::type const</type><template>
+ <template-type-parameter name="A0"/>
+ <template-type-parameter name="A1"/>
+ <template-type-parameter name="A2"/>
+ <template-type-parameter name="A3"/>
+ </template><parameter name="a0"><paramtype>A0 const &amp;</paramtype></parameter><parameter name="a1"><paramtype>A1 const &amp;</paramtype></parameter><parameter name="a2"><paramtype>A2 const &amp;</paramtype></parameter><parameter name="a3"><paramtype>A3 const &amp;</paramtype></parameter><description><para>This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts. </para></description></method></method-group><copy-assignment><template>
+ <template-type-parameter name="A"/>
+ </template><parameter name="a"><paramtype>A &amp;</paramtype><description><para>The rhs. </para></description></parameter><description><para>Assignment</para><para>
+
+</para></description><returns><para>A new <computeroutput>expr&lt;&gt;</computeroutput> node representing an assignment of <computeroutput>a</computeroutput> to <computeroutput>*this</computeroutput>. </para></returns></copy-assignment><copy-assignment><template>
+ <template-type-parameter name="A"/>
+ </template><parameter name="a"><paramtype>A const &amp;</paramtype></parameter><description><para>This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts. </para></description></copy-assignment><copy-assignment><template>
+ <template-type-parameter name="A"/>
+ </template><parameter name="a"><paramtype>A &amp;</paramtype></parameter><description><para>This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts. </para></description></copy-assignment><copy-assignment><template>
+ <template-type-parameter name="A"/>
+ </template><parameter name="a"><paramtype>A const &amp;</paramtype></parameter><description><para>This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts. </para></description></copy-assignment><method-group name="public static functions"><method name="make" cv=""><type>static expr</type><template>
+ <template-type-parameter name="A0"/>
+ </template><parameter name="a0"><paramtype>A0 const &amp;</paramtype></parameter><description><para>
+</para></description><returns><para>A new <computeroutput>expr&lt;&gt;</computeroutput> object initialized with the specified arguments. </para></returns></method><method name="make" cv=""><type>static expr</type><template>
+ <template-type-parameter name="A0"/>
+ </template><parameter name="a0"><paramtype>A0 &amp;</paramtype></parameter><description><para>This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts. </para></description></method><method name="make" cv=""><type>static expr</type><template>
+ <template-type-parameter name="A0"/>
+ <template-nontype-parameter name="N"><type>std::size_t</type></template-nontype-parameter>
+ </template><parameter name="a0"><paramtype>A0 &amp;</paramtype></parameter><parameter name=""><paramtype><emphasis>unspecified</emphasis></paramtype><default>0</default></parameter><description><para>This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts. </para></description></method><method name="make" cv=""><type>static expr</type><template>
+ <template-type-parameter name="A0"/>
+ <template-nontype-parameter name="N"><type>std::size_t</type></template-nontype-parameter>
+ </template><parameter name="a0"><paramtype>A0 const &amp;</paramtype></parameter><parameter name=""><paramtype><emphasis>unspecified</emphasis></paramtype><default>0</default></parameter><description><para>This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts. </para></description></method></method-group></struct-specialization><struct-specialization name="expr"><template>
+ <template-type-parameter name="Tag"/>
+ <template-type-parameter name="Args"/>
+ </template><specialization><template-arg>Tag</template-arg><template-arg>Args</template-arg><template-arg>1</template-arg></specialization><purpose>Representation of a node in an expression tree. </purpose><description><para><computeroutput>proto::expr&lt;&gt;</computeroutput> is a node in an expression template tree. It is a container for its child sub-trees. It also serves as the terminal nodes of the tree.</para><para><computeroutput>Tag</computeroutput> is type that represents the operation encoded by this expression. It is typically one of the structs in the <computeroutput>boost::proto::tag</computeroutput> namespace, but it doesn't have to be. If the <computeroutput>Tag</computeroutput> type is <computeroutput>boost::proto::tag::terminal</computeroutput> then this <computeroutput>expr&lt;&gt;</computeroutput> type represents a leaf in the expression tree.</para><para><computeroutput>Args</computeroutput> is a type list representing the type of the children of this expression. It is an instantiati
on of one of <computeroutput>proto::list1&lt;&gt;</computeroutput>, <computeroutput>proto::list2&lt;&gt;</computeroutput>, etc. The child types must all themselves be either <computeroutput>expr&lt;&gt;</computeroutput> or <computeroutput>proto::ref_&lt;proto::expr&lt;&gt;&gt;</computeroutput>, unless the <computeroutput>Tag</computeroutput> type is <computeroutput>boost::proto::tag::terminal</computeroutput>, in which case <computeroutput>Args</computeroutput> must be <computeroutput>proto::term&lt;T&gt;</computeroutput>, where <computeroutput>T</computeroutput> can be any type.</para><para><computeroutput>proto::expr&lt;&gt;</computeroutput> is a valid Fusion random-access sequence, where the elements of the sequence are the child expressions. </para></description><struct name="result"><template>
+ <template-type-parameter name="Sig"/>
+ </template><description><para>Encodes the return type of <computeroutput>expr&lt;&gt;operator()</computeroutput>, for use with <computeroutput>boost::result_of&lt;&gt;</computeroutput> </para></description><typedef name="type"><type>result_of::funop&lt; Sig, expr, <classname>default_domain</classname> &gt;::type</type></typedef></struct><typedef name="proto_tag"><type>Tag</type></typedef><typedef name="proto_arity"><type>mpl::long_&lt; 1 &gt;</type></typedef><typedef name="proto_base_expr"><type>expr</type></typedef><typedef name="proto_args"><type>Args</type></typedef><typedef name="proto_domain"><type><classname>default_domain</classname></type></typedef><typedef name="fusion_tag"><type>proto::tag::proto_expr</type></typedef><typedef name="proto_is_expr_"><type>void</type></typedef><typedef name="proto_derived_expr"><type>expr</type></typedef><typedef name="proto_child0"><type>Args::child0</type></typedef><typedef name="proto_child1"><type>void</type></typedef><typedef name="proto_child2"><type>void</
type></typedef><typedef name="proto_child3"><type>void</type></typedef><typedef name="proto_child4"><type>void</type></typedef><typedef name="address_of_hack_type_"><description><para>If <computeroutput>Tag</computeroutput> is <computeroutput>boost::proto::tag::address_of</computeroutput> and <computeroutput>proto_child0</computeroutput> is <computeroutput>proto::ref_&lt;T&gt;</computeroutput>, then <computeroutput>address_of_hack_type_</computeroutput> is <computeroutput>T*</computeroutput>. Otherwise, it is some undefined type. </para></description><type><emphasis>unspecified</emphasis></type></typedef><data-member name="child0"><type>proto_child0</type></data-member><method-group name="public member functions"><method name="proto_base" cv="const"><type>expr const &amp;</type><description><para>
+</para></description><returns><para>*this </para></returns></method><method name="proto_base" cv=""><type>expr &amp;</type><description><para>This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts. </para></description></method><method name="conversion-operator" cv="const"><type>address_of_hack_type_</type><description><para>
+
+</para></description><returns><para>The address of <computeroutput>this-&gt;child0</computeroutput> if <computeroutput>Tag</computeroutput> is <computeroutput>boost::proto::tag::address_of</computeroutput>. Otherwise, this function will fail to compile.</para></returns><notes><para>Proto overloads <computeroutput>operator&amp;</computeroutput>, which means that proto-ified objects cannot have their addresses taken, unless we use the following hack to make <computeroutput>&amp;x</computeroutput> implicitly convertible to <computeroutput>X*</computeroutput>. </para></notes></method><method name="operator[]" cv="const"><type>proto::expr&lt; <classname>proto::tag::subscript</classname>, <classname>list2</classname>&lt; <classname>ref_</classname>&lt; expr const &gt;, typename <classname>result_of::as_child</classname>&lt; A &gt;::type &gt; &gt; const</type><template>
+ <template-type-parameter name="A"/>
+ </template><parameter name="a"><paramtype>A &amp;</paramtype><description><para>The rhs. </para></description></parameter><description><para>Subscript</para><para>
+
+</para></description><returns><para>A new <computeroutput>expr&lt;&gt;</computeroutput> node representing <computeroutput>*this</computeroutput> subscripted with <computeroutput>a</computeroutput>. </para></returns></method><method name="operator[]" cv="const"><type>proto::expr&lt; <classname>proto::tag::subscript</classname>, <classname>list2</classname>&lt; <classname>ref_</classname>&lt; expr const &gt;, typename <classname>result_of::as_child</classname>&lt; A const &gt;::type &gt; &gt; const</type><template>
+ <template-type-parameter name="A"/>
+ </template><parameter name="a"><paramtype>A const &amp;</paramtype></parameter><description><para>This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts. </para></description></method><method name="operator()" cv="const"><type>proto::expr&lt; <classname>proto::tag::function</classname>, <classname>list1</classname>&lt; <classname>ref_</classname>&lt; expr const &gt; &gt; &gt; const</type><description><para>Function call</para><para>
+</para></description><returns><para>A new <computeroutput>expr&lt;&gt;</computeroutput> node representing the function invocation of <computeroutput/>(*this)(). </para></returns></method><method name="operator()" cv="const"><type><classname>result_of::funop1</classname>&lt; expr const, <classname>default_domain</classname>, const A0 &gt;::type const</type><template>
+ <template-type-parameter name="A0"/>
+ </template><parameter name="a0"><paramtype>A0 const &amp;</paramtype></parameter><description><para>This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts. </para></description></method><method name="operator()" cv="const"><type><classname>result_of::funop2</classname>&lt; expr const, <classname>default_domain</classname>, const A0, const A1 &gt;::type const</type><template>
+ <template-type-parameter name="A0"/>
+ <template-type-parameter name="A1"/>
+ </template><parameter name="a0"><paramtype>A0 const &amp;</paramtype></parameter><parameter name="a1"><paramtype>A1 const &amp;</paramtype></parameter><description><para>This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts. </para></description></method><method name="operator()" cv="const"><type><classname>result_of::funop3</classname>&lt; expr const, <classname>default_domain</classname>, const A0, const A1, const A2 &gt;::type const</type><template>
+ <template-type-parameter name="A0"/>
+ <template-type-parameter name="A1"/>
+ <template-type-parameter name="A2"/>
+ </template><parameter name="a0"><paramtype>A0 const &amp;</paramtype></parameter><parameter name="a1"><paramtype>A1 const &amp;</paramtype></parameter><parameter name="a2"><paramtype>A2 const &amp;</paramtype></parameter><description><para>This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts. </para></description></method><method name="operator()" cv="const"><type><classname>result_of::funop4</classname>&lt; expr const, <classname>default_domain</classname>, const A0, const A1, const A2, const A3 &gt;::type const</type><template>
+ <template-type-parameter name="A0"/>
+ <template-type-parameter name="A1"/>
+ <template-type-parameter name="A2"/>
+ <template-type-parameter name="A3"/>
+ </template><parameter name="a0"><paramtype>A0 const &amp;</paramtype></parameter><parameter name="a1"><paramtype>A1 const &amp;</paramtype></parameter><parameter name="a2"><paramtype>A2 const &amp;</paramtype></parameter><parameter name="a3"><paramtype>A3 const &amp;</paramtype></parameter><description><para>This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts. </para></description></method></method-group><copy-assignment><template>
+ <template-type-parameter name="A"/>
+ </template><parameter name="a"><paramtype>A &amp;</paramtype><description><para>The rhs. </para></description></parameter><description><para>Assignment</para><para>
+
+</para></description><returns><para>A new <computeroutput>expr&lt;&gt;</computeroutput> node representing an assignment of <computeroutput>a</computeroutput> to <computeroutput>*this</computeroutput>. </para></returns></copy-assignment><copy-assignment><template>
+ <template-type-parameter name="A"/>
+ </template><parameter name="a"><paramtype>A const &amp;</paramtype></parameter><description><para>This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts. </para></description></copy-assignment><method-group name="public static functions"><method name="make" cv=""><type>static expr</type><template>
+ <template-type-parameter name="A0"/>
+ </template><parameter name="a0"><paramtype>A0 const &amp;</paramtype></parameter><description><para>
+</para></description><returns><para>A new <computeroutput>expr&lt;&gt;</computeroutput> object initialized with the specified arguments. </para></returns></method></method-group></struct-specialization><struct-specialization name="expr"><template>
+ <template-type-parameter name="Tag"/>
+ <template-type-parameter name="Args"/>
+ </template><specialization><template-arg>Tag</template-arg><template-arg>Args</template-arg><template-arg>2</template-arg></specialization><purpose>Representation of a node in an expression tree. </purpose><description><para><computeroutput>proto::expr&lt;&gt;</computeroutput> is a node in an expression template tree. It is a container for its child sub-trees. It also serves as the terminal nodes of the tree.</para><para><computeroutput>Tag</computeroutput> is type that represents the operation encoded by this expression. It is typically one of the structs in the <computeroutput>boost::proto::tag</computeroutput> namespace, but it doesn't have to be. If the <computeroutput>Tag</computeroutput> type is <computeroutput>boost::proto::tag::terminal</computeroutput> then this <computeroutput>expr&lt;&gt;</computeroutput> type represents a leaf in the expression tree.</para><para><computeroutput>Args</computeroutput> is a type list representing the type of the children of this expression. It is an instantiati
on of one of <computeroutput>proto::list1&lt;&gt;</computeroutput>, <computeroutput>proto::list2&lt;&gt;</computeroutput>, etc. The child types must all themselves be either <computeroutput>expr&lt;&gt;</computeroutput> or <computeroutput>proto::ref_&lt;proto::expr&lt;&gt;&gt;</computeroutput>, unless the <computeroutput>Tag</computeroutput> type is <computeroutput>boost::proto::tag::terminal</computeroutput>, in which case <computeroutput>Args</computeroutput> must be <computeroutput>proto::term&lt;T&gt;</computeroutput>, where <computeroutput>T</computeroutput> can be any type.</para><para><computeroutput>proto::expr&lt;&gt;</computeroutput> is a valid Fusion random-access sequence, where the elements of the sequence are the child expressions. </para></description><struct name="result"><template>
+ <template-type-parameter name="Sig"/>
+ </template><description><para>Encodes the return type of <computeroutput>expr&lt;&gt;operator()</computeroutput>, for use with <computeroutput>boost::result_of&lt;&gt;</computeroutput> </para></description><typedef name="type"><type>result_of::funop&lt; Sig, expr, <classname>default_domain</classname> &gt;::type</type></typedef></struct><typedef name="proto_tag"><type>Tag</type></typedef><typedef name="proto_arity"><type>mpl::long_&lt; 2 &gt;</type></typedef><typedef name="proto_base_expr"><type>expr</type></typedef><typedef name="proto_args"><type>Args</type></typedef><typedef name="proto_domain"><type><classname>default_domain</classname></type></typedef><typedef name="fusion_tag"><type>proto::tag::proto_expr</type></typedef><typedef name="proto_is_expr_"><type>void</type></typedef><typedef name="proto_derived_expr"><type>expr</type></typedef><typedef name="proto_child0"><type>Args::child0</type></typedef><typedef name="proto_child1"><type>Args::child1</type></typedef><typedef name="proto_child2"><typ
e>void</type></typedef><typedef name="proto_child3"><type>void</type></typedef><typedef name="proto_child4"><type>void</type></typedef><data-member name="child0"><type>proto_child0</type></data-member><data-member name="child1"><type>proto_child1</type></data-member><method-group name="public member functions"><method name="proto_base" cv="const"><type>expr const &amp;</type><description><para>
+</para></description><returns><para>*this </para></returns></method><method name="proto_base" cv=""><type>expr &amp;</type><description><para>This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts. </para></description></method><method name="operator[]" cv="const"><type>proto::expr&lt; <classname>proto::tag::subscript</classname>, <classname>list2</classname>&lt; <classname>ref_</classname>&lt; expr const &gt;, typename <classname>result_of::as_child</classname>&lt; A &gt;::type &gt; &gt; const</type><template>
+ <template-type-parameter name="A"/>
+ </template><parameter name="a"><paramtype>A &amp;</paramtype><description><para>The rhs. </para></description></parameter><description><para>Subscript</para><para>
+
+</para></description><returns><para>A new <computeroutput>expr&lt;&gt;</computeroutput> node representing <computeroutput>*this</computeroutput> subscripted with <computeroutput>a</computeroutput>. </para></returns></method><method name="operator[]" cv="const"><type>proto::expr&lt; <classname>proto::tag::subscript</classname>, <classname>list2</classname>&lt; <classname>ref_</classname>&lt; expr const &gt;, typename <classname>result_of::as_child</classname>&lt; A const &gt;::type &gt; &gt; const</type><template>
+ <template-type-parameter name="A"/>
+ </template><parameter name="a"><paramtype>A const &amp;</paramtype></parameter><description><para>This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts. </para></description></method><method name="operator()" cv="const"><type>proto::expr&lt; <classname>proto::tag::function</classname>, <classname>list1</classname>&lt; <classname>ref_</classname>&lt; expr const &gt; &gt; &gt; const</type><description><para>Function call</para><para>
+</para></description><returns><para>A new <computeroutput>expr&lt;&gt;</computeroutput> node representing the function invocation of <computeroutput/>(*this)(). </para></returns></method><method name="operator()" cv="const"><type><classname>result_of::funop1</classname>&lt; expr const, <classname>default_domain</classname>, const A0 &gt;::type const</type><template>
+ <template-type-parameter name="A0"/>
+ </template><parameter name="a0"><paramtype>A0 const &amp;</paramtype></parameter><description><para>This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts. </para></description></method><method name="operator()" cv="const"><type><classname>result_of::funop2</classname>&lt; expr const, <classname>default_domain</classname>, const A0, const A1 &gt;::type const</type><template>
+ <template-type-parameter name="A0"/>
+ <template-type-parameter name="A1"/>
+ </template><parameter name="a0"><paramtype>A0 const &amp;</paramtype></parameter><parameter name="a1"><paramtype>A1 const &amp;</paramtype></parameter><description><para>This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts. </para></description></method><method name="operator()" cv="const"><type><classname>result_of::funop3</classname>&lt; expr const, <classname>default_domain</classname>, const A0, const A1, const A2 &gt;::type const</type><template>
+ <template-type-parameter name="A0"/>
+ <template-type-parameter name="A1"/>
+ <template-type-parameter name="A2"/>
+ </template><parameter name="a0"><paramtype>A0 const &amp;</paramtype></parameter><parameter name="a1"><paramtype>A1 const &amp;</paramtype></parameter><parameter name="a2"><paramtype>A2 const &amp;</paramtype></parameter><description><para>This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts. </para></description></method><method name="operator()" cv="const"><type><classname>result_of::funop4</classname>&lt; expr const, <classname>default_domain</classname>, const A0, const A1, const A2, const A3 &gt;::type const</type><template>
+ <template-type-parameter name="A0"/>
+ <template-type-parameter name="A1"/>
+ <template-type-parameter name="A2"/>
+ <template-type-parameter name="A3"/>
+ </template><parameter name="a0"><paramtype>A0 const &amp;</paramtype></parameter><parameter name="a1"><paramtype>A1 const &amp;</paramtype></parameter><parameter name="a2"><paramtype>A2 const &amp;</paramtype></parameter><parameter name="a3"><paramtype>A3 const &amp;</paramtype></parameter><description><para>This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts. </para></description></method></method-group><copy-assignment><template>
+ <template-type-parameter name="A"/>
+ </template><parameter name="a"><paramtype>A &amp;</paramtype><description><para>The rhs. </para></description></parameter><description><para>Assignment</para><para>
+
+</para></description><returns><para>A new <computeroutput>expr&lt;&gt;</computeroutput> node representing an assignment of <computeroutput>a</computeroutput> to <computeroutput>*this</computeroutput>. </para></returns></copy-assignment><copy-assignment><template>
+ <template-type-parameter name="A"/>
+ </template><parameter name="a"><paramtype>A const &amp;</paramtype></parameter><description><para>This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts. </para></description></copy-assignment><method-group name="public static functions"><method name="make" cv=""><type>static expr</type><template>
+ <template-type-parameter name="A0"/>
+ <template-type-parameter name="A1"/>
+ </template><parameter name="a0"><paramtype>A0 const &amp;</paramtype></parameter><parameter name="a1"><paramtype>A1 const &amp;</paramtype></parameter><description><para>
+</para></description><returns><para>A new <computeroutput>expr&lt;&gt;</computeroutput> object initialized with the specified arguments. </para></returns></method></method-group></struct-specialization><struct-specialization name="expr"><template>
+ <template-type-parameter name="Tag"/>
+ <template-type-parameter name="Args"/>
+ </template><specialization><template-arg>Tag</template-arg><template-arg>Args</template-arg><template-arg>3</template-arg></specialization><purpose>Representation of a node in an expression tree. </purpose><description><para><computeroutput>proto::expr&lt;&gt;</computeroutput> is a node in an expression template tree. It is a container for its child sub-trees. It also serves as the terminal nodes of the tree.</para><para><computeroutput>Tag</computeroutput> is type that represents the operation encoded by this expression. It is typically one of the structs in the <computeroutput>boost::proto::tag</computeroutput> namespace, but it doesn't have to be. If the <computeroutput>Tag</computeroutput> type is <computeroutput>boost::proto::tag::terminal</computeroutput> then this <computeroutput>expr&lt;&gt;</computeroutput> type represents a leaf in the expression tree.</para><para><computeroutput>Args</computeroutput> is a type list representing the type of the children of this expression. It is an instantiati
on of one of <computeroutput>proto::list1&lt;&gt;</computeroutput>, <computeroutput>proto::list2&lt;&gt;</computeroutput>, etc. The child types must all themselves be either <computeroutput>expr&lt;&gt;</computeroutput> or <computeroutput>proto::ref_&lt;proto::expr&lt;&gt;&gt;</computeroutput>, unless the <computeroutput>Tag</computeroutput> type is <computeroutput>boost::proto::tag::terminal</computeroutput>, in which case <computeroutput>Args</computeroutput> must be <computeroutput>proto::term&lt;T&gt;</computeroutput>, where <computeroutput>T</computeroutput> can be any type.</para><para><computeroutput>proto::expr&lt;&gt;</computeroutput> is a valid Fusion random-access sequence, where the elements of the sequence are the child expressions. </para></description><struct name="result"><template>
+ <template-type-parameter name="Sig"/>
+ </template><description><para>Encodes the return type of <computeroutput>expr&lt;&gt;operator()</computeroutput>, for use with <computeroutput>boost::result_of&lt;&gt;</computeroutput> </para></description><typedef name="type"><type>result_of::funop&lt; Sig, expr, <classname>default_domain</classname> &gt;::type</type></typedef></struct><typedef name="proto_tag"><type>Tag</type></typedef><typedef name="proto_arity"><type>mpl::long_&lt; 3 &gt;</type></typedef><typedef name="proto_base_expr"><type>expr</type></typedef><typedef name="proto_args"><type>Args</type></typedef><typedef name="proto_domain"><type><classname>default_domain</classname></type></typedef><typedef name="fusion_tag"><type>proto::tag::proto_expr</type></typedef><typedef name="proto_is_expr_"><type>void</type></typedef><typedef name="proto_derived_expr"><type>expr</type></typedef><typedef name="proto_child0"><type>Args::child0</type></typedef><typedef name="proto_child1"><type>Args::child1</type></typedef><typedef name="proto_child2"><typ
e>Args::child2</type></typedef><typedef name="proto_child3"><type>void</type></typedef><typedef name="proto_child4"><type>void</type></typedef><data-member name="child0"><type>proto_child0</type></data-member><data-member name="child1"><type>proto_child1</type></data-member><data-member name="child2"><type>proto_child2</type></data-member><method-group name="public member functions"><method name="proto_base" cv="const"><type>expr const &amp;</type><description><para>
+</para></description><returns><para>*this </para></returns></method><method name="proto_base" cv=""><type>expr &amp;</type><description><para>This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts. </para></description></method><method name="operator[]" cv="const"><type>proto::expr&lt; <classname>proto::tag::subscript</classname>, <classname>list2</classname>&lt; <classname>ref_</classname>&lt; expr const &gt;, typename <classname>result_of::as_child</classname>&lt; A &gt;::type &gt; &gt; const</type><template>
+ <template-type-parameter name="A"/>
+ </template><parameter name="a"><paramtype>A &amp;</paramtype><description><para>The rhs. </para></description></parameter><description><para>Subscript</para><para>
+
+</para></description><returns><para>A new <computeroutput>expr&lt;&gt;</computeroutput> node representing <computeroutput>*this</computeroutput> subscripted with <computeroutput>a</computeroutput>. </para></returns></method><method name="operator[]" cv="const"><type>proto::expr&lt; <classname>proto::tag::subscript</classname>, <classname>list2</classname>&lt; <classname>ref_</classname>&lt; expr const &gt;, typename <classname>result_of::as_child</classname>&lt; A const &gt;::type &gt; &gt; const</type><template>
+ <template-type-parameter name="A"/>
+ </template><parameter name="a"><paramtype>A const &amp;</paramtype></parameter><description><para>This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts. </para></description></method><method name="operator()" cv="const"><type>proto::expr&lt; <classname>proto::tag::function</classname>, <classname>list1</classname>&lt; <classname>ref_</classname>&lt; expr const &gt; &gt; &gt; const</type><description><para>Function call</para><para>
+</para></description><returns><para>A new <computeroutput>expr&lt;&gt;</computeroutput> node representing the function invocation of <computeroutput/>(*this)(). </para></returns></method><method name="operator()" cv="const"><type><classname>result_of::funop1</classname>&lt; expr const, <classname>default_domain</classname>, const A0 &gt;::type const</type><template>
+ <template-type-parameter name="A0"/>
+ </template><parameter name="a0"><paramtype>A0 const &amp;</paramtype></parameter><description><para>This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts. </para></description></method><method name="operator()" cv="const"><type><classname>result_of::funop2</classname>&lt; expr const, <classname>default_domain</classname>, const A0, const A1 &gt;::type const</type><template>
+ <template-type-parameter name="A0"/>
+ <template-type-parameter name="A1"/>
+ </template><parameter name="a0"><paramtype>A0 const &amp;</paramtype></parameter><parameter name="a1"><paramtype>A1 const &amp;</paramtype></parameter><description><para>This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts. </para></description></method><method name="operator()" cv="const"><type><classname>result_of::funop3</classname>&lt; expr const, <classname>default_domain</classname>, const A0, const A1, const A2 &gt;::type const</type><template>
+ <template-type-parameter name="A0"/>
+ <template-type-parameter name="A1"/>
+ <template-type-parameter name="A2"/>
+ </template><parameter name="a0"><paramtype>A0 const &amp;</paramtype></parameter><parameter name="a1"><paramtype>A1 const &amp;</paramtype></parameter><parameter name="a2"><paramtype>A2 const &amp;</paramtype></parameter><description><para>This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts. </para></description></method><method name="operator()" cv="const"><type><classname>result_of::funop4</classname>&lt; expr const, <classname>default_domain</classname>, const A0, const A1, const A2, const A3 &gt;::type const</type><template>
+ <template-type-parameter name="A0"/>
+ <template-type-parameter name="A1"/>
+ <template-type-parameter name="A2"/>
+ <template-type-parameter name="A3"/>
+ </template><parameter name="a0"><paramtype>A0 const &amp;</paramtype></parameter><parameter name="a1"><paramtype>A1 const &amp;</paramtype></parameter><parameter name="a2"><paramtype>A2 const &amp;</paramtype></parameter><parameter name="a3"><paramtype>A3 const &amp;</paramtype></parameter><description><para>This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts. </para></description></method></method-group><copy-assignment><template>
+ <template-type-parameter name="A"/>
+ </template><parameter name="a"><paramtype>A &amp;</paramtype><description><para>The rhs. </para></description></parameter><description><para>Assignment</para><para>
+
+</para></description><returns><para>A new <computeroutput>expr&lt;&gt;</computeroutput> node representing an assignment of <computeroutput>a</computeroutput> to <computeroutput>*this</computeroutput>. </para></returns></copy-assignment><copy-assignment><template>
+ <template-type-parameter name="A"/>
+ </template><parameter name="a"><paramtype>A const &amp;</paramtype></parameter><description><para>This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts. </para></description></copy-assignment><method-group name="public static functions"><method name="make" cv=""><type>static expr</type><template>
+ <template-type-parameter name="A0"/>
+ <template-type-parameter name="A1"/>
+ <template-type-parameter name="A2"/>
+ </template><parameter name="a0"><paramtype>A0 const &amp;</paramtype></parameter><parameter name="a1"><paramtype>A1 const &amp;</paramtype></parameter><parameter name="a2"><paramtype>A2 const &amp;</paramtype></parameter><description><para>
+</para></description><returns><para>A new <computeroutput>expr&lt;&gt;</computeroutput> object initialized with the specified arguments. </para></returns></method></method-group></struct-specialization><struct-specialization name="expr"><template>
+ <template-type-parameter name="Tag"/>
+ <template-type-parameter name="Args"/>
+ </template><specialization><template-arg>Tag</template-arg><template-arg>Args</template-arg><template-arg>4</template-arg></specialization><purpose>Representation of a node in an expression tree. </purpose><description><para><computeroutput>proto::expr&lt;&gt;</computeroutput> is a node in an expression template tree. It is a container for its child sub-trees. It also serves as the terminal nodes of the tree.</para><para><computeroutput>Tag</computeroutput> is type that represents the operation encoded by this expression. It is typically one of the structs in the <computeroutput>boost::proto::tag</computeroutput> namespace, but it doesn't have to be. If the <computeroutput>Tag</computeroutput> type is <computeroutput>boost::proto::tag::terminal</computeroutput> then this <computeroutput>expr&lt;&gt;</computeroutput> type represents a leaf in the expression tree.</para><para><computeroutput>Args</computeroutput> is a type list representing the type of the children of this expression. It is an instantiati
on of one of <computeroutput>proto::list1&lt;&gt;</computeroutput>, <computeroutput>proto::list2&lt;&gt;</computeroutput>, etc. The child types must all themselves be either <computeroutput>expr&lt;&gt;</computeroutput> or <computeroutput>proto::ref_&lt;proto::expr&lt;&gt;&gt;</computeroutput>, unless the <computeroutput>Tag</computeroutput> type is <computeroutput>boost::proto::tag::terminal</computeroutput>, in which case <computeroutput>Args</computeroutput> must be <computeroutput>proto::term&lt;T&gt;</computeroutput>, where <computeroutput>T</computeroutput> can be any type.</para><para><computeroutput>proto::expr&lt;&gt;</computeroutput> is a valid Fusion random-access sequence, where the elements of the sequence are the child expressions. </para></description><struct name="result"><template>
+ <template-type-parameter name="Sig"/>
+ </template><description><para>Encodes the return type of <computeroutput>expr&lt;&gt;operator()</computeroutput>, for use with <computeroutput>boost::result_of&lt;&gt;</computeroutput> </para></description><typedef name="type"><type>result_of::funop&lt; Sig, expr, <classname>default_domain</classname> &gt;::type</type></typedef></struct><typedef name="proto_tag"><type>Tag</type></typedef><typedef name="proto_arity"><type>mpl::long_&lt; 4 &gt;</type></typedef><typedef name="proto_base_expr"><type>expr</type></typedef><typedef name="proto_args"><type>Args</type></typedef><typedef name="proto_domain"><type><classname>default_domain</classname></type></typedef><typedef name="fusion_tag"><type>proto::tag::proto_expr</type></typedef><typedef name="proto_is_expr_"><type>void</type></typedef><typedef name="proto_derived_expr"><type>expr</type></typedef><typedef name="proto_child0"><type>Args::child0</type></typedef><typedef name="proto_child1"><type>Args::child1</type></typedef><typedef name="proto_child2"><typ
e>Args::child2</type></typedef><typedef name="proto_child3"><type>Args::child3</type></typedef><typedef name="proto_child4"><type>void</type></typedef><data-member name="child0"><type>proto_child0</type></data-member><data-member name="child1"><type>proto_child1</type></data-member><data-member name="child2"><type>proto_child2</type></data-member><data-member name="child3"><type>proto_child3</type></data-member><method-group name="public member functions"><method name="proto_base" cv="const"><type>expr const &amp;</type><description><para>
+</para></description><returns><para>*this </para></returns></method><method name="proto_base" cv=""><type>expr &amp;</type><description><para>This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts. </para></description></method><method name="operator[]" cv="const"><type>proto::expr&lt; <classname>proto::tag::subscript</classname>, <classname>list2</classname>&lt; <classname>ref_</classname>&lt; expr const &gt;, typename <classname>result_of::as_child</classname>&lt; A &gt;::type &gt; &gt; const</type><template>
+ <template-type-parameter name="A"/>
+ </template><parameter name="a"><paramtype>A &amp;</paramtype><description><para>The rhs. </para></description></parameter><description><para>Subscript</para><para>
+
+</para></description><returns><para>A new <computeroutput>expr&lt;&gt;</computeroutput> node representing <computeroutput>*this</computeroutput> subscripted with <computeroutput>a</computeroutput>. </para></returns></method><method name="operator[]" cv="const"><type>proto::expr&lt; <classname>proto::tag::subscript</classname>, <classname>list2</classname>&lt; <classname>ref_</classname>&lt; expr const &gt;, typename <classname>result_of::as_child</classname>&lt; A const &gt;::type &gt; &gt; const</type><template>
+ <template-type-parameter name="A"/>
+ </template><parameter name="a"><paramtype>A const &amp;</paramtype></parameter><description><para>This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts. </para></description></method><method name="operator()" cv="const"><type>proto::expr&lt; <classname>proto::tag::function</classname>, <classname>list1</classname>&lt; <classname>ref_</classname>&lt; expr const &gt; &gt; &gt; const</type><description><para>Function call</para><para>
+</para></description><returns><para>A new <computeroutput>expr&lt;&gt;</computeroutput> node representing the function invocation of <computeroutput/>(*this)(). </para></returns></method><method name="operator()" cv="const"><type><classname>result_of::funop1</classname>&lt; expr const, <classname>default_domain</classname>, const A0 &gt;::type const</type><template>
+ <template-type-parameter name="A0"/>
+ </template><parameter name="a0"><paramtype>A0 const &amp;</paramtype></parameter><description><para>This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts. </para></description></method><method name="operator()" cv="const"><type><classname>result_of::funop2</classname>&lt; expr const, <classname>default_domain</classname>, const A0, const A1 &gt;::type const</type><template>
+ <template-type-parameter name="A0"/>
+ <template-type-parameter name="A1"/>
+ </template><parameter name="a0"><paramtype>A0 const &amp;</paramtype></parameter><parameter name="a1"><paramtype>A1 const &amp;</paramtype></parameter><description><para>This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts. </para></description></method><method name="operator()" cv="const"><type><classname>result_of::funop3</classname>&lt; expr const, <classname>default_domain</classname>, const A0, const A1, const A2 &gt;::type const</type><template>
+ <template-type-parameter name="A0"/>
+ <template-type-parameter name="A1"/>
+ <template-type-parameter name="A2"/>
+ </template><parameter name="a0"><paramtype>A0 const &amp;</paramtype></parameter><parameter name="a1"><paramtype>A1 const &amp;</paramtype></parameter><parameter name="a2"><paramtype>A2 const &amp;</paramtype></parameter><description><para>This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts. </para></description></method><method name="operator()" cv="const"><type><classname>result_of::funop4</classname>&lt; expr const, <classname>default_domain</classname>, const A0, const A1, const A2, const A3 &gt;::type const</type><template>
+ <template-type-parameter name="A0"/>
+ <template-type-parameter name="A1"/>
+ <template-type-parameter name="A2"/>
+ <template-type-parameter name="A3"/>
+ </template><parameter name="a0"><paramtype>A0 const &amp;</paramtype></parameter><parameter name="a1"><paramtype>A1 const &amp;</paramtype></parameter><parameter name="a2"><paramtype>A2 const &amp;</paramtype></parameter><parameter name="a3"><paramtype>A3 const &amp;</paramtype></parameter><description><para>This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts. </para></description></method></method-group><copy-assignment><template>
+ <template-type-parameter name="A"/>
+ </template><parameter name="a"><paramtype>A &amp;</paramtype><description><para>The rhs. </para></description></parameter><description><para>Assignment</para><para>
+
+</para></description><returns><para>A new <computeroutput>expr&lt;&gt;</computeroutput> node representing an assignment of <computeroutput>a</computeroutput> to <computeroutput>*this</computeroutput>. </para></returns></copy-assignment><copy-assignment><template>
+ <template-type-parameter name="A"/>
+ </template><parameter name="a"><paramtype>A const &amp;</paramtype></parameter><description><para>This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts. </para></description></copy-assignment><method-group name="public static functions"><method name="make" cv=""><type>static expr</type><template>
+ <template-type-parameter name="A0"/>
+ <template-type-parameter name="A1"/>
+ <template-type-parameter name="A2"/>
+ <template-type-parameter name="A3"/>
+ </template><parameter name="a0"><paramtype>A0 const &amp;</paramtype></parameter><parameter name="a1"><paramtype>A1 const &amp;</paramtype></parameter><parameter name="a2"><paramtype>A2 const &amp;</paramtype></parameter><parameter name="a3"><paramtype>A3 const &amp;</paramtype></parameter><description><para>
+</para></description><returns><para>A new <computeroutput>expr&lt;&gt;</computeroutput> object initialized with the specified arguments. </para></returns></method></method-group></struct-specialization><struct-specialization name="expr"><template>
+ <template-type-parameter name="Tag"/>
+ <template-type-parameter name="Args"/>
+ </template><specialization><template-arg>Tag</template-arg><template-arg>Args</template-arg><template-arg>5</template-arg></specialization><purpose>Representation of a node in an expression tree. </purpose><description><para><computeroutput>proto::expr&lt;&gt;</computeroutput> is a node in an expression template tree. It is a container for its child sub-trees. It also serves as the terminal nodes of the tree.</para><para><computeroutput>Tag</computeroutput> is type that represents the operation encoded by this expression. It is typically one of the structs in the <computeroutput>boost::proto::tag</computeroutput> namespace, but it doesn't have to be. If the <computeroutput>Tag</computeroutput> type is <computeroutput>boost::proto::tag::terminal</computeroutput> then this <computeroutput>expr&lt;&gt;</computeroutput> type represents a leaf in the expression tree.</para><para><computeroutput>Args</computeroutput> is a type list representing the type of the children of this expression. It is an instantiati
on of one of <computeroutput>proto::list1&lt;&gt;</computeroutput>, <computeroutput>proto::list2&lt;&gt;</computeroutput>, etc. The child types must all themselves be either <computeroutput>expr&lt;&gt;</computeroutput> or <computeroutput>proto::ref_&lt;proto::expr&lt;&gt;&gt;</computeroutput>, unless the <computeroutput>Tag</computeroutput> type is <computeroutput>boost::proto::tag::terminal</computeroutput>, in which case <computeroutput>Args</computeroutput> must be <computeroutput>proto::term&lt;T&gt;</computeroutput>, where <computeroutput>T</computeroutput> can be any type.</para><para><computeroutput>proto::expr&lt;&gt;</computeroutput> is a valid Fusion random-access sequence, where the elements of the sequence are the child expressions. </para></description><struct name="result"><template>
+ <template-type-parameter name="Sig"/>
+ </template><description><para>Encodes the return type of <computeroutput>expr&lt;&gt;operator()</computeroutput>, for use with <computeroutput>boost::result_of&lt;&gt;</computeroutput> </para></description><typedef name="type"><type>result_of::funop&lt; Sig, expr, <classname>default_domain</classname> &gt;::type</type></typedef></struct><typedef name="proto_tag"><type>Tag</type></typedef><typedef name="proto_arity"><type>mpl::long_&lt; 5 &gt;</type></typedef><typedef name="proto_base_expr"><type>expr</type></typedef><typedef name="proto_args"><type>Args</type></typedef><typedef name="proto_domain"><type><classname>default_domain</classname></type></typedef><typedef name="fusion_tag"><type>proto::tag::proto_expr</type></typedef><typedef name="proto_is_expr_"><type>void</type></typedef><typedef name="proto_derived_expr"><type>expr</type></typedef><typedef name="proto_child0"><type>Args::child0</type></typedef><typedef name="proto_child1"><type>Args::child1</type></typedef><typedef name="proto_child2"><typ
e>Args::child2</type></typedef><typedef name="proto_child3"><type>Args::child3</type></typedef><typedef name="proto_child4"><type>Args::child4</type></typedef><data-member name="child0"><type>proto_child0</type></data-member><data-member name="child1"><type>proto_child1</type></data-member><data-member name="child2"><type>proto_child2</type></data-member><data-member name="child3"><type>proto_child3</type></data-member><data-member name="child4"><type>proto_child4</type></data-member><method-group name="public member functions"><method name="proto_base" cv="const"><type>expr const &amp;</type><description><para>
+</para></description><returns><para>*this </para></returns></method><method name="proto_base" cv=""><type>expr &amp;</type><description><para>This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts. </para></description></method><method name="operator[]" cv="const"><type>proto::expr&lt; <classname>proto::tag::subscript</classname>, <classname>list2</classname>&lt; <classname>ref_</classname>&lt; expr const &gt;, typename <classname>result_of::as_child</classname>&lt; A &gt;::type &gt; &gt; const</type><template>
+ <template-type-parameter name="A"/>
+ </template><parameter name="a"><paramtype>A &amp;</paramtype><description><para>The rhs. </para></description></parameter><description><para>Subscript</para><para>
+
+</para></description><returns><para>A new <computeroutput>expr&lt;&gt;</computeroutput> node representing <computeroutput>*this</computeroutput> subscripted with <computeroutput>a</computeroutput>. </para></returns></method><method name="operator[]" cv="const"><type>proto::expr&lt; <classname>proto::tag::subscript</classname>, <classname>list2</classname>&lt; <classname>ref_</classname>&lt; expr const &gt;, typename <classname>result_of::as_child</classname>&lt; A const &gt;::type &gt; &gt; const</type><template>
+ <template-type-parameter name="A"/>
+ </template><parameter name="a"><paramtype>A const &amp;</paramtype></parameter><description><para>This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts. </para></description></method><method name="operator()" cv="const"><type>proto::expr&lt; <classname>proto::tag::function</classname>, <classname>list1</classname>&lt; <classname>ref_</classname>&lt; expr const &gt; &gt; &gt; const</type><description><para>Function call</para><para>
+</para></description><returns><para>A new <computeroutput>expr&lt;&gt;</computeroutput> node representing the function invocation of <computeroutput/>(*this)(). </para></returns></method><method name="operator()" cv="const"><type><classname>result_of::funop1</classname>&lt; expr const, <classname>default_domain</classname>, const A0 &gt;::type const</type><template>
+ <template-type-parameter name="A0"/>
+ </template><parameter name="a0"><paramtype>A0 const &amp;</paramtype></parameter><description><para>This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts. </para></description></method><method name="operator()" cv="const"><type><classname>result_of::funop2</classname>&lt; expr const, <classname>default_domain</classname>, const A0, const A1 &gt;::type const</type><template>
+ <template-type-parameter name="A0"/>
+ <template-type-parameter name="A1"/>
+ </template><parameter name="a0"><paramtype>A0 const &amp;</paramtype></parameter><parameter name="a1"><paramtype>A1 const &amp;</paramtype></parameter><description><para>This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts. </para></description></method><method name="operator()" cv="const"><type><classname>result_of::funop3</classname>&lt; expr const, <classname>default_domain</classname>, const A0, const A1, const A2 &gt;::type const</type><template>
+ <template-type-parameter name="A0"/>
+ <template-type-parameter name="A1"/>
+ <template-type-parameter name="A2"/>
+ </template><parameter name="a0"><paramtype>A0 const &amp;</paramtype></parameter><parameter name="a1"><paramtype>A1 const &amp;</paramtype></parameter><parameter name="a2"><paramtype>A2 const &amp;</paramtype></parameter><description><para>This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts. </para></description></method><method name="operator()" cv="const"><type><classname>result_of::funop4</classname>&lt; expr const, <classname>default_domain</classname>, const A0, const A1, const A2, const A3 &gt;::type const</type><template>
+ <template-type-parameter name="A0"/>
+ <template-type-parameter name="A1"/>
+ <template-type-parameter name="A2"/>
+ <template-type-parameter name="A3"/>
+ </template><parameter name="a0"><paramtype>A0 const &amp;</paramtype></parameter><parameter name="a1"><paramtype>A1 const &amp;</paramtype></parameter><parameter name="a2"><paramtype>A2 const &amp;</paramtype></parameter><parameter name="a3"><paramtype>A3 const &amp;</paramtype></parameter><description><para>This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts. </para></description></method></method-group><copy-assignment><template>
+ <template-type-parameter name="A"/>
+ </template><parameter name="a"><paramtype>A &amp;</paramtype><description><para>The rhs. </para></description></parameter><description><para>Assignment</para><para>
+
+</para></description><returns><para>A new <computeroutput>expr&lt;&gt;</computeroutput> node representing an assignment of <computeroutput>a</computeroutput> to <computeroutput>*this</computeroutput>. </para></returns></copy-assignment><copy-assignment><template>
+ <template-type-parameter name="A"/>
+ </template><parameter name="a"><paramtype>A const &amp;</paramtype></parameter><description><para>This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts. </para></description></copy-assignment><method-group name="public static functions"><method name="make" cv=""><type>static expr</type><template>
+ <template-type-parameter name="A0"/>
+ <template-type-parameter name="A1"/>
+ <template-type-parameter name="A2"/>
+ <template-type-parameter name="A3"/>
+ <template-type-parameter name="A4"/>
+ </template><parameter name="a0"><paramtype>A0 const &amp;</paramtype></parameter><parameter name="a1"><paramtype>A1 const &amp;</paramtype></parameter><parameter name="a2"><paramtype>A2 const &amp;</paramtype></parameter><parameter name="a3"><paramtype>A3 const &amp;</paramtype></parameter><parameter name="a4"><paramtype>A4 const &amp;</paramtype></parameter><description><para>
+</para></description><returns><para>A new <computeroutput>expr&lt;&gt;</computeroutput> object initialized with the specified arguments. </para></returns></method></method-group></struct-specialization><namespace name="result_of"><struct name="funop0"><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="Domain"/>
+ </template><purpose>A helper metafunction for computing the return type of <computeroutput>proto::expr&lt;&gt;operator()</computeroutput>. </purpose><typedef name="type"><type>proto::expr&lt; <classname>tag::function</classname>, <classname>list1</classname>&lt; <classname>ref_</classname>&lt; Expr &gt;&gt;&gt;</type></typedef><method-group name="public static functions"><method name="call" cv=""><type>static type const</type><parameter name="expr"><paramtype>Expr &amp;</paramtype></parameter></method></method-group></struct><struct-specialization name="funop"><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="This"/>
+ <template-type-parameter name="Domain"/>
+ </template><specialization><template-arg>Expr()</template-arg><template-arg>This</template-arg><template-arg>Domain</template-arg></specialization><inherit access="public">boost::proto::result_of::funop0&lt; This, Domain &gt;</inherit><purpose>A helper metafunction for computing the return type of <computeroutput>proto::expr&lt;&gt;operator()</computeroutput>. </purpose></struct-specialization><struct-specialization name="funop"><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="This"/>
+ <template-type-parameter name="Domain"/>
+ </template><specialization><template-arg>Expr const ()</template-arg><template-arg>This</template-arg><template-arg>Domain</template-arg></specialization><inherit access="public">boost::proto::result_of::funop0&lt; Expr, Domain &gt;</inherit><purpose>A helper metafunction for computing the return type of <computeroutput>proto::expr&lt;&gt;operator()</computeroutput>. </purpose></struct-specialization><struct name="funop1"><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="Domain"/>
+ <template-type-parameter name="A0"/>
+ </template><purpose>A helper metafunction for computing the return type of <computeroutput>proto::expr&lt;&gt;operator()</computeroutput>. </purpose><typedef name="type"><type>proto::expr&lt; <classname>tag::function</classname>, <classname>list2</classname>&lt; <classname>ref_</classname>&lt; Expr &gt;, typename <classname>proto::result_of::as_child</classname>&lt; A0, Domain &gt;::type &gt;&gt;</type></typedef><method-group name="public static functions"><method name="call" cv=""><type>static type const</type><parameter name="expr"><paramtype>Expr &amp;</paramtype></parameter><parameter name="a0"><paramtype>A0 &amp;</paramtype></parameter></method></method-group></struct><struct-specialization name="funop"><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="A0"/>
+ <template-type-parameter name="This"/>
+ <template-type-parameter name="Domain"/>
+ </template><specialization><template-arg>Expr(A0)</template-arg><template-arg>This</template-arg><template-arg>Domain</template-arg></specialization><inherit access="public">boost::proto::result_of::funop1&lt; This, Domain, remove_reference&lt; A0 &gt;::type &gt;</inherit><purpose>A helper metafunction for computing the return type of <computeroutput>proto::expr&lt;&gt;operator()</computeroutput>. </purpose></struct-specialization><struct-specialization name="funop"><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="A0"/>
+ <template-type-parameter name="This"/>
+ <template-type-parameter name="Domain"/>
+ </template><specialization><template-arg>Expr const (A0)</template-arg><template-arg>This</template-arg><template-arg>Domain</template-arg></specialization><inherit access="public">boost::proto::result_of::funop1&lt; Expr, Domain, A0 &gt;</inherit><purpose>A helper metafunction for computing the return type of <computeroutput>proto::expr&lt;&gt;operator()</computeroutput>. </purpose></struct-specialization><struct name="funop2"><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="Domain"/>
+ <template-type-parameter name="A0"/>
+ <template-type-parameter name="A1"/>
+ </template><purpose>A helper metafunction for computing the return type of <computeroutput>proto::expr&lt;&gt;operator()</computeroutput>. </purpose><typedef name="type"><type>proto::expr&lt; <classname>tag::function</classname>, <classname>list3</classname>&lt; <classname>ref_</classname>&lt; Expr &gt;, typename <classname>proto::result_of::as_child</classname>&lt; A0, Domain &gt;::type, typename <classname>proto::result_of::as_child</classname>&lt; A1, Domain &gt;::type &gt;&gt;</type></typedef><method-group name="public static functions"><method name="call" cv=""><type>static type const</type><parameter name="expr"><paramtype>Expr &amp;</paramtype></parameter><parameter name="a0"><paramtype>A0 &amp;</paramtype></parameter><parameter name="a1"><paramtype>A1 &amp;</paramtype></parameter></method></method-group></struct><struct-specialization name="funop"><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="A0"/>
+ <template-type-parameter name="A1"/>
+ <template-type-parameter name="This"/>
+ <template-type-parameter name="Domain"/>
+ </template><specialization><template-arg>Expr(A0</template-arg><template-arg>A1)</template-arg><template-arg>This</template-arg><template-arg>Domain</template-arg></specialization><inherit access="public">boost::proto::result_of::funop2&lt; This, Domain, remove_reference&lt; A0 &gt;::type, remove_reference&lt; A1 &gt;::type &gt;</inherit><purpose>A helper metafunction for computing the return type of <computeroutput>proto::expr&lt;&gt;operator()</computeroutput>. </purpose></struct-specialization><struct-specialization name="funop"><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="A0"/>
+ <template-type-parameter name="A1"/>
+ <template-type-parameter name="This"/>
+ <template-type-parameter name="Domain"/>
+ </template><specialization><template-arg>Expr const (A0</template-arg><template-arg>A1)</template-arg><template-arg>This</template-arg><template-arg>Domain</template-arg></specialization><inherit access="public">boost::proto::result_of::funop2&lt; Expr, Domain, A0, A1 &gt;</inherit><purpose>A helper metafunction for computing the return type of <computeroutput>proto::expr&lt;&gt;operator()</computeroutput>. </purpose></struct-specialization><struct name="funop3"><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="Domain"/>
+ <template-type-parameter name="A0"/>
+ <template-type-parameter name="A1"/>
+ <template-type-parameter name="A2"/>
+ </template><purpose>A helper metafunction for computing the return type of <computeroutput>proto::expr&lt;&gt;operator()</computeroutput>. </purpose><typedef name="type"><type>proto::expr&lt; <classname>tag::function</classname>, <classname>list4</classname>&lt; <classname>ref_</classname>&lt; Expr &gt;, typename <classname>proto::result_of::as_child</classname>&lt; A0, Domain &gt;::type, typename <classname>proto::result_of::as_child</classname>&lt; A1, Domain &gt;::type, typename <classname>proto::result_of::as_child</classname>&lt; A2, Domain &gt;::type &gt;&gt;</type></typedef><method-group name="public static functions"><method name="call" cv=""><type>static type const</type><parameter name="expr"><paramtype>Expr &amp;</paramtype></parameter><parameter name="a0"><paramtype>A0 &amp;</paramtype></parameter><parameter name="a1"><paramtype>A1 &amp;</paramtype></parameter><parameter name="a2"><paramtype>A2 &amp;</paramtype></parameter></method></method-group></struct><struct-specialization name="funop">
<template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="A0"/>
+ <template-type-parameter name="A1"/>
+ <template-type-parameter name="A2"/>
+ <template-type-parameter name="This"/>
+ <template-type-parameter name="Domain"/>
+ </template><specialization><template-arg>Expr(A0</template-arg><template-arg>A1</template-arg><template-arg>A2)</template-arg><template-arg>This</template-arg><template-arg>Domain</template-arg></specialization><inherit access="public">boost::proto::result_of::funop3&lt; This, Domain, remove_reference&lt; A0 &gt;::type, remove_reference&lt; A1 &gt;::type, remove_reference&lt; A2 &gt;::type &gt;</inherit><purpose>A helper metafunction for computing the return type of <computeroutput>proto::expr&lt;&gt;operator()</computeroutput>. </purpose></struct-specialization><struct-specialization name="funop"><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="A0"/>
+ <template-type-parameter name="A1"/>
+ <template-type-parameter name="A2"/>
+ <template-type-parameter name="This"/>
+ <template-type-parameter name="Domain"/>
+ </template><specialization><template-arg>Expr const (A0</template-arg><template-arg>A1</template-arg><template-arg>A2)</template-arg><template-arg>This</template-arg><template-arg>Domain</template-arg></specialization><inherit access="public">boost::proto::result_of::funop3&lt; Expr, Domain, A0, A1, A2 &gt;</inherit><purpose>A helper metafunction for computing the return type of <computeroutput>proto::expr&lt;&gt;operator()</computeroutput>. </purpose></struct-specialization><struct name="funop4"><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="Domain"/>
+ <template-type-parameter name="A0"/>
+ <template-type-parameter name="A1"/>
+ <template-type-parameter name="A2"/>
+ <template-type-parameter name="A3"/>
+ </template><purpose>A helper metafunction for computing the return type of <computeroutput>proto::expr&lt;&gt;operator()</computeroutput>. </purpose><typedef name="type"><type>proto::expr&lt; <classname>tag::function</classname>, <classname>list5</classname>&lt; <classname>ref_</classname>&lt; Expr &gt;, typename <classname>proto::result_of::as_child</classname>&lt; A0, Domain &gt;::type, typename <classname>proto::result_of::as_child</classname>&lt; A1, Domain &gt;::type, typename <classname>proto::result_of::as_child</classname>&lt; A2, Domain &gt;::type, typename <classname>proto::result_of::as_child</classname>&lt; A3, Domain &gt;::type &gt;&gt;</type></typedef><method-group name="public static functions"><method name="call" cv=""><type>static type const</type><parameter name="expr"><paramtype>Expr &amp;</paramtype></parameter><parameter name="a0"><paramtype>A0 &amp;</paramtype></parameter><parameter name="a1"><paramtype>A1 &amp;</paramtype></parameter><parameter name="a2"><paramtype>A2 &amp;</param
type></parameter><parameter name="a3"><paramtype>A3 &amp;</paramtype></parameter></method></method-group></struct><struct-specialization name="funop"><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="A0"/>
+ <template-type-parameter name="A1"/>
+ <template-type-parameter name="A2"/>
+ <template-type-parameter name="A3"/>
+ <template-type-parameter name="This"/>
+ <template-type-parameter name="Domain"/>
+ </template><specialization><template-arg>Expr(A0</template-arg><template-arg>A1</template-arg><template-arg>A2</template-arg><template-arg>A3)</template-arg><template-arg>This</template-arg><template-arg>Domain</template-arg></specialization><inherit access="public">boost::proto::result_of::funop4&lt; This, Domain, remove_reference&lt; A0 &gt;::type, remove_reference&lt; A1 &gt;::type, remove_reference&lt; A2 &gt;::type, remove_reference&lt; A3 &gt;::type &gt;</inherit><purpose>A helper metafunction for computing the return type of <computeroutput>proto::expr&lt;&gt;operator()</computeroutput>. </purpose></struct-specialization><struct-specialization name="funop"><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="A0"/>
+ <template-type-parameter name="A1"/>
+ <template-type-parameter name="A2"/>
+ <template-type-parameter name="A3"/>
+ <template-type-parameter name="This"/>
+ <template-type-parameter name="Domain"/>
+ </template><specialization><template-arg>Expr const (A0</template-arg><template-arg>A1</template-arg><template-arg>A2</template-arg><template-arg>A3)</template-arg><template-arg>This</template-arg><template-arg>Domain</template-arg></specialization><inherit access="public">boost::proto::result_of::funop4&lt; Expr, Domain, A0, A1, A2, A3 &gt;</inherit><purpose>A helper metafunction for computing the return type of <computeroutput>proto::expr&lt;&gt;operator()</computeroutput>. </purpose></struct-specialization></namespace></namespace></namespace></header><header name="boost/proto/extends.hpp"><para>Macros and a base class for defining end-user expression types </para><namespace name="boost"><namespace name="proto"><struct name="is_proto_expr"><purpose>Empty type to be used as a dummy template parameter of POD expression wrappers. It allows argument-dependent lookup to find Proto's operator overloads. </purpose><description><para><computeroutput>proto::is_proto_expr</computeroutput> allows argument-depend
ent lookup to find Proto's operator overloads. For example:</para><para><programlisting> template&lt;typename T, typename Dummy = proto::is_proto_expr&gt;
+ struct my_terminal
+ {
+ BOOST_PROTO_BASIC_EXTENDS(
+ typename proto::terminal&lt;T&gt;::type
+ , my_terminal&lt;T&gt;
+ , default_domain
+ )
+ };
+
+ // ...
+ my_terminal&lt;int&gt; _1, _2;
+ _1 + _2; // OK, uses proto::operator+
+</programlisting></para><para>Without the second <computeroutput>Dummy</computeroutput> template parameter, Proto's operator overloads would not be considered by name lookup. </para></description></struct><struct name="extends"><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="Derived"/>
+ <template-type-parameter name="Domain"><default>default_domain</default></template-type-parameter>
+ <template-type-parameter name="Tag"><default>typename Expr::proto_tag</default></template-type-parameter>
+ </template><purpose>extends&lt;&gt; class template for adding behaviors to a Proto expression template </purpose><struct name="result"><template>
+ <template-type-parameter name="Sig"/>
+ </template><typedef name="type"><type>boost::result_of&lt; proto_domain(typename boost::proto::result_of::funop&lt; Sig, proto_derived_expr, proto_domain &gt;::type) &gt;::type</type></typedef></struct><data-member name="expr"><type>Expr</type></data-member><typedef name="proto_base_expr"><type>Expr::proto_base_expr</type></typedef><typedef name="proto_domain"><type>Domain</type></typedef><typedef name="proto_derived_expr"><type>Derived</type></typedef><typedef name="proto_tag"><type>proto_base_expr::proto_tag</type></typedef><typedef name="proto_args"><type>proto_base_expr::proto_args</type></typedef><typedef name="proto_arity"><type>proto_base_expr::proto_arity</type></typedef><typedef name="proto_is_expr_"><type>void</type></typedef><typedef name="fusion_tag"><type>boost::proto::tag::proto_expr</type></typedef><typedef name="proto_child0"><type>proto_base_expr::proto_child0</type></typedef><typedef name="proto_child1"><type>proto_base_expr::proto_child1</type></typedef><typedef name="proto_child2"><t
ype>proto_base_expr::proto_child2</type></typedef><typedef name="proto_child3"><type>proto_base_expr::proto_child3</type></typedef><typedef name="proto_child4"><type>proto_base_expr::proto_child4</type></typedef><method-group name="public member functions"><method name="proto_base" cv=""><type>proto_base_expr &amp;</type></method><method name="proto_base" cv="const"><type>proto_base_expr const &amp;</type></method></method-group><constructor/><constructor><parameter name="that"><paramtype><classname>extends</classname> const &amp;</paramtype></parameter></constructor><constructor><parameter name="expr_"><paramtype>Expr const &amp;</paramtype></parameter></constructor><method-group name="public static functions"><method name="make" cv=""><type>static proto_derived_expr const</type><parameter name="expr"><paramtype>Expr const &amp;</paramtype></parameter></method></method-group></struct><struct-specialization name="extends"><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="Derived"/>
+ <template-type-parameter name="Domain"/>
+ </template><specialization><template-arg>Expr</template-arg><template-arg>Derived</template-arg><template-arg>Domain</template-arg><template-arg>tag::terminal</template-arg></specialization><purpose>extends&lt;&gt; class template for adding behaviors to a Proto expression template </purpose><struct name="result"><template>
+ <template-type-parameter name="Sig"/>
+ </template><typedef name="type"><type>boost::result_of&lt; proto_domain(typename boost::proto::result_of::funop&lt; Sig, proto_derived_expr, proto_domain &gt;::type) &gt;::type</type></typedef></struct><data-member name="expr"><type>Expr</type></data-member><typedef name="proto_base_expr"><type>Expr::proto_base_expr</type></typedef><typedef name="proto_domain"><type>Domain</type></typedef><typedef name="proto_derived_expr"><type>Derived</type></typedef><typedef name="proto_tag"><type>proto_base_expr::proto_tag</type></typedef><typedef name="proto_args"><type>proto_base_expr::proto_args</type></typedef><typedef name="proto_arity"><type>proto_base_expr::proto_arity</type></typedef><typedef name="proto_is_expr_"><type>void</type></typedef><typedef name="fusion_tag"><type>boost::proto::tag::proto_expr</type></typedef><typedef name="proto_child0"><type>proto_base_expr::proto_child0</type></typedef><typedef name="proto_child1"><type>proto_base_expr::proto_child1</type></typedef><typedef name="proto_child2"><t
ype>proto_base_expr::proto_child2</type></typedef><typedef name="proto_child3"><type>proto_base_expr::proto_child3</type></typedef><typedef name="proto_child4"><type>proto_base_expr::proto_child4</type></typedef><method-group name="public member functions"><method name="extends" cv=""><type/></method><method name="extends" cv=""><type/><parameter name="that"><paramtype><classname>extends</classname> const &amp;</paramtype></parameter></method><method name="extends" cv=""><type/><parameter name="expr_"><paramtype>Expr const &amp;</paramtype></parameter></method><method name="proto_base" cv=""><type>proto_base_expr &amp;</type></method><method name="proto_base" cv="const"><type>proto_base_expr const &amp;</type></method></method-group><method-group name="public static functions"><method name="make" cv=""><type>static proto_derived_expr const</type><parameter name="expr"><paramtype>Expr const &amp;</paramtype></parameter></method></method-group></struct-specialization></namespace></namespace></header><header na
me="boost/proto/fusion.hpp"><para>Make any Proto expression a valid Fusion sequence </para><namespace name="boost"><namespace name="proto"><namespace name="functor"><struct name="flatten"><purpose>A PolymorphicFunctionObject type that returns a "flattened" view of a Proto expression tree. </purpose><description><para>A PolymorphicFunctionObject type that returns a "flattened" view of a Proto expression tree. For a tree with a top-most node tag of type <computeroutput>T</computeroutput>, the elements of the flattened sequence are determined by recursing into each child node with the same tag type and returning those nodes of different type. So for instance, the Proto expression tree corresponding to the expression <computeroutput>a | b | c</computeroutput> has a flattened view with elements [a, b, c], even though the tree is grouped as <computeroutput>((a | b) | c)</computeroutput>. </para></description><struct-specialization name="result"><template>
+ <template-type-parameter name="This"/>
+ <template-type-parameter name="Expr"/>
+ </template><specialization><template-arg>This(Expr)</template-arg></specialization><typedef name="type"><type><emphasis>unspecified</emphasis></type></typedef></struct-specialization><typedef name="proto_is_callable_"><type>void</type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Expr"/>
+ </template><parameter name="expr"><paramtype>Expr const &amp;</paramtype></parameter></method></method-group></struct><struct name="pop_front"><purpose>A PolymorphicFunctionObject type that invokes the <computeroutput>fusion::pop_front()</computeroutput> algorithm on its argument. </purpose><description><para>A PolymorphicFunctionObject type that invokes the <computeroutput>fusion::pop_front()</computeroutput> algorithm on its argument. This is useful for defining a CallableTransform like <computeroutput>pop_front(_)</computeroutput> which removes the first child from a Proto expression node. Such a transform might be used as the first argument to the <computeroutput>proto::fold&lt;&gt;</computeroutput> transform; that is, fold all but the first child. </para></description><struct-specialization name="result"><template>
+ <template-type-parameter name="This"/>
+ <template-type-parameter name="Expr"/>
+ </template><specialization><template-arg>This(Expr)</template-arg></specialization><typedef name="type"><type>fusion::result_of::pop_front&lt; typename boost::remove_reference&lt; Expr &gt;::type const &gt;::type</type></typedef></struct-specialization><typedef name="proto_is_callable_"><type>void</type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type>fusion::result_of::pop_front&lt; Expr const &gt;::type</type><template>
+ <template-type-parameter name="Expr"/>
+ </template><parameter name="expr"><paramtype>Expr const &amp;</paramtype></parameter></method></method-group></struct><struct name="reverse"><purpose>A PolymorphicFunctionObject type that invokes the <computeroutput>fusion::reverse()</computeroutput> algorithm on its argument. </purpose><description><para>A PolymorphicFunctionObject type that invokes the <computeroutput>fusion::reverse()</computeroutput> algorithm on its argument. This is useful for defining a CallableTransform like <computeroutput>reverse(_)</computeroutput> which reverses the order of the children of a Proto expression node. </para></description><struct-specialization name="result"><template>
+ <template-type-parameter name="This"/>
+ <template-type-parameter name="Expr"/>
+ </template><specialization><template-arg>This(Expr)</template-arg></specialization><typedef name="type"><type>fusion::result_of::reverse&lt; typename boost::remove_reference&lt; Expr &gt;::type const &gt;::type</type></typedef></struct-specialization><typedef name="proto_is_callable_"><type>void</type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type>fusion::result_of::reverse&lt; Expr const &gt;::type</type><template>
+ <template-type-parameter name="Expr"/>
+ </template><parameter name="expr"><paramtype>Expr const &amp;</paramtype></parameter></method></method-group></struct></namespace><function name="flatten"><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Expr"/>
+ </template><parameter name="expr"><paramtype>Expr const &amp;</paramtype></parameter><purpose>A function that returns a "flattened" view of a Proto expression tree. </purpose><description><para>For a tree with a top-most node tag of type <computeroutput>T</computeroutput>, the elements of the flattened sequence are determined by recursing into each child node with the same tag type and returning those nodes of different type. So for instance, the Proto expression tree corresponding to the expression <computeroutput>a | b | c</computeroutput> has a flattened view with elements [a, b, c], even though the tree is grouped as <computeroutput>((a | b) | c)</computeroutput>. </para></description></function></namespace></namespace></header><header name="boost/proto/generate.hpp"><para>Contains definition of generate&lt;&gt; class template, which end users can specialize for generating domain-specific expression wrappers. </para><namespace name="boost"><namespace name="proto"><struct name="default_generator"
><purpose>A simple generator that passes an expression through unchanged. </purpose><description><para>Generators are intended for use as the first template parameter to the <computeroutput>domain&lt;&gt;</computeroutput> class template and control if and how expressions within that domain are to be customized. The <computeroutput>default_generator</computeroutput> makes no modifications to the expressions passed to it. </para></description><struct-specialization name="result"><template>
+ <template-type-parameter name="This"/>
+ <template-type-parameter name="Expr"/>
+ </template><specialization><template-arg>This(Expr)</template-arg></specialization><typedef name="type"><type>Expr</type></typedef></struct-specialization><method-group name="public member functions"><method name="operator()" cv="const"><type>Expr const &amp;</type><template>
+ <template-type-parameter name="Expr"/>
+ </template><parameter name="expr"><paramtype>Expr const &amp;</paramtype><description><para>A Proto expression </para></description></parameter><description><para>
+
+</para></description><returns><para>expr </para></returns></method></method-group></struct><struct name="generator"><template>
+ <template-nontype-parameter name="Extends"><type>template&lt; typename &gt; class</type></template-nontype-parameter>
+ </template><purpose>A generator that wraps expressions passed to it in the specified extension wrapper. </purpose><description><para>Generators are intended for use as the first template parameter to the <computeroutput>domain&lt;&gt;</computeroutput> class template and control if and how expressions within that domain are to be customized. <computeroutput>generator&lt;&gt;</computeroutput> wraps each expression passed to it in the <computeroutput>Extends&lt;&gt;</computeroutput> wrapper. </para></description><struct-specialization name="result"><template>
+ <template-type-parameter name="This"/>
+ <template-type-parameter name="Expr"/>
+ </template><specialization><template-arg>This(Expr)</template-arg></specialization><typedef name="type"><type>Extends&lt; Expr &gt;</type></typedef></struct-specialization><method-group name="public member functions"><method name="operator()" cv="const"><type>Extends&lt; Expr &gt;</type><template>
+ <template-type-parameter name="Expr"/>
+ </template><parameter name="expr"><paramtype>Expr const &amp;</paramtype><description><para>A Proto expression </para></description></parameter><description><para>
+
+</para></description><returns><para>Extends&lt;Expr&gt;(expr) </para></returns></method></method-group></struct><struct name="pod_generator"><template>
+ <template-nontype-parameter name="Extends"><type>template&lt; typename &gt; class</type></template-nontype-parameter>
+ </template><purpose>A generator that wraps expressions passed to it in the specified extension wrapper and uses aggregate initialization for the wrapper. </purpose><description><para>Generators are intended for use as the first template parameter to the <computeroutput>domain&lt;&gt;</computeroutput> class template and control if and how expressions within that domain are to be customized. <computeroutput>pod_generator&lt;&gt;</computeroutput> wraps each expression passed to it in the <computeroutput>Extends&lt;&gt;</computeroutput> wrapper, and uses aggregate initialzation for the wrapped object. </para></description><struct-specialization name="result"><template>
+ <template-type-parameter name="This"/>
+ <template-type-parameter name="Expr"/>
+ </template><specialization><template-arg>This(Expr)</template-arg></specialization><typedef name="type"><type>Extends&lt; Expr &gt;</type></typedef></struct-specialization><method-group name="public member functions"><method name="operator()" cv="const"><type>Extends&lt; Expr &gt;</type><template>
+ <template-type-parameter name="Expr"/>
+ </template><parameter name="expr"><paramtype>Expr const &amp;</paramtype><description><para>The expression to wrap </para></description></parameter><description><para>
+
+</para></description><returns><para><computeroutput>Extends&lt;Expr&gt; that = {expr}; return that;</computeroutput> </para></returns></method></method-group></struct><struct name="by_value_generator"><purpose>A generator that replaces child nodes held by reference with ones held by value. Use with <computeroutput>compose_generators</computeroutput> to forward that result to another generator. </purpose><description><para>Generators are intended for use as the first template parameter to the <computeroutput>domain&lt;&gt;</computeroutput> class template and control if and how expressions within that domain are to be customized. <computeroutput>by_value_generator</computeroutput> ensures all child nodes are held by value. This generator is typically composed with a second generator for further processing, as <computeroutput>compose_generators&lt;by_value_generator, MyGenerator&gt;</computeroutput>. </para></description><struct-specialization name="result"><template>
+ <template-type-parameter name="This"/>
+ <template-type-parameter name="Expr"/>
+ </template><specialization><template-arg>This(Expr)</template-arg></specialization><typedef name="type"><type><emphasis>unspecified</emphasis></type></typedef></struct-specialization><method-group name="public member functions"><method name="operator()" cv="const"><type>result&lt; void(Expr)&gt;::type</type><template>
+ <template-type-parameter name="Expr"/>
+ </template><parameter name="expr"><paramtype>Expr const &amp;</paramtype><description><para>The expression to modify. </para></description></parameter><description><para>
+
+</para></description><returns><para><computeroutput>deep_copy(expr)</computeroutput> </para></returns></method></method-group></struct><struct name="compose_generators"><template>
+ <template-type-parameter name="First"/>
+ <template-type-parameter name="Second"/>
+ </template><purpose>A composite generator that first applies one transform to an expression and then forwards the result on to another generator for further transformation. </purpose><description><para>Generators are intended for use as the first template parameter to the <computeroutput>domain&lt;&gt;</computeroutput> class template and control if and how expressions within that domain are to be customized. <computeroutput>compose_generators&lt;&gt;</computeroutput> is a composite generator that first applies one transform to an expression and then forwards the result on to another generator for further transformation. </para></description><struct-specialization name="result"><template>
+ <template-type-parameter name="This"/>
+ <template-type-parameter name="Expr"/>
+ </template><specialization><template-arg>This(Expr)</template-arg></specialization><typedef name="type"><type>Second::template result&lt; typename First::template result&lt; void(Expr)&gt;::type &gt;::type</type></typedef></struct-specialization><method-group name="public member functions"><method name="operator()" cv="const"><type>result&lt; void(Expr)&gt;::type</type><template>
+ <template-type-parameter name="Expr"/>
+ </template><parameter name="expr"><paramtype>Expr const &amp;</paramtype><description><para>The expression to modify. </para></description></parameter><description><para>
+
+</para></description><returns><para>Second()(First()(expr)) </para></returns></method></method-group></struct></namespace></namespace></header><header name="boost/proto/literal.hpp"><para>The literal&lt;&gt; terminal wrapper, and the proto::lit() function for creating literal&lt;&gt; wrappers. </para><namespace name="boost"><namespace name="proto"><namespace name="utility"><struct name="literal"><template>
+ <template-type-parameter name="T"/>
+ <template-type-parameter name="Domain"><default>default_domain</default></template-type-parameter>
+ </template><inherit access="public">boost::proto::extends&lt; Expr, Derived, Domain, Tag &gt;</inherit><purpose>A simple wrapper for a terminal, provided for ease of use. </purpose><description><para>A simple wrapper for a terminal, provided for ease of use. In all cases, <computeroutput>literal&lt;X&gt; l(x);</computeroutput> is equivalent to <computeroutput>terminal&lt;X&gt;::type l = {x};</computeroutput>.</para><para>The <computeroutput>Domain</computeroutput> template parameter defaults to <computeroutput>proto::default_domain</computeroutput>. </para></description><typedef name="value_type"><type><classname>proto::result_of::value</classname>&lt; terminal_type &gt;::type</type></typedef><typedef name="reference"><type><classname>proto::result_of::value</classname>&lt; terminal_type &gt;::reference</type></typedef><typedef name="const_reference"><type><classname>proto::result_of::value</classname>&lt; terminal_type &gt;::const_reference</type></typedef><method-group name="public member functions"><
method name="get" cv=""><type>reference</type></method><method name="get" cv="const"><type>const_reference</type></method></method-group><constructor><template>
+ <template-type-parameter name="U"/>
+ </template><parameter name="u"><paramtype>U &amp;</paramtype></parameter></constructor><constructor><template>
+ <template-type-parameter name="U"/>
+ </template><parameter name="u"><paramtype>U const &amp;</paramtype></parameter></constructor><constructor><template>
+ <template-type-parameter name="U"/>
+ </template><parameter name="u"><paramtype><classname>literal</classname>&lt; U, Domain &gt; const &amp;</paramtype></parameter></constructor></struct></namespace><overloaded-function name="lit"><signature><type>literal&lt; T &amp; &gt;</type><template>
+ <template-type-parameter name="T"/>
+ </template><parameter name="t"><paramtype>T &amp;</paramtype><description><para>The object to wrap. </para></description></parameter></signature><signature><type>literal&lt; T const &amp; &gt;</type><template>
+ <template-type-parameter name="T"/>
+ </template><parameter name="t"><paramtype>T const &amp;</paramtype></parameter></signature><purpose>A helper function for creating a <computeroutput>literal&lt;&gt;</computeroutput> wrapper. </purpose><description><para>
+
+
+
+</para></description><returns><para>literal&lt;T &amp;&gt;(t) </para></returns><throws><simpara>Will not throw.</simpara></throws><notes><para>The returned value holds the argument by reference. </para></notes></overloaded-function></namespace></namespace></header><header name="boost/proto/make_expr.hpp"><para>Definition of the <computeroutput>make_expr()</computeroutput> and <computeroutput>unpack_expr()</computeroutput> utilities for building Proto expression nodes from child nodes or from a Fusion sequence of child nodes, respectively. </para><namespace name="boost"><namespace name="proto"><namespace name="functor"><struct name="make_expr"><template>
+ <template-type-parameter name="Tag"/>
+ <template-type-parameter name="Domain"><default>deduce_domain</default></template-type-parameter>
+ </template><purpose>A callable function object equivalent to the <computeroutput>proto::make_expr()</computeroutput> function. </purpose><description><para>In all cases, <computeroutput>functor::make_expr&lt;Tag, Domain&gt;()(a0, ... aN)</computeroutput> is equivalent to <computeroutput>proto::make_expr&lt;Tag, Domain&gt;(a0, ... aN)</computeroutput>.</para><para><computeroutput>functor::make_expr&lt;Tag&gt;()(a0, ... aN)</computeroutput> is equivalent to <computeroutput>proto::make_expr&lt;Tag&gt;(a0, ... aN)</computeroutput>. </para></description><struct-specialization name="result"><template>
+ <template-type-parameter name="This"/>
+ <template-type-parameter name="A0"/>
+ </template><specialization><template-arg>This(A0)</template-arg></specialization><typedef name="type"><type><classname>result_of::make_expr</classname>&lt; Tag, Domain, A0 &gt;::type</type></typedef></struct-specialization><struct-specialization name="result"><template>
+ <template-type-parameter name="This"/>
+ <template-type-parameter name="A0"/>
+ <template-type-parameter name="A1"/>
+ </template><specialization><template-arg>This(A0</template-arg><template-arg>A1)</template-arg></specialization><typedef name="type"><type><classname>result_of::make_expr</classname>&lt; Tag, Domain, A0, A1 &gt;::type</type></typedef></struct-specialization><struct-specialization name="result"><template>
+ <template-type-parameter name="This"/>
+ <template-type-parameter name="A0"/>
+ <template-type-parameter name="A1"/>
+ <template-type-parameter name="A2"/>
+ </template><specialization><template-arg>This(A0</template-arg><template-arg>A1</template-arg><template-arg>A2)</template-arg></specialization><typedef name="type"><type><classname>result_of::make_expr</classname>&lt; Tag, Domain, A0, A1, A2 &gt;::type</type></typedef></struct-specialization><struct-specialization name="result"><template>
+ <template-type-parameter name="This"/>
+ <template-type-parameter name="A0"/>
+ <template-type-parameter name="A1"/>
+ <template-type-parameter name="A2"/>
+ <template-type-parameter name="A3"/>
+ </template><specialization><template-arg>This(A0</template-arg><template-arg>A1</template-arg><template-arg>A2</template-arg><template-arg>A3)</template-arg></specialization><typedef name="type"><type><classname>result_of::make_expr</classname>&lt; Tag, Domain, A0, A1, A2, A3 &gt;::type</type></typedef></struct-specialization><struct-specialization name="result"><template>
+ <template-type-parameter name="This"/>
+ <template-type-parameter name="A0"/>
+ <template-type-parameter name="A1"/>
+ <template-type-parameter name="A2"/>
+ <template-type-parameter name="A3"/>
+ <template-type-parameter name="A4"/>
+ </template><specialization><template-arg>This(A0</template-arg><template-arg>A1</template-arg><template-arg>A2</template-arg><template-arg>A3</template-arg><template-arg>A4)</template-arg></specialization><typedef name="type"><type><classname>result_of::make_expr</classname>&lt; Tag, Domain, A0, A1, A2, A3, A4 &gt;::type</type></typedef></struct-specialization><typedef name="proto_is_callable_"><type>void</type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type><classname>result_of::make_expr</classname>&lt; Tag, Domain, A0 const &gt;::type const</type><template>
+ <template-type-parameter name="A0"/>
+ </template><parameter name="a0"><paramtype>A0 const &amp;</paramtype></parameter><description><para>Construct an expression node with tag type <computeroutput>Tag</computeroutput> and in the domain <computeroutput>Domain</computeroutput>.</para><para>
+</para></description><returns><para><computeroutput>proto::make_expr&lt;Tag, Domain&gt;(a0,...aN)</computeroutput> </para></returns></method><method name="operator()" cv="const"><type><classname>result_of::make_expr</classname>&lt; Tag, Domain, const A0, const A1 &gt;::type const</type><template>
+ <template-type-parameter name="A0"/>
+ <template-type-parameter name="A1"/>
+ </template><parameter name="a0"><paramtype>const A0 &amp;</paramtype></parameter><parameter name="a1"><paramtype>const A1 &amp;</paramtype></parameter><description><para>This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts. </para></description></method><method name="operator()" cv="const"><type><classname>result_of::make_expr</classname>&lt; Tag, Domain, const A0, const A1, const A2 &gt;::type const</type><template>
+ <template-type-parameter name="A0"/>
+ <template-type-parameter name="A1"/>
+ <template-type-parameter name="A2"/>
+ </template><parameter name="a0"><paramtype>const A0 &amp;</paramtype></parameter><parameter name="a1"><paramtype>const A1 &amp;</paramtype></parameter><parameter name="a2"><paramtype>const A2 &amp;</paramtype></parameter><description><para>This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts. </para></description></method><method name="operator()" cv="const"><type><classname>result_of::make_expr</classname>&lt; Tag, Domain, const A0, const A1, const A2, const A3 &gt;::type const</type><template>
+ <template-type-parameter name="A0"/>
+ <template-type-parameter name="A1"/>
+ <template-type-parameter name="A2"/>
+ <template-type-parameter name="A3"/>
+ </template><parameter name="a0"><paramtype>const A0 &amp;</paramtype></parameter><parameter name="a1"><paramtype>const A1 &amp;</paramtype></parameter><parameter name="a2"><paramtype>const A2 &amp;</paramtype></parameter><parameter name="a3"><paramtype>const A3 &amp;</paramtype></parameter><description><para>This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts. </para></description></method><method name="operator()" cv="const"><type><classname>result_of::make_expr</classname>&lt; Tag, Domain, const A0, const A1, const A2, const A3, const A4 &gt;::type const</type><template>
+ <template-type-parameter name="A0"/>
+ <template-type-parameter name="A1"/>
+ <template-type-parameter name="A2"/>
+ <template-type-parameter name="A3"/>
+ <template-type-parameter name="A4"/>
+ </template><parameter name="a0"><paramtype>const A0 &amp;</paramtype></parameter><parameter name="a1"><paramtype>const A1 &amp;</paramtype></parameter><parameter name="a2"><paramtype>const A2 &amp;</paramtype></parameter><parameter name="a3"><paramtype>const A3 &amp;</paramtype></parameter><parameter name="a4"><paramtype>const A4 &amp;</paramtype></parameter><description><para>This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts. </para></description></method></method-group></struct><struct name="unpack_expr"><template>
+ <template-type-parameter name="Tag"/>
+ <template-type-parameter name="Domain"><default>deduce_domain</default></template-type-parameter>
+ </template><purpose>A callable function object equivalent to the <computeroutput>proto::unpack_expr()</computeroutput> function. </purpose><description><para>In all cases, <computeroutput>functor::unpack_expr&lt;Tag, Domain&gt;()(seq)</computeroutput> is equivalent to <computeroutput>proto::unpack_expr&lt;Tag, Domain&gt;(seq)</computeroutput>.</para><para><computeroutput>functor::unpack_expr&lt;Tag&gt;()(seq)</computeroutput> is equivalent to <computeroutput>proto::unpack_expr&lt;Tag&gt;(seq)</computeroutput>. </para></description><struct name="result"><template>
+ <template-type-parameter name="Sig"/>
+ </template></struct><struct-specialization name="result"><template>
+ <template-type-parameter name="This"/>
+ <template-type-parameter name="Sequence"/>
+ </template><specialization><template-arg>This(Sequence)</template-arg></specialization><typedef name="type"><type><classname>result_of::unpack_expr</classname>&lt; Tag, Domain, typename remove_reference&lt; Sequence &gt;::type &gt;::type</type></typedef></struct-specialization><typedef name="proto_is_callable_"><type>void</type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type><classname>result_of::unpack_expr</classname>&lt; Tag, Domain, Sequence const &gt;::type const</type><template>
+ <template-type-parameter name="Sequence"/>
+ </template><parameter name="sequence"><paramtype>Sequence const &amp;</paramtype><description><para>A Fusion Random Access Sequence </para></description></parameter><description><para>Construct an expression node with tag type <computeroutput>Tag</computeroutput> and in the domain <computeroutput>Domain</computeroutput>.</para><para>
+
+</para></description><returns><para><computeroutput>proto::unpack_expr&lt;Tag, Domain&gt;(sequence)</computeroutput> </para></returns></method></method-group></struct></namespace><namespace name="result_of"><struct name="make_expr"><template>
+ <template-type-parameter name="Tag"/>
+ <template-type-parameter name="A0"/>
+ <template-type-parameter name="A1"><default>void</default></template-type-parameter>
+ <template-type-parameter name="A2"><default>void</default></template-type-parameter>
+ <template-type-parameter name="A3"><default>void</default></template-type-parameter>
+ <template-type-parameter name="A4"><default>void</default></template-type-parameter>
+ <template-type-parameter name="Void1"><default>void</default></template-type-parameter>
+ <template-type-parameter name="Void2"><default>void</default></template-type-parameter>
+ </template><purpose>Metafunction that computes the return type of the <computeroutput>make_expr()</computeroutput> function, with a domain deduced from the domains of the children. </purpose><description><para>Use the <computeroutput>result_of::make_expr&lt;&gt;</computeroutput> metafunction to compute the return type of the <computeroutput>make_expr()</computeroutput> function.</para><para>In this specialization, the domain is deduced from the domains of the child types. (If <computeroutput>is_domain&lt;A0&gt;::value</computeroutput> is <computeroutput>true</computeroutput>, then another specialization is selected.) </para></description><typedef name="type"><description><para>Same as <computeroutput>result_of::make_expr&lt;Tag, D, A0, ... AN&gt;::type</computeroutput> where <computeroutput>D</computeroutput> is the deduced domain, which is calculated as follows:</para><para>For each <computeroutput>x</computeroutput> in <computeroutput>[0,N)</computeroutput> (proceeding in order beginning with <compute
routput>x=0</computeroutput>), if <computeroutput>domain_of&lt;Ax&gt;::type</computeroutput> is not <computeroutput>default_domain</computeroutput>, then <computeroutput>D</computeroutput> is <computeroutput>domain_of&lt;Ax&gt;::type</computeroutput>. Otherwise, <computeroutput>D</computeroutput> is <computeroutput>default_domain</computeroutput>. </para></description><type><emphasis>unspecified</emphasis></type></typedef></struct><struct-specialization name="make_expr"><template>
+ <template-type-parameter name="Tag"/>
+ <template-type-parameter name="Domain"/>
+ <template-type-parameter name="A0"/>
+ <template-type-parameter name="A1"/>
+ <template-type-parameter name="A2"/>
+ <template-type-parameter name="A3"/>
+ <template-type-parameter name="A4"/>
+ </template><specialization><template-arg>Tag</template-arg><template-arg>Domain</template-arg><template-arg>A0</template-arg><template-arg>A1</template-arg><template-arg>A2</template-arg><template-arg>A3</template-arg><template-arg>A4</template-arg><template-arg>typename Domain::proto_is_domain_</template-arg></specialization><purpose>Metafunction that computes the return type of the <computeroutput>make_expr()</computeroutput> function, within the specified domain. </purpose><description><para>Use the <computeroutput>result_of::make_expr&lt;&gt;</computeroutput> metafunction to compute the return type of the <computeroutput>make_expr()</computeroutput> function. </para></description><typedef name="type"><description><para>If <computeroutput>Tag</computeroutput> is <computeroutput>tag::terminal</computeroutput>, then <computeroutput>type</computeroutput> is a typedef for <computeroutput>boost::result_of&lt;Domain(expr&lt;tag::terminal, term&lt;A0&gt; &gt;)&gt;::type</computeroutput>.</para><para>Otherwi
se, <computeroutput>type</computeroutput> is a typedef for <computeroutput>boost::result_of&lt;Domain(expr&lt;Tag, listN&lt; as_child&lt;A0&gt;::type, ... as_child&lt;AN&gt;::type&gt;) &gt;::type</computeroutput>, where <computeroutput>N</computeroutput> is the number of non-void template arguments, and <computeroutput>as_child&lt;A&gt;::type</computeroutput> is evaluated as follows:</para><para><itemizedlist>
+<listitem><para>If <computeroutput>is_expr&lt;A&gt;::value</computeroutput> is <computeroutput>true</computeroutput>, then the child type is <computeroutput>A</computeroutput>. </para></listitem>
+<listitem><para>If <computeroutput>A</computeroutput> is <computeroutput>B &amp;</computeroutput> or <computeroutput>cv boost::reference_wrapper&lt;B&gt;</computeroutput>, and <computeroutput>is_expr&lt;B&gt;::value</computeroutput> is <computeroutput>true</computeroutput>, then the child type is <computeroutput>ref_&lt;B&gt;</computeroutput>. </para></listitem>
+<listitem><para>If <computeroutput>is_expr&lt;A&gt;::value</computeroutput> is <computeroutput>false</computeroutput>, then the child type is <computeroutput>boost::result_of&lt;Domain(expr&lt;tag::terminal, term&lt;A&gt; &gt; )&gt;::type</computeroutput>. </para></listitem>
+<listitem><para>If <computeroutput>A</computeroutput> is <computeroutput>B &amp;</computeroutput> or <computeroutput>cv boost::reference_wrapper&lt;B&gt;</computeroutput>, and <computeroutput>is_expr&lt;B&gt;::value</computeroutput> is <computeroutput>false</computeroutput>, then the child type is <computeroutput>boost::result_of&lt;Domain(expr&lt;tag::terminal, term&lt;B &amp;&gt; &gt; )&gt;::type</computeroutput>. </para></listitem>
+</itemizedlist>
+</para></description><type><emphasis>unspecified</emphasis></type></typedef></struct-specialization><struct name="unpack_expr"><template>
+ <template-type-parameter name="Tag"/>
+ <template-type-parameter name="Sequence"/>
+ <template-type-parameter name="Void1"><default>void</default></template-type-parameter>
+ <template-type-parameter name="Void2"><default>void</default></template-type-parameter>
+ </template><purpose>Metafunction that computes the return type of the <computeroutput>unpack_expr()</computeroutput> function, with a domain deduced from the domains of the children. </purpose><description><para>Use the <computeroutput>result_of::unpack_expr&lt;&gt;</computeroutput> metafunction to compute the return type of the <computeroutput>unpack_expr()</computeroutput> function.</para><para><computeroutput>Sequence</computeroutput> is a Fusion Random Access Sequence.</para><para>In this specialization, the domain is deduced from the domains of the child types. (If <computeroutput>is_domain&lt;Sequence&gt;::value</computeroutput> is <computeroutput>true</computeroutput>, then another specialization is selected.) </para></description><typedef name="type"><description><para>Same as <computeroutput>result_of::make_expr&lt;Tag, fusion::value_at&lt;Sequence, 0&gt;::type, ... fusion::value_at&lt;Sequence, N-1&gt;::type&gt;::type</computeroutput>, where <computeroutput>N</computeroutput> is the size of <c
omputeroutput>Sequence</computeroutput>. </para></description><type><emphasis>unspecified</emphasis></type></typedef></struct><struct-specialization name="unpack_expr"><template>
+ <template-type-parameter name="Tag"/>
+ <template-type-parameter name="Domain"/>
+ <template-type-parameter name="Sequence"/>
+ </template><specialization><template-arg>Tag</template-arg><template-arg>Domain</template-arg><template-arg>Sequence</template-arg><template-arg>typename Domain::proto_is_domain_</template-arg></specialization><purpose>Metafunction that computes the return type of the <computeroutput>unpack_expr()</computeroutput> function, within the specified domain. </purpose><description><para>Use the <computeroutput>result_of::make_expr&lt;&gt;</computeroutput> metafunction to compute the return type of the <computeroutput>make_expr()</computeroutput> function. </para></description><typedef name="type"><description><para>Same as <computeroutput>result_of::make_expr&lt;Tag, Domain, fusion::value_at&lt;Sequence, 0&gt;::type, ... fusion::value_at&lt;Sequence, N-1&gt;::type&gt;::type</computeroutput>, where <computeroutput>N</computeroutput> is the size of <computeroutput>Sequence</computeroutput>. </para></description><type><emphasis>unspecified</emphasis></type></typedef></struct-specialization></namespace><overloade
d-function name="make_expr"><signature><type>lazy_disable_if&lt; is_domain&lt; A0 &gt;, <classname>result_of::make_expr</classname>&lt; Tag, A0 const &gt;&gt;::type const</type><template>
+ <template-type-parameter name="Tag"/>
+ <template-type-parameter name="A0"/>
+ </template><parameter name="a0"><paramtype>A0 const &amp;</paramtype></parameter></signature><signature><type><classname>result_of::make_expr</classname>&lt; Tag, Domain, B0 const &gt;::type const</type><template>
+ <template-type-parameter name="Tag"/>
+ <template-type-parameter name="Domain"/>
+ <template-type-parameter name="B0"/>
+ </template><parameter name="b0"><paramtype>B0 const &amp;</paramtype></parameter></signature><signature><type>lazy_disable_if&lt; is_domain&lt; A0 &gt;, <classname>result_of::make_expr</classname>&lt; Tag, const A0, const A1 &gt;&gt;::type const</type><template>
+ <template-type-parameter name="Tag"/>
+ <template-type-parameter name="A0"/>
+ <template-type-parameter name="A1"/>
+ </template><parameter name="a0"><paramtype>const A0 &amp;</paramtype></parameter><parameter name="a1"><paramtype>const A1 &amp;</paramtype></parameter></signature><signature><type><classname>result_of::make_expr</classname>&lt; Tag, Domain, const B0, const B1 &gt;::type const</type><template>
+ <template-type-parameter name="Tag"/>
+ <template-type-parameter name="Domain"/>
+ <template-type-parameter name="B0"/>
+ <template-type-parameter name="B1"/>
+ </template><parameter name="b0"><paramtype>const B0 &amp;</paramtype></parameter><parameter name="b1"><paramtype>const B1 &amp;</paramtype></parameter></signature><signature><type>lazy_disable_if&lt; is_domain&lt; A0 &gt;, <classname>result_of::make_expr</classname>&lt; Tag, const A0, const A1, const A2 &gt;&gt;::type const</type><template>
+ <template-type-parameter name="Tag"/>
+ <template-type-parameter name="A0"/>
+ <template-type-parameter name="A1"/>
+ <template-type-parameter name="A2"/>
+ </template><parameter name="a0"><paramtype>const A0 &amp;</paramtype></parameter><parameter name="a1"><paramtype>const A1 &amp;</paramtype></parameter><parameter name="a2"><paramtype>const A2 &amp;</paramtype></parameter></signature><signature><type><classname>result_of::make_expr</classname>&lt; Tag, Domain, const B0, const B1, const B2 &gt;::type const</type><template>
+ <template-type-parameter name="Tag"/>
+ <template-type-parameter name="Domain"/>
+ <template-type-parameter name="B0"/>
+ <template-type-parameter name="B1"/>
+ <template-type-parameter name="B2"/>
+ </template><parameter name="b0"><paramtype>const B0 &amp;</paramtype></parameter><parameter name="b1"><paramtype>const B1 &amp;</paramtype></parameter><parameter name="b2"><paramtype>const B2 &amp;</paramtype></parameter></signature><signature><type>lazy_disable_if&lt; is_domain&lt; A0 &gt;, <classname>result_of::make_expr</classname>&lt; Tag, const A0, const A1, const A2, const A3 &gt;&gt;::type const</type><template>
+ <template-type-parameter name="Tag"/>
+ <template-type-parameter name="A0"/>
+ <template-type-parameter name="A1"/>
+ <template-type-parameter name="A2"/>
+ <template-type-parameter name="A3"/>
+ </template><parameter name="a0"><paramtype>const A0 &amp;</paramtype></parameter><parameter name="a1"><paramtype>const A1 &amp;</paramtype></parameter><parameter name="a2"><paramtype>const A2 &amp;</paramtype></parameter><parameter name="a3"><paramtype>const A3 &amp;</paramtype></parameter></signature><signature><type><classname>result_of::make_expr</classname>&lt; Tag, Domain, const B0, const B1, const B2, const B3 &gt;::type const</type><template>
+ <template-type-parameter name="Tag"/>
+ <template-type-parameter name="Domain"/>
+ <template-type-parameter name="B0"/>
+ <template-type-parameter name="B1"/>
+ <template-type-parameter name="B2"/>
+ <template-type-parameter name="B3"/>
+ </template><parameter name="b0"><paramtype>const B0 &amp;</paramtype></parameter><parameter name="b1"><paramtype>const B1 &amp;</paramtype></parameter><parameter name="b2"><paramtype>const B2 &amp;</paramtype></parameter><parameter name="b3"><paramtype>const B3 &amp;</paramtype></parameter></signature><signature><type>lazy_disable_if&lt; is_domain&lt; A0 &gt;, <classname>result_of::make_expr</classname>&lt; Tag, const A0, const A1, const A2, const A3, const A4 &gt;&gt;::type const</type><template>
+ <template-type-parameter name="Tag"/>
+ <template-type-parameter name="A0"/>
+ <template-type-parameter name="A1"/>
+ <template-type-parameter name="A2"/>
+ <template-type-parameter name="A3"/>
+ <template-type-parameter name="A4"/>
+ </template><parameter name="a0"><paramtype>const A0 &amp;</paramtype></parameter><parameter name="a1"><paramtype>const A1 &amp;</paramtype></parameter><parameter name="a2"><paramtype>const A2 &amp;</paramtype></parameter><parameter name="a3"><paramtype>const A3 &amp;</paramtype></parameter><parameter name="a4"><paramtype>const A4 &amp;</paramtype></parameter></signature><signature><type><classname>result_of::make_expr</classname>&lt; Tag, Domain, const B0, const B1, const B2, const B3, const B4 &gt;::type const</type><template>
+ <template-type-parameter name="Tag"/>
+ <template-type-parameter name="Domain"/>
+ <template-type-parameter name="B0"/>
+ <template-type-parameter name="B1"/>
+ <template-type-parameter name="B2"/>
+ <template-type-parameter name="B3"/>
+ <template-type-parameter name="B4"/>
+ </template><parameter name="b0"><paramtype>const B0 &amp;</paramtype></parameter><parameter name="b1"><paramtype>const B1 &amp;</paramtype></parameter><parameter name="b2"><paramtype>const B2 &amp;</paramtype></parameter><parameter name="b3"><paramtype>const B3 &amp;</paramtype></parameter><parameter name="b4"><paramtype>const B4 &amp;</paramtype></parameter></signature><purpose>Construct an expression of the requested tag type with a domain and with the specified arguments as children. </purpose><description><para>This function template may be invoked either with or without specifying a <computeroutput>Domain</computeroutput> argument. If no domain is specified, the domain is deduced by examining in order the domains of the given arguments and taking the first that is not <computeroutput>default_domain</computeroutput>, if any such domain exists, or <computeroutput>default_domain</computeroutput> otherwise.</para><para>Let <computeroutput>wrap_(x)</computeroutput> be defined such that: <itemizedlis
t>
+<listitem><para>If <computeroutput>x</computeroutput> is a <computeroutput>boost::reference_wrapper&lt;&gt;</computeroutput>, <computeroutput>wrap_(x)</computeroutput> is equivalent to <computeroutput>as_child&lt;Domain&gt;(x.get())</computeroutput>. </para></listitem>
+<listitem><para>Otherwise, <computeroutput>wrap_(x)</computeroutput> is equivalent to <computeroutput>as_expr&lt;Domain&gt;(x)</computeroutput>.</para></listitem>
+</itemizedlist>
+Let <computeroutput>make_&lt;Tag&gt;(b0,...bN)</computeroutput> be defined as <computeroutput>expr&lt;Tag, listN&lt;B0,...BN&gt; &gt;::make(b0,...bN)</computeroutput> where <computeroutput>Bx</computeroutput> is the type of <computeroutput>bx</computeroutput>.</para><para>
+</para></description><returns><para><computeroutput>Domain()(make_&lt;Tag&gt;(wrap_(a0),...wrap_(aN)))</computeroutput>. </para></returns></overloaded-function><overloaded-function name="unpack_expr"><signature><type>lazy_disable_if&lt; is_domain&lt; Sequence &gt;, <classname>result_of::unpack_expr</classname>&lt; Tag, Sequence const &gt;&gt;::type const</type><template>
+ <template-type-parameter name="Tag"/>
+ <template-type-parameter name="Sequence"/>
+ </template><parameter name="sequence"><paramtype>Sequence const &amp;</paramtype><description><para>a Fusion Random Access Sequence. </para></description></parameter></signature><signature><type><classname>result_of::unpack_expr</classname>&lt; Tag, Domain, Sequence2 const &gt;::type const</type><template>
+ <template-type-parameter name="Tag"/>
+ <template-type-parameter name="Domain"/>
+ <template-type-parameter name="Sequence2"/>
+ </template><parameter name="sequence2"><paramtype>Sequence2 const &amp;</paramtype></parameter></signature><purpose>Construct an expression of the requested tag type with a domain and with childres from the specified Fusion Random Access Sequence. </purpose><description><para>This function template may be invoked either with or without specifying a <computeroutput>Domain</computeroutput> argument. If no domain is specified, the domain is deduced by examining in order the domains of the elements of <computeroutput>sequence</computeroutput> and taking the first that is not <computeroutput>default_domain</computeroutput>, if any such domain exists, or <computeroutput>default_domain</computeroutput> otherwise.</para><para>Let <computeroutput>wrap_&lt;N&gt;(s)</computeroutput>, where <computeroutput>s</computeroutput> has type <computeroutput>S</computeroutput>, be defined such that: <itemizedlist>
+<listitem><para>If <computeroutput>fusion::value_at&lt;S,N&gt;::type</computeroutput> is a reference, <computeroutput>wrap_&lt;N&gt;(s)</computeroutput> is equivalent to <computeroutput>as_child&lt;Domain&gt;(fusion::at_c&lt;N&gt;(s))</computeroutput>. </para></listitem>
+<listitem><para>Otherwise, <computeroutput>wrap_&lt;N&gt;(s)</computeroutput> is equivalent to <computeroutput>as_expr&lt;Domain&gt;(fusion::at_c&lt;N&gt;(s))</computeroutput>.</para></listitem>
+</itemizedlist>
+Let <computeroutput>make_&lt;Tag&gt;(b0,...bN)</computeroutput> be defined as <computeroutput>expr&lt;Tag, listN&lt;B0,...BN&gt; &gt;::make(b0,...bN)</computeroutput> where <computeroutput>Bx</computeroutput> is the type of <computeroutput>bx</computeroutput>.</para><para>
+
+</para></description><returns><para><computeroutput>Domain()(make_&lt;Tag&gt;(wrap_&lt;0&gt;(s),...wrap_&lt;N-1&gt;(S)))</computeroutput>, where N is the size of <computeroutput>Sequence</computeroutput>. </para></returns></overloaded-function></namespace></namespace></header><header name="boost/proto/matches.hpp"><para>Contains definition of matches&lt;&gt; metafunction for determining if a given expression matches a given pattern. </para><namespace name="boost"><namespace name="proto"><namespace name="control"><struct name="not_"><template>
+ <template-type-parameter name="Grammar"/>
+ </template><inherit access="public">boost::proto::callable</inherit><purpose>Inverts the set of expressions matched by a grammar. When used as a transform, <computeroutput>not_&lt;&gt;</computeroutput> returns the current expression unchanged. </purpose><description><para>If an expression type <computeroutput>E</computeroutput> does not match a grammar <computeroutput>G</computeroutput>, then <computeroutput>E</computeroutput> does match <computeroutput>not_&lt;G&gt;</computeroutput>. For example, <computeroutput>not_&lt;terminal&lt;_&gt; &gt;</computeroutput> will match any non-terminal. </para></description><struct-specialization name="result"><template>
+ <template-type-parameter name="This"/>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="State"/>
+ <template-type-parameter name="Data"/>
+ </template><specialization><template-arg>This(Expr</template-arg><template-arg>State</template-arg><template-arg>Data)</template-arg></specialization><typedef name="type"><type>Expr</type></typedef></struct-specialization><typedef name="proto_base_expr"><type><classname>not_</classname></type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type>Expr const &amp;</type><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="State"/>
+ <template-type-parameter name="Data"/>
+ </template><parameter name="expr"><paramtype>Expr const &amp;</paramtype><description><para>An expression </para></description></parameter><parameter name=""><paramtype>State const &amp;</paramtype></parameter><parameter name=""><paramtype>Data &amp;</paramtype></parameter><description><para>
+
+
+</para></description><requires><para><computeroutput>matches&lt;Expr,not_&gt;::value</computeroutput> is <computeroutput>true</computeroutput>. </para></requires><returns><para><computeroutput>expr</computeroutput> </para></returns></method></method-group></struct><struct name="if_"><template>
+ <template-type-parameter name="If"/>
+ <template-type-parameter name="Then"><default>_</default></template-type-parameter>
+ <template-type-parameter name="Else"><default>not_&lt;_&gt;</default></template-type-parameter>
+ </template><inherit access="public">boost::proto::callable</inherit><purpose>Used to select one grammar or another based on the result of a compile-time Boolean. When used as a transform, <computeroutput>if_&lt;&gt;</computeroutput> selects between two transforms based on a compile-time Boolean. </purpose><description><para>When <computeroutput>if_&lt;If,Then,Else&gt;</computeroutput> is used as a grammar, <computeroutput>If</computeroutput> must be a Proto transform and <computeroutput>Then</computeroutput> and <computeroutput>Else</computeroutput> must be grammars. An expression type <computeroutput>E</computeroutput> matches <computeroutput>if_&lt;If,Then,Else&gt;</computeroutput> if <computeroutput>when&lt;_,If&gt;::result&lt;void(E,int,int)&gt;::type::value</computeroutput> is <computeroutput>true</computeroutput> and <computeroutput>E</computeroutput> matches <computeroutput>U</computeroutput>; or, if <computeroutput>when&lt;_,If&gt;::result&lt;void(E,int,int)&gt;::type::value</computeroutput> is
<computeroutput>false</computeroutput> and <computeroutput>E</computeroutput> matches <computeroutput>V</computeroutput>.</para><para>The template parameter <computeroutput>Then</computeroutput> defaults to <computeroutput>_</computeroutput> and <computeroutput>Else</computeroutput> defaults to <computeroutput>not&lt;_&gt;</computeroutput>, so an expression type <computeroutput>E</computeroutput> will match <computeroutput>if_&lt;If&gt;</computeroutput> if and only if <computeroutput>when&lt;_,If&gt;::result&lt;void(E,int,int)&gt;::type::value</computeroutput> is <computeroutput>true</computeroutput>.</para><para><programlisting> // A grammar that only matches integral terminals,
+ // using is_integral&lt;&gt; from Boost.Type_traits.
+ struct IsIntegral
+ : and_&lt;
+ terminal&lt;_&gt;
+ , if_&lt; is_integral&lt;_value&gt;() &gt;
+ &gt;
+ {};
+</programlisting></para><para>When <computeroutput>if_&lt;If,Then,Else&gt;</computeroutput> is used as a transform, <computeroutput>If</computeroutput>, <computeroutput>Then</computeroutput> and <computeroutput>Else</computeroutput> must be Proto transforms. When applying the transform to an expression <computeroutput>E</computeroutput>, state <computeroutput>S</computeroutput> and data <computeroutput>V</computeroutput>, if <computeroutput>when&lt;_,If&gt;::result&lt;void(E,S,V)&gt;::type::value</computeroutput> is <computeroutput>true</computeroutput> then the <computeroutput>Then</computeroutput> transform is applied; otherwise the <computeroutput>Else</computeroutput> transform is applied.</para><para><programlisting> // Match a terminal. If the terminal is integral, return
+ // mpl::true_; otherwise, return mpl::false_.
+ struct IsIntegral2
+ : when&lt;
+ terminal&lt;_&gt;
+ , if_&lt;
+ is_integral&lt;_value&gt;()
+ , mpl::true_()
+ , mpl::false_()
+ &gt;
+ &gt;
+ {};
+</programlisting> </para></description><struct-specialization name="result"><template>
+ <template-type-parameter name="This"/>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="State"/>
+ <template-type-parameter name="Data"/>
+ </template><specialization><template-arg>This(Expr</template-arg><template-arg>State</template-arg><template-arg>Data)</template-arg></specialization><typedef name="condition"><type><classname>when</classname>&lt; _, If &gt;::template result&lt; void(Expr, State, Data)&gt;::type</type></typedef><typedef name="which"><type>mpl::if_&lt; condition, <classname>when</classname>&lt; _, Then &gt;, <classname>when</classname>&lt; _, Else &gt;&gt;::type</type></typedef><typedef name="type"><type>which::template result&lt; void(Expr, State, Data)&gt;::type</type></typedef></struct-specialization><typedef name="proto_base_expr"><type><classname>if_</classname></type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type>result&lt; void(Expr, State, Data)&gt;::type</type><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="State"/>
+ <template-type-parameter name="Data"/>
+ </template><parameter name="expr"><paramtype>Expr const &amp;</paramtype><description><para>An expression </para></description></parameter><parameter name="state"><paramtype>State const &amp;</paramtype><description><para>The current state </para></description></parameter><parameter name="data"><paramtype>Data &amp;</paramtype><description><para>A data of arbitrary type </para></description></parameter><description><para>
+
+</para></description><returns><para><computeroutput>result&lt;void(Expr, State, Data)&gt;::which()(expr, state, data)</computeroutput> </para></returns></method></method-group></struct><struct name="or_"><template>
+ <template-type-parameter name="G0"/>
+ <template-type-parameter name="G1"/>
+ <template-type-parameter name="G2"/>
+ <template-type-parameter name="G3"/>
+ <template-type-parameter name="G4"/>
+ <template-type-parameter name="G5"/>
+ <template-type-parameter name="G6"/>
+ <template-type-parameter name="G7"/>
+ </template><inherit access="public">boost::proto::callable</inherit><purpose>For matching one of a set of alternate grammars. Alternates tried in order to avoid ambiguity. When used as a transform, <computeroutput>or_&lt;&gt;</computeroutput> applies the transform associated with the first grammar that matches the expression. </purpose><description><para>An expression type <computeroutput>E</computeroutput> matches <computeroutput>or_&lt;B0,B1,...Bn&gt;</computeroutput> if <computeroutput>E</computeroutput> matches any <computeroutput>Bx</computeroutput> for <computeroutput>x</computeroutput> in <computeroutput>[0,n)</computeroutput>.</para><para>When applying <computeroutput>or_&lt;B0,B1,...Bn&gt;</computeroutput> as a transform with an expression <computeroutput>e</computeroutput> of type <computeroutput>E</computeroutput>, state <computeroutput>s</computeroutput> and data <computeroutput>v</computeroutput>, it is equivalent to <computeroutput>Bx()(e, s, v)</computeroutput>, where <computeroutput>x</c
omputeroutput> is the lowest number such that <computeroutput>matches&lt;E,Bx&gt;::value</computeroutput> is <computeroutput>true</computeroutput>. </para></description><struct-specialization name="result"><template>
+ <template-type-parameter name="This"/>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="State"/>
+ <template-type-parameter name="Data"/>
+ </template><specialization><template-arg>This(Expr</template-arg><template-arg>State</template-arg><template-arg>Data)</template-arg></specialization><typedef name="which"><type><emphasis>unspecified</emphasis></type></typedef><typedef name="type"><type>which::template result&lt; void(Expr, State, Data)&gt;::type</type></typedef></struct-specialization><typedef name="proto_base_expr"><type><classname>or_</classname></type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type>result&lt; void(Expr, State, Data)&gt;::type</type><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="State"/>
+ <template-type-parameter name="Data"/>
+ </template><parameter name="expr"><paramtype>Expr const &amp;</paramtype><description><para>An expression </para></description></parameter><parameter name="state"><paramtype>State const &amp;</paramtype><description><para>The current state </para></description></parameter><parameter name="data"><paramtype>Data &amp;</paramtype><description><para>A data of arbitrary type </para></description></parameter><description><para>
+
+
+</para></description><requires><para><computeroutput>matches&lt;Expr,or_&gt;::value</computeroutput> is <computeroutput>true</computeroutput>. </para></requires><returns><para><computeroutput>result&lt;void(Expr, State, Data)&gt;::which()(expr, state, data)</computeroutput> </para></returns></method></method-group></struct><struct name="and_"><template>
+ <template-type-parameter name="G0"/>
+ <template-type-parameter name="G1"/>
+ <template-type-parameter name="G2"/>
+ <template-type-parameter name="G3"/>
+ <template-type-parameter name="G4"/>
+ <template-type-parameter name="G5"/>
+ <template-type-parameter name="G6"/>
+ <template-type-parameter name="G7"/>
+ </template><inherit access="public">boost::proto::callable</inherit><purpose>For matching all of a set of grammars. When used as a transform, <computeroutput>and_&lt;&gt;</computeroutput> applies the transform associated with the last grammar in the set. </purpose><description><para>An expression type <computeroutput>E</computeroutput> matches <computeroutput>and_&lt;B0,B1,...Bn&gt;</computeroutput> if <computeroutput>E</computeroutput> matches all <computeroutput>Bx</computeroutput> for <computeroutput>x</computeroutput> in <computeroutput>[0,n)</computeroutput>.</para><para>When applying <computeroutput>and_&lt;B0,B1,...Bn&gt;</computeroutput> as a transform with an expression <computeroutput>e</computeroutput>, state <computeroutput>s</computeroutput> and data <computeroutput>v</computeroutput>, it is equivalent to <computeroutput>Bn()(e, s, v)</computeroutput>. </para></description><struct-specialization name="result"><template>
+ <template-type-parameter name="This"/>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="State"/>
+ <template-type-parameter name="Data"/>
+ </template><specialization><template-arg>This(Expr</template-arg><template-arg>State</template-arg><template-arg>Data)</template-arg></specialization><typedef name="which"><type><emphasis>unspecified</emphasis></type></typedef><typedef name="type"><type>which::template result&lt; void(Expr, State, Data)&gt;::type</type></typedef></struct-specialization><typedef name="proto_base_expr"><type><classname>and_</classname></type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type>result&lt; void(Expr, State, Data)&gt;::type</type><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="State"/>
+ <template-type-parameter name="Data"/>
+ </template><parameter name="expr"><paramtype>Expr const &amp;</paramtype><description><para>An expression </para></description></parameter><parameter name="state"><paramtype>State const &amp;</paramtype><description><para>The current state </para></description></parameter><parameter name="data"><paramtype>Data &amp;</paramtype><description><para>A data of arbitrary type </para></description></parameter><description><para>
+
+
+</para></description><requires><para><computeroutput>matches&lt;Expr,and_&gt;::value</computeroutput> is <computeroutput>true</computeroutput>. </para></requires><returns><para><computeroutput>result&lt;void(Expr, State, Data)&gt;::which()(expr, state, data)</computeroutput> </para></returns></method></method-group></struct><struct name="switch_"><template>
+ <template-type-parameter name="Cases"/>
+ </template><inherit access="public">boost::proto::callable</inherit><purpose>For matching one of a set of alternate grammars, which are looked up based on an expression's tag type. When used as a transform, <computeroutput>switch_&lt;&gt;</computeroutput> applies the transform associated with the grammar that matches the expression. </purpose><description><para>
+An expression type <computeroutput>E</computeroutput> matches <computeroutput>switch_&lt;C&gt;</computeroutput> if <computeroutput>E</computeroutput> matches <computeroutput>C::case_&lt;E::proto_tag&gt;</computeroutput>.</para><para>When applying <computeroutput>switch_&lt;C&gt;</computeroutput> as a transform with an expression <computeroutput>e</computeroutput> of type <computeroutput>E</computeroutput>, state <computeroutput>s</computeroutput> and data <computeroutput>v</computeroutput>, it is equivalent to <computeroutput>C::case_&lt;E::proto_tag&gt;()(e, s, v)</computeroutput>. </para></description><struct-specialization name="result"><template>
+ <template-type-parameter name="This"/>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="State"/>
+ <template-type-parameter name="Data"/>
+ </template><specialization><template-arg>This(Expr</template-arg><template-arg>State</template-arg><template-arg>Data)</template-arg></specialization><typedef name="which"><type>Cases::template case_&lt; typename Expr::proto_tag &gt;</type></typedef><typedef name="type"><type>which::template result&lt; void(Expr, State, Data)&gt;::type</type></typedef></struct-specialization><typedef name="proto_base_expr"><type><classname>switch_</classname></type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type>result&lt; void(Expr, State, Data)&gt;::type</type><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="State"/>
+ <template-type-parameter name="Data"/>
+ </template><parameter name="expr"><paramtype>Expr const &amp;</paramtype><description><para>An expression </para></description></parameter><parameter name="state"><paramtype>State const &amp;</paramtype><description><para>The current state </para></description></parameter><parameter name="data"><paramtype>Data &amp;</paramtype><description><para>A data of arbitrary type </para></description></parameter><description><para>
+
+
+</para></description><requires><para><computeroutput>matches&lt;Expr,switch_&gt;::value</computeroutput> is <computeroutput>true</computeroutput>. </para></requires><returns><para><computeroutput>result&lt;void(Expr, State, Data)&gt;::which()(expr, state, data)</computeroutput> </para></returns></method></method-group></struct><struct name="exact"><template>
+ <template-type-parameter name="T"/>
+ </template><purpose>For forcing exact matches of terminal types. </purpose><description><para>By default, matching terminals ignores references and cv-qualifiers. For instance, a terminal expression of type <computeroutput>terminal&lt;int const &amp;&gt;::type</computeroutput> will match the grammar <computeroutput>terminal&lt;int&gt;</computeroutput>. If that is not desired, you can force an exact match with <computeroutput>terminal&lt;exact&lt;int&gt; &gt;</computeroutput>. This will only match integer terminals where the terminal is held by value. </para></description></struct><struct name="convertible_to"><template>
+ <template-type-parameter name="T"/>
+ </template><purpose>For matching terminals that are convertible to a type. </purpose><description><para>Use <computeroutput>convertible_to&lt;&gt;</computeroutput> to match a terminal that is convertible to some type. For example, the grammar <computeroutput>terminal&lt;convertible_to&lt;int&gt; &gt;</computeroutput> will match any terminal whose argument is convertible to an integer.</para><para>
+</para></description></struct><struct name="vararg"><template>
+ <template-type-parameter name="Grammar"/>
+ </template><purpose>For matching a Grammar to a variable number of sub-expressions. </purpose><description><para>An expression type <computeroutput>expr&lt;AT, listN&lt;A0,...An,U0,...Um&gt; &gt;</computeroutput> matches a grammar <computeroutput>expr&lt;BT, listM&lt;B0,...Bn,vararg&lt;V&gt; &gt; &gt;</computeroutput> if <computeroutput>BT</computeroutput> is <computeroutput>_</computeroutput> or <computeroutput>AT</computeroutput>, and if <computeroutput>Ax</computeroutput> matches <computeroutput>Bx</computeroutput> for each <computeroutput>x</computeroutput> in <computeroutput>[0,n)</computeroutput> and if <computeroutput>Ux</computeroutput> matches <computeroutput>V</computeroutput> for each <computeroutput>x</computeroutput> in <computeroutput>[0,m)</computeroutput>.</para><para>For example:</para><para><programlisting> // Match any function call expression, irregardless
+ // of the number of function arguments:
+ struct Function
+ : function&lt; vararg&lt;_&gt; &gt;
+ {};
+</programlisting></para><para>When used as a transform, <computeroutput>vararg&lt;G&gt;</computeroutput> applies <computeroutput>G</computeroutput>'s transform. </para></description><typedef name="proto_is_vararg_"><type>void</type></typedef></struct></namespace><namespace name="result_of"><struct name="matches"><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="Grammar"/>
+ </template><purpose>A Boolean metafunction that evaluates whether a given expression type matches a grammar. </purpose><description><para><computeroutput>matches&lt;Expr,Grammar&gt;</computeroutput> inherits (indirectly) from <computeroutput>mpl::true_</computeroutput> if <computeroutput>Expr::proto_base_expr</computeroutput> matches <computeroutput>Grammar::proto_base_expr</computeroutput>, and from <computeroutput>mpl::false_</computeroutput> otherwise.</para><para>Non-terminal expressions are matched against a grammar according to the following rules:</para><para><itemizedlist>
+<listitem><para>The wildcard pattern, <computeroutput>_</computeroutput>, matches any expression. </para></listitem>
+<listitem><para>An expression <computeroutput>expr&lt;AT, listN&lt;A0,A1,...An&gt; &gt;</computeroutput> matches a grammar <computeroutput>expr&lt;BT, listN&lt;B0,B1,...Bn&gt; &gt;</computeroutput> if <computeroutput>BT</computeroutput> is <computeroutput>_</computeroutput> or <computeroutput>AT</computeroutput>, and if <computeroutput>Ax</computeroutput> matches <computeroutput>Bx</computeroutput> for each <computeroutput>x</computeroutput> in <computeroutput>[0,n)</computeroutput>. </para></listitem>
+<listitem><para>An expression <computeroutput>expr&lt;AT, listN&lt;A0,...An,U0,...Um&gt; &gt;</computeroutput> matches a grammar <computeroutput>expr&lt;BT, listM&lt;B0,...Bn,vararg&lt;V&gt; &gt; &gt;</computeroutput> if <computeroutput>BT</computeroutput> is <computeroutput>_</computeroutput> or <computeroutput>AT</computeroutput>, and if <computeroutput>Ax</computeroutput> matches <computeroutput>Bx</computeroutput> for each <computeroutput>x</computeroutput> in <computeroutput>[0,n)</computeroutput> and if <computeroutput>Ux</computeroutput> matches <computeroutput>V</computeroutput> for each <computeroutput>x</computeroutput> in <computeroutput>[0,m)</computeroutput>. </para></listitem>
+<listitem><para>An expression <computeroutput>E</computeroutput> matches <computeroutput>or_&lt;B0,B1,...Bn&gt;</computeroutput> if <computeroutput>E</computeroutput> matches some <computeroutput>Bx</computeroutput> for <computeroutput>x</computeroutput> in <computeroutput>[0,n)</computeroutput>. </para></listitem>
+<listitem><para>An expression <computeroutput>E</computeroutput> matches <computeroutput>and_&lt;B0,B1,...Bn&gt;</computeroutput> if <computeroutput>E</computeroutput> matches all <computeroutput>Bx</computeroutput> for <computeroutput>x</computeroutput> in <computeroutput>[0,n)</computeroutput>. </para></listitem>
+<listitem><para>An expression <computeroutput>E</computeroutput> matches <computeroutput>if_&lt;T,U,V&gt;</computeroutput> if <computeroutput>when&lt;_,T&gt;::result&lt;void(E,int,int)&gt;::type::value</computeroutput> is <computeroutput>true</computeroutput> and <computeroutput>E</computeroutput> matches <computeroutput>U</computeroutput>; or, if <computeroutput>when&lt;_,T&gt;::result&lt;void(E,int,int)&gt;::type::value</computeroutput> is <computeroutput>false</computeroutput> and <computeroutput>E</computeroutput> matches <computeroutput>V</computeroutput>. (Note: <computeroutput>U</computeroutput> defaults to <computeroutput>_</computeroutput> and <computeroutput>V</computeroutput> defaults to <computeroutput>not_&lt;_&gt;</computeroutput>.) </para></listitem>
+<listitem><para>An expression <computeroutput>E</computeroutput> matches <computeroutput>not_&lt;T&gt;</computeroutput> if <computeroutput>E</computeroutput> does not match <computeroutput>T</computeroutput>. </para></listitem>
+<listitem><para>An expression <computeroutput>E</computeroutput> matches <computeroutput>switch_&lt;C&gt;</computeroutput> if <computeroutput>E</computeroutput> matches <computeroutput>C::case_&lt;E::proto_tag&gt;</computeroutput>.</para></listitem>
+</itemizedlist>
+A terminal expression <computeroutput>expr&lt;tag::terminal,term&lt;A&gt; &gt;</computeroutput> matches a grammar <computeroutput>expr&lt;BT,term&lt;B&gt; &gt;</computeroutput> if <computeroutput>BT</computeroutput> is <computeroutput>_</computeroutput> or <computeroutput>tag::terminal</computeroutput> and one of the following is true:</para><para><itemizedlist>
+<listitem><para><computeroutput>B</computeroutput> is the wildcard pattern, <computeroutput>_</computeroutput> </para></listitem>
+<listitem><para><computeroutput>A</computeroutput> is <computeroutput>B</computeroutput> </para></listitem>
+<listitem><para><computeroutput>A</computeroutput> is <computeroutput>B &amp;</computeroutput> </para></listitem>
+<listitem><para><computeroutput>A</computeroutput> is <computeroutput>B const &amp;</computeroutput> </para></listitem>
+<listitem><para><computeroutput>B</computeroutput> is <computeroutput>exact&lt;A&gt;</computeroutput> </para></listitem>
+<listitem><para><computeroutput>B</computeroutput> is <computeroutput>convertible_to&lt;X&gt;</computeroutput> and <computeroutput>is_convertible&lt;A,X&gt;::value</computeroutput> is <computeroutput>true</computeroutput>. </para></listitem>
+<listitem><para><computeroutput>A</computeroutput> is <computeroutput>X[M]</computeroutput> or <computeroutput>X(&amp;)[M]</computeroutput> and <computeroutput>B</computeroutput> is <computeroutput>X[proto::N]</computeroutput>. </para></listitem>
+<listitem><para><computeroutput>A</computeroutput> is <computeroutput>X(&amp;)[M]</computeroutput> and <computeroutput>B</computeroutput> is <computeroutput>X(&amp;)[proto::N]</computeroutput>. </para></listitem>
+<listitem><para><computeroutput>A</computeroutput> is <computeroutput>X[M]</computeroutput> or <computeroutput>X(&amp;)[M]</computeroutput> and <computeroutput>B</computeroutput> is <computeroutput>X*</computeroutput>. </para></listitem>
+<listitem><para><computeroutput>B</computeroutput> lambda-matches <computeroutput>A</computeroutput> (see below).</para></listitem>
+</itemizedlist>
+A type <computeroutput>B</computeroutput> lambda-matches <computeroutput>A</computeroutput> if one of the following is true:</para><para><itemizedlist>
+<listitem><para><computeroutput>B</computeroutput> is <computeroutput>A</computeroutput> </para></listitem>
+<listitem><para><computeroutput>B</computeroutput> is the wildcard pattern, <computeroutput>_</computeroutput> </para></listitem>
+<listitem><para><computeroutput>B</computeroutput> is <computeroutput>T&lt;B0,B1,...Bn&gt;</computeroutput> and <computeroutput>A</computeroutput> is <computeroutput>T&lt;A0,A1,...An&gt;</computeroutput> and for each <computeroutput>x</computeroutput> in <computeroutput>[0,n)</computeroutput>, <computeroutput>Ax</computeroutput> and <computeroutput>Bx</computeroutput> are types such that <computeroutput>Ax</computeroutput> lambda-matches <computeroutput>Bx</computeroutput> </para></listitem>
+</itemizedlist>
+</para></description></struct></namespace><namespace name="wildcardns_"><struct name="_"><inherit access="public">boost::proto::callable</inherit><purpose>A wildcard grammar element that matches any expression, and a transform that returns the current expression unchanged. </purpose><description><para>The wildcard type, <computeroutput>_</computeroutput>, is a grammar element such that <computeroutput>matches&lt;E,_&gt;::value</computeroutput> is <computeroutput>true</computeroutput> for any expression type <computeroutput>E</computeroutput>.</para><para>The wildcard can also be used as a stand-in for a template argument when matching terminals. For instance, the following is a grammar that will match any <computeroutput>std::complex&lt;&gt;</computeroutput> terminal:</para><para><programlisting> BOOST_MPL_ASSERT((
+ matches&lt;
+ terminal&lt;std::complex&lt;double&gt; &gt;::type
+ , terminal&lt;std::complex&lt; _ &gt; &gt;
+ &gt;
+ ));
+</programlisting></para><para>When used as a transform, <computeroutput>_</computeroutput> returns the current expression unchanged. For instance, in the following, <computeroutput>_</computeroutput> is used with the <computeroutput>fold&lt;&gt;</computeroutput> transform to fold the children of a node:</para><para><programlisting> struct CountChildren
+ : or_&lt;
+ // Terminals have no children
+ when&lt;terminal&lt;_&gt;, mpl::int_&lt;0&gt;()&gt;
+ // Use fold&lt;&gt; to count the children of non-terminals
+ , otherwise&lt;
+ fold&lt;
+ _ // &lt;-- fold the current expression
+ , mpl::int_&lt;0&gt;()
+ , mpl::plus&lt;_state, mpl::int_&lt;1&gt; &gt;()
+ &gt;
+ &gt;
+ &gt;
+ {};
+</programlisting> </para></description><struct-specialization name="result"><template>
+ <template-type-parameter name="This"/>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="State"/>
+ <template-type-parameter name="Data"/>
+ </template><specialization><template-arg>This(Expr</template-arg><template-arg>State</template-arg><template-arg>Data)</template-arg></specialization><typedef name="type"><type>Expr</type></typedef></struct-specialization><typedef name="proto_base_expr"><type><classname>_</classname></type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type>Expr const &amp;</type><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="State"/>
+ <template-type-parameter name="Data"/>
+ </template><parameter name="expr"><paramtype>Expr const &amp;</paramtype><description><para>An expression </para></description></parameter><parameter name=""><paramtype>State const &amp;</paramtype></parameter><parameter name=""><paramtype>Data &amp;</paramtype></parameter><description><para>
+
+</para></description><returns><para><computeroutput>expr</computeroutput> </para></returns></method></method-group></struct></namespace></namespace></namespace></header><header name="boost/proto/operators.hpp"><para>Contains all the overloaded operators that make it possible to build Proto expression trees. </para><namespace name="boost"><namespace name="proto"><struct name="is_extension"><template>
+ <template-type-parameter name="T"/>
+ </template><inherit access="public">boost::mpl::false_</inherit></struct><function name="operator+"><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Arg"/>
+ </template><parameter name="arg"><paramtype>Arg &amp;</paramtype></parameter></function><function name="operator+"><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Arg"/>
+ </template><parameter name="arg"><paramtype>Arg const &amp;</paramtype></parameter></function><function name="operator-"><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Arg"/>
+ </template><parameter name="arg"><paramtype>Arg &amp;</paramtype></parameter></function><function name="operator-"><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Arg"/>
+ </template><parameter name="arg"><paramtype>Arg const &amp;</paramtype></parameter></function><function name="operator*"><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Arg"/>
+ </template><parameter name="arg"><paramtype>Arg &amp;</paramtype></parameter></function><function name="operator*"><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Arg"/>
+ </template><parameter name="arg"><paramtype>Arg const &amp;</paramtype></parameter></function><function name="operator~"><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Arg"/>
+ </template><parameter name="arg"><paramtype>Arg &amp;</paramtype></parameter></function><function name="operator~"><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Arg"/>
+ </template><parameter name="arg"><paramtype>Arg const &amp;</paramtype></parameter></function><function name="operator&amp;"><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Arg"/>
+ </template><parameter name="arg"><paramtype>Arg &amp;</paramtype></parameter></function><function name="operator&amp;"><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Arg"/>
+ </template><parameter name="arg"><paramtype>Arg const &amp;</paramtype></parameter></function><function name="operator!"><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Arg"/>
+ </template><parameter name="arg"><paramtype>Arg &amp;</paramtype></parameter></function><function name="operator!"><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Arg"/>
+ </template><parameter name="arg"><paramtype>Arg const &amp;</paramtype></parameter></function><function name="operator++"><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Arg"/>
+ </template><parameter name="arg"><paramtype>Arg &amp;</paramtype></parameter></function><function name="operator++"><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Arg"/>
+ </template><parameter name="arg"><paramtype>Arg const &amp;</paramtype></parameter></function><function name="operator--"><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Arg"/>
+ </template><parameter name="arg"><paramtype>Arg &amp;</paramtype></parameter></function><function name="operator--"><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Arg"/>
+ </template><parameter name="arg"><paramtype>Arg const &amp;</paramtype></parameter></function><function name="operator++"><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Arg"/>
+ </template><parameter name="arg"><paramtype>Arg &amp;</paramtype></parameter><parameter name=""><paramtype>int</paramtype></parameter></function><function name="operator++"><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Arg"/>
+ </template><parameter name="arg"><paramtype>Arg const &amp;</paramtype></parameter><parameter name=""><paramtype>int</paramtype></parameter></function><function name="operator--"><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Arg"/>
+ </template><parameter name="arg"><paramtype>Arg &amp;</paramtype></parameter><parameter name=""><paramtype>int</paramtype></parameter></function><function name="operator--"><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Arg"/>
+ </template><parameter name="arg"><paramtype>Arg const &amp;</paramtype></parameter><parameter name=""><paramtype>int</paramtype></parameter></function><function name="operator&lt;&lt;"><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Left"/>
+ <template-type-parameter name="Right"/>
+ </template><parameter name="left"><paramtype>Left &amp;</paramtype></parameter><parameter name="right"><paramtype>Right &amp;</paramtype></parameter></function><function name="operator&lt;&lt;"><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Left"/>
+ <template-type-parameter name="Right"/>
+ </template><parameter name="left"><paramtype>Left &amp;</paramtype></parameter><parameter name="right"><paramtype>Right const &amp;</paramtype></parameter></function><function name="operator&lt;&lt;"><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Left"/>
+ <template-type-parameter name="Right"/>
+ </template><parameter name="left"><paramtype>Left const &amp;</paramtype></parameter><parameter name="right"><paramtype>Right &amp;</paramtype></parameter></function><function name="operator&lt;&lt;"><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Left"/>
+ <template-type-parameter name="Right"/>
+ </template><parameter name="left"><paramtype>Left const &amp;</paramtype></parameter><parameter name="right"><paramtype>Right const &amp;</paramtype></parameter></function><function name="operator&gt;&gt;"><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Left"/>
+ <template-type-parameter name="Right"/>
+ </template><parameter name="left"><paramtype>Left &amp;</paramtype></parameter><parameter name="right"><paramtype>Right &amp;</paramtype></parameter></function><function name="operator&gt;&gt;"><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Left"/>
+ <template-type-parameter name="Right"/>
+ </template><parameter name="left"><paramtype>Left &amp;</paramtype></parameter><parameter name="right"><paramtype>Right const &amp;</paramtype></parameter></function><function name="operator&gt;&gt;"><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Left"/>
+ <template-type-parameter name="Right"/>
+ </template><parameter name="left"><paramtype>Left const &amp;</paramtype></parameter><parameter name="right"><paramtype>Right &amp;</paramtype></parameter></function><function name="operator&gt;&gt;"><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Left"/>
+ <template-type-parameter name="Right"/>
+ </template><parameter name="left"><paramtype>Left const &amp;</paramtype></parameter><parameter name="right"><paramtype>Right const &amp;</paramtype></parameter></function><function name="operator*"><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Left"/>
+ <template-type-parameter name="Right"/>
+ </template><parameter name="left"><paramtype>Left &amp;</paramtype></parameter><parameter name="right"><paramtype>Right &amp;</paramtype></parameter></function><function name="operator*"><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Left"/>
+ <template-type-parameter name="Right"/>
+ </template><parameter name="left"><paramtype>Left &amp;</paramtype></parameter><parameter name="right"><paramtype>Right const &amp;</paramtype></parameter></function><function name="operator*"><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Left"/>
+ <template-type-parameter name="Right"/>
+ </template><parameter name="left"><paramtype>Left const &amp;</paramtype></parameter><parameter name="right"><paramtype>Right &amp;</paramtype></parameter></function><function name="operator*"><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Left"/>
+ <template-type-parameter name="Right"/>
+ </template><parameter name="left"><paramtype>Left const &amp;</paramtype></parameter><parameter name="right"><paramtype>Right const &amp;</paramtype></parameter></function><function name="operator/"><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Left"/>
+ <template-type-parameter name="Right"/>
+ </template><parameter name="left"><paramtype>Left &amp;</paramtype></parameter><parameter name="right"><paramtype>Right &amp;</paramtype></parameter></function><function name="operator/"><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Left"/>
+ <template-type-parameter name="Right"/>
+ </template><parameter name="left"><paramtype>Left &amp;</paramtype></parameter><parameter name="right"><paramtype>Right const &amp;</paramtype></parameter></function><function name="operator/"><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Left"/>
+ <template-type-parameter name="Right"/>
+ </template><parameter name="left"><paramtype>Left const &amp;</paramtype></parameter><parameter name="right"><paramtype>Right &amp;</paramtype></parameter></function><function name="operator/"><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Left"/>
+ <template-type-parameter name="Right"/>
+ </template><parameter name="left"><paramtype>Left const &amp;</paramtype></parameter><parameter name="right"><paramtype>Right const &amp;</paramtype></parameter></function><function name="operator%"><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Left"/>
+ <template-type-parameter name="Right"/>
+ </template><parameter name="left"><paramtype>Left &amp;</paramtype></parameter><parameter name="right"><paramtype>Right &amp;</paramtype></parameter></function><function name="operator%"><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Left"/>
+ <template-type-parameter name="Right"/>
+ </template><parameter name="left"><paramtype>Left &amp;</paramtype></parameter><parameter name="right"><paramtype>Right const &amp;</paramtype></parameter></function><function name="operator%"><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Left"/>
+ <template-type-parameter name="Right"/>
+ </template><parameter name="left"><paramtype>Left const &amp;</paramtype></parameter><parameter name="right"><paramtype>Right &amp;</paramtype></parameter></function><function name="operator%"><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Left"/>
+ <template-type-parameter name="Right"/>
+ </template><parameter name="left"><paramtype>Left const &amp;</paramtype></parameter><parameter name="right"><paramtype>Right const &amp;</paramtype></parameter></function><function name="operator+"><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Left"/>
+ <template-type-parameter name="Right"/>
+ </template><parameter name="left"><paramtype>Left &amp;</paramtype></parameter><parameter name="right"><paramtype>Right &amp;</paramtype></parameter></function><function name="operator+"><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Left"/>
+ <template-type-parameter name="Right"/>
+ </template><parameter name="left"><paramtype>Left &amp;</paramtype></parameter><parameter name="right"><paramtype>Right const &amp;</paramtype></parameter></function><function name="operator+"><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Left"/>
+ <template-type-parameter name="Right"/>
+ </template><parameter name="left"><paramtype>Left const &amp;</paramtype></parameter><parameter name="right"><paramtype>Right &amp;</paramtype></parameter></function><function name="operator+"><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Left"/>
+ <template-type-parameter name="Right"/>
+ </template><parameter name="left"><paramtype>Left const &amp;</paramtype></parameter><parameter name="right"><paramtype>Right const &amp;</paramtype></parameter></function><function name="operator-"><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Left"/>
+ <template-type-parameter name="Right"/>
+ </template><parameter name="left"><paramtype>Left &amp;</paramtype></parameter><parameter name="right"><paramtype>Right &amp;</paramtype></parameter></function><function name="operator-"><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Left"/>
+ <template-type-parameter name="Right"/>
+ </template><parameter name="left"><paramtype>Left &amp;</paramtype></parameter><parameter name="right"><paramtype>Right const &amp;</paramtype></parameter></function><function name="operator-"><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Left"/>
+ <template-type-parameter name="Right"/>
+ </template><parameter name="left"><paramtype>Left const &amp;</paramtype></parameter><parameter name="right"><paramtype>Right &amp;</paramtype></parameter></function><function name="operator-"><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Left"/>
+ <template-type-parameter name="Right"/>
+ </template><parameter name="left"><paramtype>Left const &amp;</paramtype></parameter><parameter name="right"><paramtype>Right const &amp;</paramtype></parameter></function><function name="operator&lt;"><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Left"/>
+ <template-type-parameter name="Right"/>
+ </template><parameter name="left"><paramtype>Left &amp;</paramtype></parameter><parameter name="right"><paramtype>Right &amp;</paramtype></parameter></function><function name="operator&lt;"><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Left"/>
+ <template-type-parameter name="Right"/>
+ </template><parameter name="left"><paramtype>Left &amp;</paramtype></parameter><parameter name="right"><paramtype>Right const &amp;</paramtype></parameter></function><function name="operator&lt;"><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Left"/>
+ <template-type-parameter name="Right"/>
+ </template><parameter name="left"><paramtype>Left const &amp;</paramtype></parameter><parameter name="right"><paramtype>Right &amp;</paramtype></parameter></function><function name="operator&lt;"><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Left"/>
+ <template-type-parameter name="Right"/>
+ </template><parameter name="left"><paramtype>Left const &amp;</paramtype></parameter><parameter name="right"><paramtype>Right const &amp;</paramtype></parameter></function><function name="operator&gt;"><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Left"/>
+ <template-type-parameter name="Right"/>
+ </template><parameter name="left"><paramtype>Left &amp;</paramtype></parameter><parameter name="right"><paramtype>Right &amp;</paramtype></parameter></function><function name="operator&gt;"><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Left"/>
+ <template-type-parameter name="Right"/>
+ </template><parameter name="left"><paramtype>Left &amp;</paramtype></parameter><parameter name="right"><paramtype>Right const &amp;</paramtype></parameter></function><function name="operator&gt;"><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Left"/>
+ <template-type-parameter name="Right"/>
+ </template><parameter name="left"><paramtype>Left const &amp;</paramtype></parameter><parameter name="right"><paramtype>Right &amp;</paramtype></parameter></function><function name="operator&gt;"><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Left"/>
+ <template-type-parameter name="Right"/>
+ </template><parameter name="left"><paramtype>Left const &amp;</paramtype></parameter><parameter name="right"><paramtype>Right const &amp;</paramtype></parameter></function><function name="operator&lt;="><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Left"/>
+ <template-type-parameter name="Right"/>
+ </template><parameter name="left"><paramtype>Left &amp;</paramtype></parameter><parameter name="right"><paramtype>Right &amp;</paramtype></parameter></function><function name="operator&lt;="><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Left"/>
+ <template-type-parameter name="Right"/>
+ </template><parameter name="left"><paramtype>Left &amp;</paramtype></parameter><parameter name="right"><paramtype>Right const &amp;</paramtype></parameter></function><function name="operator&lt;="><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Left"/>
+ <template-type-parameter name="Right"/>
+ </template><parameter name="left"><paramtype>Left const &amp;</paramtype></parameter><parameter name="right"><paramtype>Right &amp;</paramtype></parameter></function><function name="operator&lt;="><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Left"/>
+ <template-type-parameter name="Right"/>
+ </template><parameter name="left"><paramtype>Left const &amp;</paramtype></parameter><parameter name="right"><paramtype>Right const &amp;</paramtype></parameter></function><function name="operator&gt;="><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Left"/>
+ <template-type-parameter name="Right"/>
+ </template><parameter name="left"><paramtype>Left &amp;</paramtype></parameter><parameter name="right"><paramtype>Right &amp;</paramtype></parameter></function><function name="operator&gt;="><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Left"/>
+ <template-type-parameter name="Right"/>
+ </template><parameter name="left"><paramtype>Left &amp;</paramtype></parameter><parameter name="right"><paramtype>Right const &amp;</paramtype></parameter></function><function name="operator&gt;="><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Left"/>
+ <template-type-parameter name="Right"/>
+ </template><parameter name="left"><paramtype>Left const &amp;</paramtype></parameter><parameter name="right"><paramtype>Right &amp;</paramtype></parameter></function><function name="operator&gt;="><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Left"/>
+ <template-type-parameter name="Right"/>
+ </template><parameter name="left"><paramtype>Left const &amp;</paramtype></parameter><parameter name="right"><paramtype>Right const &amp;</paramtype></parameter></function><function name="operator=="><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Left"/>
+ <template-type-parameter name="Right"/>
+ </template><parameter name="left"><paramtype>Left &amp;</paramtype></parameter><parameter name="right"><paramtype>Right &amp;</paramtype></parameter></function><function name="operator=="><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Left"/>
+ <template-type-parameter name="Right"/>
+ </template><parameter name="left"><paramtype>Left &amp;</paramtype></parameter><parameter name="right"><paramtype>Right const &amp;</paramtype></parameter></function><function name="operator=="><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Left"/>
+ <template-type-parameter name="Right"/>
+ </template><parameter name="left"><paramtype>Left const &amp;</paramtype></parameter><parameter name="right"><paramtype>Right &amp;</paramtype></parameter></function><function name="operator=="><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Left"/>
+ <template-type-parameter name="Right"/>
+ </template><parameter name="left"><paramtype>Left const &amp;</paramtype></parameter><parameter name="right"><paramtype>Right const &amp;</paramtype></parameter></function><function name="operator!="><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Left"/>
+ <template-type-parameter name="Right"/>
+ </template><parameter name="left"><paramtype>Left &amp;</paramtype></parameter><parameter name="right"><paramtype>Right &amp;</paramtype></parameter></function><function name="operator!="><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Left"/>
+ <template-type-parameter name="Right"/>
+ </template><parameter name="left"><paramtype>Left &amp;</paramtype></parameter><parameter name="right"><paramtype>Right const &amp;</paramtype></parameter></function><function name="operator!="><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Left"/>
+ <template-type-parameter name="Right"/>
+ </template><parameter name="left"><paramtype>Left const &amp;</paramtype></parameter><parameter name="right"><paramtype>Right &amp;</paramtype></parameter></function><function name="operator!="><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Left"/>
+ <template-type-parameter name="Right"/>
+ </template><parameter name="left"><paramtype>Left const &amp;</paramtype></parameter><parameter name="right"><paramtype>Right const &amp;</paramtype></parameter></function><function name="operator||"><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Left"/>
+ <template-type-parameter name="Right"/>
+ </template><parameter name="left"><paramtype>Left &amp;</paramtype></parameter><parameter name="right"><paramtype>Right &amp;</paramtype></parameter></function><function name="operator||"><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Left"/>
+ <template-type-parameter name="Right"/>
+ </template><parameter name="left"><paramtype>Left &amp;</paramtype></parameter><parameter name="right"><paramtype>Right const &amp;</paramtype></parameter></function><function name="operator||"><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Left"/>
+ <template-type-parameter name="Right"/>
+ </template><parameter name="left"><paramtype>Left const &amp;</paramtype></parameter><parameter name="right"><paramtype>Right &amp;</paramtype></parameter></function><function name="operator||"><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Left"/>
+ <template-type-parameter name="Right"/>
+ </template><parameter name="left"><paramtype>Left const &amp;</paramtype></parameter><parameter name="right"><paramtype>Right const &amp;</paramtype></parameter></function><function name="operator&amp;&amp;"><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Left"/>
+ <template-type-parameter name="Right"/>
+ </template><parameter name="left"><paramtype>Left &amp;</paramtype></parameter><parameter name="right"><paramtype>Right &amp;</paramtype></parameter></function><function name="operator&amp;&amp;"><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Left"/>
+ <template-type-parameter name="Right"/>
+ </template><parameter name="left"><paramtype>Left &amp;</paramtype></parameter><parameter name="right"><paramtype>Right const &amp;</paramtype></parameter></function><function name="operator&amp;&amp;"><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Left"/>
+ <template-type-parameter name="Right"/>
+ </template><parameter name="left"><paramtype>Left const &amp;</paramtype></parameter><parameter name="right"><paramtype>Right &amp;</paramtype></parameter></function><function name="operator&amp;&amp;"><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Left"/>
+ <template-type-parameter name="Right"/>
+ </template><parameter name="left"><paramtype>Left const &amp;</paramtype></parameter><parameter name="right"><paramtype>Right const &amp;</paramtype></parameter></function><function name="operator&amp;"><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Left"/>
+ <template-type-parameter name="Right"/>
+ </template><parameter name="left"><paramtype>Left &amp;</paramtype></parameter><parameter name="right"><paramtype>Right &amp;</paramtype></parameter></function><function name="operator&amp;"><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Left"/>
+ <template-type-parameter name="Right"/>
+ </template><parameter name="left"><paramtype>Left &amp;</paramtype></parameter><parameter name="right"><paramtype>Right const &amp;</paramtype></parameter></function><function name="operator&amp;"><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Left"/>
+ <template-type-parameter name="Right"/>
+ </template><parameter name="left"><paramtype>Left const &amp;</paramtype></parameter><parameter name="right"><paramtype>Right &amp;</paramtype></parameter></function><function name="operator&amp;"><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Left"/>
+ <template-type-parameter name="Right"/>
+ </template><parameter name="left"><paramtype>Left const &amp;</paramtype></parameter><parameter name="right"><paramtype>Right const &amp;</paramtype></parameter></function><function name="operator|"><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Left"/>
+ <template-type-parameter name="Right"/>
+ </template><parameter name="left"><paramtype>Left &amp;</paramtype></parameter><parameter name="right"><paramtype>Right &amp;</paramtype></parameter></function><function name="operator|"><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Left"/>
+ <template-type-parameter name="Right"/>
+ </template><parameter name="left"><paramtype>Left &amp;</paramtype></parameter><parameter name="right"><paramtype>Right const &amp;</paramtype></parameter></function><function name="operator|"><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Left"/>
+ <template-type-parameter name="Right"/>
+ </template><parameter name="left"><paramtype>Left const &amp;</paramtype></parameter><parameter name="right"><paramtype>Right &amp;</paramtype></parameter></function><function name="operator|"><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Left"/>
+ <template-type-parameter name="Right"/>
+ </template><parameter name="left"><paramtype>Left const &amp;</paramtype></parameter><parameter name="right"><paramtype>Right const &amp;</paramtype></parameter></function><function name="operator^"><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Left"/>
+ <template-type-parameter name="Right"/>
+ </template><parameter name="left"><paramtype>Left &amp;</paramtype></parameter><parameter name="right"><paramtype>Right &amp;</paramtype></parameter></function><function name="operator^"><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Left"/>
+ <template-type-parameter name="Right"/>
+ </template><parameter name="left"><paramtype>Left &amp;</paramtype></parameter><parameter name="right"><paramtype>Right const &amp;</paramtype></parameter></function><function name="operator^"><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Left"/>
+ <template-type-parameter name="Right"/>
+ </template><parameter name="left"><paramtype>Left const &amp;</paramtype></parameter><parameter name="right"><paramtype>Right &amp;</paramtype></parameter></function><function name="operator^"><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Left"/>
+ <template-type-parameter name="Right"/>
+ </template><parameter name="left"><paramtype>Left const &amp;</paramtype></parameter><parameter name="right"><paramtype>Right const &amp;</paramtype></parameter></function><function name="operator,"><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Left"/>
+ <template-type-parameter name="Right"/>
+ </template><parameter name="left"><paramtype>Left &amp;</paramtype></parameter><parameter name="right"><paramtype>Right &amp;</paramtype></parameter></function><function name="operator,"><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Left"/>
+ <template-type-parameter name="Right"/>
+ </template><parameter name="left"><paramtype>Left &amp;</paramtype></parameter><parameter name="right"><paramtype>Right const &amp;</paramtype></parameter></function><function name="operator,"><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Left"/>
+ <template-type-parameter name="Right"/>
+ </template><parameter name="left"><paramtype>Left const &amp;</paramtype></parameter><parameter name="right"><paramtype>Right &amp;</paramtype></parameter></function><function name="operator,"><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Left"/>
+ <template-type-parameter name="Right"/>
+ </template><parameter name="left"><paramtype>Left const &amp;</paramtype></parameter><parameter name="right"><paramtype>Right const &amp;</paramtype></parameter></function><function name="operator-&gt;*"><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Left"/>
+ <template-type-parameter name="Right"/>
+ </template><parameter name="left"><paramtype>Left &amp;</paramtype></parameter><parameter name="right"><paramtype>Right &amp;</paramtype></parameter></function><function name="operator-&gt;*"><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Left"/>
+ <template-type-parameter name="Right"/>
+ </template><parameter name="left"><paramtype>Left &amp;</paramtype></parameter><parameter name="right"><paramtype>Right const &amp;</paramtype></parameter></function><function name="operator-&gt;*"><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Left"/>
+ <template-type-parameter name="Right"/>
+ </template><parameter name="left"><paramtype>Left const &amp;</paramtype></parameter><parameter name="right"><paramtype>Right &amp;</paramtype></parameter></function><function name="operator-&gt;*"><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Left"/>
+ <template-type-parameter name="Right"/>
+ </template><parameter name="left"><paramtype>Left const &amp;</paramtype></parameter><parameter name="right"><paramtype>Right const &amp;</paramtype></parameter></function><function name="operator&lt;&lt;="><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Left"/>
+ <template-type-parameter name="Right"/>
+ </template><parameter name="left"><paramtype>Left &amp;</paramtype></parameter><parameter name="right"><paramtype>Right &amp;</paramtype></parameter></function><function name="operator&lt;&lt;="><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Left"/>
+ <template-type-parameter name="Right"/>
+ </template><parameter name="left"><paramtype>Left &amp;</paramtype></parameter><parameter name="right"><paramtype>Right const &amp;</paramtype></parameter></function><function name="operator&lt;&lt;="><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Left"/>
+ <template-type-parameter name="Right"/>
+ </template><parameter name="left"><paramtype>Left const &amp;</paramtype></parameter><parameter name="right"><paramtype>Right &amp;</paramtype></parameter></function><function name="operator&lt;&lt;="><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Left"/>
+ <template-type-parameter name="Right"/>
+ </template><parameter name="left"><paramtype>Left const &amp;</paramtype></parameter><parameter name="right"><paramtype>Right const &amp;</paramtype></parameter></function><function name="operator&gt;&gt;="><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Left"/>
+ <template-type-parameter name="Right"/>
+ </template><parameter name="left"><paramtype>Left &amp;</paramtype></parameter><parameter name="right"><paramtype>Right &amp;</paramtype></parameter></function><function name="operator&gt;&gt;="><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Left"/>
+ <template-type-parameter name="Right"/>
+ </template><parameter name="left"><paramtype>Left &amp;</paramtype></parameter><parameter name="right"><paramtype>Right const &amp;</paramtype></parameter></function><function name="operator&gt;&gt;="><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Left"/>
+ <template-type-parameter name="Right"/>
+ </template><parameter name="left"><paramtype>Left const &amp;</paramtype></parameter><parameter name="right"><paramtype>Right &amp;</paramtype></parameter></function><function name="operator&gt;&gt;="><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Left"/>
+ <template-type-parameter name="Right"/>
+ </template><parameter name="left"><paramtype>Left const &amp;</paramtype></parameter><parameter name="right"><paramtype>Right const &amp;</paramtype></parameter></function><function name="operator*="><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Left"/>
+ <template-type-parameter name="Right"/>
+ </template><parameter name="left"><paramtype>Left &amp;</paramtype></parameter><parameter name="right"><paramtype>Right &amp;</paramtype></parameter></function><function name="operator*="><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Left"/>
+ <template-type-parameter name="Right"/>
+ </template><parameter name="left"><paramtype>Left &amp;</paramtype></parameter><parameter name="right"><paramtype>Right const &amp;</paramtype></parameter></function><function name="operator*="><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Left"/>
+ <template-type-parameter name="Right"/>
+ </template><parameter name="left"><paramtype>Left const &amp;</paramtype></parameter><parameter name="right"><paramtype>Right &amp;</paramtype></parameter></function><function name="operator*="><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Left"/>
+ <template-type-parameter name="Right"/>
+ </template><parameter name="left"><paramtype>Left const &amp;</paramtype></parameter><parameter name="right"><paramtype>Right const &amp;</paramtype></parameter></function><function name="operator/="><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Left"/>
+ <template-type-parameter name="Right"/>
+ </template><parameter name="left"><paramtype>Left &amp;</paramtype></parameter><parameter name="right"><paramtype>Right &amp;</paramtype></parameter></function><function name="operator/="><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Left"/>
+ <template-type-parameter name="Right"/>
+ </template><parameter name="left"><paramtype>Left &amp;</paramtype></parameter><parameter name="right"><paramtype>Right const &amp;</paramtype></parameter></function><function name="operator/="><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Left"/>
+ <template-type-parameter name="Right"/>
+ </template><parameter name="left"><paramtype>Left const &amp;</paramtype></parameter><parameter name="right"><paramtype>Right &amp;</paramtype></parameter></function><function name="operator/="><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Left"/>
+ <template-type-parameter name="Right"/>
+ </template><parameter name="left"><paramtype>Left const &amp;</paramtype></parameter><parameter name="right"><paramtype>Right const &amp;</paramtype></parameter></function><function name="operator%="><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Left"/>
+ <template-type-parameter name="Right"/>
+ </template><parameter name="left"><paramtype>Left &amp;</paramtype></parameter><parameter name="right"><paramtype>Right &amp;</paramtype></parameter></function><function name="operator%="><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Left"/>
+ <template-type-parameter name="Right"/>
+ </template><parameter name="left"><paramtype>Left &amp;</paramtype></parameter><parameter name="right"><paramtype>Right const &amp;</paramtype></parameter></function><function name="operator%="><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Left"/>
+ <template-type-parameter name="Right"/>
+ </template><parameter name="left"><paramtype>Left const &amp;</paramtype></parameter><parameter name="right"><paramtype>Right &amp;</paramtype></parameter></function><function name="operator%="><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Left"/>
+ <template-type-parameter name="Right"/>
+ </template><parameter name="left"><paramtype>Left const &amp;</paramtype></parameter><parameter name="right"><paramtype>Right const &amp;</paramtype></parameter></function><function name="operator+="><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Left"/>
+ <template-type-parameter name="Right"/>
+ </template><parameter name="left"><paramtype>Left &amp;</paramtype></parameter><parameter name="right"><paramtype>Right &amp;</paramtype></parameter></function><function name="operator+="><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Left"/>
+ <template-type-parameter name="Right"/>
+ </template><parameter name="left"><paramtype>Left &amp;</paramtype></parameter><parameter name="right"><paramtype>Right const &amp;</paramtype></parameter></function><function name="operator+="><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Left"/>
+ <template-type-parameter name="Right"/>
+ </template><parameter name="left"><paramtype>Left const &amp;</paramtype></parameter><parameter name="right"><paramtype>Right &amp;</paramtype></parameter></function><function name="operator+="><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Left"/>
+ <template-type-parameter name="Right"/>
+ </template><parameter name="left"><paramtype>Left const &amp;</paramtype></parameter><parameter name="right"><paramtype>Right const &amp;</paramtype></parameter></function><function name="operator-="><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Left"/>
+ <template-type-parameter name="Right"/>
+ </template><parameter name="left"><paramtype>Left &amp;</paramtype></parameter><parameter name="right"><paramtype>Right &amp;</paramtype></parameter></function><function name="operator-="><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Left"/>
+ <template-type-parameter name="Right"/>
+ </template><parameter name="left"><paramtype>Left &amp;</paramtype></parameter><parameter name="right"><paramtype>Right const &amp;</paramtype></parameter></function><function name="operator-="><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Left"/>
+ <template-type-parameter name="Right"/>
+ </template><parameter name="left"><paramtype>Left const &amp;</paramtype></parameter><parameter name="right"><paramtype>Right &amp;</paramtype></parameter></function><function name="operator-="><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Left"/>
+ <template-type-parameter name="Right"/>
+ </template><parameter name="left"><paramtype>Left const &amp;</paramtype></parameter><parameter name="right"><paramtype>Right const &amp;</paramtype></parameter></function><function name="operator&amp;="><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Left"/>
+ <template-type-parameter name="Right"/>
+ </template><parameter name="left"><paramtype>Left &amp;</paramtype></parameter><parameter name="right"><paramtype>Right &amp;</paramtype></parameter></function><function name="operator&amp;="><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Left"/>
+ <template-type-parameter name="Right"/>
+ </template><parameter name="left"><paramtype>Left &amp;</paramtype></parameter><parameter name="right"><paramtype>Right const &amp;</paramtype></parameter></function><function name="operator&amp;="><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Left"/>
+ <template-type-parameter name="Right"/>
+ </template><parameter name="left"><paramtype>Left const &amp;</paramtype></parameter><parameter name="right"><paramtype>Right &amp;</paramtype></parameter></function><function name="operator&amp;="><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Left"/>
+ <template-type-parameter name="Right"/>
+ </template><parameter name="left"><paramtype>Left const &amp;</paramtype></parameter><parameter name="right"><paramtype>Right const &amp;</paramtype></parameter></function><function name="operator|="><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Left"/>
+ <template-type-parameter name="Right"/>
+ </template><parameter name="left"><paramtype>Left &amp;</paramtype></parameter><parameter name="right"><paramtype>Right &amp;</paramtype></parameter></function><function name="operator|="><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Left"/>
+ <template-type-parameter name="Right"/>
+ </template><parameter name="left"><paramtype>Left &amp;</paramtype></parameter><parameter name="right"><paramtype>Right const &amp;</paramtype></parameter></function><function name="operator|="><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Left"/>
+ <template-type-parameter name="Right"/>
+ </template><parameter name="left"><paramtype>Left const &amp;</paramtype></parameter><parameter name="right"><paramtype>Right &amp;</paramtype></parameter></function><function name="operator|="><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Left"/>
+ <template-type-parameter name="Right"/>
+ </template><parameter name="left"><paramtype>Left const &amp;</paramtype></parameter><parameter name="right"><paramtype>Right const &amp;</paramtype></parameter></function><function name="operator^="><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Left"/>
+ <template-type-parameter name="Right"/>
+ </template><parameter name="left"><paramtype>Left &amp;</paramtype></parameter><parameter name="right"><paramtype>Right &amp;</paramtype></parameter></function><function name="operator^="><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Left"/>
+ <template-type-parameter name="Right"/>
+ </template><parameter name="left"><paramtype>Left &amp;</paramtype></parameter><parameter name="right"><paramtype>Right const &amp;</paramtype></parameter></function><function name="operator^="><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Left"/>
+ <template-type-parameter name="Right"/>
+ </template><parameter name="left"><paramtype>Left const &amp;</paramtype></parameter><parameter name="right"><paramtype>Right &amp;</paramtype></parameter></function><function name="operator^="><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Left"/>
+ <template-type-parameter name="Right"/>
+ </template><parameter name="left"><paramtype>Left const &amp;</paramtype></parameter><parameter name="right"><paramtype>Right const &amp;</paramtype></parameter></function><function name="if_else"><type><classname>boost::proto::result_of::make_expr</classname>&lt; <classname>tag::if_else_</classname>, <classname>deduce_domain</classname>, A0 const &amp;, A1 const &amp;, A2 const &amp; &gt;::type const</type><template>
+ <template-type-parameter name="A0"/>
+ <template-type-parameter name="A1"/>
+ <template-type-parameter name="A2"/>
+ </template><parameter name="a0"><paramtype>A0 const &amp;</paramtype></parameter><parameter name="a1"><paramtype>A1 const &amp;</paramtype></parameter><parameter name="a2"><paramtype>A2 const &amp;</paramtype></parameter><description><para>if_else </para></description></function></namespace></namespace></header><header name="boost/proto/proto.hpp"><para>Includes all of Proto. </para></header><header name="boost/proto/proto_fwd.hpp"><para>Forward declarations of all of proto's public types and functions. </para><namespace name="boost"><namespace name="proto"><struct name="callable"><typedef name="proto_is_callable_"><type>void</type></typedef></struct><namespace name="context"/><namespace name="control"><data-member name="N"><type>int const</type></data-member></namespace><namespace name="exops"/><namespace name="functor"><typedef name="make_terminal"><type><classname>make_expr</classname>&lt; <classname>tag::terminal</classname> &gt;</type></typedef><typedef name="make_posit"><type><classname>make_e
xpr</classname>&lt; <classname>tag::unary_plus</classname> &gt;</type></typedef><typedef name="make_negate"><type><classname>make_expr</classname>&lt; <classname>tag::negate</classname> &gt;</type></typedef><typedef name="make_dereference"><type><classname>make_expr</classname>&lt; <classname>tag::dereference</classname> &gt;</type></typedef><typedef name="make_complement"><type><classname>make_expr</classname>&lt; <classname>tag::complement</classname> &gt;</type></typedef><typedef name="make_address_of"><type><classname>make_expr</classname>&lt; <classname>tag::address_of</classname> &gt;</type></typedef><typedef name="make_logical_not"><type><classname>make_expr</classname>&lt; <classname>tag::logical_not</classname> &gt;</type></typedef><typedef name="make_pre_inc"><type><classname>make_expr</classname>&lt; <classname>tag::pre_inc</classname> &gt;</type></typedef><typedef name="make_pre_dec"><type><classname>make_expr</classname>&lt; <classname>tag::pre_dec</classname> &gt;</type></typedef><typedef name=
"make_post_inc"><type><classname>make_expr</classname>&lt; <classname>tag::post_inc</classname> &gt;</type></typedef><typedef name="make_post_dec"><type><classname>make_expr</classname>&lt; <classname>tag::post_dec</classname> &gt;</type></typedef><typedef name="make_shift_left"><type><classname>make_expr</classname>&lt; <classname>tag::shift_left</classname> &gt;</type></typedef><typedef name="make_shift_right"><type><classname>make_expr</classname>&lt; <classname>tag::shift_right</classname> &gt;</type></typedef><typedef name="make_multiplies"><type><classname>make_expr</classname>&lt; <classname>tag::multiplies</classname> &gt;</type></typedef><typedef name="make_divides"><type><classname>make_expr</classname>&lt; <classname>tag::divides</classname> &gt;</type></typedef><typedef name="make_modulus"><type><classname>make_expr</classname>&lt; <classname>tag::modulus</classname> &gt;</type></typedef><typedef name="make_plus"><type><classname>make_expr</classname>&lt; <classname>tag::plus</classname> &gt;</ty
pe></typedef><typedef name="make_minus"><type><classname>make_expr</classname>&lt; <classname>tag::minus</classname> &gt;</type></typedef><typedef name="make_less"><type><classname>make_expr</classname>&lt; <classname>tag::less</classname> &gt;</type></typedef><typedef name="make_greater"><type><classname>make_expr</classname>&lt; <classname>tag::greater</classname> &gt;</type></typedef><typedef name="make_less_equal"><type><classname>make_expr</classname>&lt; <classname>tag::less_equal</classname> &gt;</type></typedef><typedef name="make_greater_equal"><type><classname>make_expr</classname>&lt; <classname>tag::greater_equal</classname> &gt;</type></typedef><typedef name="make_equal_to"><type><classname>make_expr</classname>&lt; <classname>tag::equal_to</classname> &gt;</type></typedef><typedef name="make_not_equal_to"><type><classname>make_expr</classname>&lt; <classname>tag::not_equal_to</classname> &gt;</type></typedef><typedef name="make_logical_or"><type><classname>make_expr</classname>&lt; <classname>t
ag::logical_or</classname> &gt;</type></typedef><typedef name="make_logical_and"><type><classname>make_expr</classname>&lt; <classname>tag::logical_and</classname> &gt;</type></typedef><typedef name="make_bitwise_and"><type><classname>make_expr</classname>&lt; <classname>tag::bitwise_and</classname> &gt;</type></typedef><typedef name="make_bitwise_or"><type><classname>make_expr</classname>&lt; <classname>tag::bitwise_or</classname> &gt;</type></typedef><typedef name="make_bitwise_xor"><type><classname>make_expr</classname>&lt; <classname>tag::bitwise_xor</classname> &gt;</type></typedef><typedef name="make_comma"><type><classname>make_expr</classname>&lt; <classname>tag::comma</classname> &gt;</type></typedef><typedef name="make_mem_ptr"><type><classname>make_expr</classname>&lt; <classname>tag::mem_ptr</classname> &gt;</type></typedef><typedef name="make_assign"><type><classname>make_expr</classname>&lt; <classname>tag::assign</classname> &gt;</type></typedef><typedef name="make_shift_left_assign"><type><cl
assname>make_expr</classname>&lt; <classname>tag::shift_left_assign</classname> &gt;</type></typedef><typedef name="make_shift_right_assign"><type><classname>make_expr</classname>&lt; <classname>tag::shift_right_assign</classname> &gt;</type></typedef><typedef name="make_multiplies_assign"><type><classname>make_expr</classname>&lt; <classname>tag::multiplies_assign</classname> &gt;</type></typedef><typedef name="make_divides_assign"><type><classname>make_expr</classname>&lt; <classname>tag::divides_assign</classname> &gt;</type></typedef><typedef name="make_modulus_assign"><type><classname>make_expr</classname>&lt; <classname>tag::modulus_assign</classname> &gt;</type></typedef><typedef name="make_plus_assign"><type><classname>make_expr</classname>&lt; <classname>tag::plus_assign</classname> &gt;</type></typedef><typedef name="make_minus_assign"><type><classname>make_expr</classname>&lt; <classname>tag::minus_assign</classname> &gt;</type></typedef><typedef name="make_bitwise_and_assign"><type><classname>mak
e_expr</classname>&lt; <classname>tag::bitwise_and_assign</classname> &gt;</type></typedef><typedef name="make_bitwise_or_assign"><type><classname>make_expr</classname>&lt; <classname>tag::bitwise_or_assign</classname> &gt;</type></typedef><typedef name="make_bitwise_xor_assign"><type><classname>make_expr</classname>&lt; <classname>tag::bitwise_xor_assign</classname> &gt;</type></typedef><typedef name="make_subscript"><type><classname>make_expr</classname>&lt; <classname>tag::subscript</classname> &gt;</type></typedef><typedef name="make_if_else"><type><classname>make_expr</classname>&lt; <classname>tag::if_else_</classname> &gt;</type></typedef><typedef name="make_function"><type><classname>make_expr</classname>&lt; <classname>tag::function</classname> &gt;</type></typedef></namespace><namespace name="op"/><namespace name="result_of"/><namespace name="tag"/><namespace name="utility"/><typedef name="_make_terminal"><type><classname>functor::make_terminal</classname></type></typedef><typedef name="_make_posit
"><type><classname>functor::make_posit</classname></type></typedef><typedef name="_make_negate"><type><classname>functor::make_negate</classname></type></typedef><typedef name="_make_dereference"><type><classname>functor::make_dereference</classname></type></typedef><typedef name="_make_complement"><type><classname>functor::make_complement</classname></type></typedef><typedef name="_make_address_of"><type><classname>functor::make_address_of</classname></type></typedef><typedef name="_make_logical_not"><type><classname>functor::make_logical_not</classname></type></typedef><typedef name="_make_pre_inc"><type><classname>functor::make_pre_inc</classname></type></typedef><typedef name="_make_pre_dec"><type><classname>functor::make_pre_dec</classname></type></typedef><typedef name="_make_post_inc"><type><classname>functor::make_post_inc</classname></type></typedef><typedef name="_make_post_dec"><type><classname>functor::make_post_dec</classname></type></typedef><typedef name="_make_shift_left"><type><classname>fun
ctor::make_shift_left</classname></type></typedef><typedef name="_make_shift_right"><type><classname>functor::make_shift_right</classname></type></typedef><typedef name="_make_multiplies"><type><classname>functor::make_multiplies</classname></type></typedef><typedef name="_make_divides"><type><classname>functor::make_divides</classname></type></typedef><typedef name="_make_modulus"><type><classname>functor::make_modulus</classname></type></typedef><typedef name="_make_plus"><type><classname>functor::make_plus</classname></type></typedef><typedef name="_make_minus"><type><classname>functor::make_minus</classname></type></typedef><typedef name="_make_less"><type><classname>functor::make_less</classname></type></typedef><typedef name="_make_greater"><type><classname>functor::make_greater</classname></type></typedef><typedef name="_make_less_equal"><type><classname>functor::make_less_equal</classname></type></typedef><typedef name="_make_greater_equal"><type><classname>functor::make_greater_equal</classname></ty
pe></typedef><typedef name="_make_equal_to"><type><classname>functor::make_equal_to</classname></type></typedef><typedef name="_make_not_equal_to"><type><classname>functor::make_not_equal_to</classname></type></typedef><typedef name="_make_logical_or"><type><classname>functor::make_logical_or</classname></type></typedef><typedef name="_make_logical_and"><type><classname>functor::make_logical_and</classname></type></typedef><typedef name="_make_bitwise_and"><type><classname>functor::make_bitwise_and</classname></type></typedef><typedef name="_make_bitwise_or"><type><classname>functor::make_bitwise_or</classname></type></typedef><typedef name="_make_bitwise_xor"><type><classname>functor::make_bitwise_xor</classname></type></typedef><typedef name="_make_comma"><type><classname>functor::make_comma</classname></type></typedef><typedef name="_make_mem_ptr"><type><classname>functor::make_mem_ptr</classname></type></typedef><typedef name="_make_assign"><type><classname>functor::make_assign</classname></type></typede
f><typedef name="_make_shift_left_assign"><type><classname>functor::make_shift_left_assign</classname></type></typedef><typedef name="_make_shift_right_assign"><type><classname>functor::make_shift_right_assign</classname></type></typedef><typedef name="_make_multiplies_assign"><type><classname>functor::make_multiplies_assign</classname></type></typedef><typedef name="_make_divides_assign"><type><classname>functor::make_divides_assign</classname></type></typedef><typedef name="_make_modulus_assign"><type><classname>functor::make_modulus_assign</classname></type></typedef><typedef name="_make_plus_assign"><type><classname>functor::make_plus_assign</classname></type></typedef><typedef name="_make_minus_assign"><type><classname>functor::make_minus_assign</classname></type></typedef><typedef name="_make_bitwise_and_assign"><type><classname>functor::make_bitwise_and_assign</classname></type></typedef><typedef name="_make_bitwise_or_assign"><type><classname>functor::make_bitwise_or_assign</classname></type></typede
f><typedef name="_make_bitwise_xor_assign"><type><classname>functor::make_bitwise_xor_assign</classname></type></typedef><typedef name="_make_subscript"><type><classname>functor::make_subscript</classname></type></typedef><typedef name="_make_if_else"><type><classname>functor::make_if_else</classname></type></typedef><typedef name="_make_function"><type><classname>functor::make_function</classname></type></typedef><typedef name="_flatten"><type><classname>functor::flatten</classname></type></typedef><typedef name="_pop_front"><type><classname>functor::pop_front</classname></type></typedef><typedef name="_reverse"><type><classname>functor::reverse</classname></type></typedef><typedef name="_eval"><type><classname>functor::deep_copy</classname></type></typedef><typedef name="_deep_copy"><type><classname>functor::deep_copy</classname></type></typedef><typedef name="_child0"><type><classname>_child_c</classname>&lt; 0 &gt;</type></typedef><typedef name="_child1"><type><classname>_child_c</classname>&lt; 1 &gt;</
type></typedef><typedef name="_child2"><type><classname>_child_c</classname>&lt; 2 &gt;</type></typedef><typedef name="_child"><type><classname>_child0</classname></type></typedef><typedef name="_value"><type><classname>_child0</classname></type></typedef><typedef name="_left"><type><classname>_child0</classname></type></typedef><typedef name="_right"><type><classname>_child1</classname></type></typedef><typedef name="_child3"><type><classname>_child_c</classname>&lt; 3 &gt;</type></typedef></namespace></namespace></header><header name="boost/proto/ref.hpp"><para>Utility for storing a sub-expr by reference </para><namespace name="boost"><namespace name="proto"><struct name="ref_"><template>
+ <template-type-parameter name="Expr"/>
+ </template><purpose>A simple reference wrapper for a Proto expression type, used by <computeroutput>expr&lt;&gt;</computeroutput> to hold child expressions by reference. </purpose><description><para><computeroutput>ref_&lt;&gt;</computeroutput> is used by <computeroutput>expr&lt;&gt;</computeroutput> to hold child expression types by reference. It forwards enough of the child expression's interface so that <computeroutput>expr&lt;&gt;</computeroutput> can handle children uniformly regardless of whether it is stored by reference or by value.</para><para>This type is largely an implementation detail. </para></description><typedef name="proto_base_expr"><type>Expr::proto_base_expr</type></typedef><typedef name="proto_tag"><type>Expr::proto_tag</type></typedef><typedef name="proto_args"><type>Expr::proto_args</type></typedef><typedef name="proto_arity"><type>Expr::proto_arity</type></typedef><typedef name="proto_domain"><type>Expr::proto_domain</type></typedef><typedef name="proto_is_ref_"><type>void</type>
</typedef><typedef name="proto_is_expr_"><type>void</type></typedef><typedef name="proto_derived_expr"><type>Expr</type></typedef><typedef name="proto_child0"><type>Expr::proto_child0</type></typedef><typedef name="proto_child1"><type>Expr::proto_child1</type></typedef><typedef name="proto_child2"><type>Expr::proto_child2</type></typedef><typedef name="proto_child3"><type>Expr::proto_child3</type></typedef><typedef name="proto_child4"><type>Expr::proto_child4</type></typedef><data-member name="expr"><type>Expr &amp;</type></data-member><method-group name="public member functions"><method name="proto_base" cv="const"><type>mpl::if_c&lt; is_const&lt; Expr &gt;::value, proto_base_expr const &amp;, proto_base_expr &amp; &gt;::type</type></method></method-group><method-group name="public static functions"><method name="make" cv=""><type>static <classname>ref_</classname>&lt; Expr &gt;</type><parameter name="expr"><paramtype>Expr &amp;</paramtype></parameter></method></method-group></struct><namespace name="functo
r"><struct name="unref"><purpose>A callable PolymorphicFunctionObject equivalent to the <computeroutput>proto::unref()</computeroutput> function that removes top-level reference wrappers. </purpose><struct-specialization name="result"><template>
+ <template-type-parameter name="This"/>
+ <template-type-parameter name="T"/>
+ </template><specialization><template-arg>This(T)</template-arg></specialization><typedef name="uncvref_type"><type>boost::remove_const&lt; typename boost::remove_reference&lt; T &gt;::type &gt;::type</type></typedef><typedef name="type"><type><classname>result_of::unref</classname>&lt; uncvref_type &gt;::type</type></typedef></struct-specialization><typedef name="proto_is_callable_"><type>void</type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type>T &amp;</type><template>
+ <template-type-parameter name="T"/>
+ </template><parameter name="t"><paramtype>T &amp;</paramtype><description><para>The object to unwrap </para></description></parameter><purpose>Remove a top-level <computeroutput>ref_&lt;&gt;</computeroutput> reference wrapper, if it exists. </purpose><description><para>
+
+</para></description><returns><para>If <computeroutput>T</computeroutput> t is a <computeroutput>ref_&lt;&gt;</computeroutput>, return <computeroutput>t.expr</computeroutput>. Otherwise, return <computeroutput>t</computeroutput>. </para></returns></method><method name="operator()" cv="const"><type>T const &amp;</type><template>
+ <template-type-parameter name="T"/>
+ </template><parameter name="t"><paramtype>T const &amp;</paramtype></parameter><description><para>This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts. </para></description></method><method name="operator()" cv="const"><type>T &amp;</type><template>
+ <template-type-parameter name="T"/>
+ </template><parameter name="t"><paramtype><classname>ref_</classname>&lt; T &gt; &amp;</paramtype></parameter><description><para>This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts. </para></description></method><method name="operator()" cv="const"><type>T &amp;</type><template>
+ <template-type-parameter name="T"/>
+ </template><parameter name="t"><paramtype><classname>ref_</classname>&lt; T &gt; const &amp;</paramtype></parameter><description><para>This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts. </para></description></method></method-group></struct></namespace><namespace name="result_of"><struct name="unref"><template>
+ <template-type-parameter name="T"/>
+ </template><purpose>Trait for stripping top-level references and reference wrappers. </purpose><typedef name="type"><purpose>Suitable for return by value. </purpose><type>T</type></typedef><typedef name="reference"><purpose>Suitable for return by reference. </purpose><type>T &amp;</type></typedef><typedef name="const_reference"><purpose>Suitable for return by const reference. </purpose><type>T const &amp;</type></typedef></struct><struct-specialization name="unref"><template>
+ <template-type-parameter name="T"/>
+ </template><specialization><template-arg>ref_&lt; T &gt;</template-arg></specialization><purpose>Trait for stripping top-level references and reference wrappers. </purpose><typedef name="type"><purpose>Suitable for return by value. </purpose><type>T</type></typedef><typedef name="reference"><purpose>Suitable for return by reference. </purpose><type>T &amp;</type></typedef><typedef name="const_reference"><purpose>Suitable for return by const reference. </purpose><type>T &amp;</type></typedef></struct-specialization><struct-specialization name="unref"><template>
+ <template-type-parameter name="T"/>
+ </template><specialization><template-arg>ref_&lt; T const &gt;</template-arg></specialization><purpose>Trait for stripping top-level references and reference wrappers. </purpose><typedef name="type"><purpose>Suitable for return by value. </purpose><type>T</type></typedef><typedef name="reference"><purpose>Suitable for return by reference. </purpose><type>T const &amp;</type></typedef><typedef name="const_reference"><purpose>Suitable for return by const reference. </purpose><type>T const &amp;</type></typedef></struct-specialization><struct-specialization name="unref"><template>
+ <template-type-parameter name="T"/>
+ </template><specialization><template-arg>T &amp;</template-arg></specialization><purpose>Trait for stripping top-level references and reference wrappers. </purpose><typedef name="type"><purpose>Suitable for return by value. </purpose><type>T</type></typedef><typedef name="reference"><purpose>Suitable for return by reference. </purpose><type>T &amp;</type></typedef><typedef name="const_reference"><purpose>Suitable for return by const reference. </purpose><type>T &amp;</type></typedef></struct-specialization><struct-specialization name="unref"><template>
+ <template-type-parameter name="T"/>
+ </template><specialization><template-arg>T const &amp;</template-arg></specialization><purpose>Trait for stripping top-level references and reference wrappers. </purpose><typedef name="type"><purpose>Suitable for return by value. </purpose><type>T</type></typedef><typedef name="reference"><purpose>Suitable for return by reference. </purpose><type>T const &amp;</type></typedef><typedef name="const_reference"><purpose>Suitable for return by const reference. </purpose><type>T const &amp;</type></typedef></struct-specialization></namespace><overloaded-function name="unref"><signature><type>T &amp;</type><template>
+ <template-type-parameter name="T"/>
+ </template><parameter name="t"><paramtype>T &amp;</paramtype><description><para>The object to unwrap </para></description></parameter></signature><signature><type>T const &amp;</type><template>
+ <template-type-parameter name="T"/>
+ </template><parameter name="t"><paramtype>T const &amp;</paramtype></parameter></signature><signature><type>T &amp;</type><template>
+ <template-type-parameter name="T"/>
+ </template><parameter name="t"><paramtype><classname>ref_</classname>&lt; T &gt; &amp;</paramtype></parameter></signature><signature><type>T &amp;</type><template>
+ <template-type-parameter name="T"/>
+ </template><parameter name="t"><paramtype><classname>ref_</classname>&lt; T &gt; const &amp;</paramtype></parameter></signature><purpose>Remove a top-level <computeroutput>ref_&lt;&gt;</computeroutput> reference wrapper, if it exists. </purpose><description><para>
+
+
+</para></description><returns><para>If <computeroutput>T</computeroutput> t is a <computeroutput>ref_&lt;&gt;</computeroutput>, return <computeroutput>t.expr</computeroutput>. Otherwise, return <computeroutput>t</computeroutput>. </para></returns><throws><simpara>Will not throw.</simpara></throws></overloaded-function></namespace></namespace></header><header name="boost/proto/tags.hpp"><para>Contains the tags for all the overloadable operators in C++ </para><namespace name="boost"><namespace name="proto"><namespace name="tag"><struct name="terminal"><purpose>Tag type for terminals; aka, leaves in the expression tree. </purpose></struct><struct name="unary_plus"><purpose>Tag type for the unary + operator. </purpose></struct><struct name="negate"><purpose>Tag type for the unary - operator. </purpose></struct><struct name="dereference"><purpose>Tag type for the unary * operator. </purpose></struct><struct name="complement"><purpose>Tag type for the unary ~ operator. </purpose></struct><struct name="address_of"
><purpose>Tag type for the unary &amp; operator. </purpose></struct><struct name="logical_not"><purpose>Tag type for the unary ! operator. </purpose></struct><struct name="pre_inc"><purpose>Tag type for the unary prefix ++ operator. </purpose></struct><struct name="pre_dec"><purpose>Tag type for the unary prefix -- operator. </purpose></struct><struct name="post_inc"><purpose>Tag type for the unary postfix ++ operator. </purpose></struct><struct name="post_dec"><purpose>Tag type for the unary postfix -- operator. </purpose></struct><struct name="shift_left"><purpose>Tag type for the binary &lt;&lt; operator. </purpose></struct><struct name="shift_right"><purpose>Tag type for the binary &gt;&gt; operator. </purpose></struct><struct name="multiplies"><purpose>Tag type for the binary * operator. </purpose></struct><struct name="divides"><purpose>Tag type for the binary / operator. </purpose></struct><struct name="modulus"><purpose>Tag type for the binary % operator. </purpose></struct><struct name="plus"><purpo
se>Tag type for the binary + operator. </purpose></struct><struct name="minus"><purpose>Tag type for the binary - operator. </purpose></struct><struct name="less"><purpose>Tag type for the binary &lt; operator. </purpose></struct><struct name="greater"><purpose>Tag type for the binary &gt; operator. </purpose></struct><struct name="less_equal"><purpose>Tag type for the binary &lt;= operator. </purpose></struct><struct name="greater_equal"><purpose>Tag type for the binary &gt;= operator. </purpose></struct><struct name="equal_to"><purpose>Tag type for the binary == operator. </purpose></struct><struct name="not_equal_to"><purpose>Tag type for the binary != operator. </purpose></struct><struct name="logical_or"><purpose>Tag type for the binary || operator. </purpose></struct><struct name="logical_and"><purpose>Tag type for the binary &amp;&amp; operator. </purpose></struct><struct name="bitwise_and"><purpose>Tag type for the binary &amp; operator. </purpose></struct><struct name="bitwise_or"><purpose>Tag type
for the binary | operator. </purpose></struct><struct name="bitwise_xor"><purpose>Tag type for the binary ^ operator. </purpose></struct><struct name="comma"><purpose>Tag type for the binary , operator. </purpose></struct><struct name="mem_ptr"><purpose>Tag type for the binary -&gt;* operator. </purpose></struct><struct name="assign"><purpose>Tag type for the binary = operator. </purpose></struct><struct name="shift_left_assign"><purpose>Tag type for the binary &lt;&lt;= operator. </purpose></struct><struct name="shift_right_assign"><purpose>Tag type for the binary &gt;&gt;= operator. </purpose></struct><struct name="multiplies_assign"><purpose>Tag type for the binary *= operator. </purpose></struct><struct name="divides_assign"><purpose>Tag type for the binary /= operator. </purpose></struct><struct name="modulus_assign"><purpose>Tag type for the binary = operator. </purpose></struct><struct name="plus_assign"><purpose>Tag type for the binary += operator. </purpose></struct><struct name="minus_assign"><purp
ose>Tag type for the binary -= operator. </purpose></struct><struct name="bitwise_and_assign"><purpose>Tag type for the binary &amp;= operator. </purpose></struct><struct name="bitwise_or_assign"><purpose>Tag type for the binary |= operator. </purpose></struct><struct name="bitwise_xor_assign"><purpose>Tag type for the binary ^= operator. </purpose></struct><struct name="subscript"><purpose>Tag type for the binary subscript operator. </purpose></struct><struct name="if_else_"><purpose>Tag type for the ternary ?: conditional operator. </purpose></struct><struct name="function"><purpose>Tag type for the n-ary function call operator. </purpose></struct></namespace></namespace></namespace></header><header name="boost/proto/traits.hpp"><para>Contains definitions for child&lt;&gt;, child_c&lt;&gt;, left&lt;&gt;, right&lt;&gt;, tag_of&lt;&gt;, and the helper functions child(), child_c(), value(), left() and right(). </para><namespace name="boost"><namespace name="proto"><struct name="is_callable"><template>
+ <template-type-parameter name="T"/>
+ </template><purpose>Boolean metafunction which detects whether a type is a callable function object type or not. </purpose><description><para><computeroutput>is_callable&lt;&gt;</computeroutput> is used by the <computeroutput>when&lt;&gt;</computeroutput> transform to determine whether a function type <computeroutput>R(A1,A2,...AN)</computeroutput> is a callable transform or an object transform. (The former are evaluated using <computeroutput>call&lt;&gt;</computeroutput> and the later with <computeroutput>make&lt;&gt;</computeroutput>.) If <computeroutput>is_callable&lt;R&gt;::value</computeroutput> is <computeroutput>true</computeroutput>, the function type is a callable transform; otherwise, it is an object transform.</para><para>Unless specialized for a type <computeroutput>T</computeroutput>, <computeroutput>is_callable&lt;T&gt;::value</computeroutput> is computed as follows:</para><para><itemizedlist>
+<listitem><para>If <computeroutput>T</computeroutput> is a template type <computeroutput>X&lt;Y0,Y1,...YN&gt;</computeroutput>, where all <computeroutput>Yx</computeroutput> are types for <computeroutput>x</computeroutput> in <computeroutput>[0,N]</computeroutput>, <computeroutput>is_callable&lt;T&gt;::value</computeroutput> is <computeroutput>is_same&lt;YN, proto::callable&gt;::value</computeroutput>. </para></listitem>
+<listitem><para>If <computeroutput>T</computeroutput> has a nested type <computeroutput>proto_is_callable_</computeroutput> that is a typedef for <computeroutput>void</computeroutput>, <computeroutput>is_callable&lt;T&gt;::value</computeroutput> is <computeroutput>true</computeroutput>. (Note: this is the case for any type that derives from <computeroutput>proto::callable</computeroutput>.) </para></listitem>
+<listitem><para>Otherwise, <computeroutput>is_callable&lt;T&gt;::value</computeroutput> is <computeroutput>false</computeroutput>. </para></listitem>
+</itemizedlist>
+</para></description></struct><struct name="is_aggregate"><template>
+ <template-type-parameter name="T"/>
+ </template><purpose>A Boolean metafunction that indicates whether a type requires aggregate initialization. </purpose><description><para><computeroutput>is_aggregate&lt;&gt;</computeroutput> is used by the <computeroutput>make&lt;&gt;</computeroutput> transform to determine how to construct an object of some type <computeroutput>T</computeroutput>, given some initialization arguments <computeroutput>a0,a1,...aN</computeroutput>. If <computeroutput>is_aggregate&lt;T&gt;::value</computeroutput> is <computeroutput>true</computeroutput>, then an object of type T will be initialized as <computeroutput>T t = {a0,a1,...aN};</computeroutput>. Otherwise, it will be initialized as <computeroutput>T t(a0,a1,...aN)</computeroutput>. </para></description></struct><struct-specialization name="is_aggregate"><template>
+ <template-type-parameter name="Tag"/>
+ <template-type-parameter name="Args"/>
+ <template-nontype-parameter name="N"><type>long</type></template-nontype-parameter>
+ </template><specialization><template-arg>proto::expr&lt; Tag</template-arg><template-arg>Args</template-arg><template-arg>N &gt;</template-arg></specialization><inherit access="public">boost::mpl::true_</inherit><purpose>Specialization of <computeroutput>is_aggregate&lt;&gt;</computeroutput> that indicates that objects of <computeroutput>expr&lt;&gt;</computeroutput> type require aggregate initialization. </purpose></struct-specialization><namespace name="functor"><struct name="as_expr"><template>
+ <template-type-parameter name="Domain"><default>default_domain</default></template-type-parameter>
+ </template><purpose>A callable PolymorphicFunctionObject that is equivalent to the <computeroutput>as_expr()</computeroutput> function. </purpose><struct-specialization name="result"><template>
+ <template-type-parameter name="This"/>
+ <template-type-parameter name="T"/>
+ </template><specialization><template-arg>This(T)</template-arg></specialization><typedef name="unref_type"><type>remove_reference&lt; T &gt;::type</type></typedef><typedef name="type"><type><classname>result_of::as_expr</classname>&lt; unref_type, Domain &gt;::type</type></typedef></struct-specialization><typedef name="proto_is_callable_"><type>void</type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type><classname>result_of::as_expr</classname>&lt; T, Domain &gt;::reference</type><template>
+ <template-type-parameter name="T"/>
+ </template><parameter name="t"><paramtype>T &amp;</paramtype><description><para>The object to wrap. </para></description></parameter><purpose>Wrap an object in a Proto terminal if it isn't a Proto expression already. </purpose><description><para>
+
+</para></description><returns><para><computeroutput>proto::as_expr&lt;Domain&gt;(t)</computeroutput> </para></returns></method><method name="operator()" cv="const"><type><classname>result_of::as_expr</classname>&lt; T const, Domain &gt;::reference</type><template>
+ <template-type-parameter name="T"/>
+ </template><parameter name="t"><paramtype>T const &amp;</paramtype></parameter><description><para>This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts. </para></description></method></method-group></struct><struct name="as_child"><template>
+ <template-type-parameter name="Domain"><default>default_domain</default></template-type-parameter>
+ </template><purpose>A callable PolymorphicFunctionObject that is equivalent to the <computeroutput>as_child()</computeroutput> function. </purpose><struct-specialization name="result"><template>
+ <template-type-parameter name="This"/>
+ <template-type-parameter name="T"/>
+ </template><specialization><template-arg>This(T)</template-arg></specialization><typedef name="unref_type"><type>remove_reference&lt; T &gt;::type</type></typedef><typedef name="type"><type><classname>result_of::as_child</classname>&lt; unref_type, Domain &gt;::type</type></typedef></struct-specialization><typedef name="proto_is_callable_"><type>void</type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type><classname>result_of::as_child</classname>&lt; T, Domain &gt;::type</type><template>
+ <template-type-parameter name="T"/>
+ </template><parameter name="t"><paramtype>T &amp;</paramtype><description><para>The object to wrap. </para></description></parameter><purpose>Wrap an object in a Proto terminal if it isn't a Proto expression already. </purpose><description><para>
+
+</para></description><returns><para><computeroutput>proto::as_child&lt;Domain&gt;(t)</computeroutput> </para></returns></method><method name="operator()" cv="const"><type><classname>result_of::as_child</classname>&lt; T const, Domain &gt;::type</type><template>
+ <template-type-parameter name="T"/>
+ </template><parameter name="t"><paramtype>T const &amp;</paramtype></parameter><description><para>This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts. </para></description></method></method-group></struct><struct name="child_c"><template>
+ <template-nontype-parameter name="N"><type>long</type></template-nontype-parameter>
+ </template><purpose>A callable PolymorphicFunctionObject that is equivalent to the <computeroutput>child_c()</computeroutput> function. </purpose><struct-specialization name="result"><template>
+ <template-type-parameter name="This"/>
+ <template-type-parameter name="Expr"/>
+ </template><specialization><template-arg>This(Expr)</template-arg></specialization><typedef name="uncvref_type"><type>boost::remove_const&lt; typename boost::remove_reference&lt; Expr &gt;::type &gt;::type</type></typedef><typedef name="type"><type>result_of::child_c&lt; uncvref_type, N &gt;::type</type></typedef></struct-specialization><typedef name="proto_is_callable_"><type>void</type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type>result_of::child_c&lt; Expr, N &gt;::reference</type><template>
+ <template-type-parameter name="Expr"/>
+ </template><parameter name="expr"><paramtype>Expr &amp;</paramtype><description><para>The expression node. </para></description></parameter><purpose>Return the Nth child of the given expression. </purpose><description><para>
+
+
+
+</para></description><requires><para><computeroutput>is_expr&lt;Expr&gt;::value</computeroutput> is <computeroutput>true</computeroutput> </para><para><computeroutput>N == 0 || N &lt; Expr::proto_arity::value</computeroutput> </para></requires><returns><para><computeroutput>proto::child_c&lt;N&gt;(expr)</computeroutput> </para></returns><throws><simpara>Will not throw.</simpara></throws></method><method name="operator()" cv="const"><type>result_of::child_c&lt; Expr, N &gt;::const_reference</type><template>
+ <template-type-parameter name="Expr"/>
+ </template><parameter name="expr"><paramtype>Expr const &amp;</paramtype></parameter><description><para>This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts. </para></description></method></method-group></struct><struct name="child"><template>
+ <template-type-parameter name="N"><default>mpl::long_&lt;0&gt;</default></template-type-parameter>
+ </template><purpose>A callable PolymorphicFunctionObject that is equivalent to the <computeroutput>child()</computeroutput> function. </purpose><description><para>A callable PolymorphicFunctionObject that is equivalent to the <computeroutput>child()</computeroutput> function. <computeroutput>N</computeroutput> is required to be an MPL Integral Constant. </para></description><struct-specialization name="result"><template>
+ <template-type-parameter name="This"/>
+ <template-type-parameter name="Expr"/>
+ </template><specialization><template-arg>This(Expr)</template-arg></specialization><typedef name="uncvref_type"><type>boost::remove_const&lt; typename boost::remove_reference&lt; Expr &gt;::type &gt;::type</type></typedef><typedef name="type"><type><classname>result_of::child</classname>&lt; uncvref_type, N &gt;::type</type></typedef></struct-specialization><typedef name="proto_is_callable_"><type>void</type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type><classname>result_of::child</classname>&lt; Expr, N &gt;::reference</type><template>
+ <template-type-parameter name="Expr"/>
+ </template><parameter name="expr"><paramtype>Expr &amp;</paramtype><description><para>The expression node. </para></description></parameter><purpose>Return the Nth child of the given expression. </purpose><description><para>
+
+
+
+</para></description><requires><para><computeroutput>is_expr&lt;Expr&gt;::value</computeroutput> is <computeroutput>true</computeroutput> </para><para><computeroutput>N::value == 0 || N::value &lt; Expr::proto_arity::value</computeroutput> </para></requires><returns><para><computeroutput>proto::child&lt;N&gt;(expr)</computeroutput> </para></returns><throws><simpara>Will not throw.</simpara></throws></method><method name="operator()" cv="const"><type><classname>result_of::child</classname>&lt; Expr, N &gt;::const_reference</type><template>
+ <template-type-parameter name="Expr"/>
+ </template><parameter name="expr"><paramtype>Expr const &amp;</paramtype></parameter><description><para>This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts. </para></description></method></method-group></struct><struct name="value"><purpose>A callable PolymorphicFunctionObject that is equivalent to the <computeroutput>value()</computeroutput> function. </purpose><struct-specialization name="result"><template>
+ <template-type-parameter name="This"/>
+ <template-type-parameter name="Expr"/>
+ </template><specialization><template-arg>This(Expr)</template-arg></specialization><typedef name="uncvref_type"><type>boost::remove_const&lt; typename boost::remove_reference&lt; Expr &gt;::type &gt;::type</type></typedef><typedef name="type"><type><classname>result_of::value</classname>&lt; uncvref_type &gt;::type</type></typedef></struct-specialization><typedef name="proto_is_callable_"><type>void</type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type><classname>result_of::value</classname>&lt; Expr &gt;::reference</type><template>
+ <template-type-parameter name="Expr"/>
+ </template><parameter name="expr"><paramtype>Expr &amp;</paramtype><description><para>The terminal expression node. </para></description></parameter><purpose>Return the value of the given terminal expression. </purpose><description><para>
+
+
+
+</para></description><requires><para><computeroutput>is_expr&lt;Expr&gt;::value</computeroutput> is <computeroutput>true</computeroutput> </para><para><computeroutput>0 == Expr::proto_arity::value</computeroutput> </para><para><computeroutput>Expr::proto_tag</computeroutput> is <computeroutput>tag::terminal</computeroutput> </para></requires><returns><para><computeroutput>proto::value(expr)</computeroutput> </para></returns><throws><simpara>Will not throw.</simpara></throws></method><method name="operator()" cv="const"><type><classname>result_of::value</classname>&lt; Expr &gt;::const_reference</type><template>
+ <template-type-parameter name="Expr"/>
+ </template><parameter name="expr"><paramtype>Expr const &amp;</paramtype></parameter><description><para>This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts. </para></description></method></method-group></struct><struct name="left"><purpose>A callable PolymorphicFunctionObject that is equivalent to the <computeroutput>left()</computeroutput> function. </purpose><struct-specialization name="result"><template>
+ <template-type-parameter name="This"/>
+ <template-type-parameter name="Expr"/>
+ </template><specialization><template-arg>This(Expr)</template-arg></specialization><typedef name="uncvref_type"><type>boost::remove_const&lt; typename boost::remove_reference&lt; Expr &gt;::type &gt;::type</type></typedef><typedef name="type"><type><classname>result_of::left</classname>&lt; uncvref_type &gt;::type</type></typedef></struct-specialization><typedef name="proto_is_callable_"><type>void</type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type><classname>result_of::left</classname>&lt; Expr &gt;::reference</type><template>
+ <template-type-parameter name="Expr"/>
+ </template><parameter name="expr"><paramtype>Expr &amp;</paramtype><description><para>The expression node. </para></description></parameter><purpose>Return the left child of the given binary expression. </purpose><description><para>
+
+
+
+</para></description><requires><para><computeroutput>is_expr&lt;Expr&gt;::value</computeroutput> is <computeroutput>true</computeroutput> </para><para><computeroutput>2 == Expr::proto_arity::value</computeroutput> </para></requires><returns><para><computeroutput>proto::left(expr)</computeroutput> </para></returns><throws><simpara>Will not throw.</simpara></throws></method><method name="operator()" cv="const"><type><classname>result_of::left</classname>&lt; Expr &gt;::const_reference</type><template>
+ <template-type-parameter name="Expr"/>
+ </template><parameter name="expr"><paramtype>Expr const &amp;</paramtype></parameter><description><para>This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts. </para></description></method></method-group></struct><struct name="right"><purpose>A callable PolymorphicFunctionObject that is equivalent to the <computeroutput>right()</computeroutput> function. </purpose><struct-specialization name="result"><template>
+ <template-type-parameter name="This"/>
+ <template-type-parameter name="Expr"/>
+ </template><specialization><template-arg>This(Expr)</template-arg></specialization><typedef name="uncvref_type"><type>boost::remove_const&lt; typename boost::remove_reference&lt; Expr &gt;::type &gt;::type</type></typedef><typedef name="type"><type><classname>result_of::right</classname>&lt; uncvref_type &gt;::type</type></typedef></struct-specialization><typedef name="proto_is_callable_"><type>void</type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type><classname>result_of::right</classname>&lt; Expr &gt;::reference</type><template>
+ <template-type-parameter name="Expr"/>
+ </template><parameter name="expr"><paramtype>Expr &amp;</paramtype><description><para>The expression node. </para></description></parameter><purpose>Return the right child of the given binary expression. </purpose><description><para>
+
+
+
+</para></description><requires><para><computeroutput>is_expr&lt;Expr&gt;::value</computeroutput> is <computeroutput>true</computeroutput> </para><para><computeroutput>2 == Expr::proto_arity::value</computeroutput> </para></requires><returns><para><computeroutput>proto::right(expr)</computeroutput> </para></returns><throws><simpara>Will not throw.</simpara></throws></method><method name="operator()" cv="const"><type><classname>result_of::right</classname>&lt; Expr &gt;::const_reference</type><template>
+ <template-type-parameter name="Expr"/>
+ </template><parameter name="expr"><paramtype>Expr const &amp;</paramtype></parameter></method></method-group></struct></namespace><namespace name="op"><struct name="terminal"><template>
+ <template-type-parameter name="T"/>
+ </template><purpose>A metafunction for generating terminal expression types, a grammar element for matching terminal expressions, and a PrimitiveTransform that returns the current expression unchanged. </purpose><struct-specialization name="result"><template>
+ <template-type-parameter name="This"/>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="State"/>
+ <template-type-parameter name="Data"/>
+ </template><specialization><template-arg>This(Expr</template-arg><template-arg>State</template-arg><template-arg>Data)</template-arg></specialization><typedef name="type"><type>Expr</type></typedef></struct-specialization><typedef name="type"><type>proto::expr&lt; <classname>proto::tag::terminal</classname>, <classname>term</classname>&lt; T &gt; &gt;</type></typedef><typedef name="proto_base_expr"><type>type</type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type>Expr const &amp;</type><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="State"/>
+ <template-type-parameter name="Data"/>
+ </template><parameter name="expr"><paramtype>Expr const &amp;</paramtype><description><para>The current expression </para></description></parameter><parameter name=""><paramtype>State const &amp;</paramtype></parameter><parameter name=""><paramtype>Data &amp;</paramtype></parameter><description><para>
+
+
+
+</para></description><requires><para><computeroutput>matches&lt;Expr, terminal&lt;T&gt; &gt;::value</computeroutput> is <computeroutput>true</computeroutput>. </para></requires><returns><para><computeroutput>expr</computeroutput> </para></returns><throws><simpara>Will not throw.</simpara></throws></method></method-group></struct><struct name="if_else_"><template>
+ <template-type-parameter name="T"/>
+ <template-type-parameter name="U"/>
+ <template-type-parameter name="V"/>
+ </template><purpose>A metafunction for generating ternary conditional expression types, a grammar element for matching ternary conditional expressions, and a PrimitiveTransform that dispatches to the <computeroutput>pass_through&lt;&gt;</computeroutput> transform. </purpose><struct name="result"><template>
+ <template-type-parameter name="Sig"/>
+ </template><typedef name="type"><type><classname>pass_through</classname>&lt; <classname>if_else_</classname> &gt;::template <classname>result</classname>&lt; Sig &gt;::type</type></typedef></struct><typedef name="type"><type>proto::expr&lt; <classname>proto::tag::if_else_</classname>, <classname>list3</classname>&lt; T, U, V &gt; &gt;</type></typedef><typedef name="proto_base_expr"><type>type</type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type><classname>result</classname>&lt; void(Expr, State, Data)&gt;::type</type><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="State"/>
+ <template-type-parameter name="Data"/>
+ </template><parameter name="expr"><paramtype>Expr const &amp;</paramtype><description><para>The current expression </para></description></parameter><parameter name="state"><paramtype>State const &amp;</paramtype><description><para>The current state </para></description></parameter><parameter name="data"><paramtype>Data &amp;</paramtype><description><para>An arbitrary data </para></description></parameter><description><para>
+
+
+</para></description><requires><para><computeroutput>matches&lt;Expr, if_else_&lt;T,U,V&gt; &gt;::value</computeroutput> is <computeroutput>true</computeroutput>. </para></requires><returns><para><computeroutput>pass_through&lt;if_else_&lt;T,U,V&gt; &gt;()(expr, state, data)</computeroutput> </para></returns></method></method-group></struct><struct name="unary_expr"><template>
+ <template-type-parameter name="Tag"/>
+ <template-type-parameter name="T"/>
+ </template><purpose>A metafunction for generating unary expression types with a specified tag type, a grammar element for matching unary expressions, and a PrimitiveTransform that dispatches to the <computeroutput>pass_through&lt;&gt;</computeroutput> transform. </purpose><description><para>Use <computeroutput>unary_expr&lt;_, _&gt;</computeroutput> as a grammar element to match any unary expression. </para></description><struct name="result"><template>
+ <template-type-parameter name="Sig"/>
+ </template><typedef name="type"><type><classname>pass_through</classname>&lt; <classname>unary_expr</classname> &gt;::template <classname>result</classname>&lt; Sig &gt;::type</type></typedef></struct><typedef name="type"><type>proto::expr&lt; Tag, <classname>list1</classname>&lt; T &gt; &gt;</type></typedef><typedef name="proto_base_expr"><type>type</type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type><classname>result</classname>&lt; void(Expr, State, Data)&gt;::type</type><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="State"/>
+ <template-type-parameter name="Data"/>
+ </template><parameter name="expr"><paramtype>Expr const &amp;</paramtype><description><para>The current expression </para></description></parameter><parameter name="state"><paramtype>State const &amp;</paramtype><description><para>The current state </para></description></parameter><parameter name="data"><paramtype>Data &amp;</paramtype><description><para>An arbitrary data </para></description></parameter><description><para>
+
+
+</para></description><requires><para><computeroutput>matches&lt;Expr, unary_expr&lt;Tag, T&gt; &gt;::value</computeroutput> is <computeroutput>true</computeroutput>. </para></requires><returns><para><computeroutput>pass_through&lt;unary_expr&lt;Tag, T&gt; &gt;()(expr, state, data)</computeroutput> </para></returns></method></method-group></struct><struct name="binary_expr"><template>
+ <template-type-parameter name="Tag"/>
+ <template-type-parameter name="T"/>
+ <template-type-parameter name="U"/>
+ </template><purpose>A metafunction for generating binary expression types with a specified tag type, a grammar element for matching binary expressions, and a PrimitiveTransform that dispatches to the <computeroutput>pass_through&lt;&gt;</computeroutput> transform. </purpose><description><para>Use <computeroutput>binary_expr&lt;_, _, _&gt;</computeroutput> as a grammar element to match any binary expression. </para></description><struct name="result"><template>
+ <template-type-parameter name="Sig"/>
+ </template><typedef name="type"><type><classname>pass_through</classname>&lt; <classname>binary_expr</classname> &gt;::template <classname>result</classname>&lt; Sig &gt;::type</type></typedef></struct><typedef name="type"><type>proto::expr&lt; Tag, <classname>list2</classname>&lt; T, U &gt; &gt;</type></typedef><typedef name="proto_base_expr"><type>type</type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type><classname>result</classname>&lt; void(Expr, State, Data)&gt;::type</type><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="State"/>
+ <template-type-parameter name="Data"/>
+ </template><parameter name="expr"><paramtype>Expr const &amp;</paramtype><description><para>The current expression </para></description></parameter><parameter name="state"><paramtype>State const &amp;</paramtype><description><para>The current state </para></description></parameter><parameter name="data"><paramtype>Data &amp;</paramtype><description><para>An arbitrary data </para></description></parameter><description><para>
+
+
+</para></description><requires><para><computeroutput>matches&lt;Expr, binary_expr&lt;Tag,T,U&gt; &gt;::value</computeroutput> is <computeroutput>true</computeroutput>. </para></requires><returns><para><computeroutput>pass_through&lt;binary_expr&lt;Tag,T,U&gt; &gt;()(expr, state, data)</computeroutput> </para></returns></method></method-group></struct><struct name="unary_plus"><template>
+ <template-type-parameter name="T"/>
+ </template><purpose>A metafunction for generating unary plus expression types, a grammar element for matching unary plus expressions, and a PrimitiveTransform that dispatches to the <computeroutput>pass_through&lt;&gt;</computeroutput> transform. </purpose><struct name="result"><template>
+ <template-type-parameter name="Sig"/>
+ </template><typedef name="type"><type><classname>pass_through</classname>&lt; <classname>unary_plus</classname> &gt;::template <classname>result</classname>&lt; Sig &gt;::type</type></typedef></struct><typedef name="type"><type>proto::expr&lt; <classname>proto::tag::unary_plus</classname>, <classname>list1</classname>&lt; T &gt; &gt;</type></typedef><typedef name="proto_base_expr"><type>type</type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type><classname>result</classname>&lt; void(Expr, State, Data)&gt;::type</type><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="State"/>
+ <template-type-parameter name="Data"/>
+ </template><parameter name="expr"><paramtype>Expr const &amp;</paramtype><description><para>The current expression </para></description></parameter><parameter name="state"><paramtype>State const &amp;</paramtype><description><para>The current state </para></description></parameter><parameter name="data"><paramtype>Data &amp;</paramtype><description><para>An arbitrary data </para></description></parameter><description><para>
+
+
+</para></description><requires><para><computeroutput>matches&lt;Expr, unary_plus&lt;T&gt; &gt;::value</computeroutput> is <computeroutput>true</computeroutput>. </para></requires><returns><para><computeroutput>pass_through&lt;unary_plus&lt;T&gt; &gt;()(expr, state, data)</computeroutput> </para></returns></method></method-group></struct><struct name="negate"><template>
+ <template-type-parameter name="T"/>
+ </template><purpose>A metafunction for generating unary minus expression types, a grammar element for matching unary minus expressions, and a PrimitiveTransform that dispatches to the <computeroutput>pass_through&lt;&gt;</computeroutput> transform. </purpose><struct name="result"><template>
+ <template-type-parameter name="Sig"/>
+ </template><typedef name="type"><type><classname>pass_through</classname>&lt; <classname>negate</classname> &gt;::template <classname>result</classname>&lt; Sig &gt;::type</type></typedef></struct><typedef name="type"><type>proto::expr&lt; <classname>proto::tag::negate</classname>, <classname>list1</classname>&lt; T &gt; &gt;</type></typedef><typedef name="proto_base_expr"><type>type</type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type><classname>result</classname>&lt; void(Expr, State, Data)&gt;::type</type><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="State"/>
+ <template-type-parameter name="Data"/>
+ </template><parameter name="expr"><paramtype>Expr const &amp;</paramtype><description><para>The current expression </para></description></parameter><parameter name="state"><paramtype>State const &amp;</paramtype><description><para>The current state </para></description></parameter><parameter name="data"><paramtype>Data &amp;</paramtype><description><para>An arbitrary data </para></description></parameter><description><para>
+
+
+</para></description><requires><para><computeroutput>matches&lt;Expr, negate&lt;T&gt; &gt;::value</computeroutput> is <computeroutput>true</computeroutput>. </para></requires><returns><para><computeroutput>pass_through&lt;negate&lt;T&gt; &gt;()(expr, state, data)</computeroutput> </para></returns></method></method-group></struct><struct name="dereference"><template>
+ <template-type-parameter name="T"/>
+ </template><purpose>A metafunction for generating defereference expression types, a grammar element for matching dereference expressions, and a PrimitiveTransform that dispatches to the <computeroutput>pass_through&lt;&gt;</computeroutput> transform. </purpose><struct name="result"><template>
+ <template-type-parameter name="Sig"/>
+ </template><typedef name="type"><type><classname>pass_through</classname>&lt; <classname>dereference</classname> &gt;::template <classname>result</classname>&lt; Sig &gt;::type</type></typedef></struct><typedef name="type"><type>proto::expr&lt; <classname>proto::tag::dereference</classname>, <classname>list1</classname>&lt; T &gt; &gt;</type></typedef><typedef name="proto_base_expr"><type>type</type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type><classname>result</classname>&lt; void(Expr, State, Data)&gt;::type</type><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="State"/>
+ <template-type-parameter name="Data"/>
+ </template><parameter name="expr"><paramtype>Expr const &amp;</paramtype><description><para>The current expression </para></description></parameter><parameter name="state"><paramtype>State const &amp;</paramtype><description><para>The current state </para></description></parameter><parameter name="data"><paramtype>Data &amp;</paramtype><description><para>An arbitrary data </para></description></parameter><description><para>
+
+
+</para></description><requires><para><computeroutput>matches&lt;Expr, dereference&lt;T&gt; &gt;::value</computeroutput> is <computeroutput>true</computeroutput>. </para></requires><returns><para><computeroutput>pass_through&lt;dereference&lt;T&gt; &gt;()(expr, state, data)</computeroutput> </para></returns></method></method-group></struct><struct name="complement"><template>
+ <template-type-parameter name="T"/>
+ </template><purpose>A metafunction for generating complement expression types, a grammar element for matching complement expressions, and a PrimitiveTransform that dispatches to the <computeroutput>pass_through&lt;&gt;</computeroutput> transform. </purpose><struct name="result"><template>
+ <template-type-parameter name="Sig"/>
+ </template><typedef name="type"><type><classname>pass_through</classname>&lt; <classname>complement</classname> &gt;::template <classname>result</classname>&lt; Sig &gt;::type</type></typedef></struct><typedef name="type"><type>proto::expr&lt; <classname>proto::tag::complement</classname>, <classname>list1</classname>&lt; T &gt; &gt;</type></typedef><typedef name="proto_base_expr"><type>type</type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type><classname>result</classname>&lt; void(Expr, State, Data)&gt;::type</type><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="State"/>
+ <template-type-parameter name="Data"/>
+ </template><parameter name="expr"><paramtype>Expr const &amp;</paramtype><description><para>The current expression </para></description></parameter><parameter name="state"><paramtype>State const &amp;</paramtype><description><para>The current state </para></description></parameter><parameter name="data"><paramtype>Data &amp;</paramtype><description><para>An arbitrary data </para></description></parameter><description><para>
+
+
+</para></description><requires><para><computeroutput>matches&lt;Expr, complement&lt;T&gt; &gt;::value</computeroutput> is <computeroutput>true</computeroutput>. </para></requires><returns><para><computeroutput>pass_through&lt;complement&lt;T&gt; &gt;()(expr, state, data)</computeroutput> </para></returns></method></method-group></struct><struct name="address_of"><template>
+ <template-type-parameter name="T"/>
+ </template><purpose>A metafunction for generating address_of expression types, a grammar element for matching address_of expressions, and a PrimitiveTransform that dispatches to the <computeroutput>pass_through&lt;&gt;</computeroutput> transform. </purpose><struct name="result"><template>
+ <template-type-parameter name="Sig"/>
+ </template><typedef name="type"><type><classname>pass_through</classname>&lt; <classname>address_of</classname> &gt;::template <classname>result</classname>&lt; Sig &gt;::type</type></typedef></struct><typedef name="type"><type>proto::expr&lt; <classname>proto::tag::address_of</classname>, <classname>list1</classname>&lt; T &gt; &gt;</type></typedef><typedef name="proto_base_expr"><type>type</type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type><classname>result</classname>&lt; void(Expr, State, Data)&gt;::type</type><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="State"/>
+ <template-type-parameter name="Data"/>
+ </template><parameter name="expr"><paramtype>Expr const &amp;</paramtype><description><para>The current expression </para></description></parameter><parameter name="state"><paramtype>State const &amp;</paramtype><description><para>The current state </para></description></parameter><parameter name="data"><paramtype>Data &amp;</paramtype><description><para>An arbitrary data </para></description></parameter><description><para>
+
+
+</para></description><requires><para><computeroutput>matches&lt;Expr, address_of&lt;T&gt; &gt;::value</computeroutput> is <computeroutput>true</computeroutput>. </para></requires><returns><para><computeroutput>pass_through&lt;address_of&lt;T&gt; &gt;()(expr, state, data)</computeroutput> </para></returns></method></method-group></struct><struct name="logical_not"><template>
+ <template-type-parameter name="T"/>
+ </template><purpose>A metafunction for generating logical_not expression types, a grammar element for matching logical_not expressions, and a PrimitiveTransform that dispatches to the <computeroutput>pass_through&lt;&gt;</computeroutput> transform. </purpose><struct name="result"><template>
+ <template-type-parameter name="Sig"/>
+ </template><typedef name="type"><type><classname>pass_through</classname>&lt; <classname>logical_not</classname> &gt;::template <classname>result</classname>&lt; Sig &gt;::type</type></typedef></struct><typedef name="type"><type>proto::expr&lt; <classname>proto::tag::logical_not</classname>, <classname>list1</classname>&lt; T &gt; &gt;</type></typedef><typedef name="proto_base_expr"><type>type</type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type><classname>result</classname>&lt; void(Expr, State, Data)&gt;::type</type><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="State"/>
+ <template-type-parameter name="Data"/>
+ </template><parameter name="expr"><paramtype>Expr const &amp;</paramtype><description><para>The current expression </para></description></parameter><parameter name="state"><paramtype>State const &amp;</paramtype><description><para>The current state </para></description></parameter><parameter name="data"><paramtype>Data &amp;</paramtype><description><para>An arbitrary data </para></description></parameter><description><para>
+
+
+</para></description><requires><para><computeroutput>matches&lt;Expr, logical_not&lt;T&gt; &gt;::value</computeroutput> is <computeroutput>true</computeroutput>. </para></requires><returns><para><computeroutput>pass_through&lt;logical_not&lt;T&gt; &gt;()(expr, state, data)</computeroutput> </para></returns></method></method-group></struct><struct name="pre_inc"><template>
+ <template-type-parameter name="T"/>
+ </template><purpose>A metafunction for generating pre-increment expression types, a grammar element for matching pre-increment expressions, and a PrimitiveTransform that dispatches to the <computeroutput>pass_through&lt;&gt;</computeroutput> transform. </purpose><struct name="result"><template>
+ <template-type-parameter name="Sig"/>
+ </template><typedef name="type"><type><classname>pass_through</classname>&lt; <classname>pre_inc</classname> &gt;::template <classname>result</classname>&lt; Sig &gt;::type</type></typedef></struct><typedef name="type"><type>proto::expr&lt; <classname>proto::tag::pre_inc</classname>, <classname>list1</classname>&lt; T &gt; &gt;</type></typedef><typedef name="proto_base_expr"><type>type</type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type><classname>result</classname>&lt; void(Expr, State, Data)&gt;::type</type><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="State"/>
+ <template-type-parameter name="Data"/>
+ </template><parameter name="expr"><paramtype>Expr const &amp;</paramtype><description><para>The current expression </para></description></parameter><parameter name="state"><paramtype>State const &amp;</paramtype><description><para>The current state </para></description></parameter><parameter name="data"><paramtype>Data &amp;</paramtype><description><para>An arbitrary data </para></description></parameter><description><para>
+
+
+</para></description><requires><para><computeroutput>matches&lt;Expr, pre_inc&lt;T&gt; &gt;::value</computeroutput> is <computeroutput>true</computeroutput>. </para></requires><returns><para><computeroutput>pass_through&lt;pre_inc&lt;T&gt; &gt;()(expr, state, data)</computeroutput> </para></returns></method></method-group></struct><struct name="pre_dec"><template>
+ <template-type-parameter name="T"/>
+ </template><purpose>A metafunction for generating pre-decrement expression types, a grammar element for matching pre-decrement expressions, and a PrimitiveTransform that dispatches to the <computeroutput>pass_through&lt;&gt;</computeroutput> transform. </purpose><struct name="result"><template>
+ <template-type-parameter name="Sig"/>
+ </template><typedef name="type"><type><classname>pass_through</classname>&lt; <classname>pre_dec</classname> &gt;::template <classname>result</classname>&lt; Sig &gt;::type</type></typedef></struct><typedef name="type"><type>proto::expr&lt; <classname>proto::tag::pre_dec</classname>, <classname>list1</classname>&lt; T &gt; &gt;</type></typedef><typedef name="proto_base_expr"><type>type</type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type><classname>result</classname>&lt; void(Expr, State, Data)&gt;::type</type><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="State"/>
+ <template-type-parameter name="Data"/>
+ </template><parameter name="expr"><paramtype>Expr const &amp;</paramtype><description><para>The current expression </para></description></parameter><parameter name="state"><paramtype>State const &amp;</paramtype><description><para>The current state </para></description></parameter><parameter name="data"><paramtype>Data &amp;</paramtype><description><para>An arbitrary data </para></description></parameter><description><para>
+
+
+</para></description><requires><para><computeroutput>matches&lt;Expr, pre_dec&lt;T&gt; &gt;::value</computeroutput> is <computeroutput>true</computeroutput>. </para></requires><returns><para><computeroutput>pass_through&lt;pre_dec&lt;T&gt; &gt;()(expr, state, data)</computeroutput> </para></returns></method></method-group></struct><struct name="post_inc"><template>
+ <template-type-parameter name="T"/>
+ </template><purpose>A metafunction for generating post-increment expression types, a grammar element for matching post-increment expressions, and a PrimitiveTransform that dispatches to the <computeroutput>pass_through&lt;&gt;</computeroutput> transform. </purpose><struct name="result"><template>
+ <template-type-parameter name="Sig"/>
+ </template><typedef name="type"><type><classname>pass_through</classname>&lt; <classname>post_inc</classname> &gt;::template <classname>result</classname>&lt; Sig &gt;::type</type></typedef></struct><typedef name="type"><type>proto::expr&lt; <classname>proto::tag::post_inc</classname>, <classname>list1</classname>&lt; T &gt; &gt;</type></typedef><typedef name="proto_base_expr"><type>type</type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type><classname>result</classname>&lt; void(Expr, State, Data)&gt;::type</type><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="State"/>
+ <template-type-parameter name="Data"/>
+ </template><parameter name="expr"><paramtype>Expr const &amp;</paramtype><description><para>The current expression </para></description></parameter><parameter name="state"><paramtype>State const &amp;</paramtype><description><para>The current state </para></description></parameter><parameter name="data"><paramtype>Data &amp;</paramtype><description><para>An arbitrary data </para></description></parameter><description><para>
+
+
+</para></description><requires><para><computeroutput>matches&lt;Expr, post_inc&lt;T&gt; &gt;::value</computeroutput> is <computeroutput>true</computeroutput>. </para></requires><returns><para><computeroutput>pass_through&lt;post_inc&lt;T&gt; &gt;()(expr, state, data)</computeroutput> </para></returns></method></method-group></struct><struct name="post_dec"><template>
+ <template-type-parameter name="T"/>
+ </template><purpose>A metafunction for generating post-decrement expression types, a grammar element for matching post-decrement expressions, and a PrimitiveTransform that dispatches to the <computeroutput>pass_through&lt;&gt;</computeroutput> transform. </purpose><struct name="result"><template>
+ <template-type-parameter name="Sig"/>
+ </template><typedef name="type"><type><classname>pass_through</classname>&lt; <classname>post_dec</classname> &gt;::template <classname>result</classname>&lt; Sig &gt;::type</type></typedef></struct><typedef name="type"><type>proto::expr&lt; <classname>proto::tag::post_dec</classname>, <classname>list1</classname>&lt; T &gt; &gt;</type></typedef><typedef name="proto_base_expr"><type>type</type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type><classname>result</classname>&lt; void(Expr, State, Data)&gt;::type</type><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="State"/>
+ <template-type-parameter name="Data"/>
+ </template><parameter name="expr"><paramtype>Expr const &amp;</paramtype><description><para>The current expression </para></description></parameter><parameter name="state"><paramtype>State const &amp;</paramtype><description><para>The current state </para></description></parameter><parameter name="data"><paramtype>Data &amp;</paramtype><description><para>An arbitrary data </para></description></parameter><description><para>
+
+
+</para></description><requires><para><computeroutput>matches&lt;Expr, post_dec&lt;T&gt; &gt;::value</computeroutput> is <computeroutput>true</computeroutput>. </para></requires><returns><para><computeroutput>pass_through&lt;post_dec&lt;T&gt; &gt;()(expr, state, data)</computeroutput> </para></returns></method></method-group></struct><struct name="shift_left"><template>
+ <template-type-parameter name="T"/>
+ <template-type-parameter name="U"/>
+ </template><purpose>A metafunction for generating left-shift expression types, a grammar element for matching left-shift expressions, and a PrimitiveTransform that dispatches to the <computeroutput>pass_through&lt;&gt;</computeroutput> transform. </purpose><struct name="result"><template>
+ <template-type-parameter name="Sig"/>
+ </template><typedef name="type"><type><classname>pass_through</classname>&lt; <classname>shift_left</classname> &gt;::template <classname>result</classname>&lt; Sig &gt;::type</type></typedef></struct><typedef name="type"><type>proto::expr&lt; <classname>proto::tag::shift_left</classname>, <classname>list2</classname>&lt; T, U &gt; &gt;</type></typedef><typedef name="proto_base_expr"><type>type</type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type><classname>result</classname>&lt; void(Expr, State, Data)&gt;::type</type><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="State"/>
+ <template-type-parameter name="Data"/>
+ </template><parameter name="expr"><paramtype>Expr const &amp;</paramtype><description><para>The current expression </para></description></parameter><parameter name="state"><paramtype>State const &amp;</paramtype><description><para>The current state </para></description></parameter><parameter name="data"><paramtype>Data &amp;</paramtype><description><para>An arbitrary data </para></description></parameter><description><para>
+
+
+</para></description><requires><para><computeroutput>matches&lt;Expr, shift_left&lt;T,U&gt; &gt;::value</computeroutput> is <computeroutput>true</computeroutput>. </para></requires><returns><para><computeroutput>pass_through&lt;shift_left&lt;T,U&gt; &gt;()(expr, state, data)</computeroutput> </para></returns></method></method-group></struct><struct name="shift_right"><template>
+ <template-type-parameter name="T"/>
+ <template-type-parameter name="U"/>
+ </template><purpose>A metafunction for generating right-shift expression types, a grammar element for matching right-shift expressions, and a PrimitiveTransform that dispatches to the <computeroutput>pass_through&lt;&gt;</computeroutput> transform. </purpose><struct name="result"><template>
+ <template-type-parameter name="Sig"/>
+ </template><typedef name="type"><type><classname>pass_through</classname>&lt; <classname>shift_right</classname> &gt;::template <classname>result</classname>&lt; Sig &gt;::type</type></typedef></struct><typedef name="type"><type>proto::expr&lt; <classname>proto::tag::shift_right</classname>, <classname>list2</classname>&lt; T, U &gt; &gt;</type></typedef><typedef name="proto_base_expr"><type>type</type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type><classname>result</classname>&lt; void(Expr, State, Data)&gt;::type</type><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="State"/>
+ <template-type-parameter name="Data"/>
+ </template><parameter name="expr"><paramtype>Expr const &amp;</paramtype><description><para>The current expression </para></description></parameter><parameter name="state"><paramtype>State const &amp;</paramtype><description><para>The current state </para></description></parameter><parameter name="data"><paramtype>Data &amp;</paramtype><description><para>An arbitrary data </para></description></parameter><description><para>
+
+
+</para></description><requires><para><computeroutput>matches&lt;Expr, shift_right&lt;T,U&gt; &gt;::value</computeroutput> is <computeroutput>true</computeroutput>. </para></requires><returns><para><computeroutput>pass_through&lt;shift_right&lt;T,U&gt; &gt;()(expr, state, data)</computeroutput> </para></returns></method></method-group></struct><struct name="multiplies"><template>
+ <template-type-parameter name="T"/>
+ <template-type-parameter name="U"/>
+ </template><purpose>A metafunction for generating multiplies expression types, a grammar element for matching multiplies expressions, and a PrimitiveTransform that dispatches to the <computeroutput>pass_through&lt;&gt;</computeroutput> transform. </purpose><struct name="result"><template>
+ <template-type-parameter name="Sig"/>
+ </template><typedef name="type"><type><classname>pass_through</classname>&lt; <classname>multiplies</classname> &gt;::template <classname>result</classname>&lt; Sig &gt;::type</type></typedef></struct><typedef name="type"><type>proto::expr&lt; <classname>proto::tag::multiplies</classname>, <classname>list2</classname>&lt; T, U &gt; &gt;</type></typedef><typedef name="proto_base_expr"><type>type</type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type><classname>result</classname>&lt; void(Expr, State, Data)&gt;::type</type><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="State"/>
+ <template-type-parameter name="Data"/>
+ </template><parameter name="expr"><paramtype>Expr const &amp;</paramtype><description><para>The current expression </para></description></parameter><parameter name="state"><paramtype>State const &amp;</paramtype><description><para>The current state </para></description></parameter><parameter name="data"><paramtype>Data &amp;</paramtype><description><para>An arbitrary data </para></description></parameter><description><para>
+
+
+</para></description><requires><para><computeroutput>matches&lt;Expr, multiplies&lt;T,U&gt; &gt;::value</computeroutput> is <computeroutput>true</computeroutput>. </para></requires><returns><para><computeroutput>pass_through&lt;multiplies&lt;T,U&gt; &gt;()(expr, state, data)</computeroutput> </para></returns></method></method-group></struct><struct name="divides"><template>
+ <template-type-parameter name="T"/>
+ <template-type-parameter name="U"/>
+ </template><purpose>A metafunction for generating divides expression types, a grammar element for matching divides expressions, and a PrimitiveTransform that dispatches to the <computeroutput>pass_through&lt;&gt;</computeroutput> transform. </purpose><struct name="result"><template>
+ <template-type-parameter name="Sig"/>
+ </template><typedef name="type"><type><classname>pass_through</classname>&lt; <classname>divides</classname> &gt;::template <classname>result</classname>&lt; Sig &gt;::type</type></typedef></struct><typedef name="type"><type>proto::expr&lt; <classname>proto::tag::divides</classname>, <classname>list2</classname>&lt; T, U &gt; &gt;</type></typedef><typedef name="proto_base_expr"><type>type</type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type><classname>result</classname>&lt; void(Expr, State, Data)&gt;::type</type><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="State"/>
+ <template-type-parameter name="Data"/>
+ </template><parameter name="expr"><paramtype>Expr const &amp;</paramtype><description><para>The current expression </para></description></parameter><parameter name="state"><paramtype>State const &amp;</paramtype><description><para>The current state </para></description></parameter><parameter name="data"><paramtype>Data &amp;</paramtype><description><para>An arbitrary data </para></description></parameter><description><para>
+
+
+</para></description><requires><para><computeroutput>matches&lt;Expr, divides&lt;T,U&gt; &gt;::value</computeroutput> is <computeroutput>true</computeroutput>. </para></requires><returns><para><computeroutput>pass_through&lt;divides&lt;T,U&gt; &gt;()(expr, state, data)</computeroutput> </para></returns></method></method-group></struct><struct name="modulus"><template>
+ <template-type-parameter name="T"/>
+ <template-type-parameter name="U"/>
+ </template><purpose>A metafunction for generating modulus expression types, a grammar element for matching modulus expressions, and a PrimitiveTransform that dispatches to the <computeroutput>pass_through&lt;&gt;</computeroutput> transform. </purpose><struct name="result"><template>
+ <template-type-parameter name="Sig"/>
+ </template><typedef name="type"><type><classname>pass_through</classname>&lt; <classname>modulus</classname> &gt;::template <classname>result</classname>&lt; Sig &gt;::type</type></typedef></struct><typedef name="type"><type>proto::expr&lt; <classname>proto::tag::modulus</classname>, <classname>list2</classname>&lt; T, U &gt; &gt;</type></typedef><typedef name="proto_base_expr"><type>type</type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type><classname>result</classname>&lt; void(Expr, State, Data)&gt;::type</type><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="State"/>
+ <template-type-parameter name="Data"/>
+ </template><parameter name="expr"><paramtype>Expr const &amp;</paramtype><description><para>The current expression </para></description></parameter><parameter name="state"><paramtype>State const &amp;</paramtype><description><para>The current state </para></description></parameter><parameter name="data"><paramtype>Data &amp;</paramtype><description><para>An arbitrary data </para></description></parameter><description><para>
+
+
+</para></description><requires><para><computeroutput>matches&lt;Expr, modulus&lt;T,U&gt; &gt;::value</computeroutput> is <computeroutput>true</computeroutput>. </para></requires><returns><para><computeroutput>pass_through&lt;modulus&lt;T,U&gt; &gt;()(expr, state, data)</computeroutput> </para></returns></method></method-group></struct><struct name="plus"><template>
+ <template-type-parameter name="T"/>
+ <template-type-parameter name="U"/>
+ </template><purpose>A metafunction for generating binary plus expression types, a grammar element for matching binary plus expressions, and a PrimitiveTransform that dispatches to the <computeroutput>pass_through&lt;&gt;</computeroutput> transform. </purpose><struct name="result"><template>
+ <template-type-parameter name="Sig"/>
+ </template><typedef name="type"><type><classname>pass_through</classname>&lt; <classname>plus</classname> &gt;::template <classname>result</classname>&lt; Sig &gt;::type</type></typedef></struct><typedef name="type"><type>proto::expr&lt; <classname>proto::tag::plus</classname>, <classname>list2</classname>&lt; T, U &gt; &gt;</type></typedef><typedef name="proto_base_expr"><type>type</type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type><classname>result</classname>&lt; void(Expr, State, Data)&gt;::type</type><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="State"/>
+ <template-type-parameter name="Data"/>
+ </template><parameter name="expr"><paramtype>Expr const &amp;</paramtype><description><para>The current expression </para></description></parameter><parameter name="state"><paramtype>State const &amp;</paramtype><description><para>The current state </para></description></parameter><parameter name="data"><paramtype>Data &amp;</paramtype><description><para>An arbitrary data </para></description></parameter><description><para>
+
+
+</para></description><requires><para><computeroutput>matches&lt;Expr, plus&lt;T,U&gt; &gt;::value</computeroutput> is <computeroutput>true</computeroutput>. </para></requires><returns><para><computeroutput>pass_through&lt;plus&lt;T,U&gt; &gt;()(expr, state, data)</computeroutput> </para></returns></method></method-group></struct><struct name="minus"><template>
+ <template-type-parameter name="T"/>
+ <template-type-parameter name="U"/>
+ </template><purpose>A metafunction for generating binary minus expression types, a grammar element for matching binary minus expressions, and a PrimitiveTransform that dispatches to the <computeroutput>pass_through&lt;&gt;</computeroutput> transform. </purpose><struct name="result"><template>
+ <template-type-parameter name="Sig"/>
+ </template><typedef name="type"><type><classname>pass_through</classname>&lt; <classname>minus</classname> &gt;::template <classname>result</classname>&lt; Sig &gt;::type</type></typedef></struct><typedef name="type"><type>proto::expr&lt; <classname>proto::tag::minus</classname>, <classname>list2</classname>&lt; T, U &gt; &gt;</type></typedef><typedef name="proto_base_expr"><type>type</type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type><classname>result</classname>&lt; void(Expr, State, Data)&gt;::type</type><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="State"/>
+ <template-type-parameter name="Data"/>
+ </template><parameter name="expr"><paramtype>Expr const &amp;</paramtype><description><para>The current expression </para></description></parameter><parameter name="state"><paramtype>State const &amp;</paramtype><description><para>The current state </para></description></parameter><parameter name="data"><paramtype>Data &amp;</paramtype><description><para>An arbitrary data </para></description></parameter><description><para>
+
+
+</para></description><requires><para><computeroutput>matches&lt;Expr, minus&lt;T,U&gt; &gt;::value</computeroutput> is <computeroutput>true</computeroutput>. </para></requires><returns><para><computeroutput>pass_through&lt;minus&lt;T,U&gt; &gt;()(expr, state, data)</computeroutput> </para></returns></method></method-group></struct><struct name="less"><template>
+ <template-type-parameter name="T"/>
+ <template-type-parameter name="U"/>
+ </template><purpose>A metafunction for generating less expression types, a grammar element for matching less expressions, and a PrimitiveTransform that dispatches to the <computeroutput>pass_through&lt;&gt;</computeroutput> transform. </purpose><struct name="result"><template>
+ <template-type-parameter name="Sig"/>
+ </template><typedef name="type"><type><classname>pass_through</classname>&lt; <classname>less</classname> &gt;::template <classname>result</classname>&lt; Sig &gt;::type</type></typedef></struct><typedef name="type"><type>proto::expr&lt; <classname>proto::tag::less</classname>, <classname>list2</classname>&lt; T, U &gt; &gt;</type></typedef><typedef name="proto_base_expr"><type>type</type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type><classname>result</classname>&lt; void(Expr, State, Data)&gt;::type</type><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="State"/>
+ <template-type-parameter name="Data"/>
+ </template><parameter name="expr"><paramtype>Expr const &amp;</paramtype><description><para>The current expression </para></description></parameter><parameter name="state"><paramtype>State const &amp;</paramtype><description><para>The current state </para></description></parameter><parameter name="data"><paramtype>Data &amp;</paramtype><description><para>An arbitrary data </para></description></parameter><description><para>
+
+
+</para></description><requires><para><computeroutput>matches&lt;Expr, less&lt;T,U&gt; &gt;::value</computeroutput> is <computeroutput>true</computeroutput>. </para></requires><returns><para><computeroutput>pass_through&lt;less&lt;T,U&gt; &gt;()(expr, state, data)</computeroutput> </para></returns></method></method-group></struct><struct name="greater"><template>
+ <template-type-parameter name="T"/>
+ <template-type-parameter name="U"/>
+ </template><purpose>A metafunction for generating greater expression types, a grammar element for matching greater expressions, and a PrimitiveTransform that dispatches to the <computeroutput>pass_through&lt;&gt;</computeroutput> transform. </purpose><struct name="result"><template>
+ <template-type-parameter name="Sig"/>
+ </template><typedef name="type"><type><classname>pass_through</classname>&lt; <classname>greater</classname> &gt;::template <classname>result</classname>&lt; Sig &gt;::type</type></typedef></struct><typedef name="type"><type>proto::expr&lt; <classname>proto::tag::greater</classname>, <classname>list2</classname>&lt; T, U &gt; &gt;</type></typedef><typedef name="proto_base_expr"><type>type</type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type><classname>result</classname>&lt; void(Expr, State, Data)&gt;::type</type><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="State"/>
+ <template-type-parameter name="Data"/>
+ </template><parameter name="expr"><paramtype>Expr const &amp;</paramtype><description><para>The current expression </para></description></parameter><parameter name="state"><paramtype>State const &amp;</paramtype><description><para>The current state </para></description></parameter><parameter name="data"><paramtype>Data &amp;</paramtype><description><para>An arbitrary data </para></description></parameter><description><para>
+
+
+</para></description><requires><para><computeroutput>matches&lt;Expr, greater&lt;T,U&gt; &gt;::value</computeroutput> is <computeroutput>true</computeroutput>. </para></requires><returns><para><computeroutput>pass_through&lt;greater&lt;T,U&gt; &gt;()(expr, state, data)</computeroutput> </para></returns></method></method-group></struct><struct name="less_equal"><template>
+ <template-type-parameter name="T"/>
+ <template-type-parameter name="U"/>
+ </template><purpose>A metafunction for generating less-or-equal expression types, a grammar element for matching less-or-equal expressions, and a PrimitiveTransform that dispatches to the <computeroutput>pass_through&lt;&gt;</computeroutput> transform. </purpose><struct name="result"><template>
+ <template-type-parameter name="Sig"/>
+ </template><typedef name="type"><type><classname>pass_through</classname>&lt; <classname>less_equal</classname> &gt;::template <classname>result</classname>&lt; Sig &gt;::type</type></typedef></struct><typedef name="type"><type>proto::expr&lt; <classname>proto::tag::less_equal</classname>, <classname>list2</classname>&lt; T, U &gt; &gt;</type></typedef><typedef name="proto_base_expr"><type>type</type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type><classname>result</classname>&lt; void(Expr, State, Data)&gt;::type</type><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="State"/>
+ <template-type-parameter name="Data"/>
+ </template><parameter name="expr"><paramtype>Expr const &amp;</paramtype><description><para>The current expression </para></description></parameter><parameter name="state"><paramtype>State const &amp;</paramtype><description><para>The current state </para></description></parameter><parameter name="data"><paramtype>Data &amp;</paramtype><description><para>An arbitrary data </para></description></parameter><description><para>
+
+
+</para></description><requires><para><computeroutput>matches&lt;Expr, less_equal&lt;T,U&gt; &gt;::value</computeroutput> is <computeroutput>true</computeroutput>. </para></requires><returns><para><computeroutput>pass_through&lt;less_equal&lt;T,U&gt; &gt;()(expr, state, data)</computeroutput> </para></returns></method></method-group></struct><struct name="greater_equal"><template>
+ <template-type-parameter name="T"/>
+ <template-type-parameter name="U"/>
+ </template><purpose>A metafunction for generating greater-or-equal expression types, a grammar element for matching greater-or-equal expressions, and a PrimitiveTransform that dispatches to the <computeroutput>pass_through&lt;&gt;</computeroutput> transform. </purpose><struct name="result"><template>
+ <template-type-parameter name="Sig"/>
+ </template><typedef name="type"><type><classname>pass_through</classname>&lt; <classname>greater_equal</classname> &gt;::template <classname>result</classname>&lt; Sig &gt;::type</type></typedef></struct><typedef name="type"><type>proto::expr&lt; <classname>proto::tag::greater_equal</classname>, <classname>list2</classname>&lt; T, U &gt; &gt;</type></typedef><typedef name="proto_base_expr"><type>type</type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type><classname>result</classname>&lt; void(Expr, State, Data)&gt;::type</type><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="State"/>
+ <template-type-parameter name="Data"/>
+ </template><parameter name="expr"><paramtype>Expr const &amp;</paramtype><description><para>The current expression </para></description></parameter><parameter name="state"><paramtype>State const &amp;</paramtype><description><para>The current state </para></description></parameter><parameter name="data"><paramtype>Data &amp;</paramtype><description><para>An arbitrary data </para></description></parameter><description><para>
+
+
+</para></description><requires><para><computeroutput>matches&lt;Expr, greater_equal&lt;T,U&gt; &gt;::value</computeroutput> is <computeroutput>true</computeroutput>. </para></requires><returns><para><computeroutput>pass_through&lt;greater_equal&lt;T,U&gt; &gt;()(expr, state, data)</computeroutput> </para></returns></method></method-group></struct><struct name="equal_to"><template>
+ <template-type-parameter name="T"/>
+ <template-type-parameter name="U"/>
+ </template><purpose>A metafunction for generating equal-to expression types, a grammar element for matching equal-to expressions, and a PrimitiveTransform that dispatches to the <computeroutput>pass_through&lt;&gt;</computeroutput> transform. </purpose><struct name="result"><template>
+ <template-type-parameter name="Sig"/>
+ </template><typedef name="type"><type><classname>pass_through</classname>&lt; <classname>equal_to</classname> &gt;::template <classname>result</classname>&lt; Sig &gt;::type</type></typedef></struct><typedef name="type"><type>proto::expr&lt; <classname>proto::tag::equal_to</classname>, <classname>list2</classname>&lt; T, U &gt; &gt;</type></typedef><typedef name="proto_base_expr"><type>type</type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type><classname>result</classname>&lt; void(Expr, State, Data)&gt;::type</type><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="State"/>
+ <template-type-parameter name="Data"/>
+ </template><parameter name="expr"><paramtype>Expr const &amp;</paramtype><description><para>The current expression </para></description></parameter><parameter name="state"><paramtype>State const &amp;</paramtype><description><para>The current state </para></description></parameter><parameter name="data"><paramtype>Data &amp;</paramtype><description><para>An arbitrary data </para></description></parameter><description><para>
+
+
+</para></description><requires><para><computeroutput>matches&lt;Expr, equal_to&lt;T,U&gt; &gt;::value</computeroutput> is <computeroutput>true</computeroutput>. </para></requires><returns><para><computeroutput>pass_through&lt;equal_to&lt;T,U&gt; &gt;()(expr, state, data)</computeroutput> </para></returns></method></method-group></struct><struct name="not_equal_to"><template>
+ <template-type-parameter name="T"/>
+ <template-type-parameter name="U"/>
+ </template><purpose>A metafunction for generating not-equal-to expression types, a grammar element for matching not-equal-to expressions, and a PrimitiveTransform that dispatches to the <computeroutput>pass_through&lt;&gt;</computeroutput> transform. </purpose><struct name="result"><template>
+ <template-type-parameter name="Sig"/>
+ </template><typedef name="type"><type><classname>pass_through</classname>&lt; <classname>not_equal_to</classname> &gt;::template <classname>result</classname>&lt; Sig &gt;::type</type></typedef></struct><typedef name="type"><type>proto::expr&lt; <classname>proto::tag::not_equal_to</classname>, <classname>list2</classname>&lt; T, U &gt; &gt;</type></typedef><typedef name="proto_base_expr"><type>type</type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type><classname>result</classname>&lt; void(Expr, State, Data)&gt;::type</type><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="State"/>
+ <template-type-parameter name="Data"/>
+ </template><parameter name="expr"><paramtype>Expr const &amp;</paramtype><description><para>The current expression </para></description></parameter><parameter name="state"><paramtype>State const &amp;</paramtype><description><para>The current state </para></description></parameter><parameter name="data"><paramtype>Data &amp;</paramtype><description><para>An arbitrary data </para></description></parameter><description><para>
+
+
+</para></description><requires><para><computeroutput>matches&lt;Expr, not_equal_to&lt;T,U&gt; &gt;::value</computeroutput> is <computeroutput>true</computeroutput>. </para></requires><returns><para><computeroutput>pass_through&lt;not_equal_to&lt;T,U&gt; &gt;()(expr, state, data)</computeroutput> </para></returns></method></method-group></struct><struct name="logical_or"><template>
+ <template-type-parameter name="T"/>
+ <template-type-parameter name="U"/>
+ </template><purpose>A metafunction for generating logical-or expression types, a grammar element for matching logical-or expressions, and a PrimitiveTransform that dispatches to the <computeroutput>pass_through&lt;&gt;</computeroutput> transform. </purpose><struct name="result"><template>
+ <template-type-parameter name="Sig"/>
+ </template><typedef name="type"><type><classname>pass_through</classname>&lt; <classname>logical_or</classname> &gt;::template <classname>result</classname>&lt; Sig &gt;::type</type></typedef></struct><typedef name="type"><type>proto::expr&lt; <classname>proto::tag::logical_or</classname>, <classname>list2</classname>&lt; T, U &gt; &gt;</type></typedef><typedef name="proto_base_expr"><type>type</type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type><classname>result</classname>&lt; void(Expr, State, Data)&gt;::type</type><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="State"/>
+ <template-type-parameter name="Data"/>
+ </template><parameter name="expr"><paramtype>Expr const &amp;</paramtype><description><para>The current expression </para></description></parameter><parameter name="state"><paramtype>State const &amp;</paramtype><description><para>The current state </para></description></parameter><parameter name="data"><paramtype>Data &amp;</paramtype><description><para>An arbitrary data </para></description></parameter><description><para>
+
+
+</para></description><requires><para><computeroutput>matches&lt;Expr, logical_or&lt;T,U&gt; &gt;::value</computeroutput> is <computeroutput>true</computeroutput>. </para></requires><returns><para><computeroutput>pass_through&lt;logical_or&lt;T,U&gt; &gt;()(expr, state, data)</computeroutput> </para></returns></method></method-group></struct><struct name="logical_and"><template>
+ <template-type-parameter name="T"/>
+ <template-type-parameter name="U"/>
+ </template><purpose>A metafunction for generating logical-and expression types, a grammar element for matching logical-and expressions, and a PrimitiveTransform that dispatches to the <computeroutput>pass_through&lt;&gt;</computeroutput> transform. </purpose><struct name="result"><template>
+ <template-type-parameter name="Sig"/>
+ </template><typedef name="type"><type><classname>pass_through</classname>&lt; <classname>logical_and</classname> &gt;::template <classname>result</classname>&lt; Sig &gt;::type</type></typedef></struct><typedef name="type"><type>proto::expr&lt; <classname>proto::tag::logical_and</classname>, <classname>list2</classname>&lt; T, U &gt; &gt;</type></typedef><typedef name="proto_base_expr"><type>type</type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type><classname>result</classname>&lt; void(Expr, State, Data)&gt;::type</type><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="State"/>
+ <template-type-parameter name="Data"/>
+ </template><parameter name="expr"><paramtype>Expr const &amp;</paramtype><description><para>The current expression </para></description></parameter><parameter name="state"><paramtype>State const &amp;</paramtype><description><para>The current state </para></description></parameter><parameter name="data"><paramtype>Data &amp;</paramtype><description><para>An arbitrary data </para></description></parameter><description><para>
+
+
+</para></description><requires><para><computeroutput>matches&lt;Expr, logical_and&lt;T,U&gt; &gt;::value</computeroutput> is <computeroutput>true</computeroutput>. </para></requires><returns><para><computeroutput>pass_through&lt;logical_and&lt;T,U&gt; &gt;()(expr, state, data)</computeroutput> </para></returns></method></method-group></struct><struct name="bitwise_and"><template>
+ <template-type-parameter name="T"/>
+ <template-type-parameter name="U"/>
+ </template><purpose>A metafunction for generating bitwise-and expression types, a grammar element for matching bitwise-and expressions, and a PrimitiveTransform that dispatches to the <computeroutput>pass_through&lt;&gt;</computeroutput> transform. </purpose><struct name="result"><template>
+ <template-type-parameter name="Sig"/>
+ </template><typedef name="type"><type><classname>pass_through</classname>&lt; <classname>bitwise_and</classname> &gt;::template <classname>result</classname>&lt; Sig &gt;::type</type></typedef></struct><typedef name="type"><type>proto::expr&lt; <classname>proto::tag::bitwise_and</classname>, <classname>list2</classname>&lt; T, U &gt; &gt;</type></typedef><typedef name="proto_base_expr"><type>type</type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type><classname>result</classname>&lt; void(Expr, State, Data)&gt;::type</type><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="State"/>
+ <template-type-parameter name="Data"/>
+ </template><parameter name="expr"><paramtype>Expr const &amp;</paramtype><description><para>The current expression </para></description></parameter><parameter name="state"><paramtype>State const &amp;</paramtype><description><para>The current state </para></description></parameter><parameter name="data"><paramtype>Data &amp;</paramtype><description><para>An arbitrary data </para></description></parameter><description><para>
+
+
+</para></description><requires><para><computeroutput>matches&lt;Expr, bitwise_and&lt;T,U&gt; &gt;::value</computeroutput> is <computeroutput>true</computeroutput>. </para></requires><returns><para><computeroutput>pass_through&lt;bitwise_and&lt;T,U&gt; &gt;()(expr, state, data)</computeroutput> </para></returns></method></method-group></struct><struct name="bitwise_or"><template>
+ <template-type-parameter name="T"/>
+ <template-type-parameter name="U"/>
+ </template><purpose>A metafunction for generating bitwise-or expression types, a grammar element for matching bitwise-or expressions, and a PrimitiveTransform that dispatches to the <computeroutput>pass_through&lt;&gt;</computeroutput> transform. </purpose><struct name="result"><template>
+ <template-type-parameter name="Sig"/>
+ </template><typedef name="type"><type><classname>pass_through</classname>&lt; <classname>bitwise_or</classname> &gt;::template <classname>result</classname>&lt; Sig &gt;::type</type></typedef></struct><typedef name="type"><type>proto::expr&lt; <classname>proto::tag::bitwise_or</classname>, <classname>list2</classname>&lt; T, U &gt; &gt;</type></typedef><typedef name="proto_base_expr"><type>type</type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type><classname>result</classname>&lt; void(Expr, State, Data)&gt;::type</type><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="State"/>
+ <template-type-parameter name="Data"/>
+ </template><parameter name="expr"><paramtype>Expr const &amp;</paramtype><description><para>The current expression </para></description></parameter><parameter name="state"><paramtype>State const &amp;</paramtype><description><para>The current state </para></description></parameter><parameter name="data"><paramtype>Data &amp;</paramtype><description><para>An arbitrary data </para></description></parameter><description><para>
+
+
+</para></description><requires><para><computeroutput>matches&lt;Expr, bitwise_or&lt;T,U&gt; &gt;::value</computeroutput> is <computeroutput>true</computeroutput>. </para></requires><returns><para><computeroutput>pass_through&lt;bitwise_or&lt;T,U&gt; &gt;()(expr, state, data)</computeroutput> </para></returns></method></method-group></struct><struct name="bitwise_xor"><template>
+ <template-type-parameter name="T"/>
+ <template-type-parameter name="U"/>
+ </template><purpose>A metafunction for generating bitwise-xor expression types, a grammar element for matching bitwise-xor expressions, and a PrimitiveTransform that dispatches to the <computeroutput>pass_through&lt;&gt;</computeroutput> transform. </purpose><struct name="result"><template>
+ <template-type-parameter name="Sig"/>
+ </template><typedef name="type"><type><classname>pass_through</classname>&lt; <classname>bitwise_xor</classname> &gt;::template <classname>result</classname>&lt; Sig &gt;::type</type></typedef></struct><typedef name="type"><type>proto::expr&lt; <classname>proto::tag::bitwise_xor</classname>, <classname>list2</classname>&lt; T, U &gt; &gt;</type></typedef><typedef name="proto_base_expr"><type>type</type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type><classname>result</classname>&lt; void(Expr, State, Data)&gt;::type</type><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="State"/>
+ <template-type-parameter name="Data"/>
+ </template><parameter name="expr"><paramtype>Expr const &amp;</paramtype><description><para>The current expression </para></description></parameter><parameter name="state"><paramtype>State const &amp;</paramtype><description><para>The current state </para></description></parameter><parameter name="data"><paramtype>Data &amp;</paramtype><description><para>An arbitrary data </para></description></parameter><description><para>
+
+
+</para></description><requires><para><computeroutput>matches&lt;Expr, bitwise_xor&lt;T,U&gt; &gt;::value</computeroutput> is <computeroutput>true</computeroutput>. </para></requires><returns><para><computeroutput>pass_through&lt;bitwise_xor&lt;T,U&gt; &gt;()(expr, state, data)</computeroutput> </para></returns></method></method-group></struct><struct name="comma"><template>
+ <template-type-parameter name="T"/>
+ <template-type-parameter name="U"/>
+ </template><purpose>A metafunction for generating comma expression types, a grammar element for matching comma expressions, and a PrimitiveTransform that dispatches to the <computeroutput>pass_through&lt;&gt;</computeroutput> transform. </purpose><struct name="result"><template>
+ <template-type-parameter name="Sig"/>
+ </template><typedef name="type"><type><classname>pass_through</classname>&lt; <classname>comma</classname> &gt;::template <classname>result</classname>&lt; Sig &gt;::type</type></typedef></struct><typedef name="type"><type>proto::expr&lt; <classname>proto::tag::comma</classname>, <classname>list2</classname>&lt; T, U &gt; &gt;</type></typedef><typedef name="proto_base_expr"><type>type</type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type><classname>result</classname>&lt; void(Expr, State, Data)&gt;::type</type><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="State"/>
+ <template-type-parameter name="Data"/>
+ </template><parameter name="expr"><paramtype>Expr const &amp;</paramtype><description><para>The current expression </para></description></parameter><parameter name="state"><paramtype>State const &amp;</paramtype><description><para>The current state </para></description></parameter><parameter name="data"><paramtype>Data &amp;</paramtype><description><para>An arbitrary data </para></description></parameter><description><para>
+
+
+</para></description><requires><para><computeroutput>matches&lt;Expr, comma&lt;T,U&gt; &gt;::value</computeroutput> is <computeroutput>true</computeroutput>. </para></requires><returns><para><computeroutput>pass_through&lt;comma&lt;T,U&gt; &gt;()(expr, state, data)</computeroutput> </para></returns></method></method-group></struct><struct name="mem_ptr"><template>
+ <template-type-parameter name="T"/>
+ <template-type-parameter name="U"/>
+ </template><struct name="result"><template>
+ <template-type-parameter name="Sig"/>
+ </template><typedef name="type"><type><classname>pass_through</classname>&lt; <classname>mem_ptr</classname> &gt;::template <classname>result</classname>&lt; Sig &gt;::type</type></typedef></struct><typedef name="type"><type>proto::expr&lt; <classname>proto::tag::mem_ptr</classname>, <classname>list2</classname>&lt; T, U &gt; &gt;</type></typedef><typedef name="proto_base_expr"><type>type</type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type><classname>result</classname>&lt; void(Expr, State, Data)&gt;::type</type><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="State"/>
+ <template-type-parameter name="Data"/>
+ </template><parameter name="expr"><paramtype>Expr const &amp;</paramtype><description><para>The current expression </para></description></parameter><parameter name="state"><paramtype>State const &amp;</paramtype><description><para>The current state </para></description></parameter><parameter name="data"><paramtype>Data &amp;</paramtype><description><para>An arbitrary data </para></description></parameter><description><para>
+
+
+</para></description><requires><para><computeroutput>matches&lt;Expr, mem_ptr&lt;T,U&gt; &gt;::value</computeroutput> is <computeroutput>true</computeroutput>. </para></requires><returns><para><computeroutput>pass_through&lt;mem_ptr&lt;T,U&gt; &gt;()(expr, state, data)</computeroutput> </para></returns></method></method-group></struct><struct name="assign"><template>
+ <template-type-parameter name="T"/>
+ <template-type-parameter name="U"/>
+ </template><purpose>A metafunction for generating assignment expression types, a grammar element for matching assignment expressions, and a PrimitiveTransform that dispatches to the <computeroutput>pass_through&lt;&gt;</computeroutput> transform. </purpose><struct name="result"><template>
+ <template-type-parameter name="Sig"/>
+ </template><typedef name="type"><type><classname>pass_through</classname>&lt; <classname>assign</classname> &gt;::template <classname>result</classname>&lt; Sig &gt;::type</type></typedef></struct><typedef name="type"><type>proto::expr&lt; <classname>proto::tag::assign</classname>, <classname>list2</classname>&lt; T, U &gt; &gt;</type></typedef><typedef name="proto_base_expr"><type>type</type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type><classname>result</classname>&lt; void(Expr, State, Data)&gt;::type</type><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="State"/>
+ <template-type-parameter name="Data"/>
+ </template><parameter name="expr"><paramtype>Expr const &amp;</paramtype><description><para>The current expression </para></description></parameter><parameter name="state"><paramtype>State const &amp;</paramtype><description><para>The current state </para></description></parameter><parameter name="data"><paramtype>Data &amp;</paramtype><description><para>An arbitrary data </para></description></parameter><description><para>
+
+
+</para></description><requires><para><computeroutput>matches&lt;Expr, assign&lt;T,U&gt; &gt;::value</computeroutput> is <computeroutput>true</computeroutput>. </para></requires><returns><para><computeroutput>pass_through&lt;assign&lt;T,U&gt; &gt;()(expr, state, data)</computeroutput> </para></returns></method></method-group></struct><struct name="shift_left_assign"><template>
+ <template-type-parameter name="T"/>
+ <template-type-parameter name="U"/>
+ </template><purpose>A metafunction for generating left-shift-assign expression types, a grammar element for matching left-shift-assign expressions, and a PrimitiveTransform that dispatches to the <computeroutput>pass_through&lt;&gt;</computeroutput> transform. </purpose><struct name="result"><template>
+ <template-type-parameter name="Sig"/>
+ </template><typedef name="type"><type><classname>pass_through</classname>&lt; <classname>shift_left_assign</classname> &gt;::template <classname>result</classname>&lt; Sig &gt;::type</type></typedef></struct><typedef name="type"><type>proto::expr&lt; <classname>proto::tag::shift_left_assign</classname>, <classname>list2</classname>&lt; T, U &gt; &gt;</type></typedef><typedef name="proto_base_expr"><type>type</type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type><classname>result</classname>&lt; void(Expr, State, Data)&gt;::type</type><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="State"/>
+ <template-type-parameter name="Data"/>
+ </template><parameter name="expr"><paramtype>Expr const &amp;</paramtype><description><para>The current expression </para></description></parameter><parameter name="state"><paramtype>State const &amp;</paramtype><description><para>The current state </para></description></parameter><parameter name="data"><paramtype>Data &amp;</paramtype><description><para>An arbitrary data </para></description></parameter><description><para>
+
+
+</para></description><requires><para><computeroutput>matches&lt;Expr, shift_left_assign&lt;T,U&gt; &gt;::value</computeroutput> is <computeroutput>true</computeroutput>. </para></requires><returns><para><computeroutput>pass_through&lt;shift_left_assign&lt;T,U&gt; &gt;()(expr, state, data)</computeroutput> </para></returns></method></method-group></struct><struct name="shift_right_assign"><template>
+ <template-type-parameter name="T"/>
+ <template-type-parameter name="U"/>
+ </template><purpose>A metafunction for generating right-shift-assign expression types, a grammar element for matching right-shift-assign expressions, and a PrimitiveTransform that dispatches to the <computeroutput>pass_through&lt;&gt;</computeroutput> transform. </purpose><struct name="result"><template>
+ <template-type-parameter name="Sig"/>
+ </template><typedef name="type"><type><classname>pass_through</classname>&lt; <classname>shift_right_assign</classname> &gt;::template <classname>result</classname>&lt; Sig &gt;::type</type></typedef></struct><typedef name="type"><type>proto::expr&lt; <classname>proto::tag::shift_right_assign</classname>, <classname>list2</classname>&lt; T, U &gt; &gt;</type></typedef><typedef name="proto_base_expr"><type>type</type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type><classname>result</classname>&lt; void(Expr, State, Data)&gt;::type</type><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="State"/>
+ <template-type-parameter name="Data"/>
+ </template><parameter name="expr"><paramtype>Expr const &amp;</paramtype><description><para>The current expression </para></description></parameter><parameter name="state"><paramtype>State const &amp;</paramtype><description><para>The current state </para></description></parameter><parameter name="data"><paramtype>Data &amp;</paramtype><description><para>An arbitrary data </para></description></parameter><description><para>
+
+
+</para></description><requires><para><computeroutput>matches&lt;Expr, shift_right_assign&lt;T,U&gt; &gt;::value</computeroutput> is <computeroutput>true</computeroutput>. </para></requires><returns><para><computeroutput>pass_through&lt;shift_right_assign&lt;T,U&gt; &gt;()(expr, state, data)</computeroutput> </para></returns></method></method-group></struct><struct name="multiplies_assign"><template>
+ <template-type-parameter name="T"/>
+ <template-type-parameter name="U"/>
+ </template><purpose>A metafunction for generating multiplies-assign expression types, a grammar element for matching multiplies-assign expressions, and a PrimitiveTransform that dispatches to the <computeroutput>pass_through&lt;&gt;</computeroutput> transform. </purpose><struct name="result"><template>
+ <template-type-parameter name="Sig"/>
+ </template><typedef name="type"><type><classname>pass_through</classname>&lt; <classname>multiplies_assign</classname> &gt;::template <classname>result</classname>&lt; Sig &gt;::type</type></typedef></struct><typedef name="type"><type>proto::expr&lt; <classname>proto::tag::multiplies_assign</classname>, <classname>list2</classname>&lt; T, U &gt; &gt;</type></typedef><typedef name="proto_base_expr"><type>type</type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type><classname>result</classname>&lt; void(Expr, State, Data)&gt;::type</type><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="State"/>
+ <template-type-parameter name="Data"/>
+ </template><parameter name="expr"><paramtype>Expr const &amp;</paramtype><description><para>The current expression </para></description></parameter><parameter name="state"><paramtype>State const &amp;</paramtype><description><para>The current state </para></description></parameter><parameter name="data"><paramtype>Data &amp;</paramtype><description><para>An arbitrary data </para></description></parameter><description><para>
+
+
+</para></description><requires><para><computeroutput>matches&lt;Expr, multiplies_assign&lt;T,U&gt; &gt;::value</computeroutput> is <computeroutput>true</computeroutput>. </para></requires><returns><para><computeroutput>pass_through&lt;multiplies_assign&lt;T,U&gt; &gt;()(expr, state, data)</computeroutput> </para></returns></method></method-group></struct><struct name="divides_assign"><template>
+ <template-type-parameter name="T"/>
+ <template-type-parameter name="U"/>
+ </template><purpose>A metafunction for generating divides-assign expression types, a grammar element for matching divides-assign expressions, and a PrimitiveTransform that dispatches to the <computeroutput>pass_through&lt;&gt;</computeroutput> transform. </purpose><struct name="result"><template>
+ <template-type-parameter name="Sig"/>
+ </template><typedef name="type"><type><classname>pass_through</classname>&lt; <classname>divides_assign</classname> &gt;::template <classname>result</classname>&lt; Sig &gt;::type</type></typedef></struct><typedef name="type"><type>proto::expr&lt; <classname>proto::tag::divides_assign</classname>, <classname>list2</classname>&lt; T, U &gt; &gt;</type></typedef><typedef name="proto_base_expr"><type>type</type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type><classname>result</classname>&lt; void(Expr, State, Data)&gt;::type</type><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="State"/>
+ <template-type-parameter name="Data"/>
+ </template><parameter name="expr"><paramtype>Expr const &amp;</paramtype><description><para>The current expression </para></description></parameter><parameter name="state"><paramtype>State const &amp;</paramtype><description><para>The current state </para></description></parameter><parameter name="data"><paramtype>Data &amp;</paramtype><description><para>An arbitrary data </para></description></parameter><description><para>
+
+
+</para></description><requires><para><computeroutput>matches&lt;Expr, divides_assign&lt;T,U&gt; &gt;::value</computeroutput> is <computeroutput>true</computeroutput>. </para></requires><returns><para><computeroutput>pass_through&lt;divides_assign&lt;T,U&gt; &gt;()(expr, state, data)</computeroutput> </para></returns></method></method-group></struct><struct name="modulus_assign"><template>
+ <template-type-parameter name="T"/>
+ <template-type-parameter name="U"/>
+ </template><purpose>A metafunction for generating modulus-assign expression types, a grammar element for matching modulus-assign expressions, and a PrimitiveTransform that dispatches to the <computeroutput>pass_through&lt;&gt;</computeroutput> transform. </purpose><struct name="result"><template>
+ <template-type-parameter name="Sig"/>
+ </template><typedef name="type"><type><classname>pass_through</classname>&lt; <classname>modulus_assign</classname> &gt;::template <classname>result</classname>&lt; Sig &gt;::type</type></typedef></struct><typedef name="type"><type>proto::expr&lt; <classname>proto::tag::modulus_assign</classname>, <classname>list2</classname>&lt; T, U &gt; &gt;</type></typedef><typedef name="proto_base_expr"><type>type</type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type><classname>result</classname>&lt; void(Expr, State, Data)&gt;::type</type><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="State"/>
+ <template-type-parameter name="Data"/>
+ </template><parameter name="expr"><paramtype>Expr const &amp;</paramtype><description><para>The current expression </para></description></parameter><parameter name="state"><paramtype>State const &amp;</paramtype><description><para>The current state </para></description></parameter><parameter name="data"><paramtype>Data &amp;</paramtype><description><para>An arbitrary data </para></description></parameter><description><para>
+
+
+</para></description><requires><para><computeroutput>matches&lt;Expr, modulus_assign&lt;T,U&gt; &gt;::value</computeroutput> is <computeroutput>true</computeroutput>. </para></requires><returns><para><computeroutput>pass_through&lt;modulus_assign&lt;T,U&gt; &gt;()(expr, state, data)</computeroutput> </para></returns></method></method-group></struct><struct name="plus_assign"><template>
+ <template-type-parameter name="T"/>
+ <template-type-parameter name="U"/>
+ </template><purpose>A metafunction for generating plus-assign expression types, a grammar element for matching plus-assign expressions, and a PrimitiveTransform that dispatches to the <computeroutput>pass_through&lt;&gt;</computeroutput> transform. </purpose><struct name="result"><template>
+ <template-type-parameter name="Sig"/>
+ </template><typedef name="type"><type><classname>pass_through</classname>&lt; <classname>plus_assign</classname> &gt;::template <classname>result</classname>&lt; Sig &gt;::type</type></typedef></struct><typedef name="type"><type>proto::expr&lt; <classname>proto::tag::plus_assign</classname>, <classname>list2</classname>&lt; T, U &gt; &gt;</type></typedef><typedef name="proto_base_expr"><type>type</type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type><classname>result</classname>&lt; void(Expr, State, Data)&gt;::type</type><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="State"/>
+ <template-type-parameter name="Data"/>
+ </template><parameter name="expr"><paramtype>Expr const &amp;</paramtype><description><para>The current expression </para></description></parameter><parameter name="state"><paramtype>State const &amp;</paramtype><description><para>The current state </para></description></parameter><parameter name="data"><paramtype>Data &amp;</paramtype><description><para>An arbitrary data </para></description></parameter><description><para>
+
+
+</para></description><requires><para><computeroutput>matches&lt;Expr, plus_assign&lt;T,U&gt; &gt;::value</computeroutput> is <computeroutput>true</computeroutput>. </para></requires><returns><para><computeroutput>pass_through&lt;plus_assign&lt;T,U&gt; &gt;()(expr, state, data)</computeroutput> </para></returns></method></method-group></struct><struct name="minus_assign"><template>
+ <template-type-parameter name="T"/>
+ <template-type-parameter name="U"/>
+ </template><purpose>A metafunction for generating minus-assign expression types, a grammar element for matching minus-assign expressions, and a PrimitiveTransform that dispatches to the <computeroutput>pass_through&lt;&gt;</computeroutput> transform. </purpose><struct name="result"><template>
+ <template-type-parameter name="Sig"/>
+ </template><typedef name="type"><type><classname>pass_through</classname>&lt; <classname>minus_assign</classname> &gt;::template <classname>result</classname>&lt; Sig &gt;::type</type></typedef></struct><typedef name="type"><type>proto::expr&lt; <classname>proto::tag::minus_assign</classname>, <classname>list2</classname>&lt; T, U &gt; &gt;</type></typedef><typedef name="proto_base_expr"><type>type</type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type><classname>result</classname>&lt; void(Expr, State, Data)&gt;::type</type><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="State"/>
+ <template-type-parameter name="Data"/>
+ </template><parameter name="expr"><paramtype>Expr const &amp;</paramtype><description><para>The current expression </para></description></parameter><parameter name="state"><paramtype>State const &amp;</paramtype><description><para>The current state </para></description></parameter><parameter name="data"><paramtype>Data &amp;</paramtype><description><para>An arbitrary data </para></description></parameter><description><para>
+
+
+</para></description><requires><para><computeroutput>matches&lt;Expr, minus_assign&lt;T,U&gt; &gt;::value</computeroutput> is <computeroutput>true</computeroutput>. </para></requires><returns><para><computeroutput>pass_through&lt;minus_assign&lt;T,U&gt; &gt;()(expr, state, data)</computeroutput> </para></returns></method></method-group></struct><struct name="bitwise_and_assign"><template>
+ <template-type-parameter name="T"/>
+ <template-type-parameter name="U"/>
+ </template><purpose>A metafunction for generating bitwise-and-assign expression types, a grammar element for matching bitwise-and-assign expressions, and a PrimitiveTransform that dispatches to the <computeroutput>pass_through&lt;&gt;</computeroutput> transform. </purpose><struct name="result"><template>
+ <template-type-parameter name="Sig"/>
+ </template><typedef name="type"><type><classname>pass_through</classname>&lt; <classname>bitwise_and_assign</classname> &gt;::template <classname>result</classname>&lt; Sig &gt;::type</type></typedef></struct><typedef name="type"><type>proto::expr&lt; <classname>proto::tag::bitwise_and_assign</classname>, <classname>list2</classname>&lt; T, U &gt; &gt;</type></typedef><typedef name="proto_base_expr"><type>type</type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type><classname>result</classname>&lt; void(Expr, State, Data)&gt;::type</type><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="State"/>
+ <template-type-parameter name="Data"/>
+ </template><parameter name="expr"><paramtype>Expr const &amp;</paramtype><description><para>The current expression </para></description></parameter><parameter name="state"><paramtype>State const &amp;</paramtype><description><para>The current state </para></description></parameter><parameter name="data"><paramtype>Data &amp;</paramtype><description><para>An arbitrary data </para></description></parameter><description><para>
+
+
+</para></description><requires><para><computeroutput>matches&lt;Expr, bitwise_and_assign&lt;T,U&gt; &gt;::value</computeroutput> is <computeroutput>true</computeroutput>. </para></requires><returns><para><computeroutput>pass_through&lt;bitwise_and_assign&lt;T,U&gt; &gt;()(expr, state, data)</computeroutput> </para></returns></method></method-group></struct><struct name="bitwise_or_assign"><template>
+ <template-type-parameter name="T"/>
+ <template-type-parameter name="U"/>
+ </template><purpose>A metafunction for generating bitwise-or-assign expression types, a grammar element for matching bitwise-or-assign expressions, and a PrimitiveTransform that dispatches to the <computeroutput>pass_through&lt;&gt;</computeroutput> transform. </purpose><struct name="result"><template>
+ <template-type-parameter name="Sig"/>
+ </template><typedef name="type"><type><classname>pass_through</classname>&lt; <classname>bitwise_or_assign</classname> &gt;::template <classname>result</classname>&lt; Sig &gt;::type</type></typedef></struct><typedef name="type"><type>proto::expr&lt; <classname>proto::tag::bitwise_or_assign</classname>, <classname>list2</classname>&lt; T, U &gt; &gt;</type></typedef><typedef name="proto_base_expr"><type>type</type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type><classname>result</classname>&lt; void(Expr, State, Data)&gt;::type</type><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="State"/>
+ <template-type-parameter name="Data"/>
+ </template><parameter name="expr"><paramtype>Expr const &amp;</paramtype><description><para>The current expression </para></description></parameter><parameter name="state"><paramtype>State const &amp;</paramtype><description><para>The current state </para></description></parameter><parameter name="data"><paramtype>Data &amp;</paramtype><description><para>An arbitrary data </para></description></parameter><description><para>
+
+
+</para></description><requires><para><computeroutput>matches&lt;Expr, bitwise_or_assign&lt;T,U&gt; &gt;::value</computeroutput> is <computeroutput>true</computeroutput>. </para></requires><returns><para><computeroutput>pass_through&lt;bitwise_or_assign&lt;T,U&gt; &gt;()(expr, state, data)</computeroutput> </para></returns></method></method-group></struct><struct name="bitwise_xor_assign"><template>
+ <template-type-parameter name="T"/>
+ <template-type-parameter name="U"/>
+ </template><purpose>A metafunction for generating bitwise-xor-assign expression types, a grammar element for matching bitwise-xor-assign expressions, and a PrimitiveTransform that dispatches to the <computeroutput>pass_through&lt;&gt;</computeroutput> transform. </purpose><struct name="result"><template>
+ <template-type-parameter name="Sig"/>
+ </template><typedef name="type"><type><classname>pass_through</classname>&lt; <classname>bitwise_xor_assign</classname> &gt;::template <classname>result</classname>&lt; Sig &gt;::type</type></typedef></struct><typedef name="type"><type>proto::expr&lt; <classname>proto::tag::bitwise_xor_assign</classname>, <classname>list2</classname>&lt; T, U &gt; &gt;</type></typedef><typedef name="proto_base_expr"><type>type</type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type><classname>result</classname>&lt; void(Expr, State, Data)&gt;::type</type><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="State"/>
+ <template-type-parameter name="Data"/>
+ </template><parameter name="expr"><paramtype>Expr const &amp;</paramtype><description><para>The current expression </para></description></parameter><parameter name="state"><paramtype>State const &amp;</paramtype><description><para>The current state </para></description></parameter><parameter name="data"><paramtype>Data &amp;</paramtype><description><para>An arbitrary data </para></description></parameter><description><para>
+
+
+</para></description><requires><para><computeroutput>matches&lt;Expr, bitwise_xor_assign&lt;T,U&gt; &gt;::value</computeroutput> is <computeroutput>true</computeroutput>. </para></requires><returns><para><computeroutput>pass_through&lt;bitwise_xor_assign&lt;T,U&gt; &gt;()(expr, state, data)</computeroutput> </para></returns></method></method-group></struct><struct name="subscript"><template>
+ <template-type-parameter name="T"/>
+ <template-type-parameter name="U"/>
+ </template><purpose>A metafunction for generating subscript expression types, a grammar element for matching subscript expressions, and a PrimitiveTransform that dispatches to the <computeroutput>pass_through&lt;&gt;</computeroutput> transform. </purpose><struct name="result"><template>
+ <template-type-parameter name="Sig"/>
+ </template><typedef name="type"><type><classname>pass_through</classname>&lt; <classname>subscript</classname> &gt;::template <classname>result</classname>&lt; Sig &gt;::type</type></typedef></struct><typedef name="type"><type>proto::expr&lt; <classname>proto::tag::subscript</classname>, <classname>list2</classname>&lt; T, U &gt; &gt;</type></typedef><typedef name="proto_base_expr"><type>type</type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type><classname>result</classname>&lt; void(Expr, State, Data)&gt;::type</type><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="State"/>
+ <template-type-parameter name="Data"/>
+ </template><parameter name="expr"><paramtype>Expr const &amp;</paramtype><description><para>The current expression </para></description></parameter><parameter name="state"><paramtype>State const &amp;</paramtype><description><para>The current state </para></description></parameter><parameter name="data"><paramtype>Data &amp;</paramtype><description><para>An arbitrary data </para></description></parameter><description><para>
+
+
+</para></description><requires><para><computeroutput>matches&lt;Expr, subscript&lt;T,U&gt; &gt;::value</computeroutput> is <computeroutput>true</computeroutput>. </para></requires><returns><para><computeroutput>pass_through&lt;subscript&lt;T,U&gt; &gt;()(expr, state, data)</computeroutput> </para></returns></method></method-group></struct><struct-specialization name="function"><template>
+ <template-type-parameter name="A0"/>
+ </template><specialization><template-arg>A0</template-arg><template-arg>void</template-arg><template-arg>void</template-arg><template-arg>void</template-arg><template-arg>void</template-arg><template-arg>void</template-arg></specialization><purpose>A metafunction for generating function-call expression types, a grammar element for matching function-call expressions, and a PrimitiveTransform that dispatches to the <computeroutput>pass_through&lt;&gt;</computeroutput> transform. </purpose><struct name="result"><template>
+ <template-type-parameter name="Sig"/>
+ </template><typedef name="type"><type><classname>pass_through</classname>&lt; function &gt;::template result&lt; Sig &gt;::type</type></typedef></struct><typedef name="type"><type>proto::expr&lt; <classname>proto::tag::function</classname>, <classname>list1</classname>&lt; A0 &gt; &gt;</type></typedef><typedef name="proto_base_expr"><type>type</type></typedef><typedef name="proto_child0"><type>A0</type></typedef><typedef name="proto_child1"><type><emphasis>unspecified</emphasis></type></typedef><typedef name="proto_child2"><type><emphasis>unspecified</emphasis></type></typedef><typedef name="proto_child3"><type><emphasis>unspecified</emphasis></type></typedef><typedef name="proto_child4"><type><emphasis>unspecified</emphasis></type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type>result&lt; void(Expr, State, Data)&gt;::type</type><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="State"/>
+ <template-type-parameter name="Data"/>
+ </template><parameter name="expr"><paramtype>Expr const &amp;</paramtype><description><para>The current expression </para></description></parameter><parameter name="state"><paramtype>State const &amp;</paramtype><description><para>The current state </para></description></parameter><parameter name="data"><paramtype>Data &amp;</paramtype><description><para>An arbitrary data </para></description></parameter><description><para>
+
+
+</para></description><requires><para><computeroutput>matches&lt;Expr, function&gt;::value</computeroutput> is <computeroutput>true</computeroutput>. </para></requires><returns><para><computeroutput>pass_through&lt;function&gt;()(expr, state, data)</computeroutput> </para></returns></method></method-group></struct-specialization><struct-specialization name="nary_expr"><template>
+ <template-type-parameter name="Tag"/>
+ <template-type-parameter name="A0"/>
+ </template><specialization><template-arg>Tag</template-arg><template-arg>A0</template-arg><template-arg>void</template-arg><template-arg>void</template-arg><template-arg>void</template-arg><template-arg>void</template-arg><template-arg>void</template-arg></specialization><purpose>A metafunction for generating n-ary expression types with a specified tag type, a grammar element for matching n-ary expressions, and a PrimitiveTransform that dispatches to the <computeroutput>pass_through&lt;&gt;</computeroutput> transform. </purpose><description><para>Use <computeroutput>nary_expr&lt;_, vararg&lt;_&gt; &gt;</computeroutput> as a grammar element to match any n-ary expression; that is, any non-terminal. </para></description><struct name="result"><template>
+ <template-type-parameter name="Sig"/>
+ </template><typedef name="type"><type><classname>pass_through</classname>&lt; nary_expr &gt;::template result&lt; Sig &gt;::type</type></typedef></struct><typedef name="type"><type>proto::expr&lt; Tag, <classname>list1</classname>&lt; A0 &gt; &gt;</type></typedef><typedef name="proto_base_expr"><type>type</type></typedef><typedef name="proto_child0"><type>A0</type></typedef><typedef name="proto_child1"><type><emphasis>unspecified</emphasis></type></typedef><typedef name="proto_child2"><type><emphasis>unspecified</emphasis></type></typedef><typedef name="proto_child3"><type><emphasis>unspecified</emphasis></type></typedef><typedef name="proto_child4"><type><emphasis>unspecified</emphasis></type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type>result&lt; void(Expr, State, Data)&gt;::type</type><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="State"/>
+ <template-type-parameter name="Data"/>
+ </template><parameter name="expr"><paramtype>Expr const &amp;</paramtype><description><para>The current expression </para></description></parameter><parameter name="state"><paramtype>State const &amp;</paramtype><description><para>The current state </para></description></parameter><parameter name="data"><paramtype>Data &amp;</paramtype><description><para>An arbitrary data </para></description></parameter><description><para>
+
+
+</para></description><requires><para><computeroutput>matches&lt;Expr, nary_expr&gt;::value</computeroutput> is <computeroutput>true</computeroutput>. </para></requires><returns><para><computeroutput>pass_through&lt;nary_expr&gt;()(expr, state, data)</computeroutput> </para></returns></method></method-group></struct-specialization><struct-specialization name="function"><template>
+ <template-type-parameter name="A0"/>
+ <template-type-parameter name="A1"/>
+ </template><specialization><template-arg>A0</template-arg><template-arg>A1</template-arg><template-arg>void</template-arg><template-arg>void</template-arg><template-arg>void</template-arg><template-arg>void</template-arg></specialization><purpose>A metafunction for generating function-call expression types, a grammar element for matching function-call expressions, and a PrimitiveTransform that dispatches to the <computeroutput>pass_through&lt;&gt;</computeroutput> transform. </purpose><struct name="result"><template>
+ <template-type-parameter name="Sig"/>
+ </template><typedef name="type"><type><classname>pass_through</classname>&lt; function &gt;::template result&lt; Sig &gt;::type</type></typedef></struct><typedef name="type"><type>proto::expr&lt; <classname>proto::tag::function</classname>, <classname>list2</classname>&lt; A0, A1 &gt; &gt;</type></typedef><typedef name="proto_base_expr"><type>type</type></typedef><typedef name="proto_child0"><type>A0</type></typedef><typedef name="proto_child1"><type>A1</type></typedef><typedef name="proto_child2"><type><emphasis>unspecified</emphasis></type></typedef><typedef name="proto_child3"><type><emphasis>unspecified</emphasis></type></typedef><typedef name="proto_child4"><type><emphasis>unspecified</emphasis></type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type>result&lt; void(Expr, State, Data)&gt;::type</type><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="State"/>
+ <template-type-parameter name="Data"/>
+ </template><parameter name="expr"><paramtype>Expr const &amp;</paramtype><description><para>The current expression </para></description></parameter><parameter name="state"><paramtype>State const &amp;</paramtype><description><para>The current state </para></description></parameter><parameter name="data"><paramtype>Data &amp;</paramtype><description><para>An arbitrary data </para></description></parameter><description><para>
+
+
+</para></description><requires><para><computeroutput>matches&lt;Expr, function&gt;::value</computeroutput> is <computeroutput>true</computeroutput>. </para></requires><returns><para><computeroutput>pass_through&lt;function&gt;()(expr, state, data)</computeroutput> </para></returns></method></method-group></struct-specialization><struct-specialization name="nary_expr"><template>
+ <template-type-parameter name="Tag"/>
+ <template-type-parameter name="A0"/>
+ <template-type-parameter name="A1"/>
+ </template><specialization><template-arg>Tag</template-arg><template-arg>A0</template-arg><template-arg>A1</template-arg><template-arg>void</template-arg><template-arg>void</template-arg><template-arg>void</template-arg><template-arg>void</template-arg></specialization><purpose>A metafunction for generating n-ary expression types with a specified tag type, a grammar element for matching n-ary expressions, and a PrimitiveTransform that dispatches to the <computeroutput>pass_through&lt;&gt;</computeroutput> transform. </purpose><description><para>Use <computeroutput>nary_expr&lt;_, vararg&lt;_&gt; &gt;</computeroutput> as a grammar element to match any n-ary expression; that is, any non-terminal. </para></description><struct name="result"><template>
+ <template-type-parameter name="Sig"/>
+ </template><typedef name="type"><type><classname>pass_through</classname>&lt; nary_expr &gt;::template result&lt; Sig &gt;::type</type></typedef></struct><typedef name="type"><type>proto::expr&lt; Tag, <classname>list2</classname>&lt; A0, A1 &gt; &gt;</type></typedef><typedef name="proto_base_expr"><type>type</type></typedef><typedef name="proto_child0"><type>A0</type></typedef><typedef name="proto_child1"><type>A1</type></typedef><typedef name="proto_child2"><type><emphasis>unspecified</emphasis></type></typedef><typedef name="proto_child3"><type><emphasis>unspecified</emphasis></type></typedef><typedef name="proto_child4"><type><emphasis>unspecified</emphasis></type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type>result&lt; void(Expr, State, Data)&gt;::type</type><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="State"/>
+ <template-type-parameter name="Data"/>
+ </template><parameter name="expr"><paramtype>Expr const &amp;</paramtype><description><para>The current expression </para></description></parameter><parameter name="state"><paramtype>State const &amp;</paramtype><description><para>The current state </para></description></parameter><parameter name="data"><paramtype>Data &amp;</paramtype><description><para>An arbitrary data </para></description></parameter><description><para>
+
+
+</para></description><requires><para><computeroutput>matches&lt;Expr, nary_expr&gt;::value</computeroutput> is <computeroutput>true</computeroutput>. </para></requires><returns><para><computeroutput>pass_through&lt;nary_expr&gt;()(expr, state, data)</computeroutput> </para></returns></method></method-group></struct-specialization><struct-specialization name="function"><template>
+ <template-type-parameter name="A0"/>
+ <template-type-parameter name="A1"/>
+ <template-type-parameter name="A2"/>
+ </template><specialization><template-arg>A0</template-arg><template-arg>A1</template-arg><template-arg>A2</template-arg><template-arg>void</template-arg><template-arg>void</template-arg><template-arg>void</template-arg></specialization><purpose>A metafunction for generating function-call expression types, a grammar element for matching function-call expressions, and a PrimitiveTransform that dispatches to the <computeroutput>pass_through&lt;&gt;</computeroutput> transform. </purpose><struct name="result"><template>
+ <template-type-parameter name="Sig"/>
+ </template><typedef name="type"><type><classname>pass_through</classname>&lt; function &gt;::template result&lt; Sig &gt;::type</type></typedef></struct><typedef name="type"><type>proto::expr&lt; <classname>proto::tag::function</classname>, <classname>list3</classname>&lt; A0, A1, A2 &gt; &gt;</type></typedef><typedef name="proto_base_expr"><type>type</type></typedef><typedef name="proto_child0"><type>A0</type></typedef><typedef name="proto_child1"><type>A1</type></typedef><typedef name="proto_child2"><type>A2</type></typedef><typedef name="proto_child3"><type><emphasis>unspecified</emphasis></type></typedef><typedef name="proto_child4"><type><emphasis>unspecified</emphasis></type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type>result&lt; void(Expr, State, Data)&gt;::type</type><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="State"/>
+ <template-type-parameter name="Data"/>
+ </template><parameter name="expr"><paramtype>Expr const &amp;</paramtype><description><para>The current expression </para></description></parameter><parameter name="state"><paramtype>State const &amp;</paramtype><description><para>The current state </para></description></parameter><parameter name="data"><paramtype>Data &amp;</paramtype><description><para>An arbitrary data </para></description></parameter><description><para>
+
+
+</para></description><requires><para><computeroutput>matches&lt;Expr, function&gt;::value</computeroutput> is <computeroutput>true</computeroutput>. </para></requires><returns><para><computeroutput>pass_through&lt;function&gt;()(expr, state, data)</computeroutput> </para></returns></method></method-group></struct-specialization><struct-specialization name="nary_expr"><template>
+ <template-type-parameter name="Tag"/>
+ <template-type-parameter name="A0"/>
+ <template-type-parameter name="A1"/>
+ <template-type-parameter name="A2"/>
+ </template><specialization><template-arg>Tag</template-arg><template-arg>A0</template-arg><template-arg>A1</template-arg><template-arg>A2</template-arg><template-arg>void</template-arg><template-arg>void</template-arg><template-arg>void</template-arg></specialization><purpose>A metafunction for generating n-ary expression types with a specified tag type, a grammar element for matching n-ary expressions, and a PrimitiveTransform that dispatches to the <computeroutput>pass_through&lt;&gt;</computeroutput> transform. </purpose><description><para>Use <computeroutput>nary_expr&lt;_, vararg&lt;_&gt; &gt;</computeroutput> as a grammar element to match any n-ary expression; that is, any non-terminal. </para></description><struct name="result"><template>
+ <template-type-parameter name="Sig"/>
+ </template><typedef name="type"><type><classname>pass_through</classname>&lt; nary_expr &gt;::template result&lt; Sig &gt;::type</type></typedef></struct><typedef name="type"><type>proto::expr&lt; Tag, <classname>list3</classname>&lt; A0, A1, A2 &gt; &gt;</type></typedef><typedef name="proto_base_expr"><type>type</type></typedef><typedef name="proto_child0"><type>A0</type></typedef><typedef name="proto_child1"><type>A1</type></typedef><typedef name="proto_child2"><type>A2</type></typedef><typedef name="proto_child3"><type><emphasis>unspecified</emphasis></type></typedef><typedef name="proto_child4"><type><emphasis>unspecified</emphasis></type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type>result&lt; void(Expr, State, Data)&gt;::type</type><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="State"/>
+ <template-type-parameter name="Data"/>
+ </template><parameter name="expr"><paramtype>Expr const &amp;</paramtype><description><para>The current expression </para></description></parameter><parameter name="state"><paramtype>State const &amp;</paramtype><description><para>The current state </para></description></parameter><parameter name="data"><paramtype>Data &amp;</paramtype><description><para>An arbitrary data </para></description></parameter><description><para>
+
+
+</para></description><requires><para><computeroutput>matches&lt;Expr, nary_expr&gt;::value</computeroutput> is <computeroutput>true</computeroutput>. </para></requires><returns><para><computeroutput>pass_through&lt;nary_expr&gt;()(expr, state, data)</computeroutput> </para></returns></method></method-group></struct-specialization><struct-specialization name="function"><template>
+ <template-type-parameter name="A0"/>
+ <template-type-parameter name="A1"/>
+ <template-type-parameter name="A2"/>
+ <template-type-parameter name="A3"/>
+ </template><specialization><template-arg>A0</template-arg><template-arg>A1</template-arg><template-arg>A2</template-arg><template-arg>A3</template-arg><template-arg>void</template-arg><template-arg>void</template-arg></specialization><purpose>A metafunction for generating function-call expression types, a grammar element for matching function-call expressions, and a PrimitiveTransform that dispatches to the <computeroutput>pass_through&lt;&gt;</computeroutput> transform. </purpose><struct name="result"><template>
+ <template-type-parameter name="Sig"/>
+ </template><typedef name="type"><type><classname>pass_through</classname>&lt; function &gt;::template result&lt; Sig &gt;::type</type></typedef></struct><typedef name="type"><type>proto::expr&lt; <classname>proto::tag::function</classname>, <classname>list4</classname>&lt; A0, A1, A2, A3 &gt; &gt;</type></typedef><typedef name="proto_base_expr"><type>type</type></typedef><typedef name="proto_child0"><type>A0</type></typedef><typedef name="proto_child1"><type>A1</type></typedef><typedef name="proto_child2"><type>A2</type></typedef><typedef name="proto_child3"><type>A3</type></typedef><typedef name="proto_child4"><type><emphasis>unspecified</emphasis></type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type>result&lt; void(Expr, State, Data)&gt;::type</type><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="State"/>
+ <template-type-parameter name="Data"/>
+ </template><parameter name="expr"><paramtype>Expr const &amp;</paramtype><description><para>The current expression </para></description></parameter><parameter name="state"><paramtype>State const &amp;</paramtype><description><para>The current state </para></description></parameter><parameter name="data"><paramtype>Data &amp;</paramtype><description><para>An arbitrary data </para></description></parameter><description><para>
+
+
+</para></description><requires><para><computeroutput>matches&lt;Expr, function&gt;::value</computeroutput> is <computeroutput>true</computeroutput>. </para></requires><returns><para><computeroutput>pass_through&lt;function&gt;()(expr, state, data)</computeroutput> </para></returns></method></method-group></struct-specialization><struct-specialization name="nary_expr"><template>
+ <template-type-parameter name="Tag"/>
+ <template-type-parameter name="A0"/>
+ <template-type-parameter name="A1"/>
+ <template-type-parameter name="A2"/>
+ <template-type-parameter name="A3"/>
+ </template><specialization><template-arg>Tag</template-arg><template-arg>A0</template-arg><template-arg>A1</template-arg><template-arg>A2</template-arg><template-arg>A3</template-arg><template-arg>void</template-arg><template-arg>void</template-arg></specialization><purpose>A metafunction for generating n-ary expression types with a specified tag type, a grammar element for matching n-ary expressions, and a PrimitiveTransform that dispatches to the <computeroutput>pass_through&lt;&gt;</computeroutput> transform. </purpose><description><para>Use <computeroutput>nary_expr&lt;_, vararg&lt;_&gt; &gt;</computeroutput> as a grammar element to match any n-ary expression; that is, any non-terminal. </para></description><struct name="result"><template>
+ <template-type-parameter name="Sig"/>
+ </template><typedef name="type"><type><classname>pass_through</classname>&lt; nary_expr &gt;::template result&lt; Sig &gt;::type</type></typedef></struct><typedef name="type"><type>proto::expr&lt; Tag, <classname>list4</classname>&lt; A0, A1, A2, A3 &gt; &gt;</type></typedef><typedef name="proto_base_expr"><type>type</type></typedef><typedef name="proto_child0"><type>A0</type></typedef><typedef name="proto_child1"><type>A1</type></typedef><typedef name="proto_child2"><type>A2</type></typedef><typedef name="proto_child3"><type>A3</type></typedef><typedef name="proto_child4"><type><emphasis>unspecified</emphasis></type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type>result&lt; void(Expr, State, Data)&gt;::type</type><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="State"/>
+ <template-type-parameter name="Data"/>
+ </template><parameter name="expr"><paramtype>Expr const &amp;</paramtype><description><para>The current expression </para></description></parameter><parameter name="state"><paramtype>State const &amp;</paramtype><description><para>The current state </para></description></parameter><parameter name="data"><paramtype>Data &amp;</paramtype><description><para>An arbitrary data </para></description></parameter><description><para>
+
+
+</para></description><requires><para><computeroutput>matches&lt;Expr, nary_expr&gt;::value</computeroutput> is <computeroutput>true</computeroutput>. </para></requires><returns><para><computeroutput>pass_through&lt;nary_expr&gt;()(expr, state, data)</computeroutput> </para></returns></method></method-group></struct-specialization><struct-specialization name="function"><template>
+ <template-type-parameter name="A0"/>
+ <template-type-parameter name="A1"/>
+ <template-type-parameter name="A2"/>
+ <template-type-parameter name="A3"/>
+ <template-type-parameter name="A4"/>
+ </template><specialization><template-arg>A0</template-arg><template-arg>A1</template-arg><template-arg>A2</template-arg><template-arg>A3</template-arg><template-arg>A4</template-arg><template-arg>void</template-arg></specialization><purpose>A metafunction for generating function-call expression types, a grammar element for matching function-call expressions, and a PrimitiveTransform that dispatches to the <computeroutput>pass_through&lt;&gt;</computeroutput> transform. </purpose><struct name="result"><template>
+ <template-type-parameter name="Sig"/>
+ </template><typedef name="type"><type><classname>pass_through</classname>&lt; function &gt;::template result&lt; Sig &gt;::type</type></typedef></struct><typedef name="type"><type>proto::expr&lt; <classname>proto::tag::function</classname>, <classname>list5</classname>&lt; A0, A1, A2, A3, A4 &gt; &gt;</type></typedef><typedef name="proto_base_expr"><type>type</type></typedef><typedef name="proto_child0"><type>A0</type></typedef><typedef name="proto_child1"><type>A1</type></typedef><typedef name="proto_child2"><type>A2</type></typedef><typedef name="proto_child3"><type>A3</type></typedef><typedef name="proto_child4"><type>A4</type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type>result&lt; void(Expr, State, Data)&gt;::type</type><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="State"/>
+ <template-type-parameter name="Data"/>
+ </template><parameter name="expr"><paramtype>Expr const &amp;</paramtype><description><para>The current expression </para></description></parameter><parameter name="state"><paramtype>State const &amp;</paramtype><description><para>The current state </para></description></parameter><parameter name="data"><paramtype>Data &amp;</paramtype><description><para>An arbitrary data </para></description></parameter><description><para>
+
+
+</para></description><requires><para><computeroutput>matches&lt;Expr, function&gt;::value</computeroutput> is <computeroutput>true</computeroutput>. </para></requires><returns><para><computeroutput>pass_through&lt;function&gt;()(expr, state, data)</computeroutput> </para></returns></method></method-group></struct-specialization><struct-specialization name="nary_expr"><template>
+ <template-type-parameter name="Tag"/>
+ <template-type-parameter name="A0"/>
+ <template-type-parameter name="A1"/>
+ <template-type-parameter name="A2"/>
+ <template-type-parameter name="A3"/>
+ <template-type-parameter name="A4"/>
+ </template><specialization><template-arg>Tag</template-arg><template-arg>A0</template-arg><template-arg>A1</template-arg><template-arg>A2</template-arg><template-arg>A3</template-arg><template-arg>A4</template-arg><template-arg>void</template-arg></specialization><purpose>A metafunction for generating n-ary expression types with a specified tag type, a grammar element for matching n-ary expressions, and a PrimitiveTransform that dispatches to the <computeroutput>pass_through&lt;&gt;</computeroutput> transform. </purpose><description><para>Use <computeroutput>nary_expr&lt;_, vararg&lt;_&gt; &gt;</computeroutput> as a grammar element to match any n-ary expression; that is, any non-terminal. </para></description><struct name="result"><template>
+ <template-type-parameter name="Sig"/>
+ </template><typedef name="type"><type><classname>pass_through</classname>&lt; nary_expr &gt;::template result&lt; Sig &gt;::type</type></typedef></struct><typedef name="type"><type>proto::expr&lt; Tag, <classname>list5</classname>&lt; A0, A1, A2, A3, A4 &gt; &gt;</type></typedef><typedef name="proto_base_expr"><type>type</type></typedef><typedef name="proto_child0"><type>A0</type></typedef><typedef name="proto_child1"><type>A1</type></typedef><typedef name="proto_child2"><type>A2</type></typedef><typedef name="proto_child3"><type>A3</type></typedef><typedef name="proto_child4"><type>A4</type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type>result&lt; void(Expr, State, Data)&gt;::type</type><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="State"/>
+ <template-type-parameter name="Data"/>
+ </template><parameter name="expr"><paramtype>Expr const &amp;</paramtype><description><para>The current expression </para></description></parameter><parameter name="state"><paramtype>State const &amp;</paramtype><description><para>The current state </para></description></parameter><parameter name="data"><paramtype>Data &amp;</paramtype><description><para>An arbitrary data </para></description></parameter><description><para>
+
+
+</para></description><requires><para><computeroutput>matches&lt;Expr, nary_expr&gt;::value</computeroutput> is <computeroutput>true</computeroutput>. </para></requires><returns><para><computeroutput>pass_through&lt;nary_expr&gt;()(expr, state, data)</computeroutput> </para></returns></method></method-group></struct-specialization></namespace><namespace name="result_of"><struct name="is_expr"><template>
+ <template-type-parameter name="T"/>
+ <template-type-parameter name="Void"><default>void</default></template-type-parameter>
+ </template><inherit access="public">boost::mpl::false_</inherit><purpose>A Boolean metafunction that indicates whether a given type <computeroutput>T</computeroutput> is a Proto expression type. </purpose><description><para>If <computeroutput>T</computeroutput> has a nested type <computeroutput>proto_is_expr_</computeroutput> that is a typedef for <computeroutput>void</computeroutput>, <computeroutput>is_expr&lt;T&gt;::value</computeroutput> is <computeroutput>true</computeroutput>. (Note, this is the case for <computeroutput>proto::expr&lt;&gt;</computeroutput>, any type that is derived from <computeroutput>proto::extends&lt;&gt;</computeroutput> or that uses the <computeroutput>BOOST_PROTO_BASIC_EXTENDS()</computeroutput> macro.) Otherwise, <computeroutput>is_expr&lt;T&gt;::value</computeroutput> is <computeroutput>false</computeroutput>. </para></description></struct><struct-specialization name="is_expr"><template>
+ <template-type-parameter name="T"/>
+ </template><specialization><template-arg>T</template-arg><template-arg>typename T::proto_is_expr_</template-arg></specialization><inherit access="public">boost::mpl::true_</inherit><purpose>A Boolean metafunction that indicates whether a given type <computeroutput>T</computeroutput> is a Proto expression type. </purpose><description><para>If <computeroutput>T</computeroutput> has a nested type <computeroutput>proto_is_expr_</computeroutput> that is a typedef for <computeroutput>void</computeroutput>, <computeroutput>is_expr&lt;T&gt;::value</computeroutput> is <computeroutput>true</computeroutput>. (Note, this is the case for <computeroutput>proto::expr&lt;&gt;</computeroutput>, any type that is derived from <computeroutput>proto::extends&lt;&gt;</computeroutput> or that uses the <computeroutput>BOOST_PROTO_BASIC_EXTENDS()</computeroutput> macro.) Otherwise, <computeroutput>is_expr&lt;T&gt;::value</computeroutput> is <computeroutput>false</computeroutput>. </para></description></struct-specialization><st
ruct name="tag_of"><template>
+ <template-type-parameter name="Expr"/>
+ </template><purpose>A metafunction that returns the tag type of a Proto expression. </purpose><typedef name="type"><type>Expr::proto_tag</type></typedef></struct><struct name="as_expr"><template>
+ <template-type-parameter name="T"/>
+ <template-type-parameter name="Domain"><default>default_domain</default></template-type-parameter>
+ <template-type-parameter name="Void"><default>void</default></template-type-parameter>
+ </template><purpose>A metafunction that computes the return type of the <computeroutput>as_expr()</computeroutput> function. </purpose><description><para>The <computeroutput>as_expr&lt;&gt;</computeroutput> metafunction turns types into Proto types, if they are not already, by making them Proto terminals held by value if possible. Types which are already Proto types are left alone.</para><para>This specialization is selected when the type is not yet a Proto type. The resulting terminal type is calculated as follows:</para><para>If <computeroutput>T</computeroutput> is a function type, let <computeroutput>A</computeroutput> be <computeroutput>T &amp;</computeroutput>. Otherwise, let <computeroutput>A</computeroutput> be the type <computeroutput>T</computeroutput> stripped of cv-qualifiers. Then, the result type <computeroutput>as_expr&lt;T, Domain&gt;::type</computeroutput> is <computeroutput>boost::result_of&lt;Domain(expr&lt; tag::terminal, term&lt;A&gt; &gt;)&gt;::type</computeroutput>. </para></descr
iption><typedef name="arg0_"><type>mpl::eval_if_c&lt; is_function&lt; T &gt;::<classname>value</classname>, add_reference&lt; T &gt;, remove_cv&lt; T &gt;&gt;::type</type></typedef><typedef name="expr_"><type>proto::expr&lt; <classname>proto::tag::terminal</classname>, <classname>term</classname>&lt; arg0_ &gt; &gt;</type></typedef><typedef name="type"><type>Domain::template result&lt; void(expr_)&gt;::type</type></typedef><typedef name="reference"><type>type const</type></typedef><method-group name="public static functions"/></struct><struct-specialization name="as_expr"><template>
+ <template-type-parameter name="T"/>
+ <template-type-parameter name="Domain"/>
+ </template><specialization><template-arg>T</template-arg><template-arg>Domain</template-arg><template-arg>typename T::proto_is_expr_</template-arg></specialization><purpose>A metafunction that computes the return type of the <computeroutput>as_expr()</computeroutput> function. </purpose><description><para>The <computeroutput>as_expr&lt;&gt;</computeroutput> metafunction turns types into Proto types, if they are not already, by making them Proto terminals held by value if possible. Types which are already Proto types are left alone.</para><para>This specialization is selected when the type is already a Proto type. The result type <computeroutput>as_expr&lt;T, Domain&gt;::type</computeroutput> is <computeroutput>T</computeroutput> stripped of cv-qualifiers. </para></description><typedef name="expr_"><type>T::proto_derived_expr</type></typedef><typedef name="type"><type>Domain::template result&lt; void(expr_)&gt;::type</type></typedef><typedef name="reference"><type>type const</type></typedef><method-group
 name="public static functions"/></struct-specialization><struct-specialization name="as_expr"><template>
+ <template-type-parameter name="T"/>
+ </template><specialization><template-arg>T</template-arg><template-arg>typename T::proto_domain</template-arg><template-arg>typename T::proto_is_expr_</template-arg></specialization><typedef name="type"><type>T::proto_derived_expr</type></typedef><typedef name="reference"><type>T &amp;</type></typedef><method-group name="public static functions"/></struct-specialization><struct name="as_child"><template>
+ <template-type-parameter name="T"/>
+ <template-type-parameter name="Domain"><default>default_domain</default></template-type-parameter>
+ <template-type-parameter name="Void"><default>void</default></template-type-parameter>
+ </template><purpose>A metafunction that computes the return type of the <computeroutput>as_child()</computeroutput> function. </purpose><description><para>The <computeroutput>as_child&lt;&gt;</computeroutput> metafunction turns types into Proto types, if they are not already, by making them Proto terminals held by reference. Types which are already Proto types are wrapped in <computeroutput>proto::ref_&lt;&gt;</computeroutput>.</para><para>This specialization is selected when the type is not yet a Proto type. The result type <computeroutput>as_child&lt;T, Domain&gt;::type</computeroutput> is <computeroutput>boost::result_of&lt;Domain(expr&lt; tag::terminal, term&lt;T &amp;&gt; &gt;)&gt;::type</computeroutput>. </para></description><typedef name="expr_"><type>proto::expr&lt; <classname>proto::tag::terminal</classname>, <classname>term</classname>&lt; T &amp; &gt; &gt;</type></typedef><typedef name="type"><type>Domain::template result&lt; void(expr_)&gt;::type</type></typedef><method-group name="public st
atic functions"/></struct><struct-specialization name="as_child"><template>
+ <template-type-parameter name="T"/>
+ <template-type-parameter name="Domain"/>
+ </template><specialization><template-arg>T</template-arg><template-arg>Domain</template-arg><template-arg>typename T::proto_is_expr_</template-arg></specialization><purpose>A metafunction that computes the return type of the <computeroutput>as_child()</computeroutput> function. </purpose><description><para>The <computeroutput>as_child&lt;&gt;</computeroutput> metafunction turns types into Proto types, if they are not already, by making them Proto terminals held by reference. Types which are already Proto types are wrapped in <computeroutput>proto::ref_&lt;&gt;</computeroutput>.</para><para>This specialization is selected when the type is already a Proto type. The result type <computeroutput>as_child&lt;T, Domain&gt;::type</computeroutput> is <computeroutput>proto::ref_&lt;T&gt;</computeroutput>. </para></description><typedef name="expr_"><type><classname>ref_</classname>&lt; T &gt;</type></typedef><typedef name="type"><type>Domain::template result&lt; void(<classname>expr_</classname>)&gt;::type</type><
/typedef><method-group name="public static functions"/></struct-specialization><struct-specialization name="as_child"><template>
+ <template-type-parameter name="T"/>
+ </template><specialization><template-arg>T</template-arg><template-arg>typename T::proto_domain</template-arg><template-arg>typename T::proto_is_expr_</template-arg></specialization><purpose>A metafunction that computes the return type of the <computeroutput>as_child()</computeroutput> function. </purpose><description><para>The <computeroutput>as_child&lt;&gt;</computeroutput> metafunction turns types into Proto types, if they are not already, by making them Proto terminals held by reference. Types which are already Proto types are wrapped in <computeroutput>proto::ref_&lt;&gt;</computeroutput>.</para><para>This specialization is selected when the type is already a Proto type. The result type <computeroutput>as_child&lt;T, Domain&gt;::type</computeroutput> is <computeroutput>proto::ref_&lt;T&gt;</computeroutput>. </para></description><typedef name="type"><type><classname>ref_</classname>&lt; T &gt;</type></typedef><method-group name="public static functions"/></struct-specialization><struct name="child"
><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="N"><default>mpl::long_&lt;0&gt;</default></template-type-parameter>
+ </template><purpose>A metafunction that returns the type of the Nth child of a Proto expression, where N is an MPL Integral Constant. </purpose><description><para><computeroutput>result_of::child&lt;Expr, N&gt;</computeroutput> is equivalent to <computeroutput>result_of::child_c&lt;Expr, N::value&gt;</computeroutput>. </para></description></struct><struct name="value"><template>
+ <template-type-parameter name="Expr"/>
+ </template><purpose>A metafunction that returns the type of the value of a terminal Proto expression. </purpose><typedef name="wrapped_type"><type>Expr::proto_child0</type></typedef><typedef name="type"><type><classname>unref</classname>&lt; wrapped_type &gt;::type</type></typedef><typedef name="reference"><type><classname>unref</classname>&lt; wrapped_type &gt;::reference</type></typedef><typedef name="const_reference"><type><classname>unref</classname>&lt; wrapped_type &gt;::const_reference</type></typedef></struct><struct name="left"><template>
+ <template-type-parameter name="Expr"/>
+ </template><purpose>A metafunction that returns the type of the left child of a binary Proto expression. </purpose><description><para><computeroutput>result_of::left&lt;Expr&gt;</computeroutput> is equivalent to <computeroutput>result_of::child_c&lt;Expr, 0&gt;</computeroutput>. </para></description><typedef name="wrapped_type"><type>Expr::proto_child0</type></typedef><typedef name="type"><type><classname>unref</classname>&lt; wrapped_type &gt;::type</type></typedef><typedef name="reference"><type><classname>unref</classname>&lt; wrapped_type &gt;::reference</type></typedef><typedef name="const_reference"><type><classname>unref</classname>&lt; wrapped_type &gt;::const_reference</type></typedef></struct><struct name="right"><template>
+ <template-type-parameter name="Expr"/>
+ </template><purpose>A metafunction that returns the type of the right child of a binary Proto expression. </purpose><description><para><computeroutput>result_of::right&lt;Expr&gt;</computeroutput> is equivalent to <computeroutput>result_of::child_c&lt;Expr, 1&gt;</computeroutput>. </para></description><typedef name="wrapped_type"><type>Expr::proto_child1</type></typedef><typedef name="type"><type><classname>unref</classname>&lt; wrapped_type &gt;::type</type></typedef><typedef name="reference"><type><classname>unref</classname>&lt; wrapped_type &gt;::reference</type></typedef><typedef name="const_reference"><type><classname>unref</classname>&lt; wrapped_type &gt;::const_reference</type></typedef></struct><struct-specialization name="child_c"><template>
+ <template-type-parameter name="Expr"/>
+ </template><specialization><template-arg>Expr</template-arg><template-arg>0</template-arg></specialization><purpose>A metafunction that returns the type of the Nth child of a Proto expression. </purpose><description><para>A metafunction that returns the type of the Nth child of a Proto expression. <computeroutput>N</computeroutput> must be 0 or less than <computeroutput>Expr::proto_arity::value</computeroutput>. </para></description><typedef name="wrapped_type"><description><para>The raw type of the Nth child as it is stored within <computeroutput>Expr</computeroutput>. This may be a value, a reference, or a Proto <computeroutput>ref_&lt;&gt;</computeroutput> wrapper. </para></description><type>Expr::proto_child0</type></typedef><typedef name="type"><description><para>The "value" type of the child, suitable for return by value, computed as follows: <itemizedlist>
+<listitem><para><computeroutput>ref_&lt;T const&gt;</computeroutput> becomes <computeroutput>T</computeroutput> </para></listitem>
+<listitem><para><computeroutput>ref_&lt;T&gt;</computeroutput> becomes <computeroutput>T</computeroutput> </para></listitem>
+<listitem><para><computeroutput>T const(&amp;)[N]</computeroutput> becomes <computeroutput>T const(&amp;)[N]</computeroutput> </para></listitem>
+<listitem><para><computeroutput>T(&amp;)[N]</computeroutput> becomes <computeroutput>T(&amp;)[N]</computeroutput> </para></listitem>
+<listitem><para><computeroutput>R(&amp;)(A0,...)</computeroutput> becomes <computeroutput>R(&amp;)(A0,...)</computeroutput> </para></listitem>
+<listitem><para><computeroutput>T const &amp;</computeroutput> becomes <computeroutput>T</computeroutput> </para></listitem>
+<listitem><para><computeroutput>T &amp;</computeroutput> becomes <computeroutput>T</computeroutput> </para></listitem>
+<listitem><para><computeroutput>T</computeroutput> becomes <computeroutput>T</computeroutput> </para></listitem>
+</itemizedlist>
+</para></description><type><classname>unref</classname>&lt; wrapped_type &gt;::type</type></typedef><typedef name="reference"><description><para>The "reference" type of the child, suitable for return by reference, computed as follows: <itemizedlist>
+<listitem><para><computeroutput>ref_&lt;T const&gt;</computeroutput> becomes <computeroutput>T const &amp;</computeroutput> </para></listitem>
+<listitem><para><computeroutput>ref_&lt;T&gt;</computeroutput> becomes <computeroutput>T &amp;</computeroutput> </para></listitem>
+<listitem><para><computeroutput>T const(&amp;)[N]</computeroutput> becomes <computeroutput>T const(&amp;)[N]</computeroutput> </para></listitem>
+<listitem><para><computeroutput>T(&amp;)[N]</computeroutput> becomes <computeroutput>T(&amp;)[N]</computeroutput> </para></listitem>
+<listitem><para><computeroutput>R(&amp;)(A0,...)</computeroutput> becomes <computeroutput>R(&amp;)(A0,...)</computeroutput> </para></listitem>
+<listitem><para><computeroutput>T const &amp;</computeroutput> becomes <computeroutput>T const &amp;</computeroutput> </para></listitem>
+<listitem><para><computeroutput>T &amp;</computeroutput> becomes <computeroutput>T &amp;</computeroutput> </para></listitem>
+<listitem><para><computeroutput>T</computeroutput> becomes <computeroutput>T &amp;</computeroutput> </para></listitem>
+</itemizedlist>
+</para></description><type><classname>unref</classname>&lt; wrapped_type &gt;::reference</type></typedef><typedef name="const_reference"><description><para>The "const reference" type of the child, suitable for return by const reference, computed as follows: <itemizedlist>
+<listitem><para><computeroutput>ref_&lt;T const&gt;</computeroutput> becomes <computeroutput>T const &amp;</computeroutput> </para></listitem>
+<listitem><para><computeroutput>ref_&lt;T&gt;</computeroutput> becomes <computeroutput>T &amp;</computeroutput> </para></listitem>
+<listitem><para><computeroutput>T const(&amp;)[N]</computeroutput> becomes <computeroutput>T const(&amp;)[N]</computeroutput> </para></listitem>
+<listitem><para><computeroutput>T(&amp;)[N]</computeroutput> becomes <computeroutput>T(&amp;)[N]</computeroutput> </para></listitem>
+<listitem><para><computeroutput>R(&amp;)(A0,...)</computeroutput> becomes <computeroutput>R(&amp;)(A0,...)</computeroutput> </para></listitem>
+<listitem><para><computeroutput>T const &amp;</computeroutput> becomes <computeroutput>T const &amp;</computeroutput> </para></listitem>
+<listitem><para><computeroutput>T &amp;</computeroutput> becomes <computeroutput>T &amp;</computeroutput> </para></listitem>
+<listitem><para><computeroutput>T</computeroutput> becomes <computeroutput>T const &amp;</computeroutput> </para></listitem>
+</itemizedlist>
+</para></description><type><classname>unref</classname>&lt; wrapped_type &gt;::const_reference</type></typedef><method-group name="public static functions"/></struct-specialization><struct-specialization name="child_c"><template>
+ <template-type-parameter name="Expr"/>
+ </template><specialization><template-arg>Expr</template-arg><template-arg>1</template-arg></specialization><purpose>A metafunction that returns the type of the Nth child of a Proto expression. </purpose><description><para>A metafunction that returns the type of the Nth child of a Proto expression. <computeroutput>N</computeroutput> must be 0 or less than <computeroutput>Expr::proto_arity::value</computeroutput>. </para></description><typedef name="wrapped_type"><description><para>The raw type of the Nth child as it is stored within <computeroutput>Expr</computeroutput>. This may be a value, a reference, or a Proto <computeroutput>ref_&lt;&gt;</computeroutput> wrapper. </para></description><type>Expr::proto_child1</type></typedef><typedef name="type"><description><para>The "value" type of the child, suitable for return by value, computed as follows: <itemizedlist>
+<listitem><para><computeroutput>ref_&lt;T const&gt;</computeroutput> becomes <computeroutput>T</computeroutput> </para></listitem>
+<listitem><para><computeroutput>ref_&lt;T&gt;</computeroutput> becomes <computeroutput>T</computeroutput> </para></listitem>
+<listitem><para><computeroutput>T const(&amp;)[N]</computeroutput> becomes <computeroutput>T const(&amp;)[N]</computeroutput> </para></listitem>
+<listitem><para><computeroutput>T(&amp;)[N]</computeroutput> becomes <computeroutput>T(&amp;)[N]</computeroutput> </para></listitem>
+<listitem><para><computeroutput>R(&amp;)(A0,...)</computeroutput> becomes <computeroutput>R(&amp;)(A0,...)</computeroutput> </para></listitem>
+<listitem><para><computeroutput>T const &amp;</computeroutput> becomes <computeroutput>T</computeroutput> </para></listitem>
+<listitem><para><computeroutput>T &amp;</computeroutput> becomes <computeroutput>T</computeroutput> </para></listitem>
+<listitem><para><computeroutput>T</computeroutput> becomes <computeroutput>T</computeroutput> </para></listitem>
+</itemizedlist>
+</para></description><type><classname>unref</classname>&lt; wrapped_type &gt;::type</type></typedef><typedef name="reference"><description><para>The "reference" type of the child, suitable for return by reference, computed as follows: <itemizedlist>
+<listitem><para><computeroutput>ref_&lt;T const&gt;</computeroutput> becomes <computeroutput>T const &amp;</computeroutput> </para></listitem>
+<listitem><para><computeroutput>ref_&lt;T&gt;</computeroutput> becomes <computeroutput>T &amp;</computeroutput> </para></listitem>
+<listitem><para><computeroutput>T const(&amp;)[N]</computeroutput> becomes <computeroutput>T const(&amp;)[N]</computeroutput> </para></listitem>
+<listitem><para><computeroutput>T(&amp;)[N]</computeroutput> becomes <computeroutput>T(&amp;)[N]</computeroutput> </para></listitem>
+<listitem><para><computeroutput>R(&amp;)(A0,...)</computeroutput> becomes <computeroutput>R(&amp;)(A0,...)</computeroutput> </para></listitem>
+<listitem><para><computeroutput>T const &amp;</computeroutput> becomes <computeroutput>T const &amp;</computeroutput> </para></listitem>
+<listitem><para><computeroutput>T &amp;</computeroutput> becomes <computeroutput>T &amp;</computeroutput> </para></listitem>
+<listitem><para><computeroutput>T</computeroutput> becomes <computeroutput>T &amp;</computeroutput> </para></listitem>
+</itemizedlist>
+</para></description><type><classname>unref</classname>&lt; wrapped_type &gt;::reference</type></typedef><typedef name="const_reference"><description><para>The "const reference" type of the child, suitable for return by const reference, computed as follows: <itemizedlist>
+<listitem><para><computeroutput>ref_&lt;T const&gt;</computeroutput> becomes <computeroutput>T const &amp;</computeroutput> </para></listitem>
+<listitem><para><computeroutput>ref_&lt;T&gt;</computeroutput> becomes <computeroutput>T &amp;</computeroutput> </para></listitem>
+<listitem><para><computeroutput>T const(&amp;)[N]</computeroutput> becomes <computeroutput>T const(&amp;)[N]</computeroutput> </para></listitem>
+<listitem><para><computeroutput>T(&amp;)[N]</computeroutput> becomes <computeroutput>T(&amp;)[N]</computeroutput> </para></listitem>
+<listitem><para><computeroutput>R(&amp;)(A0,...)</computeroutput> becomes <computeroutput>R(&amp;)(A0,...)</computeroutput> </para></listitem>
+<listitem><para><computeroutput>T const &amp;</computeroutput> becomes <computeroutput>T const &amp;</computeroutput> </para></listitem>
+<listitem><para><computeroutput>T &amp;</computeroutput> becomes <computeroutput>T &amp;</computeroutput> </para></listitem>
+<listitem><para><computeroutput>T</computeroutput> becomes <computeroutput>T const &amp;</computeroutput> </para></listitem>
+</itemizedlist>
+</para></description><type><classname>unref</classname>&lt; wrapped_type &gt;::const_reference</type></typedef><method-group name="public static functions"/></struct-specialization><struct-specialization name="child_c"><template>
+ <template-type-parameter name="Expr"/>
+ </template><specialization><template-arg>Expr</template-arg><template-arg>2</template-arg></specialization><purpose>A metafunction that returns the type of the Nth child of a Proto expression. </purpose><description><para>A metafunction that returns the type of the Nth child of a Proto expression. <computeroutput>N</computeroutput> must be 0 or less than <computeroutput>Expr::proto_arity::value</computeroutput>. </para></description><typedef name="wrapped_type"><description><para>The raw type of the Nth child as it is stored within <computeroutput>Expr</computeroutput>. This may be a value, a reference, or a Proto <computeroutput>ref_&lt;&gt;</computeroutput> wrapper. </para></description><type>Expr::proto_child2</type></typedef><typedef name="type"><description><para>The "value" type of the child, suitable for return by value, computed as follows: <itemizedlist>
+<listitem><para><computeroutput>ref_&lt;T const&gt;</computeroutput> becomes <computeroutput>T</computeroutput> </para></listitem>
+<listitem><para><computeroutput>ref_&lt;T&gt;</computeroutput> becomes <computeroutput>T</computeroutput> </para></listitem>
+<listitem><para><computeroutput>T const(&amp;)[N]</computeroutput> becomes <computeroutput>T const(&amp;)[N]</computeroutput> </para></listitem>
+<listitem><para><computeroutput>T(&amp;)[N]</computeroutput> becomes <computeroutput>T(&amp;)[N]</computeroutput> </para></listitem>
+<listitem><para><computeroutput>R(&amp;)(A0,...)</computeroutput> becomes <computeroutput>R(&amp;)(A0,...)</computeroutput> </para></listitem>
+<listitem><para><computeroutput>T const &amp;</computeroutput> becomes <computeroutput>T</computeroutput> </para></listitem>
+<listitem><para><computeroutput>T &amp;</computeroutput> becomes <computeroutput>T</computeroutput> </para></listitem>
+<listitem><para><computeroutput>T</computeroutput> becomes <computeroutput>T</computeroutput> </para></listitem>
+</itemizedlist>
+</para></description><type><classname>unref</classname>&lt; wrapped_type &gt;::type</type></typedef><typedef name="reference"><description><para>The "reference" type of the child, suitable for return by reference, computed as follows: <itemizedlist>
+<listitem><para><computeroutput>ref_&lt;T const&gt;</computeroutput> becomes <computeroutput>T const &amp;</computeroutput> </para></listitem>
+<listitem><para><computeroutput>ref_&lt;T&gt;</computeroutput> becomes <computeroutput>T &amp;</computeroutput> </para></listitem>
+<listitem><para><computeroutput>T const(&amp;)[N]</computeroutput> becomes <computeroutput>T const(&amp;)[N]</computeroutput> </para></listitem>
+<listitem><para><computeroutput>T(&amp;)[N]</computeroutput> becomes <computeroutput>T(&amp;)[N]</computeroutput> </para></listitem>
+<listitem><para><computeroutput>R(&amp;)(A0,...)</computeroutput> becomes <computeroutput>R(&amp;)(A0,...)</computeroutput> </para></listitem>
+<listitem><para><computeroutput>T const &amp;</computeroutput> becomes <computeroutput>T const &amp;</computeroutput> </para></listitem>
+<listitem><para><computeroutput>T &amp;</computeroutput> becomes <computeroutput>T &amp;</computeroutput> </para></listitem>
+<listitem><para><computeroutput>T</computeroutput> becomes <computeroutput>T &amp;</computeroutput> </para></listitem>
+</itemizedlist>
+</para></description><type><classname>unref</classname>&lt; wrapped_type &gt;::reference</type></typedef><typedef name="const_reference"><description><para>The "const reference" type of the child, suitable for return by const reference, computed as follows: <itemizedlist>
+<listitem><para><computeroutput>ref_&lt;T const&gt;</computeroutput> becomes <computeroutput>T const &amp;</computeroutput> </para></listitem>
+<listitem><para><computeroutput>ref_&lt;T&gt;</computeroutput> becomes <computeroutput>T &amp;</computeroutput> </para></listitem>
+<listitem><para><computeroutput>T const(&amp;)[N]</computeroutput> becomes <computeroutput>T const(&amp;)[N]</computeroutput> </para></listitem>
+<listitem><para><computeroutput>T(&amp;)[N]</computeroutput> becomes <computeroutput>T(&amp;)[N]</computeroutput> </para></listitem>
+<listitem><para><computeroutput>R(&amp;)(A0,...)</computeroutput> becomes <computeroutput>R(&amp;)(A0,...)</computeroutput> </para></listitem>
+<listitem><para><computeroutput>T const &amp;</computeroutput> becomes <computeroutput>T const &amp;</computeroutput> </para></listitem>
+<listitem><para><computeroutput>T &amp;</computeroutput> becomes <computeroutput>T &amp;</computeroutput> </para></listitem>
+<listitem><para><computeroutput>T</computeroutput> becomes <computeroutput>T const &amp;</computeroutput> </para></listitem>
+</itemizedlist>
+</para></description><type><classname>unref</classname>&lt; wrapped_type &gt;::const_reference</type></typedef><method-group name="public static functions"/></struct-specialization><struct-specialization name="child_c"><template>
+ <template-type-parameter name="Expr"/>
+ </template><specialization><template-arg>Expr</template-arg><template-arg>3</template-arg></specialization><purpose>A metafunction that returns the type of the Nth child of a Proto expression. </purpose><description><para>A metafunction that returns the type of the Nth child of a Proto expression. <computeroutput>N</computeroutput> must be 0 or less than <computeroutput>Expr::proto_arity::value</computeroutput>. </para></description><typedef name="wrapped_type"><description><para>The raw type of the Nth child as it is stored within <computeroutput>Expr</computeroutput>. This may be a value, a reference, or a Proto <computeroutput>ref_&lt;&gt;</computeroutput> wrapper. </para></description><type>Expr::proto_child3</type></typedef><typedef name="type"><description><para>The "value" type of the child, suitable for return by value, computed as follows: <itemizedlist>
+<listitem><para><computeroutput>ref_&lt;T const&gt;</computeroutput> becomes <computeroutput>T</computeroutput> </para></listitem>
+<listitem><para><computeroutput>ref_&lt;T&gt;</computeroutput> becomes <computeroutput>T</computeroutput> </para></listitem>
+<listitem><para><computeroutput>T const(&amp;)[N]</computeroutput> becomes <computeroutput>T const(&amp;)[N]</computeroutput> </para></listitem>
+<listitem><para><computeroutput>T(&amp;)[N]</computeroutput> becomes <computeroutput>T(&amp;)[N]</computeroutput> </para></listitem>
+<listitem><para><computeroutput>R(&amp;)(A0,...)</computeroutput> becomes <computeroutput>R(&amp;)(A0,...)</computeroutput> </para></listitem>
+<listitem><para><computeroutput>T const &amp;</computeroutput> becomes <computeroutput>T</computeroutput> </para></listitem>
+<listitem><para><computeroutput>T &amp;</computeroutput> becomes <computeroutput>T</computeroutput> </para></listitem>
+<listitem><para><computeroutput>T</computeroutput> becomes <computeroutput>T</computeroutput> </para></listitem>
+</itemizedlist>
+</para></description><type><classname>unref</classname>&lt; wrapped_type &gt;::type</type></typedef><typedef name="reference"><description><para>The "reference" type of the child, suitable for return by reference, computed as follows: <itemizedlist>
+<listitem><para><computeroutput>ref_&lt;T const&gt;</computeroutput> becomes <computeroutput>T const &amp;</computeroutput> </para></listitem>
+<listitem><para><computeroutput>ref_&lt;T&gt;</computeroutput> becomes <computeroutput>T &amp;</computeroutput> </para></listitem>
+<listitem><para><computeroutput>T const(&amp;)[N]</computeroutput> becomes <computeroutput>T const(&amp;)[N]</computeroutput> </para></listitem>
+<listitem><para><computeroutput>T(&amp;)[N]</computeroutput> becomes <computeroutput>T(&amp;)[N]</computeroutput> </para></listitem>
+<listitem><para><computeroutput>R(&amp;)(A0,...)</computeroutput> becomes <computeroutput>R(&amp;)(A0,...)</computeroutput> </para></listitem>
+<listitem><para><computeroutput>T const &amp;</computeroutput> becomes <computeroutput>T const &amp;</computeroutput> </para></listitem>
+<listitem><para><computeroutput>T &amp;</computeroutput> becomes <computeroutput>T &amp;</computeroutput> </para></listitem>
+<listitem><para><computeroutput>T</computeroutput> becomes <computeroutput>T &amp;</computeroutput> </para></listitem>
+</itemizedlist>
+</para></description><type><classname>unref</classname>&lt; wrapped_type &gt;::reference</type></typedef><typedef name="const_reference"><description><para>The "const reference" type of the child, suitable for return by const reference, computed as follows: <itemizedlist>
+<listitem><para><computeroutput>ref_&lt;T const&gt;</computeroutput> becomes <computeroutput>T const &amp;</computeroutput> </para></listitem>
+<listitem><para><computeroutput>ref_&lt;T&gt;</computeroutput> becomes <computeroutput>T &amp;</computeroutput> </para></listitem>
+<listitem><para><computeroutput>T const(&amp;)[N]</computeroutput> becomes <computeroutput>T const(&amp;)[N]</computeroutput> </para></listitem>
+<listitem><para><computeroutput>T(&amp;)[N]</computeroutput> becomes <computeroutput>T(&amp;)[N]</computeroutput> </para></listitem>
+<listitem><para><computeroutput>R(&amp;)(A0,...)</computeroutput> becomes <computeroutput>R(&amp;)(A0,...)</computeroutput> </para></listitem>
+<listitem><para><computeroutput>T const &amp;</computeroutput> becomes <computeroutput>T const &amp;</computeroutput> </para></listitem>
+<listitem><para><computeroutput>T &amp;</computeroutput> becomes <computeroutput>T &amp;</computeroutput> </para></listitem>
+<listitem><para><computeroutput>T</computeroutput> becomes <computeroutput>T const &amp;</computeroutput> </para></listitem>
+</itemizedlist>
+</para></description><type><classname>unref</classname>&lt; wrapped_type &gt;::const_reference</type></typedef><method-group name="public static functions"/></struct-specialization><struct-specialization name="child_c"><template>
+ <template-type-parameter name="Expr"/>
+ </template><specialization><template-arg>Expr</template-arg><template-arg>4</template-arg></specialization><purpose>A metafunction that returns the type of the Nth child of a Proto expression. </purpose><description><para>A metafunction that returns the type of the Nth child of a Proto expression. <computeroutput>N</computeroutput> must be 0 or less than <computeroutput>Expr::proto_arity::value</computeroutput>. </para></description><typedef name="wrapped_type"><description><para>The raw type of the Nth child as it is stored within <computeroutput>Expr</computeroutput>. This may be a value, a reference, or a Proto <computeroutput>ref_&lt;&gt;</computeroutput> wrapper. </para></description><type>Expr::proto_child4</type></typedef><typedef name="type"><description><para>The "value" type of the child, suitable for return by value, computed as follows: <itemizedlist>
+<listitem><para><computeroutput>ref_&lt;T const&gt;</computeroutput> becomes <computeroutput>T</computeroutput> </para></listitem>
+<listitem><para><computeroutput>ref_&lt;T&gt;</computeroutput> becomes <computeroutput>T</computeroutput> </para></listitem>
+<listitem><para><computeroutput>T const(&amp;)[N]</computeroutput> becomes <computeroutput>T const(&amp;)[N]</computeroutput> </para></listitem>
+<listitem><para><computeroutput>T(&amp;)[N]</computeroutput> becomes <computeroutput>T(&amp;)[N]</computeroutput> </para></listitem>
+<listitem><para><computeroutput>R(&amp;)(A0,...)</computeroutput> becomes <computeroutput>R(&amp;)(A0,...)</computeroutput> </para></listitem>
+<listitem><para><computeroutput>T const &amp;</computeroutput> becomes <computeroutput>T</computeroutput> </para></listitem>
+<listitem><para><computeroutput>T &amp;</computeroutput> becomes <computeroutput>T</computeroutput> </para></listitem>
+<listitem><para><computeroutput>T</computeroutput> becomes <computeroutput>T</computeroutput> </para></listitem>
+</itemizedlist>
+</para></description><type><classname>unref</classname>&lt; wrapped_type &gt;::type</type></typedef><typedef name="reference"><description><para>The "reference" type of the child, suitable for return by reference, computed as follows: <itemizedlist>
+<listitem><para><computeroutput>ref_&lt;T const&gt;</computeroutput> becomes <computeroutput>T const &amp;</computeroutput> </para></listitem>
+<listitem><para><computeroutput>ref_&lt;T&gt;</computeroutput> becomes <computeroutput>T &amp;</computeroutput> </para></listitem>
+<listitem><para><computeroutput>T const(&amp;)[N]</computeroutput> becomes <computeroutput>T const(&amp;)[N]</computeroutput> </para></listitem>
+<listitem><para><computeroutput>T(&amp;)[N]</computeroutput> becomes <computeroutput>T(&amp;)[N]</computeroutput> </para></listitem>
+<listitem><para><computeroutput>R(&amp;)(A0,...)</computeroutput> becomes <computeroutput>R(&amp;)(A0,...)</computeroutput> </para></listitem>
+<listitem><para><computeroutput>T const &amp;</computeroutput> becomes <computeroutput>T const &amp;</computeroutput> </para></listitem>
+<listitem><para><computeroutput>T &amp;</computeroutput> becomes <computeroutput>T &amp;</computeroutput> </para></listitem>
+<listitem><para><computeroutput>T</computeroutput> becomes <computeroutput>T &amp;</computeroutput> </para></listitem>
+</itemizedlist>
+</para></description><type><classname>unref</classname>&lt; wrapped_type &gt;::reference</type></typedef><typedef name="const_reference"><description><para>The "const reference" type of the child, suitable for return by const reference, computed as follows: <itemizedlist>
+<listitem><para><computeroutput>ref_&lt;T const&gt;</computeroutput> becomes <computeroutput>T const &amp;</computeroutput> </para></listitem>
+<listitem><para><computeroutput>ref_&lt;T&gt;</computeroutput> becomes <computeroutput>T &amp;</computeroutput> </para></listitem>
+<listitem><para><computeroutput>T const(&amp;)[N]</computeroutput> becomes <computeroutput>T const(&amp;)[N]</computeroutput> </para></listitem>
+<listitem><para><computeroutput>T(&amp;)[N]</computeroutput> becomes <computeroutput>T(&amp;)[N]</computeroutput> </para></listitem>
+<listitem><para><computeroutput>R(&amp;)(A0,...)</computeroutput> becomes <computeroutput>R(&amp;)(A0,...)</computeroutput> </para></listitem>
+<listitem><para><computeroutput>T const &amp;</computeroutput> becomes <computeroutput>T const &amp;</computeroutput> </para></listitem>
+<listitem><para><computeroutput>T &amp;</computeroutput> becomes <computeroutput>T &amp;</computeroutput> </para></listitem>
+<listitem><para><computeroutput>T</computeroutput> becomes <computeroutput>T const &amp;</computeroutput> </para></listitem>
+</itemizedlist>
+</para></description><type><classname>unref</classname>&lt; wrapped_type &gt;::const_reference</type></typedef><method-group name="public static functions"/></struct-specialization><struct-specialization name="child_c"><template>
+ <template-type-parameter name="Expr"/>
+ </template><specialization><template-arg>Expr</template-arg><template-arg>5</template-arg></specialization><purpose>A metafunction that returns the type of the Nth child of a Proto expression. </purpose><description><para>A metafunction that returns the type of the Nth child of a Proto expression. <computeroutput>N</computeroutput> must be 0 or less than <computeroutput>Expr::proto_arity::value</computeroutput>. </para></description><typedef name="wrapped_type"><description><para>The raw type of the Nth child as it is stored within <computeroutput>Expr</computeroutput>. This may be a value, a reference, or a Proto <computeroutput>ref_&lt;&gt;</computeroutput> wrapper. </para></description><type>Expr::proto_child5</type></typedef><typedef name="type"><description><para>The "value" type of the child, suitable for return by value, computed as follows: <itemizedlist>
+<listitem><para><computeroutput>ref_&lt;T const&gt;</computeroutput> becomes <computeroutput>T</computeroutput> </para></listitem>
+<listitem><para><computeroutput>ref_&lt;T&gt;</computeroutput> becomes <computeroutput>T</computeroutput> </para></listitem>
+<listitem><para><computeroutput>T const(&amp;)[N]</computeroutput> becomes <computeroutput>T const(&amp;)[N]</computeroutput> </para></listitem>
+<listitem><para><computeroutput>T(&amp;)[N]</computeroutput> becomes <computeroutput>T(&amp;)[N]</computeroutput> </para></listitem>
+<listitem><para><computeroutput>R(&amp;)(A0,...)</computeroutput> becomes <computeroutput>R(&amp;)(A0,...)</computeroutput> </para></listitem>
+<listitem><para><computeroutput>T const &amp;</computeroutput> becomes <computeroutput>T</computeroutput> </para></listitem>
+<listitem><para><computeroutput>T &amp;</computeroutput> becomes <computeroutput>T</computeroutput> </para></listitem>
+<listitem><para><computeroutput>T</computeroutput> becomes <computeroutput>T</computeroutput> </para></listitem>
+</itemizedlist>
+</para></description><type><classname>unref</classname>&lt; wrapped_type &gt;::type</type></typedef><typedef name="reference"><description><para>The "reference" type of the child, suitable for return by reference, computed as follows: <itemizedlist>
+<listitem><para><computeroutput>ref_&lt;T const&gt;</computeroutput> becomes <computeroutput>T const &amp;</computeroutput> </para></listitem>
+<listitem><para><computeroutput>ref_&lt;T&gt;</computeroutput> becomes <computeroutput>T &amp;</computeroutput> </para></listitem>
+<listitem><para><computeroutput>T const(&amp;)[N]</computeroutput> becomes <computeroutput>T const(&amp;)[N]</computeroutput> </para></listitem>
+<listitem><para><computeroutput>T(&amp;)[N]</computeroutput> becomes <computeroutput>T(&amp;)[N]</computeroutput> </para></listitem>
+<listitem><para><computeroutput>R(&amp;)(A0,...)</computeroutput> becomes <computeroutput>R(&amp;)(A0,...)</computeroutput> </para></listitem>
+<listitem><para><computeroutput>T const &amp;</computeroutput> becomes <computeroutput>T const &amp;</computeroutput> </para></listitem>
+<listitem><para><computeroutput>T &amp;</computeroutput> becomes <computeroutput>T &amp;</computeroutput> </para></listitem>
+<listitem><para><computeroutput>T</computeroutput> becomes <computeroutput>T &amp;</computeroutput> </para></listitem>
+</itemizedlist>
+</para></description><type><classname>unref</classname>&lt; wrapped_type &gt;::reference</type></typedef><typedef name="const_reference"><description><para>The "const reference" type of the child, suitable for return by const reference, computed as follows: <itemizedlist>
+<listitem><para><computeroutput>ref_&lt;T const&gt;</computeroutput> becomes <computeroutput>T const &amp;</computeroutput> </para></listitem>
+<listitem><para><computeroutput>ref_&lt;T&gt;</computeroutput> becomes <computeroutput>T &amp;</computeroutput> </para></listitem>
+<listitem><para><computeroutput>T const(&amp;)[N]</computeroutput> becomes <computeroutput>T const(&amp;)[N]</computeroutput> </para></listitem>
+<listitem><para><computeroutput>T(&amp;)[N]</computeroutput> becomes <computeroutput>T(&amp;)[N]</computeroutput> </para></listitem>
+<listitem><para><computeroutput>R(&amp;)(A0,...)</computeroutput> becomes <computeroutput>R(&amp;)(A0,...)</computeroutput> </para></listitem>
+<listitem><para><computeroutput>T const &amp;</computeroutput> becomes <computeroutput>T const &amp;</computeroutput> </para></listitem>
+<listitem><para><computeroutput>T &amp;</computeroutput> becomes <computeroutput>T &amp;</computeroutput> </para></listitem>
+<listitem><para><computeroutput>T</computeroutput> becomes <computeroutput>T const &amp;</computeroutput> </para></listitem>
+</itemizedlist>
+</para></description><type><classname>unref</classname>&lt; wrapped_type &gt;::const_reference</type></typedef><method-group name="public static functions"/></struct-specialization></namespace><overloaded-function name="as_expr"><signature><type><classname>result_of::as_expr</classname>&lt; T &gt;::reference</type><template>
+ <template-type-parameter name="T"/>
+ </template><parameter name="t"><paramtype>T &amp;</paramtype><description><para>The object to wrap.</para></description></parameter></signature><signature><type><classname>result_of::as_expr</classname>&lt; T const &gt;::reference</type><template>
+ <template-type-parameter name="T"/>
+ </template><parameter name="t"><paramtype>T const &amp;</paramtype></parameter></signature><purpose>A function that wraps non-Proto expression types in Proto terminals and leaves Proto expression types alone. </purpose><description><para>The <computeroutput>as_expr()</computeroutput> function turns objects into Proto terminals if they are not Proto expression types already. Non-Proto types are held by value, if possible. Types which are already Proto types are left alone and returned by reference.</para><para>This function can be called either with an explicitly specified <computeroutput>Domain</computeroutput> parameter (i.e., <computeroutput>as_expr&lt;Domain&gt;(t)</computeroutput>), or without (i.e., <computeroutput>as_expr(t)</computeroutput>). If no domain is specified, <computeroutput>default_domain</computeroutput> is assumed.</para><para>If <computeroutput>is_expr&lt;T&gt;::value</computeroutput> is <computeroutput>true</computeroutput>, then the argument is returned unmodified, by referenc
e. Otherwise, the argument is wrapped in a Proto terminal expression node according to the following rules. If <computeroutput>T</computeroutput> is a function type, let <computeroutput>A</computeroutput> be <computeroutput>T &amp;</computeroutput>. Otherwise, let <computeroutput>A</computeroutput> be the type <computeroutput>T</computeroutput> stripped of cv-qualifiers. Then, <computeroutput>as_expr()</computeroutput> returns <computeroutput>Domain()(terminal&lt;A&gt;::type::make(t))</computeroutput>.</para><para>
+This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts. </para></description></overloaded-function><overloaded-function name="as_child"><signature><type><classname>result_of::as_child</classname>&lt; T &gt;::type</type><template>
+ <template-type-parameter name="T"/>
+ </template><parameter name="t"><paramtype>T &amp;</paramtype><description><para>The object to wrap.</para></description></parameter></signature><signature><type><classname>result_of::as_child</classname>&lt; T const &gt;::type</type><template>
+ <template-type-parameter name="T"/>
+ </template><parameter name="t"><paramtype>T const &amp;</paramtype></parameter></signature><purpose>A function that wraps non-Proto expression types in Proto terminals (by reference) and wraps Proto expression types in <computeroutput>ref_&lt;&gt;</computeroutput>. </purpose><description><para>The <computeroutput>as_child()</computeroutput> function turns objects into Proto terminals if they are not Proto expression types already. Non-Proto types are held by reference. Types which are already Proto types are wrapped in <computeroutput>ref_&lt;&gt;</computeroutput>.</para><para>This function can be called either with an explicitly specified <computeroutput>Domain</computeroutput> parameter (i.e., <computeroutput>as_child&lt;Domain&gt;(t)</computeroutput>), or without (i.e., <computeroutput>as_child(t)</computeroutput>). If no domain is specified, <computeroutput>default_domain</computeroutput> is assumed.</para><para>If <computeroutput>is_expr&lt;T&gt;::value</computeroutput> is <computeroutput>true<
/computeroutput>, then the argument is wrapped in <computeroutput>ref_&lt;&gt;</computeroutput>, which holds the argument by reference. Otherwise, <computeroutput>as_child()</computeroutput> returns <computeroutput>Domain()(terminal&lt;T &amp;&gt;::type::make(t))</computeroutput>.</para><para>
+This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts. </para></description></overloaded-function><overloaded-function name="child"><signature><type><classname>result_of::child</classname>&lt; Expr, N &gt;::reference</type><template>
+ <template-type-parameter name="N"/>
+ <template-type-parameter name="Expr"/>
+ </template><parameter name="expr"><paramtype>Expr &amp;</paramtype><description><para>The Proto expression. </para></description></parameter></signature><signature><type><classname>result_of::child</classname>&lt; Expr, N &gt;::const_reference</type><template>
+ <template-type-parameter name="N"/>
+ <template-type-parameter name="Expr"/>
+ </template><parameter name="expr"><paramtype>Expr const &amp;</paramtype></parameter></signature><signature><type><classname>result_of::unref</classname>&lt; typename Expr2::proto_base_expr::proto_child0 &gt;::reference</type><template>
+ <template-type-parameter name="Expr2"/>
+ </template><parameter name="expr2"><paramtype>Expr2 &amp;</paramtype></parameter></signature><signature><type><classname>result_of::unref</classname>&lt; typename Expr2::proto_base_expr::proto_child0 &gt;::const_reference</type><template>
+ <template-type-parameter name="Expr2"/>
+ </template><parameter name="expr2"><paramtype>Expr2 const &amp;</paramtype></parameter></signature><purpose>Return the Nth child of the specified Proto expression. </purpose><description><para>Return the Nth child of the specified Proto expression. If <computeroutput>N</computeroutput> is not specified, as in <computeroutput>child(expr)</computeroutput>, then <computeroutput>N</computeroutput> is assumed to be <computeroutput>mpl::long_&lt;0&gt;</computeroutput>. The child is returned by reference. If the expression is holding the child in a <computeroutput>ref_&lt;&gt;</computeroutput> wrapper, it is unwrapped before it is returned.</para><para>
+
+
+
+</para></description><requires><para><computeroutput>is_expr&lt;Expr&gt;::value</computeroutput> is <computeroutput>true</computeroutput>. </para><para><computeroutput>N</computeroutput> is an MPL Integral Constant. </para><para><computeroutput>N::value == 0 || N::value &lt; Expr::proto_arity::value</computeroutput> </para></requires><returns><para>A reference to the Nth child </para></returns><throws><simpara>Will not throw.</simpara></throws></overloaded-function><overloaded-function name="child_c"><signature><type>result_of::child_c&lt; Expr, N &gt;::reference</type><template>
+ <template-nontype-parameter name="N"><type>long</type></template-nontype-parameter>
+ <template-type-parameter name="Expr"/>
+ </template><parameter name="expr"><paramtype>Expr &amp;</paramtype><description><para>The Proto expression. </para></description></parameter></signature><signature><type>result_of::child_c&lt; Expr, N &gt;::const_reference</type><template>
+ <template-nontype-parameter name="N"><type>long</type></template-nontype-parameter>
+ <template-type-parameter name="Expr"/>
+ </template><parameter name="expr"><paramtype>Expr const &amp;</paramtype></parameter></signature><purpose>Return the Nth child of the specified Proto expression. </purpose><description><para>Return the Nth child of the specified Proto expression. The child is returned by reference. If the expression is holding the child in a <computeroutput>ref_&lt;&gt;</computeroutput> wrapper, it is unwrapped before it is returned.</para><para>
+
+
+
+</para></description><requires><para><computeroutput>is_expr&lt;Expr&gt;::value</computeroutput> is <computeroutput>true</computeroutput>. </para><para><computeroutput>N == 0 || N &lt; Expr::proto_arity::value</computeroutput> </para></requires><returns><para>A reference to the Nth child </para></returns><throws><simpara>Will not throw.</simpara></throws></overloaded-function><overloaded-function name="value"><signature><type><classname>result_of::value</classname>&lt; Expr &gt;::reference</type><template>
+ <template-type-parameter name="Expr"/>
+ </template><parameter name="expr"><paramtype>Expr &amp;</paramtype><description><para>The Proto terminal expression. </para></description></parameter></signature><signature><type><classname>result_of::value</classname>&lt; Expr &gt;::const_reference</type><template>
+ <template-type-parameter name="Expr"/>
+ </template><parameter name="expr"><paramtype>Expr const &amp;</paramtype></parameter></signature><purpose>Return the value stored within the specified Proto terminal expression. </purpose><description><para>Return the the value stored within the specified Proto terminal expression. The value is returned by reference.</para><para>
+
+
+
+</para></description><requires><para><computeroutput>Expr::proto_tag</computeroutput> is <computeroutput>tag::terminal</computeroutput>. </para><para><computeroutput>N::value == 0</computeroutput> </para></requires><returns><para>A reference to the terminal's value </para></returns><throws><simpara>Will not throw.</simpara></throws></overloaded-function><overloaded-function name="left"><signature><type><classname>result_of::left</classname>&lt; Expr &gt;::reference</type><template>
+ <template-type-parameter name="Expr"/>
+ </template><parameter name="expr"><paramtype>Expr &amp;</paramtype><description><para>The Proto expression. </para></description></parameter></signature><signature><type><classname>result_of::left</classname>&lt; Expr &gt;::const_reference</type><template>
+ <template-type-parameter name="Expr"/>
+ </template><parameter name="expr"><paramtype>Expr const &amp;</paramtype></parameter></signature><purpose>Return the left child of the specified binary Proto expression. </purpose><description><para>Return the left child of the specified binary Proto expression. The child is returned by reference. If the expression is holding the child in a <computeroutput>ref_&lt;&gt;</computeroutput> wrapper, it is unwrapped before it is returned.</para><para>
+
+
+
+</para></description><requires><para><computeroutput>is_expr&lt;Expr&gt;::value</computeroutput> is <computeroutput>true</computeroutput>. </para><para><computeroutput>2 == Expr::proto_arity::value</computeroutput> </para></requires><returns><para>A reference to the left child </para></returns><throws><simpara>Will not throw.</simpara></throws></overloaded-function><overloaded-function name="right"><signature><type><classname>result_of::right</classname>&lt; Expr &gt;::reference</type><template>
+ <template-type-parameter name="Expr"/>
+ </template><parameter name="expr"><paramtype>Expr &amp;</paramtype><description><para>The Proto expression. </para></description></parameter></signature><signature><type><classname>result_of::right</classname>&lt; Expr &gt;::const_reference</type><template>
+ <template-type-parameter name="Expr"/>
+ </template><parameter name="expr"><paramtype>Expr const &amp;</paramtype></parameter></signature><purpose>Return the right child of the specified binary Proto expression. </purpose><description><para>Return the right child of the specified binary Proto expression. The child is returned by reference. If the expression is holding the child in a <computeroutput>ref_&lt;&gt;</computeroutput> wrapper, it is unwrapped before it is returned.</para><para>
+
+
+
+</para></description><requires><para><computeroutput>is_expr&lt;Expr&gt;::value</computeroutput> is <computeroutput>true</computeroutput>. </para><para><computeroutput>2 == Expr::proto_arity::value</computeroutput> </para></requires><returns><para>A reference to the right child </para></returns><throws><simpara>Will not throw.</simpara></throws></overloaded-function></namespace></namespace></header><header name="boost/proto/transform.hpp"><para>Includes all the transforms in the transform/ sub-directory. </para></header><header name="boost/proto/transform/arg.hpp"><para>Contains definition of the argN transforms. </para><namespace name="boost"><namespace name="proto"><struct name="_expr"><inherit access="public">boost::proto::callable</inherit><purpose>A PrimitiveTransform that returns the current expression unmodified. </purpose><struct-specialization name="result"><template>
+ <template-type-parameter name="This"/>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="State"/>
+ <template-type-parameter name="Data"/>
+ </template><specialization><template-arg>This(Expr</template-arg><template-arg>State</template-arg><template-arg>Data)</template-arg></specialization><typedef name="type"><type>Expr</type></typedef></struct-specialization><method-group name="public member functions"><method name="operator()" cv="const"><type>Expr const &amp;</type><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="State"/>
+ <template-type-parameter name="Data"/>
+ </template><parameter name="expr"><paramtype>Expr const &amp;</paramtype><description><para>The current expression. </para></description></parameter><parameter name=""><paramtype>State const &amp;</paramtype></parameter><parameter name=""><paramtype>Data &amp;</paramtype></parameter><description><para>
+
+
+</para></description><returns><para><computeroutput>expr</computeroutput> </para></returns><throws><simpara>Will not throw.</simpara></throws></method></method-group></struct><struct name="_state"><inherit access="public">boost::proto::callable</inherit><purpose>A PrimitiveTransform that returns the current state unmodified. </purpose><struct-specialization name="result"><template>
+ <template-type-parameter name="This"/>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="State"/>
+ <template-type-parameter name="Data"/>
+ </template><specialization><template-arg>This(Expr</template-arg><template-arg>State</template-arg><template-arg>Data)</template-arg></specialization><typedef name="type"><type>State</type></typedef></struct-specialization><method-group name="public member functions"><method name="operator()" cv="const"><type>State const &amp;</type><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="State"/>
+ <template-type-parameter name="Data"/>
+ </template><parameter name=""><paramtype>Expr const &amp;</paramtype></parameter><parameter name="state"><paramtype>State const &amp;</paramtype><description><para>The current state. </para></description></parameter><parameter name=""><paramtype>Data &amp;</paramtype></parameter><description><para>
+
+
+</para></description><returns><para><computeroutput>state</computeroutput> </para></returns><throws><simpara>Will not throw.</simpara></throws></method></method-group></struct><struct name="_data"><inherit access="public">boost::proto::callable</inherit><purpose>A PrimitiveTransform that returns the current data unmodified. </purpose><struct-specialization name="result"><template>
+ <template-type-parameter name="This"/>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="State"/>
+ <template-type-parameter name="Data"/>
+ </template><specialization><template-arg>This(Expr</template-arg><template-arg>State</template-arg><template-arg>Data)</template-arg></specialization><typedef name="type"><type>Data</type></typedef></struct-specialization><method-group name="public member functions"><method name="operator()" cv="const"><type>Data &amp;</type><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="State"/>
+ <template-type-parameter name="Data"/>
+ </template><parameter name=""><paramtype>Expr const &amp;</paramtype></parameter><parameter name=""><paramtype>State const &amp;</paramtype></parameter><parameter name="data"><paramtype>Data &amp;</paramtype><description><para>The current data </para></description></parameter><description><para>
+
+
+</para></description><returns><para><computeroutput>data</computeroutput> </para></returns><throws><simpara>Will not throw.</simpara></throws></method></method-group></struct><struct name="_child_c"><template>
+ <template-nontype-parameter name="I"><type>int</type></template-nontype-parameter>
+ </template><inherit access="public">boost::proto::callable</inherit><purpose>A PrimitiveTransform that returns I-th child of the current expression. </purpose><struct-specialization name="result"><template>
+ <template-type-parameter name="This"/>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="State"/>
+ <template-type-parameter name="Data"/>
+ </template><specialization><template-arg>This(Expr</template-arg><template-arg>State</template-arg><template-arg>Data)</template-arg></specialization><typedef name="type"><type>proto::result_of::child_c&lt; Expr, I &gt;::type</type></typedef></struct-specialization><method-group name="public member functions"><method name="operator()" cv="const"><type>proto::result_of::child_c&lt; Expr, I &gt;::const_reference</type><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="State"/>
+ <template-type-parameter name="Data"/>
+ </template><parameter name="expr"><paramtype>Expr const &amp;</paramtype><description><para>The current expression. </para></description></parameter><parameter name=""><paramtype>State const &amp;</paramtype></parameter><parameter name=""><paramtype>Data &amp;</paramtype></parameter><description><para>
+
+
+</para></description><returns><para><computeroutput>proto::child_c&lt;I&gt;(expr)</computeroutput> </para></returns><throws><simpara>Will not throw.</simpara></throws></method></method-group></struct><struct name="_ref"><inherit access="public">boost::proto::callable</inherit><purpose>A unary CallableTransform that wraps its argument in a <computeroutput>boost::reference_wrapper&lt;&gt;</computeroutput>. </purpose><struct-specialization name="result"><template>
+ <template-type-parameter name="This"/>
+ <template-type-parameter name="T"/>
+ </template><specialization><template-arg>This(T &amp;)</template-arg></specialization><typedef name="type"><type>boost::reference_wrapper&lt; T &gt;</type></typedef></struct-specialization><struct-specialization name="result"><template>
+ <template-type-parameter name="This"/>
+ <template-type-parameter name="T"/>
+ </template><specialization><template-arg>This(T)</template-arg></specialization><typedef name="type"><type>boost::reference_wrapper&lt; T const &gt;</type></typedef></struct-specialization><method-group name="public member functions"><method name="operator()" cv="const"><type>boost::reference_wrapper&lt; T &gt;</type><template>
+ <template-type-parameter name="T"/>
+ </template><parameter name="t"><paramtype>T &amp;</paramtype><description><para>The object to wrap </para></description></parameter><description><para>
+
+
+</para></description><returns><para><computeroutput>boost::ref(t)</computeroutput> </para></returns><throws><simpara>Will not throw.</simpara></throws></method><method name="operator()" cv="const"><type>boost::reference_wrapper&lt; T const &gt;</type><template>
+ <template-type-parameter name="T"/>
+ </template><parameter name="t"><paramtype>T const &amp;</paramtype></parameter><description><para>This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts. </para></description></method></method-group></struct></namespace></namespace></header><header name="boost/proto/transform/call.hpp"><para>Contains definition of the call&lt;&gt; transform. </para><namespace name="boost"><namespace name="proto"><struct name="call"><template>
+ <template-type-parameter name="PrimitiveTransform"/>
+ </template><purpose>Wrap <computeroutput>PrimitiveTransform</computeroutput> so that <computeroutput>when&lt;&gt;</computeroutput> knows it is callable. Requires that the parameter is actually a PrimitiveTransform. </purpose><description><para>This form of <computeroutput>call&lt;&gt;</computeroutput> is useful for annotating an arbitrary PrimitiveTransform as callable when using it with <computeroutput>when&lt;&gt;</computeroutput>. Consider the following transform, which is parameterized with another transform.</para><para><programlisting> template&lt;typename Grammar&gt;
+ struct Foo
+ : when&lt;
+ unary_plus&lt;Grammar&gt;
+ , Grammar(_child) // May or may not work.
+ &gt;
+ {};
+</programlisting></para><para>The problem with the above is that <computeroutput>when&lt;&gt;</computeroutput> may or may not recognize <computeroutput>Grammar</computeroutput> as callable, depending on how <computeroutput>Grammar</computeroutput> is implemented. (See <computeroutput>is_callable&lt;&gt;</computeroutput> for a discussion of this issue.) The above code can guard against the issue by wrapping <computeroutput>Grammar</computeroutput> in <computeroutput>call&lt;&gt;</computeroutput>, such as:</para><para><programlisting> template&lt;typename Grammar&gt;
+ struct Foo
+ : when&lt;
+ unary_plus&lt;Grammar&gt;
+ , call&lt;Grammar&gt;(_child) // OK, this works
+ &gt;
+ {};
+</programlisting></para><para>The above could also have been written as:</para><para><programlisting> template&lt;typename Grammar&gt;
+ struct Foo
+ : when&lt;
+ unary_plus&lt;Grammar&gt;
+ , call&lt;Grammar(_child)&gt; // OK, this works, too
+ &gt;
+ {};
+</programlisting> </para></description><typedef name="proto_is_callable_"><type>void</type></typedef></struct><struct-specialization name="call"><template>
+ <template-type-parameter name="Fun"/>
+ </template><specialization><template-arg>Fun()</template-arg></specialization><inherit access="public">boost::proto::callable</inherit><purpose>Either call the PolymorphicFunctionObject with 0 arguments, or invoke the PrimitiveTransform with 3 arguments. </purpose><struct-specialization name="result"><template>
+ <template-type-parameter name="This"/>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="State"/>
+ <template-type-parameter name="Data"/>
+ </template><specialization><template-arg>This(Expr</template-arg><template-arg>State</template-arg><template-arg>Data)</template-arg></specialization><typedef name="type"><description><para>If <computeroutput>Fun</computeroutput> is a nullary PolymorphicFunctionObject, <computeroutput>type</computeroutput> is a typedef for <computeroutput>boost::result_of&lt;Fun()&gt;::type</computeroutput>. Otherwise, it is a typedef for <computeroutput>boost::result_of&lt;Fun(Expr, State, Data)&gt;::type</computeroutput>. </para></description><type><emphasis>unspecified</emphasis></type></typedef></struct-specialization><method-group name="public member functions"><method name="operator()" cv="const"><type>result&lt; void(Expr, State, Data)&gt;::type</type><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="State"/>
+ <template-type-parameter name="Data"/>
+ </template><parameter name="expr"><paramtype>Expr const &amp;</paramtype><description><para>The current expression </para></description></parameter><parameter name="state"><paramtype>State const &amp;</paramtype><description><para>The current state </para></description></parameter><parameter name="data"><paramtype>Data &amp;</paramtype><description><para>An arbitrary data </para></description></parameter><description><para>Either call the PolymorphicFunctionObject <computeroutput>Fun</computeroutput> with 0 arguments; or invoke the PrimitiveTransform <computeroutput>Fun</computeroutput> with 3 arguments: the current expression, state, and data.</para><para>If <computeroutput>Fun</computeroutput> is a nullary PolymorphicFunctionObject, return <computeroutput>Fun()()</computeroutput>. Otherwise, return <computeroutput>Fun()(expr, state, data)</computeroutput>.</para><para>
+</para></description></method></method-group></struct-specialization><struct-specialization name="call"><template>
+ <template-type-parameter name="Fun"/>
+ <template-type-parameter name="A0"/>
+ </template><specialization><template-arg>Fun(A0)</template-arg></specialization><inherit access="public">boost::proto::callable</inherit><purpose>Either call the PolymorphicFunctionObject with 1 argument, or invoke the PrimitiveTransform with 3 arguments. </purpose><struct-specialization name="result"><template>
+ <template-type-parameter name="This"/>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="State"/>
+ <template-type-parameter name="Data"/>
+ </template><specialization><template-arg>This(Expr</template-arg><template-arg>State</template-arg><template-arg>Data)</template-arg></specialization><typedef name="type"><description><para>Let <computeroutput>x</computeroutput> be <computeroutput>when&lt;_, A0&gt;()(expr, state, data)</computeroutput> and <computeroutput>X</computeroutput> be the type of <computeroutput>x</computeroutput>. If <computeroutput>Fun</computeroutput> is a unary PolymorphicFunctionObject that accepts <computeroutput>x</computeroutput>, then <computeroutput>type</computeroutput> is a typedef for <computeroutput>boost::result_of&lt;Fun(X)&gt;::type</computeroutput>. Otherwise, it is a typedef for <computeroutput>boost::result_of&lt;Fun(X, State, Data)&gt;::type</computeroutput>. </para></description><type><emphasis>unspecified</emphasis></type></typedef></struct-specialization><method-group name="public member functions"><method name="operator()" cv="const"><type>result&lt; void(Expr, State, Data)&gt;::type</type><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="State"/>
+ <template-type-parameter name="Data"/>
+ </template><parameter name="expr"><paramtype>Expr const &amp;</paramtype><description><para>The current expression </para></description></parameter><parameter name="state"><paramtype>State const &amp;</paramtype><description><para>The current state </para></description></parameter><parameter name="data"><paramtype>Data &amp;</paramtype><description><para>An arbitrary data </para></description></parameter><description><para>Either call the PolymorphicFunctionObject with 1 argument: the result of applying the <computeroutput>A0</computeroutput> transform; or invoke the PrimitiveTransform with 3 arguments: result of applying the <computeroutput>A0</computeroutput> transform, the state, and the data.</para><para>Let <computeroutput>x</computeroutput> be <computeroutput>when&lt;_, A0&gt;()(expr, state, data)</computeroutput>. If <computeroutput>Fun</computeroutput> is a unary PolymorphicFunctionObject that accepts <computeroutput>x</computeroutput>, then return <computeroutput>Fun()(x)</computeroutput>.
Otherwise, return <computeroutput>Fun()(x, state, data)</computeroutput>.</para><para>
+</para></description></method></method-group></struct-specialization><struct-specialization name="call"><template>
+ <template-type-parameter name="Fun"/>
+ <template-type-parameter name="A0"/>
+ <template-type-parameter name="A1"/>
+ </template><specialization><template-arg>Fun(A0</template-arg><template-arg>A1)</template-arg></specialization><inherit access="public">boost::proto::callable</inherit><purpose>Either call the PolymorphicFunctionObject with 2 arguments, or invoke the PrimitiveTransform with 3 arguments. </purpose><struct-specialization name="result"><template>
+ <template-type-parameter name="This"/>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="State"/>
+ <template-type-parameter name="Data"/>
+ </template><specialization><template-arg>This(Expr</template-arg><template-arg>State</template-arg><template-arg>Data)</template-arg></specialization><typedef name="type"><description><para>Let <computeroutput>x</computeroutput> be <computeroutput>when&lt;_, A0&gt;()(expr, state, data)</computeroutput> and <computeroutput>X</computeroutput> be the type of <computeroutput>x</computeroutput>. Let <computeroutput>y</computeroutput> be <computeroutput>when&lt;_, A1&gt;()(expr, state, data)</computeroutput> and <computeroutput>Y</computeroutput> be the type of <computeroutput>y</computeroutput>. If <computeroutput>Fun</computeroutput> is a binary PolymorphicFunction object that accepts <computeroutput>x</computeroutput> and <computeroutput>y</computeroutput>, then <computeroutput>type</computeroutput> is a typedef for <computeroutput>boost::result_of&lt;Fun(X, Y)&gt;::type</computeroutput>. Otherwise, it is a typedef for <computeroutput>boost::result_of&lt;Fun(X, Y, Data)&gt;::type</computeroutput>. </para><
/description><type><emphasis>unspecified</emphasis></type></typedef></struct-specialization><method-group name="public member functions"><method name="operator()" cv="const"><type>result&lt; void(Expr, State, Data)&gt;::type</type><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="State"/>
+ <template-type-parameter name="Data"/>
+ </template><parameter name="expr"><paramtype>Expr const &amp;</paramtype><description><para>The current expression </para></description></parameter><parameter name="state"><paramtype>State const &amp;</paramtype><description><para>The current state </para></description></parameter><parameter name="data"><paramtype>Data &amp;</paramtype><description><para>An arbitrary data </para></description></parameter><description><para>Either call the PolymorphicFunctionObject with 2 arguments: the result of applying the <computeroutput>A0</computeroutput> transform, and the result of applying the <computeroutput>A1</computeroutput> transform; or invoke the PrimitiveTransform with 3 arguments: the result of applying the <computeroutput>A0</computeroutput> transform, the result of applying the <computeroutput>A1</computeroutput> transform, and the data.</para><para>Let <computeroutput>x</computeroutput> be <computeroutput>when&lt;_, A0&gt;()(expr, state, data)</computeroutput>. Let <computeroutput>y</computeroutp
ut> be <computeroutput>when&lt;_, A1&gt;()(expr, state, data)</computeroutput>. If <computeroutput>Fun</computeroutput> is a binary PolymorphicFunction object that accepts <computeroutput>x</computeroutput> and <computeroutput>y</computeroutput>, return <computeroutput>Fun()(x, y)</computeroutput>. Otherwise, return <computeroutput>Fun()(x, y, data)</computeroutput>.</para><para>
+</para></description></method></method-group></struct-specialization><struct-specialization name="call"><template>
+ <template-type-parameter name="Fun"/>
+ <template-type-parameter name="A0"/>
+ <template-type-parameter name="A1"/>
+ <template-type-parameter name="A2"/>
+ </template><specialization><template-arg>Fun(A0</template-arg><template-arg>A1</template-arg><template-arg>A2)</template-arg></specialization><inherit access="public">boost::proto::callable</inherit><purpose>Call the PolymorphicFunctionObject or the PrimitiveTransform with the current expression, state and data, transformed according to <computeroutput>A0</computeroutput>, <computeroutput>A1</computeroutput>, and <computeroutput>A2</computeroutput>, respectively. </purpose><struct-specialization name="result"><template>
+ <template-type-parameter name="This"/>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="State"/>
+ <template-type-parameter name="Data"/>
+ </template><specialization><template-arg>This(Expr</template-arg><template-arg>State</template-arg><template-arg>Data)</template-arg></specialization><typedef name="a0"><type><classname>when</classname>&lt; _, A0 &gt;::template result&lt; void(Expr, State, Data)&gt;::type</type></typedef><typedef name="a1"><type><classname>when</classname>&lt; _, A1 &gt;::template result&lt; void(Expr, State, Data)&gt;::type</type></typedef><typedef name="a2"><type><classname>when</classname>&lt; _, A2 &gt;::template result&lt; void(Expr, State, Data)&gt;::type</type></typedef><typedef name="type"><type>boost::result_of&lt; <classname>Fun</classname>(a0, a1, a2)&gt;::type</type></typedef></struct-specialization><method-group name="public member functions"><method name="operator()" cv="const"><type>result&lt; void(Expr, State, Data)&gt;::type</type><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="State"/>
+ <template-type-parameter name="Data"/>
+ </template><parameter name="expr"><paramtype>Expr const &amp;</paramtype><description><para>The current expression </para></description></parameter><parameter name="state"><paramtype>State const &amp;</paramtype><description><para>The current state </para></description></parameter><parameter name="data"><paramtype>Data &amp;</paramtype><description><para>An arbitrary data </para></description></parameter><description><para>Let <computeroutput>x</computeroutput> be <computeroutput>when&lt;_, A0&gt;()(expr, state, data)</computeroutput>. Let <computeroutput>y</computeroutput> be <computeroutput>when&lt;_, A1&gt;()(expr, state, data)</computeroutput>. Let <computeroutput>z</computeroutput> be <computeroutput>when&lt;_, A2&gt;()(expr, state, data)</computeroutput>. Return <computeroutput>Fun()(x, y, z)</computeroutput>.</para><para>
+</para></description></method></method-group></struct-specialization><struct-specialization name="call"><template>
+ <template-type-parameter name="Fun"/>
+ <template-type-parameter name="A0"/>
+ <template-type-parameter name="A1"/>
+ <template-type-parameter name="A2"/>
+ <template-type-parameter name="A3"/>
+ </template><specialization><template-arg>Fun(A0</template-arg><template-arg>A1</template-arg><template-arg>A2</template-arg><template-arg>A3)</template-arg></specialization><inherit access="public">boost::proto::callable</inherit><purpose>Call the PolymorphicFunctionObject <computeroutput>Fun</computeroutput> with the current expression, state and data, transformed according to <computeroutput>A0</computeroutput> through <computeroutput>AN</computeroutput>. </purpose><struct-specialization name="result"><template>
+ <template-type-parameter name="This"/>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="State"/>
+ <template-type-parameter name="Data"/>
+ </template><specialization><template-arg>This(Expr</template-arg><template-arg>State</template-arg><template-arg>Data)</template-arg></specialization><typedef name="a0"><type><classname>when</classname>&lt; _, A0 &gt;::template result&lt; void(Expr, State, Data)&gt;::type</type></typedef><typedef name="a1"><type><classname>when</classname>&lt; _, A1 &gt;::template result&lt; void(Expr, State, Data)&gt;::type</type></typedef><typedef name="a2"><type><classname>when</classname>&lt; _, A2 &gt;::template result&lt; void(Expr, State, Data)&gt;::type</type></typedef><typedef name="a3"><type><classname>when</classname>&lt; _, A3 &gt;::template result&lt; void(Expr, State, Data)&gt;::type</type></typedef><typedef name="type"><type>boost::result_of&lt; <classname>Fun</classname>(a0, a1, a2, a3)&gt;::type</type></typedef></struct-specialization><method-group name="public member functions"><method name="operator()" cv="const"><type>result&lt; void(Expr, State, Data)&gt;::type</type><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="State"/>
+ <template-type-parameter name="Data"/>
+ </template><parameter name="expr"><paramtype>Expr const &amp;</paramtype><description><para>The current expression </para></description></parameter><parameter name="state"><paramtype>State const &amp;</paramtype><description><para>The current state </para></description></parameter><parameter name="data"><paramtype>Data &amp;</paramtype><description><para>An arbitrary data </para></description></parameter><description><para>Let <computeroutput>ax</computeroutput> be <computeroutput>when&lt;_, Ax&gt;()(expr, state, data)</computeroutput> for each <computeroutput>x</computeroutput> in <computeroutput>[0,N]</computeroutput>. Return <computeroutput>Fun()(a0, a1,... aN)</computeroutput>.</para><para>
+</para></description></method></method-group></struct-specialization><struct-specialization name="call"><template>
+ <template-type-parameter name="Fun"/>
+ <template-type-parameter name="A0"/>
+ <template-type-parameter name="A1"/>
+ <template-type-parameter name="A2"/>
+ <template-type-parameter name="A3"/>
+ <template-type-parameter name="A4"/>
+ </template><specialization><template-arg>Fun(A0</template-arg><template-arg>A1</template-arg><template-arg>A2</template-arg><template-arg>A3</template-arg><template-arg>A4)</template-arg></specialization><inherit access="public">boost::proto::callable</inherit><purpose>Call the PolymorphicFunctionObject <computeroutput>Fun</computeroutput> with the current expression, state and data, transformed according to <computeroutput>A0</computeroutput> through <computeroutput>AN</computeroutput>. </purpose><struct-specialization name="result"><template>
+ <template-type-parameter name="This"/>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="State"/>
+ <template-type-parameter name="Data"/>
+ </template><specialization><template-arg>This(Expr</template-arg><template-arg>State</template-arg><template-arg>Data)</template-arg></specialization><typedef name="a0"><type><classname>when</classname>&lt; _, A0 &gt;::template result&lt; void(Expr, State, Data)&gt;::type</type></typedef><typedef name="a1"><type><classname>when</classname>&lt; _, A1 &gt;::template result&lt; void(Expr, State, Data)&gt;::type</type></typedef><typedef name="a2"><type><classname>when</classname>&lt; _, A2 &gt;::template result&lt; void(Expr, State, Data)&gt;::type</type></typedef><typedef name="a3"><type><classname>when</classname>&lt; _, A3 &gt;::template result&lt; void(Expr, State, Data)&gt;::type</type></typedef><typedef name="a4"><type><classname>when</classname>&lt; _, A4 &gt;::template result&lt; void(Expr, State, Data)&gt;::type</type></typedef><typedef name="type"><type>boost::result_of&lt; <classname>Fun</classname>(a0, a1, a2, a3, a4)&gt;::type</type></typedef></struct-specialization><method-group name="public m
ember functions"><method name="operator()" cv="const"><type>result&lt; void(Expr, State, Data)&gt;::type</type><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="State"/>
+ <template-type-parameter name="Data"/>
+ </template><parameter name="expr"><paramtype>Expr const &amp;</paramtype><description><para>The current expression </para></description></parameter><parameter name="state"><paramtype>State const &amp;</paramtype><description><para>The current state </para></description></parameter><parameter name="data"><paramtype>Data &amp;</paramtype><description><para>An arbitrary data </para></description></parameter><description><para>Let <computeroutput>ax</computeroutput> be <computeroutput>when&lt;_, Ax&gt;()(expr, state, data)</computeroutput> for each <computeroutput>x</computeroutput> in <computeroutput>[0,N]</computeroutput>. Return <computeroutput>Fun()(a0, a1,... aN)</computeroutput>.</para><para>
+</para></description></method></method-group></struct-specialization></namespace></namespace></header><header name="boost/proto/transform/fold.hpp"><para>Contains definition of the fold&lt;&gt; and reverse_fold&lt;&gt; transforms. </para><namespace name="boost"><namespace name="proto"><struct name="fold"><template>
+ <template-type-parameter name="Sequence"/>
+ <template-type-parameter name="State0"/>
+ <template-type-parameter name="Fun"/>
+ </template><inherit access="public">boost::proto::callable</inherit><purpose>A PrimitiveTransform that invokes the <computeroutput>fusion::fold&lt;&gt;</computeroutput> algorithm to accumulate. </purpose><struct-specialization name="result"><template>
+ <template-type-parameter name="This"/>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="State"/>
+ <template-type-parameter name="Data"/>
+ </template><specialization><template-arg>This(Expr</template-arg><template-arg>State</template-arg><template-arg>Data)</template-arg></specialization><typedef name="sequence"><purpose>A Fusion sequence. </purpose><type><classname>when</classname>&lt; _, Sequence &gt;::template result&lt; void(Expr, State, Data)&gt;::type</type></typedef><typedef name="state0"><purpose>An initial state for the fold. </purpose><type><classname>when</classname>&lt; _, State0 &gt;::template result&lt; void(Expr, State, Data)&gt;::type</type></typedef><typedef name="fun"><purpose><computeroutput>fun(v)(e,s) == when&lt;_,Fun&gt;()(e,s,v)</computeroutput> </purpose><type><emphasis>unspecified</emphasis></type></typedef><typedef name="type"><type>fusion::result_of::fold&lt; sequence, state0, <classname>fun</classname> &gt;::type</type></typedef></struct-specialization><method-group name="public member functions"><method name="operator()" cv="const"><type>result&lt; void(Expr, State, Data)&gt;::type</type><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="State"/>
+ <template-type-parameter name="Data"/>
+ </template><parameter name="expr"><paramtype>Expr const &amp;</paramtype><description><para>The current expression </para></description></parameter><parameter name="state"><paramtype>State const &amp;</paramtype><description><para>The current state </para></description></parameter><parameter name="data"><paramtype>Data &amp;</paramtype><description><para>An arbitrary data </para></description></parameter><description><para>Let <computeroutput>seq</computeroutput> be <computeroutput>when&lt;_, Sequence&gt;()(expr, state, data)</computeroutput>, let <computeroutput>state0</computeroutput> be <computeroutput>when&lt;_, State0&gt;()(expr, state, data)</computeroutput>, and let <computeroutput>fun(data)</computeroutput> be an object such that <computeroutput>fun(data)(expr, state)</computeroutput> is equivalent to <computeroutput>when&lt;_, Fun&gt;()(expr, state, data)</computeroutput>. Then, this function returns <computeroutput>fusion::fold(seq, state0, fun(data))</computeroutput>.</para><para>
+</para></description></method></method-group></struct><struct name="reverse_fold"><template>
+ <template-type-parameter name="Sequence"/>
+ <template-type-parameter name="State0"/>
+ <template-type-parameter name="Fun"/>
+ </template><inherit access="public">boost::proto::fold&lt; Sequence, State0, Fun &gt;</inherit><purpose>A PrimitiveTransform that is the same as the <computeroutput>fold&lt;&gt;</computeroutput> transform, except that it folds back-to-front instead of front-to-back. It uses the <computeroutput>_reverse</computeroutput> callable PolymorphicFunctionObject to create a <computeroutput>fusion::reverse_view&lt;&gt;</computeroutput> of the sequence before invoking <computeroutput>fusion::fold&lt;&gt;</computeroutput>. </purpose></struct></namespace></namespace></header><header name="boost/proto/transform/fold_tree.hpp"><para>Contains definition of the fold_tree&lt;&gt; and reverse_fold_tree&lt;&gt; transforms. </para><namespace name="boost"><namespace name="proto"><struct name="fold_tree"><template>
+ <template-type-parameter name="Sequence"/>
+ <template-type-parameter name="State0"/>
+ <template-type-parameter name="Fun"/>
+ </template><inherit access="public">boost::proto::callable</inherit><purpose>A PrimitiveTransform that recursively applies the <computeroutput>fold&lt;&gt;</computeroutput> transform to sub-trees that all share a common tag type. </purpose><description><para><computeroutput>fold_tree&lt;&gt;</computeroutput> is useful for flattening trees into lists; for example, you might use <computeroutput>fold_tree&lt;&gt;</computeroutput> to flatten an expression tree like <computeroutput>a | b | c</computeroutput> into a Fusion list like <computeroutput>cons(c, cons(b, cons(a)))</computeroutput>.</para><para><computeroutput>fold_tree&lt;&gt;</computeroutput> is easily understood in terms of a <computeroutput>recurse_if_&lt;&gt;</computeroutput> helper, defined as follows:</para><para><programlisting> template&lt;typename Tag, typename Fun&gt;
+ struct recurse_if_
+ : if_&lt;
+ // If the current node has type type "Tag" ...
+ is_same&lt;tag_of&lt;_&gt;, Tag&gt;()
+ // ... recurse, otherwise ...
+ , fold&lt;_, _state, recurse_if_&lt;Tag, Fun&gt; &gt;
+ // ... apply the Fun transform.
+ , Fun
+ &gt;
+ {};
+</programlisting></para><para>With <computeroutput>recurse_if_&lt;&gt;</computeroutput> as defined above, <computeroutput>fold_tree&lt;Sequence, State0, Fun&gt;()(expr, state, data)</computeroutput> is equivalent to <computeroutput>fold&lt;Sequence, State0, recurse_if_&lt;Expr::proto_tag, Fun&gt; &gt;()(expr, state, data).</computeroutput> It has the effect of folding a tree front-to-back, recursing into child nodes that share a tag type with the parent node. </para></description><struct-specialization name="result"><template>
+ <template-type-parameter name="This"/>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="State"/>
+ <template-type-parameter name="Data"/>
+ </template><specialization><template-arg>This(Expr</template-arg><template-arg>State</template-arg><template-arg>Data)</template-arg></specialization><typedef name="recurse_if_"><purpose><computeroutput>recurse_if_&lt;Expr::proto_tag, Fun&gt;</computeroutput>, as described below. </purpose><type><emphasis>unspecified</emphasis></type></typedef><typedef name="impl"><type><classname>fold</classname>&lt; Sequence, State0, <classname>recurse_if_</classname> &gt;</type></typedef><typedef name="type"><type>impl::template result&lt; void(Expr, State, Data)&gt;::type</type></typedef></struct-specialization><method-group name="public member functions"><method name="operator()" cv="const"><type>result&lt; void(Expr, State, Data)&gt;::type</type><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="State"/>
+ <template-type-parameter name="Data"/>
+ </template><parameter name="expr"><paramtype>Expr const &amp;</paramtype><description><para>The current expression </para></description></parameter><parameter name="state"><paramtype>State const &amp;</paramtype><description><para>The current state </para></description></parameter><parameter name="data"><paramtype>Data &amp;</paramtype><description><para>An arbitrary data </para></description></parameter><description><para>Let <computeroutput>R</computeroutput> be <computeroutput>recurse_if_&lt;Expr::proto_tag,Fun&gt;</computeroutput> as described below. This function returns <computeroutput>fold&lt;Sequence, State0, R&gt;()(expr, state, data)</computeroutput>.</para><para>
+</para></description></method></method-group></struct><struct name="reverse_fold_tree"><template>
+ <template-type-parameter name="Sequence"/>
+ <template-type-parameter name="State0"/>
+ <template-type-parameter name="Fun"/>
+ </template><inherit access="public">boost::proto::callable</inherit><purpose>A PrimitiveTransform that recursively applies the <computeroutput>reverse_fold&lt;&gt;</computeroutput> transform to sub-trees that all share a common tag type. </purpose><description><para><computeroutput>reverse_fold_tree&lt;&gt;</computeroutput> is useful for flattening trees into lists; for example, you might use <computeroutput>reverse_fold_tree&lt;&gt;</computeroutput> to flatten an expression tree like <computeroutput>a | b | c</computeroutput> into a Fusion list like <computeroutput>cons(a, cons(b, cons(c)))</computeroutput>.</para><para><computeroutput>reverse_fold_tree&lt;&gt;</computeroutput> is easily understood in terms of a <computeroutput>recurse_if_&lt;&gt;</computeroutput> helper, defined as follows:</para><para><programlisting> template&lt;typename Tag, typename Fun&gt;
+ struct recurse_if_
+ : if_&lt;
+ // If the current node has type type "Tag" ...
+ is_same&lt;tag_of&lt;_&gt;, Tag&gt;()
+ // ... recurse, otherwise ...
+ , reverse_fold&lt;_, _state, recurse_if_&lt;Tag, Fun&gt; &gt;
+ // ... apply the Fun transform.
+ , Fun
+ &gt;
+ {};
+</programlisting></para><para>With <computeroutput>recurse_if_&lt;&gt;</computeroutput> as defined above, <computeroutput>reverse_fold_tree&lt;Sequence, State0, Fun&gt;()(expr, state, data)</computeroutput> is equivalent to <computeroutput>reverse_fold&lt;Sequence, State0, recurse_if_&lt;Expr::proto_tag, Fun&gt; &gt;()(expr, state, data).</computeroutput> It has the effect of folding a tree back-to-front, recursing into child nodes that share a tag type with the parent node. </para></description><struct-specialization name="result"><template>
+ <template-type-parameter name="This"/>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="State"/>
+ <template-type-parameter name="Data"/>
+ </template><specialization><template-arg>This(Expr</template-arg><template-arg>State</template-arg><template-arg>Data)</template-arg></specialization><typedef name="recurse_if_"><purpose><computeroutput>recurse_if_&lt;Expr::proto_tag, Fun&gt;</computeroutput>, as described below. </purpose><type><emphasis>unspecified</emphasis></type></typedef><typedef name="impl"><type><classname>reverse_fold</classname>&lt; Sequence, State0, <classname>recurse_if_</classname> &gt;</type></typedef><typedef name="type"><type>impl::template result&lt; void(Expr, State, Data)&gt;::type</type></typedef></struct-specialization><method-group name="public member functions"><method name="operator()" cv="const"><type>result&lt; void(Expr, State, Data)&gt;::type</type><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="State"/>
+ <template-type-parameter name="Data"/>
+ </template><parameter name="expr"><paramtype>Expr const &amp;</paramtype><description><para>The current expression </para></description></parameter><parameter name="state"><paramtype>State const &amp;</paramtype><description><para>The current state </para></description></parameter><parameter name="data"><paramtype>Data &amp;</paramtype><description><para>An arbitrary data </para></description></parameter><description><para>Let <computeroutput>R</computeroutput> be <computeroutput>recurse_if_&lt;Expr::proto_tag,Fun&gt;</computeroutput> as described below. This function returns <computeroutput>reverse_fold&lt;Sequence, State0, R&gt;()(expr, state, data)</computeroutput>.</para><para>
+</para></description></method></method-group></struct></namespace></namespace></header><header name="boost/proto/transform/lazy.hpp"><para>Contains definition of the lazy&lt;&gt; transform. </para><namespace name="boost"><namespace name="proto"><struct name="lazy"><template>
+ <template-type-parameter name="Object"/>
+ </template><inherit access="public">boost::proto::callable</inherit><purpose>A PrimitiveTransform that uses <computeroutput>make&lt;&gt;</computeroutput> to build a CallableTransform, and then uses <computeroutput>call&lt;&gt;</computeroutput> to apply it. </purpose><description><para><computeroutput>lazy&lt;&gt;</computeroutput> is useful as a higher-order transform, when the transform to be applied depends on the current state of the transformation. The invocation of the <computeroutput>make&lt;&gt;</computeroutput> transform evaluates any nested transforms, and the resulting type is treated as a CallableTransform, which is evaluated with <computeroutput>call&lt;&gt;</computeroutput>. </para></description><struct-specialization name="result"><template>
+ <template-type-parameter name="This"/>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="State"/>
+ <template-type-parameter name="Data"/>
+ </template><specialization><template-arg>This(Expr</template-arg><template-arg>State</template-arg><template-arg>Data)</template-arg></specialization><typedef name="fun"><type><classname>make</classname>&lt; Object &gt;::template result&lt; void(Expr, State, Data)&gt;::type</type></typedef><typedef name="impl"><type><classname>call</classname>&lt; fun &gt;</type></typedef><typedef name="type"><type>impl::template result&lt; void(Expr, State, Data)&gt;::type</type></typedef></struct-specialization><method-group name="public member functions"><method name="operator()" cv="const"><type>result&lt; void(Expr, State, Data)&gt;::type</type><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="State"/>
+ <template-type-parameter name="Data"/>
+ </template><parameter name="expr"><paramtype>Expr const &amp;</paramtype><description><para>The current expression </para></description></parameter><parameter name="state"><paramtype>State const &amp;</paramtype><description><para>The current state </para></description></parameter><parameter name="data"><paramtype>Data &amp;</paramtype><description><para>An arbitrary data </para></description></parameter><description><para>Build a CallableTransform by applying <computeroutput>make&lt;&gt;</computeroutput> and evaluate it with <computeroutput>call&lt;&gt;</computeroutput></para><para>
+
+</para></description><returns><para><computeroutput>result&lt;void(Expr, State, Data)&gt;::impl()(expr, state, data)</computeroutput> </para></returns></method></method-group></struct><struct-specialization name="lazy"><template>
+ <template-type-parameter name="Object"/>
+ </template><specialization><template-arg>Object()</template-arg></specialization><inherit access="public">boost::proto::callable</inherit><purpose>A PrimitiveTransform that uses <computeroutput>make&lt;&gt;</computeroutput> to build a CallableTransform, and then uses <computeroutput>call&lt;&gt;</computeroutput> to apply it. </purpose><description><para><computeroutput>lazy&lt;&gt;</computeroutput> is useful as a higher-order transform, when the transform to be applied depends on the current state of the transformation. The invocation of the <computeroutput>make&lt;&gt;</computeroutput> transform evaluates any nested transforms, and the resulting type is treated as a CallableTransform, which is evaluated with <computeroutput>call&lt;&gt;</computeroutput>. </para></description><struct-specialization name="result"><template>
+ <template-type-parameter name="This"/>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="State"/>
+ <template-type-parameter name="Data"/>
+ </template><specialization><template-arg>This(Expr</template-arg><template-arg>State</template-arg><template-arg>Data)</template-arg></specialization><typedef name="fun"><type><classname>make</classname>&lt; Object &gt;::template result&lt; void(Expr, State, Data)&gt;::type</type></typedef><typedef name="impl"><type><classname>call</classname>&lt; fun()&gt;</type></typedef><typedef name="type"><type>impl::template result&lt; void(Expr, State, Data)&gt;::type</type></typedef></struct-specialization><method-group name="public member functions"><method name="operator()" cv="const"><type>result&lt; void(Expr, State, Data)&gt;::type</type><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="State"/>
+ <template-type-parameter name="Data"/>
+ </template><parameter name="expr"><paramtype>Expr const &amp;</paramtype><description><para>The current expression </para></description></parameter><parameter name="state"><paramtype>State const &amp;</paramtype><description><para>The current state </para></description></parameter><parameter name="data"><paramtype>Data &amp;</paramtype><description><para>An arbitrary data </para></description></parameter><description><para>Build a CallableTransform by applying <computeroutput>make&lt;&gt;</computeroutput> and evaluate it with <computeroutput>call&lt;&gt;</computeroutput></para><para>
+
+</para></description><returns><para><computeroutput>result&lt;void(Expr, State, Data)&gt;::impl()(expr, state, data)</computeroutput> </para></returns></method></method-group></struct-specialization><struct-specialization name="lazy"><template>
+ <template-type-parameter name="Object"/>
+ <template-type-parameter name="A0"/>
+ </template><specialization><template-arg>Object(A0)</template-arg></specialization><inherit access="public">boost::proto::callable</inherit><purpose>A PrimitiveTransform that uses <computeroutput>make&lt;&gt;</computeroutput> to build a CallableTransform, and then uses <computeroutput>call&lt;&gt;</computeroutput> to apply it. </purpose><description><para><computeroutput>lazy&lt;&gt;</computeroutput> is useful as a higher-order transform, when the transform to be applied depends on the current state of the transformation. The invocation of the <computeroutput>make&lt;&gt;</computeroutput> transform evaluates any nested transforms, and the resulting type is treated as a CallableTransform, which is evaluated with <computeroutput>call&lt;&gt;</computeroutput>. </para></description><struct-specialization name="result"><template>
+ <template-type-parameter name="This"/>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="State"/>
+ <template-type-parameter name="Data"/>
+ </template><specialization><template-arg>This(Expr</template-arg><template-arg>State</template-arg><template-arg>Data)</template-arg></specialization><typedef name="fun"><type><classname>make</classname>&lt; Object &gt;::template result&lt; void(Expr, State, Data)&gt;::type</type></typedef><typedef name="impl"><type><classname>call</classname>&lt; fun(A0)&gt;</type></typedef><typedef name="type"><type>impl::template result&lt; void(Expr, State, Data)&gt;::type</type></typedef></struct-specialization><method-group name="public member functions"><method name="operator()" cv="const"><type>result&lt; void(Expr, State, Data)&gt;::type</type><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="State"/>
+ <template-type-parameter name="Data"/>
+ </template><parameter name="expr"><paramtype>Expr const &amp;</paramtype><description><para>The current expression </para></description></parameter><parameter name="state"><paramtype>State const &amp;</paramtype><description><para>The current state </para></description></parameter><parameter name="data"><paramtype>Data &amp;</paramtype><description><para>An arbitrary data </para></description></parameter><description><para>Build a CallableTransform by applying <computeroutput>make&lt;&gt;</computeroutput> and evaluate it with <computeroutput>call&lt;&gt;</computeroutput></para><para>
+
+</para></description><returns><para><computeroutput>result&lt;void(Expr, State, Data)&gt;::impl()(expr, state, data)</computeroutput> </para></returns></method></method-group></struct-specialization><struct-specialization name="lazy"><template>
+ <template-type-parameter name="Object"/>
+ <template-type-parameter name="A0"/>
+ <template-type-parameter name="A1"/>
+ </template><specialization><template-arg>Object(A0</template-arg><template-arg>A1)</template-arg></specialization><inherit access="public">boost::proto::callable</inherit><purpose>A PrimitiveTransform that uses <computeroutput>make&lt;&gt;</computeroutput> to build a CallableTransform, and then uses <computeroutput>call&lt;&gt;</computeroutput> to apply it. </purpose><description><para><computeroutput>lazy&lt;&gt;</computeroutput> is useful as a higher-order transform, when the transform to be applied depends on the current state of the transformation. The invocation of the <computeroutput>make&lt;&gt;</computeroutput> transform evaluates any nested transforms, and the resulting type is treated as a CallableTransform, which is evaluated with <computeroutput>call&lt;&gt;</computeroutput>. </para></description><struct-specialization name="result"><template>
+ <template-type-parameter name="This"/>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="State"/>
+ <template-type-parameter name="Data"/>
+ </template><specialization><template-arg>This(Expr</template-arg><template-arg>State</template-arg><template-arg>Data)</template-arg></specialization><typedef name="fun"><type><classname>make</classname>&lt; Object &gt;::template result&lt; void(Expr, State, Data)&gt;::type</type></typedef><typedef name="impl"><type><classname>call</classname>&lt; fun(A0, A1)&gt;</type></typedef><typedef name="type"><type>impl::template result&lt; void(Expr, State, Data)&gt;::type</type></typedef></struct-specialization><method-group name="public member functions"><method name="operator()" cv="const"><type>result&lt; void(Expr, State, Data)&gt;::type</type><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="State"/>
+ <template-type-parameter name="Data"/>
+ </template><parameter name="expr"><paramtype>Expr const &amp;</paramtype><description><para>The current expression </para></description></parameter><parameter name="state"><paramtype>State const &amp;</paramtype><description><para>The current state </para></description></parameter><parameter name="data"><paramtype>Data &amp;</paramtype><description><para>An arbitrary data </para></description></parameter><description><para>Build a CallableTransform by applying <computeroutput>make&lt;&gt;</computeroutput> and evaluate it with <computeroutput>call&lt;&gt;</computeroutput></para><para>
+
+</para></description><returns><para><computeroutput>result&lt;void(Expr, State, Data)&gt;::impl()(expr, state, data)</computeroutput> </para></returns></method></method-group></struct-specialization><struct-specialization name="lazy"><template>
+ <template-type-parameter name="Object"/>
+ <template-type-parameter name="A0"/>
+ <template-type-parameter name="A1"/>
+ <template-type-parameter name="A2"/>
+ </template><specialization><template-arg>Object(A0</template-arg><template-arg>A1</template-arg><template-arg>A2)</template-arg></specialization><inherit access="public">boost::proto::callable</inherit><purpose>A PrimitiveTransform that uses <computeroutput>make&lt;&gt;</computeroutput> to build a CallableTransform, and then uses <computeroutput>call&lt;&gt;</computeroutput> to apply it. </purpose><description><para><computeroutput>lazy&lt;&gt;</computeroutput> is useful as a higher-order transform, when the transform to be applied depends on the current state of the transformation. The invocation of the <computeroutput>make&lt;&gt;</computeroutput> transform evaluates any nested transforms, and the resulting type is treated as a CallableTransform, which is evaluated with <computeroutput>call&lt;&gt;</computeroutput>. </para></description><struct-specialization name="result"><template>
+ <template-type-parameter name="This"/>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="State"/>
+ <template-type-parameter name="Data"/>
+ </template><specialization><template-arg>This(Expr</template-arg><template-arg>State</template-arg><template-arg>Data)</template-arg></specialization><typedef name="fun"><type><classname>make</classname>&lt; Object &gt;::template result&lt; void(Expr, State, Data)&gt;::type</type></typedef><typedef name="impl"><type><classname>call</classname>&lt; fun(A0, A1, A2)&gt;</type></typedef><typedef name="type"><type>impl::template result&lt; void(Expr, State, Data)&gt;::type</type></typedef></struct-specialization><method-group name="public member functions"><method name="operator()" cv="const"><type>result&lt; void(Expr, State, Data)&gt;::type</type><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="State"/>
+ <template-type-parameter name="Data"/>
+ </template><parameter name="expr"><paramtype>Expr const &amp;</paramtype><description><para>The current expression </para></description></parameter><parameter name="state"><paramtype>State const &amp;</paramtype><description><para>The current state </para></description></parameter><parameter name="data"><paramtype>Data &amp;</paramtype><description><para>An arbitrary data </para></description></parameter><description><para>Build a CallableTransform by applying <computeroutput>make&lt;&gt;</computeroutput> and evaluate it with <computeroutput>call&lt;&gt;</computeroutput></para><para>
+
+</para></description><returns><para><computeroutput>result&lt;void(Expr, State, Data)&gt;::impl()(expr, state, data)</computeroutput> </para></returns></method></method-group></struct-specialization><struct-specialization name="lazy"><template>
+ <template-type-parameter name="Object"/>
+ <template-type-parameter name="A0"/>
+ <template-type-parameter name="A1"/>
+ <template-type-parameter name="A2"/>
+ <template-type-parameter name="A3"/>
+ </template><specialization><template-arg>Object(A0</template-arg><template-arg>A1</template-arg><template-arg>A2</template-arg><template-arg>A3)</template-arg></specialization><inherit access="public">boost::proto::callable</inherit><purpose>A PrimitiveTransform that uses <computeroutput>make&lt;&gt;</computeroutput> to build a CallableTransform, and then uses <computeroutput>call&lt;&gt;</computeroutput> to apply it. </purpose><description><para><computeroutput>lazy&lt;&gt;</computeroutput> is useful as a higher-order transform, when the transform to be applied depends on the current state of the transformation. The invocation of the <computeroutput>make&lt;&gt;</computeroutput> transform evaluates any nested transforms, and the resulting type is treated as a CallableTransform, which is evaluated with <computeroutput>call&lt;&gt;</computeroutput>. </para></description><struct-specialization name="result"><template>
+ <template-type-parameter name="This"/>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="State"/>
+ <template-type-parameter name="Data"/>
+ </template><specialization><template-arg>This(Expr</template-arg><template-arg>State</template-arg><template-arg>Data)</template-arg></specialization><typedef name="fun"><type><classname>make</classname>&lt; Object &gt;::template result&lt; void(Expr, State, Data)&gt;::type</type></typedef><typedef name="impl"><type><classname>call</classname>&lt; fun(A0, A1, A2, A3)&gt;</type></typedef><typedef name="type"><type>impl::template result&lt; void(Expr, State, Data)&gt;::type</type></typedef></struct-specialization><method-group name="public member functions"><method name="operator()" cv="const"><type>result&lt; void(Expr, State, Data)&gt;::type</type><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="State"/>
+ <template-type-parameter name="Data"/>
+ </template><parameter name="expr"><paramtype>Expr const &amp;</paramtype><description><para>The current expression </para></description></parameter><parameter name="state"><paramtype>State const &amp;</paramtype><description><para>The current state </para></description></parameter><parameter name="data"><paramtype>Data &amp;</paramtype><description><para>An arbitrary data </para></description></parameter><description><para>Build a CallableTransform by applying <computeroutput>make&lt;&gt;</computeroutput> and evaluate it with <computeroutput>call&lt;&gt;</computeroutput></para><para>
+
+</para></description><returns><para><computeroutput>result&lt;void(Expr, State, Data)&gt;::impl()(expr, state, data)</computeroutput> </para></returns></method></method-group></struct-specialization><struct-specialization name="lazy"><template>
+ <template-type-parameter name="Object"/>
+ <template-type-parameter name="A0"/>
+ <template-type-parameter name="A1"/>
+ <template-type-parameter name="A2"/>
+ <template-type-parameter name="A3"/>
+ <template-type-parameter name="A4"/>
+ </template><specialization><template-arg>Object(A0</template-arg><template-arg>A1</template-arg><template-arg>A2</template-arg><template-arg>A3</template-arg><template-arg>A4)</template-arg></specialization><inherit access="public">boost::proto::callable</inherit><purpose>A PrimitiveTransform that uses <computeroutput>make&lt;&gt;</computeroutput> to build a CallableTransform, and then uses <computeroutput>call&lt;&gt;</computeroutput> to apply it. </purpose><description><para><computeroutput>lazy&lt;&gt;</computeroutput> is useful as a higher-order transform, when the transform to be applied depends on the current state of the transformation. The invocation of the <computeroutput>make&lt;&gt;</computeroutput> transform evaluates any nested transforms, and the resulting type is treated as a CallableTransform, which is evaluated with <computeroutput>call&lt;&gt;</computeroutput>. </para></description><struct-specialization name="result"><template>
+ <template-type-parameter name="This"/>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="State"/>
+ <template-type-parameter name="Data"/>
+ </template><specialization><template-arg>This(Expr</template-arg><template-arg>State</template-arg><template-arg>Data)</template-arg></specialization><typedef name="fun"><type><classname>make</classname>&lt; Object &gt;::template result&lt; void(Expr, State, Data)&gt;::type</type></typedef><typedef name="impl"><type><classname>call</classname>&lt; fun(A0, A1, A2, A3, A4)&gt;</type></typedef><typedef name="type"><type>impl::template result&lt; void(Expr, State, Data)&gt;::type</type></typedef></struct-specialization><method-group name="public member functions"><method name="operator()" cv="const"><type>result&lt; void(Expr, State, Data)&gt;::type</type><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="State"/>
+ <template-type-parameter name="Data"/>
+ </template><parameter name="expr"><paramtype>Expr const &amp;</paramtype><description><para>The current expression </para></description></parameter><parameter name="state"><paramtype>State const &amp;</paramtype><description><para>The current state </para></description></parameter><parameter name="data"><paramtype>Data &amp;</paramtype><description><para>An arbitrary data </para></description></parameter><description><para>Build a CallableTransform by applying <computeroutput>make&lt;&gt;</computeroutput> and evaluate it with <computeroutput>call&lt;&gt;</computeroutput></para><para>
+
+</para></description><returns><para><computeroutput>result&lt;void(Expr, State, Data)&gt;::impl()(expr, state, data)</computeroutput> </para></returns></method></method-group></struct-specialization></namespace></namespace></header><header name="boost/proto/transform/make.hpp"><para>Contains definition of the make&lt;&gt; transform. </para><namespace name="boost"><namespace name="proto"><struct name="make"><template>
+ <template-type-parameter name="Object"/>
+ </template><inherit access="public">boost::proto::callable</inherit><purpose>A PrimitiveTransform which computes a type by evaluating any nested transforms and then constructs an object of that type. </purpose><description><para>The <computeroutput>make&lt;&gt;</computeroutput> transform checks to see if <computeroutput>Object</computeroutput> is a template. If it is, the template type is disassembled to find nested transforms. Proto considers the following types to represent transforms:</para><para><itemizedlist>
+<listitem><para>Function types </para></listitem>
+<listitem><para>Function pointer types </para></listitem>
+<listitem><para>Types for which <computeroutput>proto::is_callable&lt; type &gt;::value</computeroutput> is <computeroutput>true</computeroutput> </para></listitem>
+</itemizedlist>
+<computeroutput>make&lt;T&lt;X0,X1,...&gt; &gt;::result&lt;void(Expr, State, Data)&gt;::type</computeroutput> is evaluated as follows. For each <computeroutput>X</computeroutput> in <computeroutput>X0,X1,...</computeroutput>, do:</para><para><itemizedlist>
+<listitem><para>If <computeroutput>X</computeroutput> is a template like <computeroutput>U&lt;Y0,Y1,...&gt;</computeroutput>, then let <computeroutput>X'</computeroutput> be <computeroutput>make&lt;U&lt;Y0,Y1,...&gt; &gt;::result&lt;void(Expr, State, Data)&gt;::type</computeroutput> (which evaluates this procedure recursively). Note whether any substitutions took place during this operation. </para></listitem>
+<listitem><para>Otherwise, if <computeroutput>X</computeroutput> is a transform, then let <computeroutput>X'</computeroutput> be <computeroutput>when&lt;_, X&gt;::result&lt;void(Expr, State, Data)&gt;::type</computeroutput>. Note that a substitution took place. </para></listitem>
+<listitem><para>Otherwise, let <computeroutput>X'</computeroutput> be <computeroutput>X</computeroutput>, and note that no substitution took place. </para></listitem>
+<listitem><para>If any substitutions took place in any of the above steps and <computeroutput>T&lt;X0',X1',...&gt;</computeroutput> has a nested <computeroutput>type</computeroutput> typedef, the result type is <computeroutput>T&lt;X0',X1',...&gt;::type</computeroutput>. </para></listitem>
+<listitem><para>Otherwise, the result type is <computeroutput>T&lt;X0',X1',...&gt;</computeroutput>.</para></listitem>
+</itemizedlist>
+Note that <computeroutput>when&lt;&gt;</computeroutput> is implemented in terms of <computeroutput>call&lt;&gt;</computeroutput> and <computeroutput>make&lt;&gt;</computeroutput>, so the above procedure is evaluated recursively. </para></description><struct-specialization name="result"><template>
+ <template-type-parameter name="This"/>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="State"/>
+ <template-type-parameter name="Data"/>
+ </template><specialization><template-arg>This(Expr</template-arg><template-arg>State</template-arg><template-arg>Data)</template-arg></specialization><typedef name="type"><type><emphasis>unspecified</emphasis></type></typedef></struct-specialization><method-group name="public member functions"><method name="operator()" cv="const"><type>result&lt; void(Expr, State, Data)&gt;::type</type><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="State"/>
+ <template-type-parameter name="Data"/>
+ </template><parameter name=""><paramtype>Expr const &amp;</paramtype></parameter><parameter name=""><paramtype>State const &amp;</paramtype></parameter><parameter name=""><paramtype>Data &amp;</paramtype></parameter><description><para>
+
+</para></description><returns><para><computeroutput>result&lt;void(Expr, State, Data)&gt;::type()</computeroutput> </para></returns></method></method-group></struct><struct-specialization name="make"><template>
+ <template-type-parameter name="Object"/>
+ </template><specialization><template-arg>Object()</template-arg></specialization><inherit access="public">boost::proto::callable</inherit><purpose>A PrimitiveTransform which computes a type by evaluating any nested transforms and then constructs an object of that type with the current expression, state and data, transformed according to <computeroutput>A0</computeroutput> through <computeroutput>AN</computeroutput>. </purpose><struct-specialization name="result"><template>
+ <template-type-parameter name="This"/>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="State"/>
+ <template-type-parameter name="Data"/>
+ </template><specialization><template-arg>This(Expr</template-arg><template-arg>State</template-arg><template-arg>Data)</template-arg></specialization><typedef name="type"><purpose><computeroutput>make&lt;Object&gt;::result&lt;void(Expr, State, Data)&gt;::type</computeroutput> </purpose><type><emphasis>unspecified</emphasis></type></typedef></struct-specialization><method-group name="public member functions"><method name="operator()" cv="const"><type>result&lt; void(Expr, State, Data)&gt;::type</type><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="State"/>
+ <template-type-parameter name="Data"/>
+ </template><parameter name="expr"><paramtype>Expr const &amp;</paramtype><description><para>The current expression </para></description></parameter><parameter name="state"><paramtype>State const &amp;</paramtype><description><para>The current state </para></description></parameter><parameter name="data"><paramtype>Data &amp;</paramtype><description><para>An arbitrary data </para></description></parameter><description><para>Let <computeroutput>ax</computeroutput> be <computeroutput>when&lt;_, Ax&gt;()(expr, state, data)</computeroutput> for each <computeroutput>x</computeroutput> in <computeroutput>[0,N]</computeroutput>. Let <computeroutput>T</computeroutput> be <computeroutput>result&lt;void(Expr, State, Data)&gt;::type</computeroutput>. Return <computeroutput>T(a0, a1,... aN)</computeroutput>.</para><para>
+</para></description></method></method-group></struct-specialization><struct-specialization name="make"><template>
+ <template-type-parameter name="Object"/>
+ <template-type-parameter name="A0"/>
+ </template><specialization><template-arg>Object(A0)</template-arg></specialization><inherit access="public">boost::proto::callable</inherit><purpose>A PrimitiveTransform which computes a type by evaluating any nested transforms and then constructs an object of that type with the current expression, state and data, transformed according to <computeroutput>A0</computeroutput> through <computeroutput>AN</computeroutput>. </purpose><struct-specialization name="result"><template>
+ <template-type-parameter name="This"/>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="State"/>
+ <template-type-parameter name="Data"/>
+ </template><specialization><template-arg>This(Expr</template-arg><template-arg>State</template-arg><template-arg>Data)</template-arg></specialization><typedef name="type"><purpose><computeroutput>make&lt;Object&gt;::result&lt;void(Expr, State, Data)&gt;::type</computeroutput> </purpose><type><emphasis>unspecified</emphasis></type></typedef></struct-specialization><method-group name="public member functions"><method name="operator()" cv="const"><type>result&lt; void(Expr, State, Data)&gt;::type</type><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="State"/>
+ <template-type-parameter name="Data"/>
+ </template><parameter name="expr"><paramtype>Expr const &amp;</paramtype><description><para>The current expression </para></description></parameter><parameter name="state"><paramtype>State const &amp;</paramtype><description><para>The current state </para></description></parameter><parameter name="data"><paramtype>Data &amp;</paramtype><description><para>An arbitrary data </para></description></parameter><description><para>Let <computeroutput>ax</computeroutput> be <computeroutput>when&lt;_, Ax&gt;()(expr, state, data)</computeroutput> for each <computeroutput>x</computeroutput> in <computeroutput>[0,N]</computeroutput>. Let <computeroutput>T</computeroutput> be <computeroutput>result&lt;void(Expr, State, Data)&gt;::type</computeroutput>. Return <computeroutput>T(a0, a1,... aN)</computeroutput>.</para><para>
+</para></description></method></method-group></struct-specialization><struct-specialization name="make"><template>
+ <template-type-parameter name="Object"/>
+ <template-type-parameter name="A0"/>
+ <template-type-parameter name="A1"/>
+ </template><specialization><template-arg>Object(A0</template-arg><template-arg>A1)</template-arg></specialization><inherit access="public">boost::proto::callable</inherit><purpose>A PrimitiveTransform which computes a type by evaluating any nested transforms and then constructs an object of that type with the current expression, state and data, transformed according to <computeroutput>A0</computeroutput> through <computeroutput>AN</computeroutput>. </purpose><struct-specialization name="result"><template>
+ <template-type-parameter name="This"/>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="State"/>
+ <template-type-parameter name="Data"/>
+ </template><specialization><template-arg>This(Expr</template-arg><template-arg>State</template-arg><template-arg>Data)</template-arg></specialization><typedef name="type"><purpose><computeroutput>make&lt;Object&gt;::result&lt;void(Expr, State, Data)&gt;::type</computeroutput> </purpose><type><emphasis>unspecified</emphasis></type></typedef></struct-specialization><method-group name="public member functions"><method name="operator()" cv="const"><type>result&lt; void(Expr, State, Data)&gt;::type</type><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="State"/>
+ <template-type-parameter name="Data"/>
+ </template><parameter name="expr"><paramtype>Expr const &amp;</paramtype><description><para>The current expression </para></description></parameter><parameter name="state"><paramtype>State const &amp;</paramtype><description><para>The current state </para></description></parameter><parameter name="data"><paramtype>Data &amp;</paramtype><description><para>An arbitrary data </para></description></parameter><description><para>Let <computeroutput>ax</computeroutput> be <computeroutput>when&lt;_, Ax&gt;()(expr, state, data)</computeroutput> for each <computeroutput>x</computeroutput> in <computeroutput>[0,N]</computeroutput>. Let <computeroutput>T</computeroutput> be <computeroutput>result&lt;void(Expr, State, Data)&gt;::type</computeroutput>. Return <computeroutput>T(a0, a1,... aN)</computeroutput>.</para><para>
+</para></description></method></method-group></struct-specialization><struct-specialization name="make"><template>
+ <template-type-parameter name="Object"/>
+ <template-type-parameter name="A0"/>
+ <template-type-parameter name="A1"/>
+ <template-type-parameter name="A2"/>
+ </template><specialization><template-arg>Object(A0</template-arg><template-arg>A1</template-arg><template-arg>A2)</template-arg></specialization><inherit access="public">boost::proto::callable</inherit><purpose>A PrimitiveTransform which computes a type by evaluating any nested transforms and then constructs an object of that type with the current expression, state and data, transformed according to <computeroutput>A0</computeroutput> through <computeroutput>AN</computeroutput>. </purpose><struct-specialization name="result"><template>
+ <template-type-parameter name="This"/>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="State"/>
+ <template-type-parameter name="Data"/>
+ </template><specialization><template-arg>This(Expr</template-arg><template-arg>State</template-arg><template-arg>Data)</template-arg></specialization><typedef name="type"><purpose><computeroutput>make&lt;Object&gt;::result&lt;void(Expr, State, Data)&gt;::type</computeroutput> </purpose><type><emphasis>unspecified</emphasis></type></typedef></struct-specialization><method-group name="public member functions"><method name="operator()" cv="const"><type>result&lt; void(Expr, State, Data)&gt;::type</type><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="State"/>
+ <template-type-parameter name="Data"/>
+ </template><parameter name="expr"><paramtype>Expr const &amp;</paramtype><description><para>The current expression </para></description></parameter><parameter name="state"><paramtype>State const &amp;</paramtype><description><para>The current state </para></description></parameter><parameter name="data"><paramtype>Data &amp;</paramtype><description><para>An arbitrary data </para></description></parameter><description><para>Let <computeroutput>ax</computeroutput> be <computeroutput>when&lt;_, Ax&gt;()(expr, state, data)</computeroutput> for each <computeroutput>x</computeroutput> in <computeroutput>[0,N]</computeroutput>. Let <computeroutput>T</computeroutput> be <computeroutput>result&lt;void(Expr, State, Data)&gt;::type</computeroutput>. Return <computeroutput>T(a0, a1,... aN)</computeroutput>.</para><para>
+</para></description></method></method-group></struct-specialization><struct-specialization name="make"><template>
+ <template-type-parameter name="Object"/>
+ <template-type-parameter name="A0"/>
+ <template-type-parameter name="A1"/>
+ <template-type-parameter name="A2"/>
+ <template-type-parameter name="A3"/>
+ </template><specialization><template-arg>Object(A0</template-arg><template-arg>A1</template-arg><template-arg>A2</template-arg><template-arg>A3)</template-arg></specialization><inherit access="public">boost::proto::callable</inherit><purpose>A PrimitiveTransform which computes a type by evaluating any nested transforms and then constructs an object of that type with the current expression, state and data, transformed according to <computeroutput>A0</computeroutput> through <computeroutput>AN</computeroutput>. </purpose><struct-specialization name="result"><template>
+ <template-type-parameter name="This"/>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="State"/>
+ <template-type-parameter name="Data"/>
+ </template><specialization><template-arg>This(Expr</template-arg><template-arg>State</template-arg><template-arg>Data)</template-arg></specialization><typedef name="type"><purpose><computeroutput>make&lt;Object&gt;::result&lt;void(Expr, State, Data)&gt;::type</computeroutput> </purpose><type><emphasis>unspecified</emphasis></type></typedef></struct-specialization><method-group name="public member functions"><method name="operator()" cv="const"><type>result&lt; void(Expr, State, Data)&gt;::type</type><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="State"/>
+ <template-type-parameter name="Data"/>
+ </template><parameter name="expr"><paramtype>Expr const &amp;</paramtype><description><para>The current expression </para></description></parameter><parameter name="state"><paramtype>State const &amp;</paramtype><description><para>The current state </para></description></parameter><parameter name="data"><paramtype>Data &amp;</paramtype><description><para>An arbitrary data </para></description></parameter><description><para>Let <computeroutput>ax</computeroutput> be <computeroutput>when&lt;_, Ax&gt;()(expr, state, data)</computeroutput> for each <computeroutput>x</computeroutput> in <computeroutput>[0,N]</computeroutput>. Let <computeroutput>T</computeroutput> be <computeroutput>result&lt;void(Expr, State, Data)&gt;::type</computeroutput>. Return <computeroutput>T(a0, a1,... aN)</computeroutput>.</para><para>
+</para></description></method></method-group></struct-specialization><struct-specialization name="make"><template>
+ <template-type-parameter name="Object"/>
+ <template-type-parameter name="A0"/>
+ <template-type-parameter name="A1"/>
+ <template-type-parameter name="A2"/>
+ <template-type-parameter name="A3"/>
+ <template-type-parameter name="A4"/>
+ </template><specialization><template-arg>Object(A0</template-arg><template-arg>A1</template-arg><template-arg>A2</template-arg><template-arg>A3</template-arg><template-arg>A4)</template-arg></specialization><inherit access="public">boost::proto::callable</inherit><purpose>A PrimitiveTransform which computes a type by evaluating any nested transforms and then constructs an object of that type with the current expression, state and data, transformed according to <computeroutput>A0</computeroutput> through <computeroutput>AN</computeroutput>. </purpose><struct-specialization name="result"><template>
+ <template-type-parameter name="This"/>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="State"/>
+ <template-type-parameter name="Data"/>
+ </template><specialization><template-arg>This(Expr</template-arg><template-arg>State</template-arg><template-arg>Data)</template-arg></specialization><typedef name="type"><purpose><computeroutput>make&lt;Object&gt;::result&lt;void(Expr, State, Data)&gt;::type</computeroutput> </purpose><type><emphasis>unspecified</emphasis></type></typedef></struct-specialization><method-group name="public member functions"><method name="operator()" cv="const"><type>result&lt; void(Expr, State, Data)&gt;::type</type><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="State"/>
+ <template-type-parameter name="Data"/>
+ </template><parameter name="expr"><paramtype>Expr const &amp;</paramtype><description><para>The current expression </para></description></parameter><parameter name="state"><paramtype>State const &amp;</paramtype><description><para>The current state </para></description></parameter><parameter name="data"><paramtype>Data &amp;</paramtype><description><para>An arbitrary data </para></description></parameter><description><para>Let <computeroutput>ax</computeroutput> be <computeroutput>when&lt;_, Ax&gt;()(expr, state, data)</computeroutput> for each <computeroutput>x</computeroutput> in <computeroutput>[0,N]</computeroutput>. Let <computeroutput>T</computeroutput> be <computeroutput>result&lt;void(Expr, State, Data)&gt;::type</computeroutput>. Return <computeroutput>T(a0, a1,... aN)</computeroutput>.</para><para>
+</para></description></method></method-group></struct-specialization></namespace></namespace></header><header name="boost/proto/transform/pass_through.hpp"><para>Definition of the pass_through transform, which is the default transform of all of the expression generator metafunctions such as unary_plus&lt;&gt;, plus&lt;&gt; and nary_expr&lt;&gt;. </para><namespace name="boost"><namespace name="proto"><struct name="pass_through"><template>
+ <template-type-parameter name="Grammar"/>
+ </template><inherit access="public">boost::proto::callable</inherit><purpose>A PrimitiveTransform that transforms the child expressions of an expression node according to the corresponding children of a Grammar. </purpose><description><para>Given a Grammar such as <computeroutput>plus&lt;T0, T1&gt;</computeroutput>, an expression type that matches the grammar such as <computeroutput>plus&lt;E0, E1&gt;::type</computeroutput>, a state <computeroutput>S</computeroutput> and a data <computeroutput>V</computeroutput>, the result of applying the <computeroutput>pass_through&lt;plus&lt;T0, T1&gt; &gt;</computeroutput> transform is:</para><para><programlisting> plus&lt;
+ T0::result&lt;void(E0, S, V)&gt;::type
+ , T1::result&lt;void(E1, S, V)&gt;::type
+ &gt;::type
+</programlisting></para><para>The above demonstrates how child transforms and child expressions are applied pairwise, and how the results are reassembled into a new expression node with the same tag type as the original.</para><para>The explicit use of <computeroutput>pass_through&lt;&gt;</computeroutput> is not usually needed, since the expression generator metafunctions such as <computeroutput>plus&lt;&gt;</computeroutput> have <computeroutput>pass_through&lt;&gt;</computeroutput> as their default transform. So, for instance, these are equivalent:</para><para><programlisting> // Within a grammar definition, these are equivalent:
+ when&lt; plus&lt;X, Y&gt;, pass_through&lt; plus&lt;X, Y&gt; &gt; &gt;
+ when&lt; plus&lt;X, Y&gt;, plus&lt;X, Y&gt; &gt;
+ when&lt; plus&lt;X, Y&gt; &gt; // because of when&lt;class X, class Y=X&gt;
+ plus&lt;X, Y&gt; // because plus&lt;&gt; is both a
+ // grammar and a transform
+</programlisting></para><para>For example, consider the following transform that promotes all <computeroutput>float</computeroutput> terminals in an expression to <computeroutput>double</computeroutput>.</para><para><programlisting> // This transform finds all float terminals in an expression and promotes
+ // them to doubles.
+ struct Promote
+ : or_&lt;
+ when&lt;terminal&lt;float&gt;, terminal&lt;double&gt;::type(_value) &gt;
+ // terminal&lt;&gt;'s default transform is a no-op:
+ , terminal&lt;_&gt;
+ // nary_expr&lt;&gt; has a pass_through&lt;&gt; transform:
+ , nary_expr&lt;_, vararg&lt;Promote&gt; &gt;
+ &gt;
+ {};
+</programlisting> </para></description><struct-specialization name="result"><template>
+ <template-type-parameter name="This"/>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="State"/>
+ <template-type-parameter name="Data"/>
+ </template><specialization><template-arg>This(Expr</template-arg><template-arg>State</template-arg><template-arg>Data)</template-arg></specialization><typedef name="impl"><type><emphasis>unspecified</emphasis></type></typedef><typedef name="type"><type>impl::type</type></typedef></struct-specialization><method-group name="public member functions"><method name="operator()" cv="const"><type>result&lt; void(Expr, State, Data)&gt;::type</type><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="State"/>
+ <template-type-parameter name="Data"/>
+ </template><parameter name="expr"><paramtype>Expr const &amp;</paramtype><description><para>The current expression </para></description></parameter><parameter name="state"><paramtype>State const &amp;</paramtype><description><para>The current state </para></description></parameter><parameter name="data"><paramtype>Data &amp;</paramtype><description><para>An arbitrary data </para></description></parameter><description><para>
+
+</para></description><requires><para><computeroutput>matches&lt;Expr, Grammar&gt;::value</computeroutput> is <computeroutput>true</computeroutput>. </para></requires></method></method-group></struct></namespace></namespace></header><header name="boost/proto/transform/when.hpp"><para>Definition of when transform. </para><namespace name="boost"><namespace name="proto"><struct name="when"><template>
+ <template-type-parameter name="Grammar"/>
+ <template-type-parameter name="PrimitiveTransform"><default>Grammar</default></template-type-parameter>
+ </template><purpose>A grammar element and a PrimitiveTransform that associates a transform with the grammar. </purpose><description><para>Use <computeroutput>when&lt;&gt;</computeroutput> to override a grammar's default transform with a custom transform. It is for used when composing larger transforms by associating smaller transforms with individual rules in your grammar, as in the following transform which counts the number of terminals in an expression.</para><para><programlisting> // Count the terminals in an expression tree.
+ // Must be invoked with initial state == mpl::int_&lt;0&gt;().
+ struct CountLeaves
+ : or_&lt;
+ when&lt;terminal&lt;_&gt;, mpl::next&lt;_state&gt;()&gt;
+ , otherwise&lt;fold&lt;_, _state, CountLeaves&gt; &gt;
+ &gt;
+ {};
+</programlisting></para><para>In <computeroutput>when&lt;G, T&gt;</computeroutput>, when <computeroutput>T</computeroutput> is a class type it is a PrimitiveTransform and the following equivalencies hold:</para><para><computeroutput>when&lt;G,T&gt;::result&lt;void(E,S,V)&gt;::type</computeroutput> is the same as <computeroutput>T::result&lt;void(E,S,V)&gt;::type</computeroutput>.</para><para><computeroutput>when&lt;G,T&gt;()(e,s,v)</computeroutput> is the same as <computeroutput>T()(e,s,v)</computeroutput>. </para></description><typedef name="proto_base_expr"><type>Grammar::proto_base_expr</type></typedef></struct><struct-specialization name="when"><template>
+ <template-type-parameter name="Grammar"/>
+ <template-type-parameter name="Fun"/>
+ </template><specialization><template-arg>Grammar</template-arg><template-arg>Fun *</template-arg></specialization><inherit access="public">boost::proto::when&lt; Grammar, Fun &gt;</inherit><purpose>A specialization that treats function pointer Transforms as if they were function type Transforms. </purpose><description><para>This specialization requires that <computeroutput>Fun</computeroutput> is actually a function type.</para><para>This specialization is required for nested transforms such as <computeroutput>when&lt;G, T0(T1(_))&gt;</computeroutput>. In C++, functions that are used as parameters to other functions automatically decay to funtion pointer types. In other words, the type <computeroutput>T0(T1(_))</computeroutput> is indistinguishable from <computeroutput>T0(T1(*)(_))</computeroutput>. This specialization is required to handle these nested function pointer type transforms properly. </para></description></struct-specialization><struct name="otherwise"><template>
+ <template-type-parameter name="Fun"/>
+ </template><inherit access="public">boost::proto::when&lt; _, Fun &gt;</inherit><purpose>Syntactic sugar for <computeroutput>when&lt;_, Fun&gt;</computeroutput>, for use in grammars to handle all the cases not yet handled. </purpose><description><para>Use <computeroutput>otherwise&lt;T&gt;</computeroutput> in your grammars as a synonym for <computeroutput>when&lt;_, T&gt;</computeroutput> as in the following transform which counts the number of terminals in an expression.</para><para><programlisting> // Count the terminals in an expression tree.
+ // Must be invoked with initial state == mpl::int_&lt;0&gt;().
+ struct CountLeaves
+ : or_&lt;
+ when&lt;terminal&lt;_&gt;, mpl::next&lt;_state&gt;()&gt;
+ , otherwise&lt;fold&lt;_, _state, CountLeaves&gt; &gt;
+ &gt;
+ {};
+</programlisting> </para></description></struct><struct-specialization name="when"><template>
+ <template-type-parameter name="Grammar"/>
+ <template-type-parameter name="R"/>
+ </template><specialization><template-arg>Grammar</template-arg><template-arg>R()</template-arg></specialization><inherit access="public">boost::proto::callable</inherit><purpose>A grammar element and a PrimitiveTransform that associates a transform with the grammar. </purpose><description><para>Use <computeroutput>when&lt;&gt;</computeroutput> to override a grammar's default transform with a custom transform. It is for used when composing larger transforms by associating smaller transforms with individual rules in your grammar, as in the following transform which counts the number of terminals in an expression.</para><para><programlisting> // Count the terminals in an expression tree.
+ // Must be invoked with initial state == mpl::int_&lt;0&gt;().
+ struct CountLeaves
+ : or_&lt;
+ when&lt;terminal&lt;_&gt;, mpl::next&lt;_state&gt;()&gt;
+ , otherwise&lt;fold&lt;_, _state, CountLeaves&gt; &gt;
+ &gt;
+ {};
+</programlisting></para><para>The <computeroutput>when&lt;G, R(A0,A1,...)&gt;</computeroutput> form accepts either a CallableTransform or an ObjectTransform as its second parameter. <computeroutput>when&lt;&gt;</computeroutput> uses <computeroutput>is_callable&lt;R&gt;::value</computeroutput> to distinguish between the two, and uses <computeroutput>call&lt;&gt;</computeroutput> to evaluate CallableTransforms and <computeroutput>make&lt;&gt;</computeroutput> to evaluate ObjectTransforms. </para></description><struct-specialization name="result"><template>
+ <template-type-parameter name="This"/>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="State"/>
+ <template-type-parameter name="Data"/>
+ </template><specialization><template-arg>This(Expr</template-arg><template-arg>State</template-arg><template-arg>Data)</template-arg></specialization><typedef name="call_"><type><classname>call</classname>&lt; R()&gt;</type></typedef><typedef name="make_"><type><classname>make</classname>&lt; R()&gt;</type></typedef><typedef name="impl"><type>mpl::if_c&lt; <classname>is_callable</classname>&lt; R &gt;::value, <classname>call_</classname>, <classname>make_</classname> &gt;::type</type></typedef><typedef name="type"><type>impl::template result&lt; void(Expr, State, Data)&gt;::type</type></typedef></struct-specialization><typedef name="proto_base_expr"><type>Grammar::proto_base_expr</type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type>result&lt; void(Expr, State, Data)&gt;::type</type><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="State"/>
+ <template-type-parameter name="Data"/>
+ </template><parameter name="expr"><paramtype>Expr const &amp;</paramtype><description><para>The current expression </para></description></parameter><parameter name="state"><paramtype>State const &amp;</paramtype><description><para>The current state </para></description></parameter><parameter name="data"><paramtype>Data &amp;</paramtype><description><para>An arbitrary data </para></description></parameter><description><para>Evaluate <computeroutput>R(A0,A1,...)</computeroutput> as a transform either with <computeroutput>call&lt;&gt;</computeroutput> or with <computeroutput>make&lt;&gt;</computeroutput> depending on whether <computeroutput>is_callable&lt;R&gt;::value</computeroutput> is <computeroutput>true</computeroutput> or <computeroutput>false</computeroutput>.</para><para>
+
+
+</para></description><requires><para><computeroutput>matches&lt;Expr, Grammar&gt;::value</computeroutput> is <computeroutput>true</computeroutput> </para></requires><returns><para><computeroutput>result&lt;void(Expr, State, Data)&gt;::impl()(expr, state, data)</computeroutput> </para></returns></method></method-group></struct-specialization><struct-specialization name="when"><template>
+ <template-type-parameter name="Grammar"/>
+ <template-type-parameter name="R"/>
+ <template-type-parameter name="A0"/>
+ </template><specialization><template-arg>Grammar</template-arg><template-arg>R(A0)</template-arg></specialization><inherit access="public">boost::proto::callable</inherit><purpose>A grammar element and a PrimitiveTransform that associates a transform with the grammar. </purpose><description><para>Use <computeroutput>when&lt;&gt;</computeroutput> to override a grammar's default transform with a custom transform. It is for used when composing larger transforms by associating smaller transforms with individual rules in your grammar, as in the following transform which counts the number of terminals in an expression.</para><para><programlisting> // Count the terminals in an expression tree.
+ // Must be invoked with initial state == mpl::int_&lt;0&gt;().
+ struct CountLeaves
+ : or_&lt;
+ when&lt;terminal&lt;_&gt;, mpl::next&lt;_state&gt;()&gt;
+ , otherwise&lt;fold&lt;_, _state, CountLeaves&gt; &gt;
+ &gt;
+ {};
+</programlisting></para><para>The <computeroutput>when&lt;G, R(A0,A1,...)&gt;</computeroutput> form accepts either a CallableTransform or an ObjectTransform as its second parameter. <computeroutput>when&lt;&gt;</computeroutput> uses <computeroutput>is_callable&lt;R&gt;::value</computeroutput> to distinguish between the two, and uses <computeroutput>call&lt;&gt;</computeroutput> to evaluate CallableTransforms and <computeroutput>make&lt;&gt;</computeroutput> to evaluate ObjectTransforms. </para></description><struct-specialization name="result"><template>
+ <template-type-parameter name="This"/>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="State"/>
+ <template-type-parameter name="Data"/>
+ </template><specialization><template-arg>This(Expr</template-arg><template-arg>State</template-arg><template-arg>Data)</template-arg></specialization><typedef name="call_"><type><classname>call</classname>&lt; R(A0)&gt;</type></typedef><typedef name="make_"><type><classname>make</classname>&lt; R(A0)&gt;</type></typedef><typedef name="impl"><type>mpl::if_c&lt; <classname>is_callable</classname>&lt; R &gt;::value, <classname>call_</classname>, <classname>make_</classname> &gt;::type</type></typedef><typedef name="type"><type>impl::template result&lt; void(Expr, State, Data)&gt;::type</type></typedef></struct-specialization><typedef name="proto_base_expr"><type>Grammar::proto_base_expr</type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type>result&lt; void(Expr, State, Data)&gt;::type</type><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="State"/>
+ <template-type-parameter name="Data"/>
+ </template><parameter name="expr"><paramtype>Expr const &amp;</paramtype><description><para>The current expression </para></description></parameter><parameter name="state"><paramtype>State const &amp;</paramtype><description><para>The current state </para></description></parameter><parameter name="data"><paramtype>Data &amp;</paramtype><description><para>An arbitrary data </para></description></parameter><description><para>Evaluate <computeroutput>R(A0,A1,...)</computeroutput> as a transform either with <computeroutput>call&lt;&gt;</computeroutput> or with <computeroutput>make&lt;&gt;</computeroutput> depending on whether <computeroutput>is_callable&lt;R&gt;::value</computeroutput> is <computeroutput>true</computeroutput> or <computeroutput>false</computeroutput>.</para><para>
+
+
+</para></description><requires><para><computeroutput>matches&lt;Expr, Grammar&gt;::value</computeroutput> is <computeroutput>true</computeroutput> </para></requires><returns><para><computeroutput>result&lt;void(Expr, State, Data)&gt;::impl()(expr, state, data)</computeroutput> </para></returns></method></method-group></struct-specialization><struct-specialization name="when"><template>
+ <template-type-parameter name="Grammar"/>
+ <template-type-parameter name="R"/>
+ <template-type-parameter name="A0"/>
+ <template-type-parameter name="A1"/>
+ </template><specialization><template-arg>Grammar</template-arg><template-arg>R(A0</template-arg><template-arg>A1)</template-arg></specialization><inherit access="public">boost::proto::callable</inherit><purpose>A grammar element and a PrimitiveTransform that associates a transform with the grammar. </purpose><description><para>Use <computeroutput>when&lt;&gt;</computeroutput> to override a grammar's default transform with a custom transform. It is for used when composing larger transforms by associating smaller transforms with individual rules in your grammar, as in the following transform which counts the number of terminals in an expression.</para><para><programlisting> // Count the terminals in an expression tree.
+ // Must be invoked with initial state == mpl::int_&lt;0&gt;().
+ struct CountLeaves
+ : or_&lt;
+ when&lt;terminal&lt;_&gt;, mpl::next&lt;_state&gt;()&gt;
+ , otherwise&lt;fold&lt;_, _state, CountLeaves&gt; &gt;
+ &gt;
+ {};
+</programlisting></para><para>The <computeroutput>when&lt;G, R(A0,A1,...)&gt;</computeroutput> form accepts either a CallableTransform or an ObjectTransform as its second parameter. <computeroutput>when&lt;&gt;</computeroutput> uses <computeroutput>is_callable&lt;R&gt;::value</computeroutput> to distinguish between the two, and uses <computeroutput>call&lt;&gt;</computeroutput> to evaluate CallableTransforms and <computeroutput>make&lt;&gt;</computeroutput> to evaluate ObjectTransforms. </para></description><struct-specialization name="result"><template>
+ <template-type-parameter name="This"/>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="State"/>
+ <template-type-parameter name="Data"/>
+ </template><specialization><template-arg>This(Expr</template-arg><template-arg>State</template-arg><template-arg>Data)</template-arg></specialization><typedef name="call_"><type><classname>call</classname>&lt; R(A0, A1)&gt;</type></typedef><typedef name="make_"><type><classname>make</classname>&lt; R(A0, A1)&gt;</type></typedef><typedef name="impl"><type>mpl::if_c&lt; <classname>is_callable</classname>&lt; R &gt;::value, <classname>call_</classname>, <classname>make_</classname> &gt;::type</type></typedef><typedef name="type"><type>impl::template result&lt; void(Expr, State, Data)&gt;::type</type></typedef></struct-specialization><typedef name="proto_base_expr"><type>Grammar::proto_base_expr</type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type>result&lt; void(Expr, State, Data)&gt;::type</type><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="State"/>
+ <template-type-parameter name="Data"/>
+ </template><parameter name="expr"><paramtype>Expr const &amp;</paramtype><description><para>The current expression </para></description></parameter><parameter name="state"><paramtype>State const &amp;</paramtype><description><para>The current state </para></description></parameter><parameter name="data"><paramtype>Data &amp;</paramtype><description><para>An arbitrary data </para></description></parameter><description><para>Evaluate <computeroutput>R(A0,A1,...)</computeroutput> as a transform either with <computeroutput>call&lt;&gt;</computeroutput> or with <computeroutput>make&lt;&gt;</computeroutput> depending on whether <computeroutput>is_callable&lt;R&gt;::value</computeroutput> is <computeroutput>true</computeroutput> or <computeroutput>false</computeroutput>.</para><para>
+
+
+</para></description><requires><para><computeroutput>matches&lt;Expr, Grammar&gt;::value</computeroutput> is <computeroutput>true</computeroutput> </para></requires><returns><para><computeroutput>result&lt;void(Expr, State, Data)&gt;::impl()(expr, state, data)</computeroutput> </para></returns></method></method-group></struct-specialization><struct-specialization name="when"><template>
+ <template-type-parameter name="Grammar"/>
+ <template-type-parameter name="R"/>
+ <template-type-parameter name="A0"/>
+ <template-type-parameter name="A1"/>
+ <template-type-parameter name="A2"/>
+ </template><specialization><template-arg>Grammar</template-arg><template-arg>R(A0</template-arg><template-arg>A1</template-arg><template-arg>A2)</template-arg></specialization><inherit access="public">boost::proto::callable</inherit><purpose>A grammar element and a PrimitiveTransform that associates a transform with the grammar. </purpose><description><para>Use <computeroutput>when&lt;&gt;</computeroutput> to override a grammar's default transform with a custom transform. It is for used when composing larger transforms by associating smaller transforms with individual rules in your grammar, as in the following transform which counts the number of terminals in an expression.</para><para><programlisting> // Count the terminals in an expression tree.
+ // Must be invoked with initial state == mpl::int_&lt;0&gt;().
+ struct CountLeaves
+ : or_&lt;
+ when&lt;terminal&lt;_&gt;, mpl::next&lt;_state&gt;()&gt;
+ , otherwise&lt;fold&lt;_, _state, CountLeaves&gt; &gt;
+ &gt;
+ {};
+</programlisting></para><para>The <computeroutput>when&lt;G, R(A0,A1,...)&gt;</computeroutput> form accepts either a CallableTransform or an ObjectTransform as its second parameter. <computeroutput>when&lt;&gt;</computeroutput> uses <computeroutput>is_callable&lt;R&gt;::value</computeroutput> to distinguish between the two, and uses <computeroutput>call&lt;&gt;</computeroutput> to evaluate CallableTransforms and <computeroutput>make&lt;&gt;</computeroutput> to evaluate ObjectTransforms. </para></description><struct-specialization name="result"><template>
+ <template-type-parameter name="This"/>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="State"/>
+ <template-type-parameter name="Data"/>
+ </template><specialization><template-arg>This(Expr</template-arg><template-arg>State</template-arg><template-arg>Data)</template-arg></specialization><typedef name="call_"><type><classname>call</classname>&lt; R(A0, A1, A2)&gt;</type></typedef><typedef name="make_"><type><classname>make</classname>&lt; R(A0, A1, A2)&gt;</type></typedef><typedef name="impl"><type>mpl::if_c&lt; <classname>is_callable</classname>&lt; R &gt;::value, <classname>call_</classname>, <classname>make_</classname> &gt;::type</type></typedef><typedef name="type"><type>impl::template result&lt; void(Expr, State, Data)&gt;::type</type></typedef></struct-specialization><typedef name="proto_base_expr"><type>Grammar::proto_base_expr</type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type>result&lt; void(Expr, State, Data)&gt;::type</type><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="State"/>
+ <template-type-parameter name="Data"/>
+ </template><parameter name="expr"><paramtype>Expr const &amp;</paramtype><description><para>The current expression </para></description></parameter><parameter name="state"><paramtype>State const &amp;</paramtype><description><para>The current state </para></description></parameter><parameter name="data"><paramtype>Data &amp;</paramtype><description><para>An arbitrary data </para></description></parameter><description><para>Evaluate <computeroutput>R(A0,A1,...)</computeroutput> as a transform either with <computeroutput>call&lt;&gt;</computeroutput> or with <computeroutput>make&lt;&gt;</computeroutput> depending on whether <computeroutput>is_callable&lt;R&gt;::value</computeroutput> is <computeroutput>true</computeroutput> or <computeroutput>false</computeroutput>.</para><para>
+
+
+</para></description><requires><para><computeroutput>matches&lt;Expr, Grammar&gt;::value</computeroutput> is <computeroutput>true</computeroutput> </para></requires><returns><para><computeroutput>result&lt;void(Expr, State, Data)&gt;::impl()(expr, state, data)</computeroutput> </para></returns></method></method-group></struct-specialization><struct-specialization name="when"><template>
+ <template-type-parameter name="Grammar"/>
+ <template-type-parameter name="R"/>
+ <template-type-parameter name="A0"/>
+ <template-type-parameter name="A1"/>
+ <template-type-parameter name="A2"/>
+ <template-type-parameter name="A3"/>
+ </template><specialization><template-arg>Grammar</template-arg><template-arg>R(A0</template-arg><template-arg>A1</template-arg><template-arg>A2</template-arg><template-arg>A3)</template-arg></specialization><inherit access="public">boost::proto::callable</inherit><purpose>A grammar element and a PrimitiveTransform that associates a transform with the grammar. </purpose><description><para>Use <computeroutput>when&lt;&gt;</computeroutput> to override a grammar's default transform with a custom transform. It is for used when composing larger transforms by associating smaller transforms with individual rules in your grammar, as in the following transform which counts the number of terminals in an expression.</para><para><programlisting> // Count the terminals in an expression tree.
+ // Must be invoked with initial state == mpl::int_&lt;0&gt;().
+ struct CountLeaves
+ : or_&lt;
+ when&lt;terminal&lt;_&gt;, mpl::next&lt;_state&gt;()&gt;
+ , otherwise&lt;fold&lt;_, _state, CountLeaves&gt; &gt;
+ &gt;
+ {};
+</programlisting></para><para>The <computeroutput>when&lt;G, R(A0,A1,...)&gt;</computeroutput> form accepts either a CallableTransform or an ObjectTransform as its second parameter. <computeroutput>when&lt;&gt;</computeroutput> uses <computeroutput>is_callable&lt;R&gt;::value</computeroutput> to distinguish between the two, and uses <computeroutput>call&lt;&gt;</computeroutput> to evaluate CallableTransforms and <computeroutput>make&lt;&gt;</computeroutput> to evaluate ObjectTransforms. </para></description><struct-specialization name="result"><template>
+ <template-type-parameter name="This"/>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="State"/>
+ <template-type-parameter name="Data"/>
+ </template><specialization><template-arg>This(Expr</template-arg><template-arg>State</template-arg><template-arg>Data)</template-arg></specialization><typedef name="call_"><type><classname>call</classname>&lt; R(A0, A1, A2, A3)&gt;</type></typedef><typedef name="make_"><type><classname>make</classname>&lt; R(A0, A1, A2, A3)&gt;</type></typedef><typedef name="impl"><type>mpl::if_c&lt; <classname>is_callable</classname>&lt; R &gt;::value, <classname>call_</classname>, <classname>make_</classname> &gt;::type</type></typedef><typedef name="type"><type>impl::template result&lt; void(Expr, State, Data)&gt;::type</type></typedef></struct-specialization><typedef name="proto_base_expr"><type>Grammar::proto_base_expr</type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type>result&lt; void(Expr, State, Data)&gt;::type</type><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="State"/>
+ <template-type-parameter name="Data"/>
+ </template><parameter name="expr"><paramtype>Expr const &amp;</paramtype><description><para>The current expression </para></description></parameter><parameter name="state"><paramtype>State const &amp;</paramtype><description><para>The current state </para></description></parameter><parameter name="data"><paramtype>Data &amp;</paramtype><description><para>An arbitrary data </para></description></parameter><description><para>Evaluate <computeroutput>R(A0,A1,...)</computeroutput> as a transform either with <computeroutput>call&lt;&gt;</computeroutput> or with <computeroutput>make&lt;&gt;</computeroutput> depending on whether <computeroutput>is_callable&lt;R&gt;::value</computeroutput> is <computeroutput>true</computeroutput> or <computeroutput>false</computeroutput>.</para><para>
+
+
+</para></description><requires><para><computeroutput>matches&lt;Expr, Grammar&gt;::value</computeroutput> is <computeroutput>true</computeroutput> </para></requires><returns><para><computeroutput>result&lt;void(Expr, State, Data)&gt;::impl()(expr, state, data)</computeroutput> </para></returns></method></method-group></struct-specialization><struct-specialization name="when"><template>
+ <template-type-parameter name="Grammar"/>
+ <template-type-parameter name="R"/>
+ <template-type-parameter name="A0"/>
+ <template-type-parameter name="A1"/>
+ <template-type-parameter name="A2"/>
+ <template-type-parameter name="A3"/>
+ <template-type-parameter name="A4"/>
+ </template><specialization><template-arg>Grammar</template-arg><template-arg>R(A0</template-arg><template-arg>A1</template-arg><template-arg>A2</template-arg><template-arg>A3</template-arg><template-arg>A4)</template-arg></specialization><inherit access="public">boost::proto::callable</inherit><purpose>A grammar element and a PrimitiveTransform that associates a transform with the grammar. </purpose><description><para>Use <computeroutput>when&lt;&gt;</computeroutput> to override a grammar's default transform with a custom transform. It is for used when composing larger transforms by associating smaller transforms with individual rules in your grammar, as in the following transform which counts the number of terminals in an expression.</para><para><programlisting> // Count the terminals in an expression tree.
+ // Must be invoked with initial state == mpl::int_&lt;0&gt;().
+ struct CountLeaves
+ : or_&lt;
+ when&lt;terminal&lt;_&gt;, mpl::next&lt;_state&gt;()&gt;
+ , otherwise&lt;fold&lt;_, _state, CountLeaves&gt; &gt;
+ &gt;
+ {};
+</programlisting></para><para>The <computeroutput>when&lt;G, R(A0,A1,...)&gt;</computeroutput> form accepts either a CallableTransform or an ObjectTransform as its second parameter. <computeroutput>when&lt;&gt;</computeroutput> uses <computeroutput>is_callable&lt;R&gt;::value</computeroutput> to distinguish between the two, and uses <computeroutput>call&lt;&gt;</computeroutput> to evaluate CallableTransforms and <computeroutput>make&lt;&gt;</computeroutput> to evaluate ObjectTransforms. </para></description><struct-specialization name="result"><template>
+ <template-type-parameter name="This"/>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="State"/>
+ <template-type-parameter name="Data"/>
+ </template><specialization><template-arg>This(Expr</template-arg><template-arg>State</template-arg><template-arg>Data)</template-arg></specialization><typedef name="call_"><type><classname>call</classname>&lt; R(A0, A1, A2, A3, A4)&gt;</type></typedef><typedef name="make_"><type><classname>make</classname>&lt; R(A0, A1, A2, A3, A4)&gt;</type></typedef><typedef name="impl"><type>mpl::if_c&lt; <classname>is_callable</classname>&lt; R &gt;::value, <classname>call_</classname>, <classname>make_</classname> &gt;::type</type></typedef><typedef name="type"><type>impl::template result&lt; void(Expr, State, Data)&gt;::type</type></typedef></struct-specialization><typedef name="proto_base_expr"><type>Grammar::proto_base_expr</type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type>result&lt; void(Expr, State, Data)&gt;::type</type><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="State"/>
+ <template-type-parameter name="Data"/>
+ </template><parameter name="expr"><paramtype>Expr const &amp;</paramtype><description><para>The current expression </para></description></parameter><parameter name="state"><paramtype>State const &amp;</paramtype><description><para>The current state </para></description></parameter><parameter name="data"><paramtype>Data &amp;</paramtype><description><para>An arbitrary data </para></description></parameter><description><para>Evaluate <computeroutput>R(A0,A1,...)</computeroutput> as a transform either with <computeroutput>call&lt;&gt;</computeroutput> or with <computeroutput>make&lt;&gt;</computeroutput> depending on whether <computeroutput>is_callable&lt;R&gt;::value</computeroutput> is <computeroutput>true</computeroutput> or <computeroutput>false</computeroutput>.</para><para>
+
+
+</para></description><requires><para><computeroutput>matches&lt;Expr, Grammar&gt;::value</computeroutput> is <computeroutput>true</computeroutput> </para></requires><returns><para><computeroutput>result&lt;void(Expr, State, Data)&gt;::impl()(expr, state, data)</computeroutput> </para></returns></method></method-group></struct-specialization></namespace></namespace></header></library-reference>

Added: branches/proto/v4/libs/proto/doc/quick_start.qbk
==============================================================================
--- (empty file)
+++ branches/proto/v4/libs/proto/doc/quick_start.qbk 2008-04-06 02:19:35 EDT (Sun, 06 Apr 2008)
@@ -0,0 +1,81 @@
+[/
+ / Copyright (c) 2008 Eric Niebler
+ /
+ / Distributed under the Boost Software License, Version 1.0. (See accompanying
+ / file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+ /]
+
+[section Hello World]
+
+Below is a very simple program that uses Proto to build an expression template
+and then execute it.
+
+ #include <iostream>
+ #include <boost/proto/proto.hpp>
+ #include <boost/proto/context.hpp>
+ #include <boost/typeof/std/ostream.hpp>
+ using namespace boost;
+
+ proto::terminal< std::ostream & >::type cout_ = { std::cout };
+
+ template< typename Expr >
+ void evaluate( Expr const & expr )
+ {
+ proto::default_context ctx;
+ proto::eval(expr, ctx);
+ }
+
+ int main()
+ {
+ evaluate( cout_ << "hello" << ',' << " world" );
+ return 0;
+ }
+
+This program outputs the following:
+
+[pre
+hello, world
+]
+
+This program builds an object representing the output operation and passes
+it to an `evaluate()` function, which then executes it.
+
+The basic idea of expression templates is to overload all the operators so
+that, rather than evaluating the expression immediately, they build a tree-like
+representation of the expression so that it can be evaluated later. For each
+operator in an expression, at least one operand must be Proto-ified in order
+for Proto's operator overloads to be found. In the expression ...
+
+ cout_ << "hello" << ',' << " world"
+
+... the Proto-ified sub-expression is `cout_`, which is the Proto-ification of
+`std::cout`. The presence of `cout_` "infects" the expression, and brings
+Proto's tree-building operator overloads into consideration. Any literals in
+the expression are then Proto-ified by wrapping them in a Proto terminal before
+they are combined into larger Proto expressions.
+
+Once Proto's operator overloads have built the expression tree, the expression
+can be lazily evaluated later by walking the tree. That is what `proto::eval()`
+does. It is a general tree-walking expression evaluator, whose behavior is
+customizable via a /context/ parameter. The use of _default_context_ assigns
+the standard meanings to the operators in the expression. (By using a different
+context, you could give the operators in your expressions different semantics.
+By default, Proto makes no assumptions about what operators actually /mean/.)
+
+[note [*Proto Design Philosophy]
+
+Before we continue, let's use the above example to illustrate an important
+design principle of Proto's. The expression template created in the ['hello
+world] example is totally general and abstract. It is not tied in any way to
+any particular domain or application, nor does it have any particular meaning
+or behavior on its own, until it is evaluated in a /context/. Expression
+templates are really just heterogeneous trees, which might mean something in
+one domain, and something else entirely in a different one.
+
+As we'll see later, there is a way to create Proto expression trees that are
+['not] purely abstract, and that have meaning and behaviors independent of any
+context. There is also a way to control which operators are overloaded for your
+particular domain. But that is not the default behavior. We'll see later why
+the default is often a good thing.]
+
+[endsect]

Added: branches/proto/v4/libs/proto/doc/rationale.qbk
==============================================================================
--- (empty file)
+++ branches/proto/v4/libs/proto/doc/rationale.qbk 2008-04-06 02:19:35 EDT (Sun, 06 Apr 2008)
@@ -0,0 +1,99 @@
+[/
+ / Copyright (c) 2008 Eric Niebler
+ /
+ / Distributed under the Boost Software License, Version 1.0. (See accompanying
+ / file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+ /]
+
+[section:rationale Appendix B: Rationale]
+
+[/==================================================]
+[section:static_initialization Static Initialization]
+[/==================================================]
+
+Proto expression types are PODs (Plain Old Data), and do not have constructors.
+They are brace-initialized, as follows:
+
+ terminal<int>::type const _i = {1};
+
+The reason is so that expression objects like `_i` above can be ['statically
+initialized]. Why is static initialization important? The terminals of many
+domain-specific embedded languages are likely to be global const objects, like
+`_1` and `_2` from the Boost Lambda Library. Were these object to require
+run-time initialization, it might be possible to use these objects before they
+are initialized. That would be bad. Statically initialized objects cannot be
+misused that way.
+
+[endsect]
+
+[/======================================================================]
+[section:result_of Proto Transforms and the Restricted ResultOf Protocol]
+[/======================================================================]
+
+All Proto primitive transforms make use of a variant of the TR1 ResultOf
+protocol for computing the type of the transform's return value. Such
+transforms must have a nested `result<>` template (not a nested `result_type`
+typedef) which takes exactly three parameter types. That is, it must be
+defined as:
+
+ template<typename Sig> struct result {};
+
+ template<typename This, typename Expr, typename State, typename Data>
+ struct result<This(Expr, State, Data)>
+ {
+ typedef ... type;
+ };
+
+In the above, `Expr`, `State`, and `Data` are assumed by Proto to be
+non-cv-qualified non-reference types. The implication is that for some
+Proto transform `Tr`, some `result_of<>` instantiations work while others
+don't. See below.
+
+ // ERROR, doesn't work:
+ boost::result_of<Tr(Expr const &, State const &, Data &)>::type
+
+ // OK, works:
+ boost::result_of<Tr(Expr, State, Data)>::type
+
+It is done this way largely for compile-time performance. Full
+compliance with the TR1 ResultOf protocol incurs a not insignificant penalty
+at compile time. Metaprogramming tricks are needed to first detect a nested
+`result_type` typedef if it exists. And each nested `result<>` template
+would need to be coded specially to handle references and cv-qualifiers, which
+incurs many instantiations of `remove_reference<>` and `remove_cv<>`. In
+private testing, this was found to have a measurable impact on compile-time
+performance in the order of 10-15%, which was deemed unacceptable.
+
+The restricted protocol improves compile times while remaining largely
+compatible with TR1's `result_of<>`. As a side benefit, it makes
+Proto's primitive transforms easier to implement, since the user need not
+worry about stripping references and cv-qualification in their nested
+`result<>` templates.
+
+[endsect]
+
+[/=========================================================]
+[section:preprocessor Why Not Reuse MPL, Fusion, et cetera?]
+[/=========================================================]
+
+Anyone who has peeked at Proto's source code has probably wondered,
+"Why all the dirty preprocessor gunk? Couldn't this have been all
+implemented cleanly on top of libraries like MPL and Fusion?" The
+answer is that Proto could have been implemented this way, and in fact
+was at one point. The problem is that template metaprogramming (TMP)
+makes for very long compile times. As a foundation upon which other
+TMP-heavy libraries will be built, Proto itself should be as lightweight
+as possible. That is achieved by prefering preprocessor metaprogramming
+to template metaprogramming. Expanding a macro is far more efficient
+than instantiating a template. In some cases, the "clean" version takes
+10x longer to compile than the "dirty" version.
+
+The "clean and slow" version of Proto can still be found at
+http://svn.boost.org/svn/boost/branches/proto/v3. Anyone who is interested
+can download it and verify that it is, in fact, unusably slow to compile.
+Note that this branch's development was abandoned, and it does not
+conform exactly with Proto's current interface.
+
+[endsect]
+
+[endsect]

Added: branches/proto/v4/libs/proto/doc/transforms.qbk
==============================================================================
--- (empty file)
+++ branches/proto/v4/libs/proto/doc/transforms.qbk 2008-04-06 02:19:35 EDT (Sun, 06 Apr 2008)
@@ -0,0 +1,1380 @@
+[/
+ / Copyright (c) 2006 Eric Niebler
+ /
+ / Distributed under the Boost Software License, Version 1.0. (See accompanying
+ / file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+ /]
+
+[import ../test/examples.cpp]
+
+[/==========================================================]
+[section:expression_transformation Expression Transformation]
+[/==========================================================]
+
+Sometimes, rather than immediately executing an expression template, you'd
+like to transform it into some other object. Maybe the transformation is simple,
+like converting all references into values. Maybe it's complicated, like
+transforming an expression template into a finite-state automata for matching a
+regular expression. Proto provides a framework for applying tree
+transformations and several canned transformations that are generally useful.
+
+[/===============]
+[heading Overview]
+[/===============]
+
+Defining tree transformations involves defining the grammar for your DSEL
+and decorating it with transformations. Each rule in your grammar will
+have an associated transform describing how sub-expressions matching that rule
+are to be transformed. Just as the grammar is defined recursively, so too
+is the tree transformation.
+
+You associate transforms with your grammar rules using _when_. For instance,
+you might want to promote all `int` terminals to `long`. You would say
+`when< terminal<int>, terminal<long>::type(_value) >`. Here,
+`terminal<long>::type(_value)` is an example of a Proto transform. It says to
+create an object of type `terminal<long>::type` and initialize it with the
+result of the `_value` transform. `_value` is a transform defined by Proto which
+extracts the value from a terminal expression.
+
+[note The transform above might look a little strange at first. It appears
+to be constructing a temporary object in place. In fact, it is a
+/function type/. Since `terminal<long>::type` and `_value` are types,
+`terminal<long>::type(_value)` is actually the type of a function that takes
+`_value` as a parameter and returns `terminal<long>::type`. That is immaterial;
+there is no such function in reality. Rather, Proto interprets this function
+type as a transform, the effect of which is described above. The resemblance
+to an in-place construction of a temporary object is intentional. It is a
+concise and natural notation for specifying transforms. Proto transforms use
+function types extensively, as we'll see.]
+
+A grammar decorated with transforms is a function object that takes three
+parameters:
+
+* `expr` -- the Proto expression to transform
+* `state` -- the initial state of the transformation
+* `data` -- any optional mutable state information
+
+Grammars with transforms are proper function objects, so you can use
+`boost::result_of<>` to calculate their return types. So, applying a
+transform typically looks like this:
+
+ // Assuming we have an expression to transform,
+ // an initial state, and a data ...
+ Expr expr;
+ State state;
+ Data data;
+
+ // ... calculate the result type of applying
+ // Grammar's transform ...
+ typedef typename
+ boost::result_of<Grammar(Expr, State, Data)>::type
+ result_type;
+
+ // ... and apply Grammar's transform:
+ result_type result = Grammar()(expr, state, data);
+
+[/==========================================]
+[section Example: Calculator Arity Transform]
+[/==========================================]
+
+Let's have another look at our trusty calculator example. If you recall, the
+calculator allows the lazy evaluation of arithmetic expressions, with
+placeholders substituted with actual values provided at evaluation time. Valid
+expressions are of the form:
+
+ (_1 + 3)
+ (_2 - _1) / _2 * 100
+
+... and so on. In the first expression, one argument must be provided before
+the expression can be evaluated. In the second, two arguments are needed. We
+could say the /arity/ of the first expression is one and of the second is two.
+The arity is determined by the highest placeholder in the expression. Our job
+will be to write a transform that calculates the arity of any calculator
+expression.
+
+[/=========================]
+[heading Defining a Grammar]
+[/=========================]
+
+First, we must write the grammar for the calculator. It's really very simple.
+Calculator expression can be made up of any combination of 5 constituents:
+
+* Placeholder 1
+* Placeholder 2
+* A literal
+* Unary operations
+* Binary operations
+
+We can immediately write the calculator grammar as follows:
+
+[CalcGrammar]
+
+We can read this as follows: a calculator expression is either placeholder 1,
+placeholder 2, some other terminal, or some unary or binary operator whose
+operands are calculator expressions. Recall that `proto::_` is a wildcard which
+matches anything. So `terminal< _ >` will match any terminal, and
+`unary_expr< _, CalcArity >` will match any unary expression
+for which the operand matches CalcArity (the `_` matches any operator
+tag).
+
+[/============================]
+[heading Writing the Transform]
+[/============================]
+
+It's straightforward to describe in words how the arity of an expression should
+be calculated. First, we describe the arity of each of the 5 constituents in
+the calculator grammar.
+
+[table Calculator Sub-Expression Arities
+ [[Sub-Expression] [Arity]]
+ [[Placeholder 1] [`1`]]
+ [[Placeholder 2] [`2`]]
+ [[Literal] [`0`]]
+ [[Unary Expression] [ /arity of the operand/ ]]
+ [[Binary Expression] [ /max arity of the two operands/ ]]
+]
+
+The total arity of a calculator expression is found by recursively evaluating
+the arity of all of the sub-expressions and taking the maximum.
+
+Let's look at the sub-expression for the placeholder `_1`. It is matched by this
+part of our grammar: `terminal< placeholder1 >`. We want to associate this
+part of our grammar with an arity of `1`. We do that by attaching a transform.
+Since the arity of an expression can be evaluated at compile time, let's use
+`mpl::int_<1>` to represent the arity of the first placeholder. The following
+attaches a transform that always evaluates to `mpl::int_<1>`:
+
+ when< terminal< placeholder1 >, mpl::int_<1>() >
+
+This grammar rule will match any `placeholder1` terminal, and will transform it
+to a (default-constructed) `mpl::int_<1>` object. As described previously,
+`mpl::int_<1>()` is a function type, but Proto interprets it as an object to
+construct. We will have a similar transform to convert `placeholder2` terminals
+into `mpl::int_<2>`, and other terminals into `mpl::int_<0>`.
+
+Next, let's write a transform for unary operators that returns the arity of the
+operand. It is simply:
+
+ when< unary_expr< _, CalcArity >, CalcArity(_child) >
+
+The transform `CalcArity(_child)` recursively applies the `CalcArity`
+transform to the child node of the unary expression. As you might have noticed,
+`CalcArity(_child)` is another function type, but Proto interprets this one
+differently. Rather than trying to construct a `CalcArity` object, Proto
+knows this is a function object and invokes it instead.
+
+[note When using function types as Proto transforms, they can either represent
+an object to construct or a function to call. It is similar to C++ where the
+syntax `foo(x)` can either be interpreted as an object to construct or a
+function to call, depending on whether `foo` is a type or a function. Proto
+can't know in general which is the case, so it uses a trait, `proto::is_callable<>`,
+to differentiate. `is_callable< mpl::int_<1> >::value` is false so `mpl::int_<1>()`
+is an object to construct, but `is_callable< CalcArity >::value` is true so
+`CalcArity(_child)` is a function to call. (`is_callable< CalcArity >::value` is true
+because `CalcArity` inherits from `proto::or_<>`, which is callable.)]
+
+[/
+ That begs the question, what does `unary_expr<>`'s transform do? Well,
+ `unary_expr< _, CalcArity >` has a default transform
+ associated with it. It is a /pass-through/ transform. When an expression
+ of the form `expr< T, list1< X > >` is passed to the transform, its `apply<>`
+ member template will invoke the `CalcArity` transform (which we haven't
+ completely defined yet -- patience) on `X` resulting in `Y`, and then
+ reassemble the expression as `expr< T, list1< Y > >`.
+
+ [note You may have noticed that Proto types like `unary_expr<>` serve several
+ different but related roles. In particular, `unary_expr<>` is ...
+
+ ... [*a meta-function]: `unary_expr<T, X>::type` is a typedef for
+ `expr<T, list1<X> >`.
+
+ ... [*a grammar]: `unary_expr<U, Y>` is a simle grammar that matches
+ `expr<T, list1<X> >` if an only if `U` is `T` or `proto::_`, and `Y` is a
+ grammar that matches `X`.
+
+ ... [*a transform]: `unary_expr<U, Y>::apply<expr<T, list1<X> >, S, V>::type`
+ applies `unary_expr<>`'s pass-through transform to `expr<T, list1<X> >` with
+ state `S` and data `V`. The result is
+ `expr<T, list1< Y::apply<X, S, V>::type > >`.
+ ]
+
+ So, putting a few things together, consider the calculator expression `+_1`,
+ which would have the following type:
+
+ expr< tag::unary_plus, list1<
+ expr< tag::terminal, term< placeholder1 > >
+ > >
+
+ If we executed the `unary_expr< _, CalcArity >` transform on this
+ expression, we would expect to get:
+
+ expr< tag::unary_plus, list1<
+ mpl::int_<1>
+ > >
+
+ And if we added the `_child<>` transform also, as in
+ `child< unary_expr< _, CalcArity > >`, we expect the result
+ to be:
+
+ mpl::int_<1>
+
+ Which is exactly what we want.
+
+ [note *Default Transforms*
+
+ All the tools Proto provides for defining grammar rules have default transforms
+ associated with them. Just as `unary_expr<>` has a pass-through transform,
+ so too does `binary_expr<>`, `shift_right<>`, and all the others.
+ `proto::or_<>` has a default transform which evaluates the transform of the
+ branch that matched. `proto::and_<>`'s default transform evaluates the
+ transform of the last branch. Even `proto::expr<>`, `proto::if_<>`,
+ `proto::not_<>`, and `proto::_` have no-op default transforms that simply return
+ unmodified the expressions passed to them.
+ ]
+]
+
+The arity of a binary operator is the maximum of the arity of the left and
+right operands. We can specify this with the help of `mpl::max<>`, which is a
+so-called meta-function that computes the maximum of two compile-time integers.
+The transform is described below:
+
+ when<
+ binary_expr< _, CalcArity, CalcArity >
+ , mpl::max< CalcArity(_left), CalcArity(_right) >()
+ >
+
+The above says to match binary calculator expressions and compute their
+arity by first computing the arity of the left and right children and then
+taking their maximum.
+
+There's a lot going on in the above transform, so let's take it one piece
+at a time, starting with the parts we know. `CalcArity(_left)`
+will calculate the arity of the left child, returning a compile-time integer.
+Likewise for `CalcArity(_right)`. What is new is that these two
+transforms are nested within another: `mpl::max<...>()`. Proto notices that
+`mpl::max<...>` is not callable, so this transform is interpreted as an
+object to construct rather than a function to invoke. Using meta-programming
+tricks, Proto disassembles the `mpl::max<...>` template looking for nested
+Proto transforms to apply. It finds two and applies them, resulting in
+`mpl::max< mpl::int_<X>, mpl::int_<Y> >`.
+
+Having first applied any nested transforms, Proto then looks to see if
+`mpl::max<X, Y>` has a nested `::type` typedef. This is a common convention
+used by meta-functions. In this case, `mpl::max<>::type` is a typedef
+for `mpl::int_< Z >` where `Z` is the maximum of `X` and `Y`. The trailing
+`()` on the transform indicates that the result should be default-constructed,
+so this transform returns `mpl::int_<Z>()`. And we're done.
+
+[note Had `mpl::max<>` not had a nested `::type` typedef, the transform
+would have created and returned a default-constructed `mpl::max<>` object
+instead. That is, the result of substituting nested transforms need not
+of necessity have a nested `::type` typedef, but it is used if it is there.]
+
+Piecing it all together, the complete `CalcArity` looks like this:
+
+[CalcArity]
+
+We can use our `CalcArity` transform to calculate the arity of any
+calculator expression:
+
+ int i = 0; // not used, dummy state and data parameter
+
+ std::cout << CalcArity()( lit(100) * 200, i, i) << '\n';
+ std::cout << CalcArity()( (_1 - _1) / _1 * 100, i, i) << '\n';
+ std::cout << CalcArity()( (_2 - _1) / _2 * 100, i, i) << '\n';
+
+This displays the following:
+
+[pre
+0
+1
+2
+]
+
+(Aside: this uses the fact that `mpl::int_<1>` has a conversion to `int(1)`.)
+
+[endsect]
+
+[/========================]
+[section Canned Transforms]
+[/========================]
+
+So far, we've seen how to write custom transforms using function types.
+These were implemented in terms of more primitive transforms provided by
+Proto, such as `_child`, `_left`, and `_right`. This section describes those
+transforms and others in detail.
+
+All the transforms defined in this section are of the following form:
+
+ struct some_transform : callable
+ {
+ template<typename Sig>
+ struct result;
+
+ template<typename This, typename Expr, typename State, typename Data>
+ struct result<This(Expr, State, Data)>
+ {
+ typedef ... type;
+ };
+
+ template<typename Expr, typename State, typename Data>
+ typename result<some_transform(Expr, State, Data)>::type
+ operator()(Expr const &expr, State const &state, Data &data) const
+ {
+ return ...;
+ }
+ };
+
+So defined, `some_transform` is a transform "in the raw". It can be used
+without needing to explicitly specify any arguments to the transform. These
+are the building blocks from which you can compose larger transforms using
+function types.
+
+[section:child_c_and_friends [^_value], [^_child], [^_left], and [^_right]]
+
+ namespace boost { namespace proto
+ {
+ struct _value;
+
+ template<long N>
+ struct _child_c;
+
+ typedef _child_c<0> _child0;
+ typedef _child_c<1> _child1;
+ // ... up to BOOST_PROTO_MAX_ARITY-1
+
+ typedef _child_c<0> _child;
+ typedef _child_c<0> _left;
+ typedef _child_c<1> _right;
+ }}
+
+These transforms are useful for extracting the ['[^N]]th argument from an
+expression. The `_left` transform is equivalent to the `_child_c<0>` transform,
+and the `_right` transform is equivalent to the `_child_c<1>` transform. The
+`_value` transform extracts the value from a terminal expression.
+
+[table
+ [ [Expression]
+ [Returns]
+ ]
+ [ [`boost::result_of<proto::_value(Expr, State, Data)>::type`]
+ [`proto::result_of::value<Expr>::type`]
+ ]
+ [ [`proto::_value()(expr, state, data)`]
+ [`proto::value(expr)`]
+ ]
+ [ [`boost::result_of<proto::_child_c<N>(Expr, State, Data)>::type`]
+ [`proto::result_of::child_c<Expr, N>::type`]
+ ]
+ [ [`proto::_child_c<N>()(expr, state, data)`]
+ [`proto::child_c<N>(expr)`]
+ ]
+ [ [`boost::result_of<proto::_left(Expr, State, Data)>::type`]
+ [`proto::result_of::left<Expr>::type`]
+ ]
+ [ [`proto::_left()(expr, state, data)`]
+ [`proto::left(expr)`]
+ ]
+ [ [`boost::result_of<proto::_right(Expr, State, Data)>::type`]
+ [`proto::result_of::right<Expr>::type`]
+ ]
+ [ [`proto::_right()(expr, state, data)`]
+ [`proto::right(expr)`]
+ ]
+]
+
+Example:
+
+ // Matches an integer terminal and extracts the int.
+ struct Int
+ : when< terminal<int>, _value >
+ {};
+
+[endsect]
+
+[section:identity_and_friends [^_expr], [^_state] and [^_data]]
+
+ namespace boost { namespace proto
+ {
+ struct _expr;
+ struct _state;
+ struct _data;
+ }}
+
+The `_expr`, `_state` and `_data` transforms merely return the
+`expr`, `state` and `data` arguments, respectively. Proto's
+wildcard pattern, `_`, behaves like `_expr` when used
+as a transform.
+
+[table
+ [ [Expression]
+ [Returns]
+ ]
+ [ [`boost::result_of<proto::_(Expr, State, Data)>::type`]
+ [`Expr`]
+ ]
+ [ [`proto::_()(expr, state, data)`]
+ [`expr`]
+ ]
+ [ [`boost::result_of<proto::_expr(Expr, State, Data)>::type`]
+ [`Expr`]
+ ]
+ [ [`proto::_expr()(expr, state, data)`]
+ [`expr`]
+ ]
+ [ [`boost::result_of<proto::_state(Expr, State, Data)>::type`]
+ [`State`]
+ ]
+ [ [`proto::_state()(expr, state, data)`]
+ [`state`]
+ ]
+ [ [`boost::result_of<proto::_data(Expr, State, Data)>::type`]
+ [`Data`]
+ ]
+ [ [`proto::_data()(expr, state, data)`]
+ [`data`]
+ ]
+]
+
+Example:
+
+ // Matches a subscript expression where the left- and right-hand operands
+ // match MyGrammar, returns the expression unmodified
+ struct Subscript
+ : proto::when< proto::subscript<MyGrammar, MyGrammar>, proto::_expr >
+ {};
+
+[endsect]
+
+[section:if [^if_<>]]
+
+ namespace boost { namespace proto
+ {
+ namespace control
+ {
+ template<
+ typename If
+ , typename Then = _
+ , typename Else = not_<_>
+ >
+ struct if_;
+ }
+
+ using control::if_;
+ }}
+
+We've already seen the _if_ template in the context of grammars, but
+_if_ can also be used as a transform. It can be used to conditionally
+apply one transform or another based on some condition. The three
+template parameters are Proto transforms. The result of applying the
+first transform should be a compile-time Boolean. If it is true, then
+the first transform is applied. The second is applied otherwise.
+
+[table
+ [ [Expression]
+ [Returns]
+ ]
+ [ [``boost::result_of<
+ proto::if_<If, Then, Else>(Expr, State, Data)
+>::type``]
+ [``typedef
+ mpl::if_<
+ boost::result_of<proto::when<_, If>(Expr, State, Data)>::type
+ , proto::when<_, Then>
+ , proto::when<_, Else>
+ >::type
+branch;
+
+typedef boost::result_of<branch(Expr, State, Data)>::type type;``]
+ ]
+ [ [`proto::if_<If, Then, Else>()(expr, state, data)`]
+ [``typedef ... branch; // Same as above
+branch()(expr, state, data);``]
+ ]
+]
+
+Example:
+
+ // Match a terminal. If size of the terminal
+ // argument is less than or equal to 4, make
+ // a new terminal that stores the argument by
+ // value. Otherwise, store the argument by
+ // reference.
+ struct ByValOrRef
+ : proto::when<
+ proto::terminal<_>
+ , proto::if_<
+ mpl::less_equal<
+ mpl::sizeof_<proto::_value>
+ , mpl::size_t<4>
+ >()
+ , proto::_make_terminal(proto::_value)
+ , proto::_make_terminal(proto::_ref(proto::_value))
+ >
+ >
+ {};
+
+[endsect]
+
+[section:and_or_not [^and_<>], [^or_<>], and [^not_<>]]
+
+ namespace boost { namespace proto
+ {
+ namespace control
+ {
+ template<typename... T>
+ struct and_;
+
+ template<typename... T>
+ struct or_;
+
+ template<typename T>
+ struct not_;
+ }
+
+ using control::and_;
+ using control::or_;
+ using control::not_;
+ }}
+
+As with _if_, the grammar elements _and_, _or_, and _not_ can
+also be used as transforms. At a high level, here is what the
+transforms do:
+
+[variablelist
+[ [`and_<T0,T1,...,Tn>`]
+ [Apply the transform `Tn`.] ]
+[ [`or_<T0,T1,...,Tn>`]
+ [Apply the transform `Tx` where `x` is the lowest number
+ such that `matches<Expr,Tx>::value` is `true`.] ]
+[ [`not_<T>`] [Return the current expression unchanged.] ]
+]
+
+The following table specifies the behaviors described above more
+precisely.
+
+[table
+ [ [Expression]
+ [Returns]
+ ]
+ [ [``boost::result_of<
+ proto::and_<A,B,C>(Expr, State, Data)
+>::type``]
+ [`boost::result_of<C(Expr, State, Data)>::type`]
+ ]
+ [ [`proto::and_<A,B,C>()(expr, state, data)`]
+ [`C()(expr, state, data)`]
+ ]
+ [ [``boost::result_of<
+ proto::or_<A,B,C>(Expr, State, Data)
+>::type``]
+ [``typedef mpl::if_<
+ proto::matches<Expr, A>
+ , A
+ , mpl::if_<
+ proto::matches<Expr, B>
+ , B
+ , C
+ >::type
+>::type which;
+
+typedef boost::result_of<which(Expr, State, Data)>::type type;``]
+ ]
+ [ [`proto::or_<A,B,C>()(expr, state, data)`]
+ [``typedef ... which; // Same as above
+which()(expr, state, data);``]
+ ]
+ [ [``boost::result_of<
+ proto::not_<A>(Expr, State, Data)
+>::type``]
+ [`Expr`]
+ ]
+ [ [`proto::not_<A>()(expr, state, data)`]
+ [`expr`]
+ ]
+]
+
+Example:
+
+ // A transform that matches any expression and
+ // unwraps any reference_wrapped terminals it
+ // finds.
+ struct UnwrapReference
+ : proto::or_<
+ // Pass through terminals that are not
+ // reference_wrappers unchanged:
+ proto::and_<
+ proto::terminal<_>
+ , proto::not_<proto::if_<boost::is_reference_wrapper<proto::_value>()> >
+ >
+ // For other terminals (i.e., reference_wrapper
+ // terminals), unwrap the reference:
+ , proto::when<
+ proto::terminal<_>
+ , proto::terminal<boost::unwrap_reference<proto::_value> >(proto::_value)
+ >
+ // Otherwise, match non-terminals and
+ // recurse.
+ , proto::when<
+ proto::nary_expr<_, proto::vararg<UnwrapReference> >
+ >
+ >
+ {};
+
+The above transform serves to illustrate the behaviors of the _and_,
+_or_, and _not_ transforms, but it is admittedly contrived. The
+transform is more easily written as follows:
+
+ // Functionally identical to the UnwrapReference
+ // transform above:
+ struct UnwrapReference
+ : proto::or_<
+ proto::when<
+ proto::terminal<boost::reference_wrapper<_> >
+ , proto::terminal<boost::unwrap_reference<proto::_value> >(proto::_value)
+ >
+ , proto::terminal<_>
+ , proto::nary_expr<_, proto::vararg<UnwrapReference> >
+ >
+ {};
+
+[endsect]
+
+[section:call [^call<>]]
+
+[def __CALLABLE__ [~[^Callable]]]
+
+ namespace boost { namespace proto
+ {
+ template<typename Fun>
+ struct call;
+ }}
+
+The `call<>` transform is used to invoke callable transforms and evaluate
+their arguments. When you use a callable transform as in
+`when< unary_plus<_>, __CALLABLE__(_child) >`, the `call<>` transform is used behind
+the scenes to evaluate `__CALLABLE__(_child)`. In fact, for any callable
+transform, the following short- and long-forms are equivalent:
+
+[table
+ [ [Short From]
+ [Long Form] ]
+ [ [ `proto::when< Grammar, __CALLABLE__(Tran1, Tran2...) >` ]
+ [ `proto::when< Grammar, proto::call< __CALLABLE__(Tran1, Tran2...) > >` ] ]
+]
+
+You might decide to use `call<>` explicitly in cases when Proto can't figure out
+that a given transform is callable. (See the discussion on the `is_callable<>` trait
+[link boost_proto.users_guide.expression_transformation.is_callable here].)
+Rather than specialize `proto::is_callable<>` for your transform, you can simply
+wrap its use in `call<>`, instead.
+
+[tip For users of legacy compilers like MSVC 7.1, `call<>` is useful to work
+around compiler bugs. Doubly-nested transforms such as `__CALLABLE__(_child1(_child2))`
+cause older compilers problems, but the equivalent `__CALLABLE__(call<_child1(_child2)>)`
+solves the problem.]
+
+The semantics of `call<>` are described in the table below:
+
+[table
+ [ [Expression]
+ [Returns]
+ ]
+ [ [`boost::result_of<proto::call<Fun(A0, A1, ... AN)>(Expr, State, Data)>::type`]
+ [``boost::result_of<Fun(
+ boost::result_of<proto::when<_, A0>(Expr, State, Data)>::type
+ , boost::result_of<proto::when<_, A1>(Expr, State, Data)>::type
+ ...
+ , boost::result_of<proto::when<_, AN>(Expr, State, Data)>::type
+)>::type``]
+ ]
+ [ [`proto::call<Fun(A0, A1, ... AN)>()(expr, state, data)`]
+ [``Fun()(
+ proto::when<_, A0>()(expr, state, data)
+ , proto::when<_, A1>()(expr, state, data)
+ ...
+ , proto::when<_, AN>()(expr, state, data)
+)``]
+ ]
+]
+
+The target of a callable transform can be any function object that implements
+the Boost.ResultOf protocol. Function objects that take up to
+`BOOST_PROTO_MAX_ARITY` are handled.
+
+For callable transforms that take 0, 1, or 2 arguments, special handling is done
+to see if the transform actually expects 3 arguments, as Proto's primitive
+transforms do. (This can be detected with meta-programming tricks.) So, even
+though a transform like `_child1` requires three parameters: expression,
+state and data; it can be "called" with just one, like `_child1(_child2)`. Proto
+treats this as if were `call<_child1(_child2, _state, _data)>`.
+
+If no transform arguments are specified at all, as in `call<_child1>`, this is
+the same as `_child1`. For this reason, `call<_child1>(_child2)` is the same as
+`call<_child1(_child2)>`.
+
+Example:
+
+[LazyMakePair2]
+
+[endsect]
+
+[section:make [^make<>]]
+
+[def __OBJECT__ [~[^Object]]]
+
+ namespace boost { namespace proto
+ {
+ template<typename Fun>
+ struct make;
+ }}
+
+The `make<>` transform is used to construct objects and evaluate
+their constructor arguments. When you use an object transform as in
+`when< unary_plus<_>, __OBJECT__(_child) >`, the `make<>` transform is used behind
+the scenes to evaluate `__OBJECT__(_child)`. In fact, for any object
+transform, the following short- and long-forms are equivalent:
+
+[table
+ [ [Short From]
+ [Long Form] ]
+ [ [ `proto::when< Grammar, __OBJECT__(Tran1, Tran2...) >` ]
+ [ `proto::when< Grammar, proto::make< __OBJECT__(Tran1, Tran2...) > >` ] ]
+]
+
+You might decide to use `make<>` to explicitly differentiate object
+transforms from callable transforms. (See `call<>`.)
+
+[tip For users of legacy compilers like MSVC 7.1, `make<>` is useful to work
+around compiler bugs. Doubly-nested transforms such as `Object1(Object2(_child))`
+cause older compilers problems, but the equivalent `Object1(make<Object2(_child)>)`
+solves the problem.]
+
+The `make<>` transform checks to see if the resulting object type is a template.
+If it is, the template type is disassembled to find nested transforms. Proto
+considers the following types to represent transforms:
+
+[def __type__ [~type]]
+[def __X__ X\']
+[def __X0__ X0\']
+[def __X1__ X1\']
+[def __MakeImpl__ [~[^MakeImpl]]]
+
+* Function types
+* Function pointer types
+* Types for which `proto::is_callable<__type__>::value` is `true`
+
+When an object transform with a template type such as
+`Object<X0,X1,...>(Args...)` is evaluated with a given
+`Expr`, `State`, and `Data`, the result type is
+`__MakeImpl__<Object<X0,X1,...>, Expr, State, Data>::type` which is
+defined as follows. For each `X` in `X0,X1,...`, do:
+
+* If `X` is a transform, then let `__X__` be
+ `boost::result_of<proto::when<_, X>(Expr, State, Data)>::type`.
+ Note that a substitution took place.
+* Otherwise, if `X` is a template like `Object2<Y0,Y1,...>`, then
+ let `__X__` be `__MakeImpl__<Object2<Y0,Y1,...>, Expr, State, Data>::type`
+ (which evaluates this procedure recursively). Note whether any
+ substitutions took place during this operation.
+* Otherwise, let `__X__` be `X`, and note that no substitution
+ took place.
+* If any substitutions took place in any of the above steps and
+ `Object<__X0__,__X1__,...>` has a nested `::type` typedef, the
+ result type is `Object<__X0__,__X1__,...>::type`.
+* Otherwise, the result type is `Object<__X0__,__X1__,...>`.
+
+Note that `when<>` is implemented in terms of `call<>` and `make<>`,
+so the above procedure is evaluated recursively.
+
+Given the above description of the `__MakeImpl__<>` helper, the semantics
+of the `make<>` transform is described as follows:
+
+[def __AN__ A[~N]]
+
+[table
+ [ [Expression]
+ [Returns]
+ ]
+ [ [`boost::result_of<proto::make<Object(A0, A1, ... __AN__)>(Expr, State, Data)>::type`]
+ [`__MakeImpl__<Object, Expr, State, Data>::type`]
+ ]
+ [ [`proto::make<Object(A0, A1, ... __AN__)>()(expr, state, data)`]
+ [``__MakeImpl__<Object, Expr, State, Data>::type(
+ proto::when<_, A0>()(expr, state, data)
+ , proto::when<_, A1>()(expr, state, data)
+ ...
+ , proto::when<_, __AN__>()(expr, state, data)
+)``]
+ ]
+]
+
+Objects with constructors that take up to `BOOST_PROTO_MAX_ARITY` are handled.
+Some types are so-called /aggregates/ that do not have constructors; rather,
+they use /aggregate initialization/. For these types, you can specialize
+`proto::is_aggregate<>` and Proto will use a brace initializer list to
+initialize the object rather than a constructor. Proto knows that `proto::expr<>`
+is such an aggregate, so if you use object transforms to "construct" a
+new node in an expression tree, the right thing happens.
+
+If no transform arguments are specified at all, as in `make<Object>`, this is
+the same as `make<Object()>`.
+
+Example:
+
+[LazyMakePair]
+
+[endsect]
+
+[section:lazy [^lazy<>]]
+
+ namespace boost { namespace proto
+ {
+ template<typename Fun>
+ struct lazy;
+ }}
+
+Sometimes you would like a higher-order transform that returns another
+transform to be evaluated. This can happen when you have a transform
+whose behavior needs to be parameterized on the current state of the
+transformation. For these situations, you can use the `lazy<>` transform,
+which is essentially an invocation of the `make<>` transform (to evaluate
+any nested transforms and create the higher-order transform) followed
+by an invocation of `call<>` (to actually execute the higher-order
+transform).
+
+The behavior of `lazy<>` is easily specified in terms of `make<>` and
+`call<>`.
+
+[table
+ [ [Expression]
+ [Returns]
+ ]
+ [ [`boost::result_of<proto::lazy<Object(A0, A1, ... __AN__)>(Expr, State, Data)>::type`]
+ [``boost::result_of<proto::call<
+ boost::result_of<proto::make<Object>(Expr, State, Data)>::type(A0, A1, ... __AN__)
+>(Expr, State, Data)>::type``]
+ ]
+ [ [`proto::lazy<Object(A0, A1, ... __AN__)>()(expr, state, data)`]
+ [``proto::call<
+ boost::result_of<proto::make<Object>(Expr, State, Data)>::type(A0, A1, ... __AN__)
+>()(expr, state, data)``]
+ ]
+]
+
+If no transform arguments are specified at all, as in `lazy<Object>`, this is
+the same as `lazy<Object(_expr, _state, _data)>`.
+
+[endsect]
+
+[section:when [^when<>]]
+
+ namespace boost { namespace proto
+ {
+ template<typename Grammar, typename Transform = Grammar>
+ struct when;
+ }}
+
+`when<>` associates a grammar rule with a transform. It can be used
+in a grammar in place of the rule; that is, it behaves as a grammar
+rule. Expression tree nodes that match the grammar rule are processed
+with the associated transform; that is, `when<>` also behaves like
+a transform.
+
+When no transform is specified, as with `when< unary_plus<Calculator> >`,
+the grammar is treated as the transform. Every grammar element has
+a default transform. For most, such as `unary_plus<>`, the default transform
+is `pass_through<>`.
+
+The `when<>` transform is easily specified in terms of `call<>`,
+`make<>`, and the `is_callable<>` trait.
+
+[table
+ [ [Expression]
+ [Returns]
+ ]
+ [ [`boost::result_of<proto::when<Grammar, R(A0, A1, ... __AN__)>(Expr, State, Data)>::type`]
+ [``boost::result_of<boost::mpl::if_<
+ proto::is_callable<R>
+ , proto::call<R(A0, A1, ... __AN__)>
+ , proto::make<R(A0, A1, ... __AN__)>
+>::type(Expr, State, Data)>::type``]
+ ]
+ [ [`proto::when<Grammar, R(A0, A1, ... __AN__)>()(expr, state, data)`]
+ [``boost::mpl::if_<
+ proto::is_callable<R>
+ , proto::call<R(A0, A1, ... __AN__)>
+ , proto::make<R(A0, A1, ... __AN__)>
+>::type()(expr, state, data)``]
+ ]
+]
+
+If no transform arguments are specified, as in `when<Grammar, _child>`, the
+transform is assumed to be callable; that is, it is equivalent to
+`when<Grammar, call<_child> >`.[footnote It is done this way to improve compile
+times.]
+
+[endsect]
+
+[section:fold [^fold<>] and [^reverse_fold<>]]
+
+ namespace boost { namespace proto
+ {
+ template<typename Sequence, typename State0, typename Fun>
+ struct fold;
+
+ template<typename Sequence, typename State0, typename Fun>
+ struct reverse_fold;
+ }}
+
+The transforms `fold<>` and `reverse_fold<>` are akin to the
+`std::accumulate()` algorithm in the STL, or the `fold()` algorithm in
+Boost.Fusion. They iterate over some sequence and
+accumulate some state at each element. The `fold<>`
+transform iterates over the children in order, starting with the 0th child.
+The `reverse_fold<>` transform does it in reverse order, starting with the Nth
+child. (Note that for building things like cons lists, you'll often want to
+built it back-to-front with `reverse_fold<>`.)
+
+Both `fold<>` and `reverse_fold<>` are implemented in terms of `fusion::fold<>`.
+The three template parameters must each be Proto transforms. The have the following
+meaning:
+
+* `Sequence`: A Proto transform that returns a Fusion sequence.
+* `State`: A Proto transform that returns the initial state of the fold.
+* `Fun`: A Proto transform representing the operation to perform at each
+ iteration of the fold algorithm.
+
+Often, the `Sequence` parameter is `proto::_`, which returns the current node
+in the Proto expression tree. Tree nodes are valid Fusion sequences, where
+the children are the elements of the sequence.
+
+[def __AS_CALLABLE__ [~[^AsCallable]]]
+
+The semantics of the `fold<>` and `reverse_fold<>` transforms can both be
+understood in terms of a helper struct, `__AS_CALLABLE__<>`, which binds the
+data and the `Fun` transform into a binary function object for use by
+`fusion::fold()`. `__AS_CALLABLE__<>` has the following behavior:
+
+[table
+ [ [Expression]
+ [Returns]
+ ]
+ [ [`boost::result_of<__AS_CALLABLE__<Fun, Data>(Expr, State)>::type`]
+ [`boost::result_of<proto::when<_, Fun>(Expr, State, Data)>::type`]
+ ]
+ [ [`__AS_CALLABLE__<Fun, Data>(data)(expr, state)`]
+ [`proto::when<_, Fun>()(expr, state, data)`]
+ ]
+]
+
+With the above `__AS_CALLABLE__<>` adaptor, `fold<>` and `reverse_fold<>`
+can be easily implemented in terms of `fusion::fold<>`:
+
+[table
+ [ [Expression]
+ [Returns]
+ ]
+ [ [`boost::result_of<proto::fold<Sequence, State0, Fun>(Expr, State, Data)>::type`]
+ [``fusion::result_of::fold<
+ boost::result_of<proto::when<_, Sequence>(Expr, State, Data)>::type
+ , boost::result_of<proto::when<_, State0>(Expr, State, Data)>::type
+ , __AS_CALLABLE__<Fun, Data>
+>::type``]
+ ]
+ [ [`proto::fold<Sequence, State0, Fun>()(expr, state, data)`]
+ [``fusion::fold(
+ proto::when<_, Sequence>()(expr, state, data)
+ , proto::when<_, State0>()(expr, state, data)
+ , __AS_CALLABLE__<Fun, Data>(data)
+)``]
+ ]
+ [ [`boost::result_of<proto::reverse_fold<Sequence, State0, Fun>(Expr, State, Data)>::type`]
+ [``fusion::result_of::fold<
+ fusion::result_of::reverse<
+ boost::result_of<proto::when<_, Sequence>(Expr, State, Data)>::type
+ >::type
+ , boost::result_of<proto::when<_, State0>(Expr, State, Data)>::type
+ , __AS_CALLABLE__<Fun, Data>
+>::type``]
+ ]
+ [ [`proto::reverse_fold<Sequence, State0, Fun>()(expr, state, data)`]
+ [``fusion::fold(
+ fusion::reverse(
+ proto::when<_, Sequence>()(expr, state, data)
+ )
+ , proto::when<_, State0>()(expr, state, data)
+ , __AS_CALLABLE__<Fun, Data>(data)
+)``]
+ ]
+]
+
+[#reverse_fold_example]Example:
+
+[AsArgList]
+
+[endsect]
+
+[section:fold_tree [^fold_tree<>] and [^reverse_fold_tree<>]]
+
+ namespace boost { namespace proto
+ {
+ template<typename Sequence, typename State0, typename Fun>
+ struct fold_tree;
+
+ template<typename Sequence, typename State0, typename Fun>
+ struct reverse_fold_tree;
+ }}
+
+The `fold_tree<>` and `reverse_fold_tree<>` transforms recursively apply the
+`fold<>` and `reverse_fold<>` transforms to sub-trees that all share a common
+tag type. This is useful for flattening trees into lists; for example, you
+might use `reverse_fold_tree<>` to flatten an expression tree like `a | b | c`
+into a Fusion list like `cons(a, cons(b, cons(c)))`.
+
+The `fold_tree<>` and `reverse_fold_tree<>` transforms are unlike the other
+transforms that Proto provides in that they operate on entire sub-trees rather
+than just single nodes within the tree.
+
+[def __FOLD_TREE_IMPL__ [~[^FoldTreeImpl]]]
+[def __REVERSE_FOLD_TREE_IMPL__ [~[^ReverseFoldTreeImpl]]]
+
+These are higher-level transforms, implemented in terms of the `fold<>`
+and `reverse_fold<>` transforms and helper structs `__FOLD_TREE_IMPL__<>` and
+`__REVERSE_FOLD_TREE_IMPL__<>`, one of which is shown below:
+
+ // FoldTreeImpl either recurses into the expression, if its Grammar
+ // matches, or else ends the recursion by matching Grammar and
+ // applying its transform.
+ template<typename Grammar, typename Fun>
+ struct __FOLD_TREE_IMPL__
+ : proto::or_<
+ proto::when<Grammar, proto::fold<_, proto::_state, __FOLD_TREE_IMPL__<Grammar, Fun> > >
+ , proto::when<_, Fun>
+ >
+ {};
+
+The `__REVERSE_FOLD_TREE_IMPL__<>` helper is specified similarly, only with
+`reverse_fold<>` instead of `fold<>`. With these two helpers, we can
+specify the behavior of `fold_tree<>` and `reverse_fold_tree<>` as
+follows:
+
+[table
+ [ [Expression]
+ [Returns]
+ ]
+ [ [``boost::result_of<
+ proto::fold_tree<Sequence, State0, Fun>(Expr, State, Data)
+>::type``]
+ [``boost::result_of<
+ proto::fold<
+ Sequence
+ , State0
+ , __FOLD_TREE_IMPL__<
+ proto::nary_expr<Expr::proto_tag, proto::vararg<_> >
+ , Fun
+ >
+ >(Expr, State, Data)
+>::type``]
+ ]
+ [ [`proto::fold_tree<Sequence, State0, Fun>()(expr, state, data)`]
+ [``proto::fold<
+ Sequence
+ , State0
+ , __FOLD_TREE_IMPL__<
+ proto::nary_expr<Expr::proto_tag, proto::vararg<_> >
+ , Fun
+ >
+>()(expr, state, data)``]
+ ]
+ [ [``boost::result_of<
+ proto::reverse_fold_tree<Sequence, State0, Fun>(Expr, State, Data)
+>::type``]
+ [``boost::result_of<
+ proto::reverse_fold<
+ Sequence
+ , State0
+ , __REVERSE_FOLD_TREE_IMPL__<
+ proto::nary_expr<Expr::proto_tag, proto::vararg<_> >
+ , Fun
+ >
+ >(Expr, State, Data)
+>::type``]
+ ]
+ [ [`proto::reverse_fold_tree<Sequence, State0, Fun>()(expr, state, data)`]
+ [``proto::reverse_fold<
+ Sequence
+ , State0
+ , __REVERSE_FOLD_TREE_IMPL__<
+ proto::nary_expr<Expr::proto_tag, proto::vararg<_> >
+ , Fun
+ >
+>()(expr, state, data)``]
+ ]
+]
+
+Example:
+
+[FoldTreeToList]
+
+[endsect]
+
+[section:pass_through [^pass_through<>]]
+
+ namespace boost { namespace proto
+ {
+ template<typename Grammar>
+ struct pass_through;
+ }}
+
+The `pass_through<>` transform iterates over the pairs of
+children in the grammar and the expression, applying the child grammar's
+transform to the corresponding child expression. The resulting transformed
+children expressions are reassembled back into an expression of the same
+type as the parent expression.
+
+As a side-effect, `pass_through<>` transforms all sub-expressions held by
+reference into ones held by value.
+
+Note that all expression generator meta-functions (Eg., `unary_plus<>`,
+`shift_right<>`, `function<>`, `nary_expr<>`, etc.) have a pass-through
+transform by default, so there is rarely any need to use the `pass_through<>`
+transform explicitly.
+
+[table
+ [ [Expression]
+ [Returns]
+ ]
+ [ [``boost::result_of<
+ proto::pass_through<Grammar>(Expr, State, Data)
+>::type``]
+ [``proto::nary_expr<
+ Expr::proto_tag
+ , boost::result_of<Grammar::proto_child0(Expr::proto_child0, State, Data)>::type
+ , boost::result_of<Grammar::proto_child1(Expr::proto_child1, State, Data)>::type
+ // ...
+ , boost::result_of<Grammar::proto_childN(Expr::proto_childN, State, Data)>::type
+>::type``]
+ ]
+ [ [`proto::pass_through<Grammar>()(expr, state, data)`]
+ [``proto::make_expr<Expr::proto_tag>(
+ Grammar::proto_child0()(proto::child_c<0>(expr), state, data)
+ Grammar::proto_child1()(proto::child_c<1>(expr), state, data)
+ // ...
+ Grammar::proto_childN()(proto::child_c<N>(expr), state, data)
+)``]
+ ]
+]
+
+Example:
+
+[Promote]
+
+[endsect]
+
+[endsect]
+
+[/======================================================]
+[section:user_defined_transforms User-Defined Transforms]
+[/======================================================]
+
+In previous sections, we've seen how to compose larger transforms
+out of smaller transforms using function types.
+We've also seen the primitive transforms that Proto provides.
+So-called primitive transforms can be used without specifying
+arguments, like `_child0` which returns the first child of the
+current node. But primitive transforms are not special in any way.
+They are merely ternary function objects that take the current
+expression, state and data as arguments.
+
+You can define your own primitive transforms. You might want to
+do this if your transform is complicated and composing it out
+of primitives becomes unwieldy. You might also do this
+to work around compiler bugs on legacy compilers that makes
+composing transforms using function types problematic. Finally,
+you might also decide to define your own primitive transforms
+to improve compile times. Since Proto can simply invoke a
+primitive transform directly without having to process arguments
+or differentiate callable transforms from object transforms,
+primitive transforms are more efficient.
+
+To define your own primitive transform, merely define a ternary
+function object that accepts an expression, a state and a data.
+Here, for example, is how Proto defines the `_child_c<>` transform:
+
+ namespace boost { namespace proto
+ {
+ // A transform that returns the I-th child
+ template<int I>
+ struct _child_c : callable
+ {
+ // Nested "result" template, used by
+ // boost::result_of<> to compute the
+ // return type of the function.
+ template<typename Sig>
+ struct result;
+
+ template<typename This, typename Expr, typename State, typename Data>
+ struct result<This(Expr, State, Data)>
+ : proto::result_of::child_c<Expr, I>
+ {};
+
+ // Function call operator that actually
+ // executes the transform.
+ template<typename Expr, typename State, typename Data>
+ typename proto::result_of::child_c<Expr, I>::const_reference
+ operator ()(Expr const &expr, State const &, Data &) const
+ {
+ return proto::child_c<I>(expr);
+ }
+ };
+
+ // Note that _child_c<I> is callable, so that
+ // it can be used with arguments, as:
+ // _child_c<0>(_child_c<1>)
+ template<int I>
+ struct is_callable<_child_c<I> >
+ : mpl::true_
+ {};
+ }}
+
+There is nothing particularly special about the definition of
+`_child_c<>`. It is just an ordinary polymorphic function object. The
+only interesting bit is the `is_callable<>` specialization, which
+will be described in the section called "Making Your Transform
+Callable".
+
+Once you have defined such a ternary function object, you can use
+it as a transform without any arguments and Proto will automatically
+pass it the current expression, state and data parameters.
+
+[endsect]
+
+[/=================================================]
+[section:is_callable Making Your Transform Callable]
+[/=================================================]
+
+Transforms are typically of the form `when< Something, R(A0,A1,...) >`. The
+question is whether `R` represents a function to call or an object to
+construct, and the answer determines how `when<>` evaluates the transform.
+`when<>` uses the `is_callable<>` trait to disambiguate between the two.
+Proto does its best to guess whether a transform is callable or not, but
+it doesn't always get it right. It's best to know the rules Proto uses,
+so that you know when you need to specialize `is_callable<>`.
+
+The first thing to know is that templates are not considered callable
+by default. This is true ['even if the template inherits from
+`proto::callable`]. Consider the following erroneous transform:
+
+ // Proto can't tell this defines a
+ // callable transform!
+ template<typename T>
+ struct times2 : callable
+ {
+ typedef T result_type;
+
+ T operator()(T i) const
+ {
+ return i * 2;
+ }
+ };
+
+ // ERROR! This is not going to
+ // multiply the int by 2.
+ struct IntTimes2
+ : when< terminal<int>, times2<int>(_value) >
+ {};
+
+The problem is that Proto doesn't know that `times2<int>` is a callable
+transform. Instead, it assumes it's an object transform and will try to
+construct a `times2<int>` object and initialize it will an `int`. That
+will not compile.
+
+[note Why can't Proto tell that `times2<int>` is callable? After all,
+it inherits from `proto::callable`, and that is detectable, right?
+In fact, determining whether some type `X<Y>` inherits from
+`callable` will cause the template `X<Y>` to be instantiated. That's a
+problem for a type like `std::vector<_value(_child1)>()`, which is a valid
+transform that default-constructs a particular instantiation of
+`std::vector<>`. But `std::vector<>` will not suffer to be instantiated
+with `_value(_child1)` as a template parameter! As a result, Proto has
+to assume that a type `X<Y>` represents an object transform and not
+a callable transform.]
+
+There are a couple of solutions to the `times2<int>` problem. One
+solution is to wrap the transform in `call<>`. This forces Proto to
+treat `times2<int>` as callable:
+
+ // OK, calls times2<int>
+ struct IntTimes2
+ : when< terminal<int>, call<times2<int>(_value)> >
+ {};
+
+This can be a bit of a pain, because we need to wrap every use of
+`times2<int>`, which can be tedious and error prone, and makes our
+grammar cluttered and harder to read.
+
+Another solution is to specialize `proto::is_callable<>` on our
+`times2<>` template:
+
+ namespace boost { namespace proto
+ {
+ template<typename T>
+ struct is_callable<times2<T> >
+ : mpl::true_
+ {};
+ }}
+
+ // OK, times2<> is callable
+ struct IntTimes2
+ : when< terminal<int>, times2<int>(_value) >
+ {};
+
+This is better, but still a pain because of the need to open
+Proto's namespace.
+
+You could simply make sure that the transform is not
+a template. Consider the following:
+
+ // No longer a template!
+ struct times2int : times2<int> {};
+
+ // OK, times2int is callable
+ struct IntTimes2
+ : when< terminal<int>, times2int(_value) >
+ {};
+
+This works because now Proto can tell that `times2int` inherits
+(indirectly) from `proto::callable`. Any non-template types can
+be safely checked for inheritance because, as they are not
+templates, there is no worry about instantiation errors.
+
+There is one last way to tell Proto that `times2<>` is callable.
+You could add an extra dummy template parameter that defaults
+to `proto::callable`:
+
+ // Proto will recognize this as callable
+ template<typename T, typename Dummy = callable>
+ struct times2 : callable
+ {
+ typedef T result_type;
+
+ T operator()(T i) const
+ {
+ return i * 2;
+ }
+ };
+
+ // OK, this works!
+ struct IntTimes2
+ : when< terminal<int>, times2<int>(_value) >
+ {};
+
+Note that in addition to the extra template parameter, `times2<>`
+still inherits from `callable`. That's not necessary in this example
+but it's good style because any types derived from `times2<>` (as
+`times2int` defined above) will still be considered callable.
+
+[endsect]
+
+[endsect]

Added: branches/proto/v4/libs/proto/doc/wave.sh
==============================================================================
--- (empty file)
+++ branches/proto/v4/libs/proto/doc/wave.sh 2008-04-06 02:19:35 EDT (Sun, 06 Apr 2008)
@@ -0,0 +1,7 @@
+../../../../dist/bin/wave\
+ -S ../../../..\
+ -S "C:\\Program Files\\Microsoft Visual Studio .NET 2003\\vc7\\include"\
+ -D _WIN32\
+ -D BOOST_PROTO_DOXYGEN_INVOKED\
+ -p 1\
+ `cygpath -d $1`

Added: branches/proto/v4/libs/proto/example/Jamfile.v2
==============================================================================
--- (empty file)
+++ branches/proto/v4/libs/proto/example/Jamfile.v2 2008-04-06 02:19:35 EDT (Sun, 06 Apr 2008)
@@ -0,0 +1,70 @@
+# (C) Copyright 2004: Eric Niebler
+# Distributed under the Boost Software License, Version 1.0.
+# (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+exe hello
+ :
+ hello.cpp
+ ;
+
+
+exe calc1
+ :
+ calc1.cpp
+ ;
+
+exe calc2
+ :
+ calc2.cpp
+ ;
+
+exe calc3
+ :
+ calc3.cpp
+ ;
+
+exe lazy_vector
+ :
+ lazy_vector.cpp
+ ;
+
+exe tarray
+ :
+ tarray.cpp
+ ;
+
+exe rgb
+ :
+ rgb.cpp
+ ;
+
+exe vec3
+ :
+ vec3.cpp
+ ;
+
+exe vector
+ :
+ vector.cpp
+ ;
+
+exe mixed
+ :
+ mixed.cpp
+ ;
+
+exe futures
+ :
+ futures.cpp
+ ;
+
+exe map_assign
+ :
+ map_assign.cpp
+ ;
+
+exe lambda
+ :
+ lambda.cpp
+ ;
+

Added: branches/proto/v4/libs/proto/example/calc1.cpp
==============================================================================
--- (empty file)
+++ branches/proto/v4/libs/proto/example/calc1.cpp 2008-04-06 02:19:35 EDT (Sun, 06 Apr 2008)
@@ -0,0 +1,70 @@
+//[ Calc1
+// Copyright 2008 Eric Niebler. Distributed under the Boost
+// Software License, Version 1.0. (See accompanying file
+// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+// This is a simple example of how to build an arithmetic expression
+// evaluator with placeholders.
+
+#include <iostream>
+#include <boost/mpl/int.hpp>
+#include <boost/proto/core.hpp>
+#include <boost/proto/context.hpp>
+namespace mpl = boost::mpl;
+namespace proto = boost::proto;
+using proto::_;
+
+template<int I> struct placeholder {};
+
+// Define some placeholders
+proto::terminal< placeholder< 1 > >::type const _1 = {{}};
+proto::terminal< placeholder< 2 > >::type const _2 = {{}};
+
+// Define a calculator context, for evaluating arithmetic expressions
+struct calculator_context
+ : proto::callable_context< calculator_context const >
+{
+ // The values bound to the placeholders
+ double d[2];
+
+ // The result of evaluating arithmetic expressions
+ typedef double result_type;
+
+ explicit calculator_context(double d1 = 0., double d2 = 0.)
+ {
+ d[0] = d1;
+ d[1] = d2;
+ }
+
+ // Handle the evaluation of the placeholder terminals
+ template<int I>
+ double operator ()(proto::tag::terminal, placeholder<I>) const
+ {
+ return d[ I - 1 ];
+ }
+};
+
+template<typename Expr>
+double evaluate( Expr const &expr, double d1 = 0., double d2 = 0. )
+{
+ // Create a calculator context with d1 and d2 substituted for _1 and _2
+ calculator_context const ctx(d1, d2);
+
+ // Evaluate the calculator expression with the calculator_context
+ return proto::eval(expr, ctx);
+}
+
+int main()
+{
+ // Displays "5"
+ std::cout << evaluate( _1 + 2.0, 3.0 ) << std::endl;
+
+ // Displays "6"
+ std::cout << evaluate( _1 * _2, 3.0, 2.0 ) << std::endl;
+
+ // Displays "0.5"
+ std::cout << evaluate( (_1 - _2) / _2, 3.0, 2.0 ) << std::endl;
+
+ return 0;
+}
+//]

Added: branches/proto/v4/libs/proto/example/calc2.cpp
==============================================================================
--- (empty file)
+++ branches/proto/v4/libs/proto/example/calc2.cpp 2008-04-06 02:19:35 EDT (Sun, 06 Apr 2008)
@@ -0,0 +1,110 @@
+//[ Calc2
+// Copyright 2008 Eric Niebler. Distributed under the Boost
+// Software License, Version 1.0. (See accompanying file
+// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+// This example enhances the simple arithmetic expression evaluator
+// in calc1.cpp by using proto::extends to make arithemetic
+// expressions immediately evaluatable with operator (), a-la a
+// function object
+
+#include <iostream>
+#include <boost/mpl/int.hpp>
+#include <boost/proto/core.hpp>
+#include <boost/proto/context.hpp>
+namespace mpl = boost::mpl;
+namespace proto = boost::proto;
+using proto::_;
+
+// Will be used to define the placeholders _1 and _2
+template<int I> struct placeholder {};
+
+// For expressions in the calculator domain, operator ()
+// will be special; it will evaluate the expression.
+struct calculator_domain;
+
+// Define a calculator context, for evaluating arithmetic expressions
+// (This is as before, in calc1.cpp)
+struct calculator_context
+ : proto::callable_context< calculator_context const >
+{
+ // The values bound to the placeholders
+ double d[2];
+
+ // The result of evaluating arithmetic expressions
+ typedef double result_type;
+
+ explicit calculator_context(double d1 = 0., double d2 = 0.)
+ {
+ d[0] = d1;
+ d[1] = d2;
+ }
+
+ // Handle the evaluation of the placeholder terminals
+ template<int I>
+ double operator ()(proto::tag::terminal, placeholder<I>) const
+ {
+ return d[ I - 1 ];
+ }
+};
+
+// Wrap all calculator expressions in this type, which defines
+// operator () to evaluate the expression.
+template<typename Expr>
+struct calculator_expression
+ : proto::extends<Expr, calculator_expression<Expr>, calculator_domain>
+{
+ typedef
+ proto::extends<Expr, calculator_expression<Expr>, calculator_domain>
+ base_type;
+
+ explicit calculator_expression(Expr const &expr = Expr())
+ : base_type(expr)
+ {}
+
+ using base_type::operator =;
+
+ // Override operator () to evaluate the expression
+ double operator ()() const
+ {
+ calculator_context const ctx;
+ return proto::eval(*this, ctx);
+ }
+
+ double operator ()(double d1) const
+ {
+ calculator_context const ctx(d1);
+ return proto::eval(*this, ctx);
+ }
+
+ double operator ()(double d1, double d2) const
+ {
+ calculator_context const ctx(d1, d2);
+ return proto::eval(*this, ctx);
+ }
+};
+
+// Tell proto how to generate expressions in the calculator_domain
+struct calculator_domain
+ : proto::domain<proto::generator<calculator_expression> >
+{};
+
+// Define some placeholders (notice they're wrapped in calculator_expression<>)
+calculator_expression<proto::terminal< placeholder< 1 > >::type> const _1;
+calculator_expression<proto::terminal< placeholder< 2 > >::type> const _2;
+
+// Now, our arithmetic expressions are immediately executable function objects:
+int main()
+{
+ // Displays "5"
+ std::cout << (_1 + 2.0)( 3.0 ) << std::endl;
+
+ // Displays "6"
+ std::cout << ( _1 * _2 )( 3.0, 2.0 ) << std::endl;
+
+ // Displays "0.5"
+ std::cout << ( (_1 - _2) / _2 )( 3.0, 2.0 ) << std::endl;
+
+ return 0;
+}
+//]

Added: branches/proto/v4/libs/proto/example/calc3.cpp
==============================================================================
--- (empty file)
+++ branches/proto/v4/libs/proto/example/calc3.cpp 2008-04-06 02:19:35 EDT (Sun, 06 Apr 2008)
@@ -0,0 +1,155 @@
+//[ Calc3
+// Copyright 2008 Eric Niebler. Distributed under the Boost
+// Software License, Version 1.0. (See accompanying file
+// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+// This example enhances the arithmetic expression evaluator
+// in calc2.cpp by using a proto transform to calculate the
+// number of arguments an expression requires and using a
+// compile-time assert to guarantee that the right number of
+// arguments are actually specified.
+
+#include <iostream>
+#include <boost/mpl/int.hpp>
+#include <boost/mpl/assert.hpp>
+#include <boost/mpl/min_max.hpp>
+#include <boost/proto/core.hpp>
+#include <boost/proto/context.hpp>
+#include <boost/proto/transform.hpp>
+namespace mpl = boost::mpl;
+namespace proto = boost::proto;
+using proto::_;
+
+// Will be used to define the placeholders _1 and _2
+template<typename I> struct placeholder : I {};
+
+// This grammar basically says that a calculator expression is one of:
+// - A placeholder terminal
+// - Some other terminal
+// - Some non-terminal whose children are calculator expressions
+// In addition, it has transforms that say how to calculate the
+// expression arity for each of the three cases.
+struct CalculatorGrammar
+ : proto::or_<
+
+ // placeholders have a non-zero arity ...
+ proto::when< proto::terminal< placeholder<_> >, proto::_value >
+
+ // Any other terminals have arity 0 ...
+ , proto::when< proto::terminal<_>, mpl::int_<0>() >
+
+ // For any non-terminals, find the arity of the children and
+ // take the maximum. This is recursive.
+ , proto::when< proto::nary_expr<_, proto::vararg<_> >
+ , proto::fold<_, mpl::int_<0>(), mpl::max<CalculatorGrammar, proto::_state>() > >
+
+ >
+{};
+
+// Simple wrapper for calculating a calculator expression's arity.
+// It specifies mpl::int_<0> as the initial state. The data, which
+// is not used, is mpl::void_.
+template<typename Expr>
+struct calculator_arity
+ : boost::result_of<CalculatorGrammar(Expr, mpl::int_<0>, mpl::void_)>
+{};
+
+// For expressions in the calculator domain, operator ()
+// will be special; it will evaluate the expression.
+struct calculator_domain;
+
+// Define a calculator context, for evaluating arithmetic expressions
+// (This is as before, in calc1.cpp and calc2.cpp)
+struct calculator_context
+ : proto::callable_context< calculator_context const >
+{
+ // The values bound to the placeholders
+ double d[2];
+
+ // The result of evaluating arithmetic expressions
+ typedef double result_type;
+
+ explicit calculator_context(double d1 = 0., double d2 = 0.)
+ {
+ d[0] = d1;
+ d[1] = d2;
+ }
+
+ // Handle the evaluation of the placeholder terminals
+ template<typename I>
+ double operator ()(proto::tag::terminal, placeholder<I>) const
+ {
+ return d[ I() - 1 ];
+ }
+};
+
+// Wrap all calculator expressions in this type, which defines
+// operator () to evaluate the expression.
+template<typename Expr>
+struct calculator_expression
+ : proto::extends<Expr, calculator_expression<Expr>, calculator_domain>
+{
+ typedef
+ proto::extends<Expr, calculator_expression<Expr>, calculator_domain>
+ base_type;
+
+ explicit calculator_expression(Expr const &expr = Expr())
+ : base_type(expr)
+ {}
+
+ using base_type::operator =;
+
+ // Override operator () to evaluate the expression
+ double operator ()() const
+ {
+ // Assert that the expression has arity 0
+ BOOST_MPL_ASSERT_RELATION(0, ==, calculator_arity<Expr>::type::value);
+ calculator_context const ctx;
+ return proto::eval(*this, ctx);
+ }
+
+ double operator ()(double d1) const
+ {
+ // Assert that the expression has arity 1
+ BOOST_MPL_ASSERT_RELATION(1, ==, calculator_arity<Expr>::type::value);
+ calculator_context const ctx(d1);
+ return proto::eval(*this, ctx);
+ }
+
+ double operator ()(double d1, double d2) const
+ {
+ // Assert that the expression has arity 2
+ BOOST_MPL_ASSERT_RELATION(2, ==, calculator_arity<Expr>::type::value);
+ calculator_context const ctx(d1, d2);
+ return proto::eval(*this, ctx);
+ }
+};
+
+// Tell proto how to generate expressions in the calculator_domain
+struct calculator_domain
+ : proto::domain<proto::generator<calculator_expression> >
+{};
+
+// Define some placeholders (notice they're wrapped in calculator_expression<>)
+calculator_expression<proto::terminal< placeholder< mpl::int_<1> > >::type> const _1;
+calculator_expression<proto::terminal< placeholder< mpl::int_<2> > >::type> const _2;
+
+// Now, our arithmetic expressions are immediately executable function objects:
+int main()
+{
+ // Displays "5"
+ std::cout << (_1 + 2.0)( 3.0 ) << std::endl;
+
+ // Displays "6"
+ std::cout << ( _1 * _2 )( 3.0, 2.0 ) << std::endl;
+
+ // Displays "0.5"
+ std::cout << ( (_1 - _2) / _2 )( 3.0, 2.0 ) << std::endl;
+
+ // This won't compile because the arity of the
+ // expression doesn't match the number of arguments
+ // ( (_1 - _2) / _2 )( 3.0 );
+
+ return 0;
+}
+//]

Added: branches/proto/v4/libs/proto/example/futures.cpp
==============================================================================
--- (empty file)
+++ branches/proto/v4/libs/proto/example/futures.cpp 2008-04-06 02:19:35 EDT (Sun, 06 Apr 2008)
@@ -0,0 +1,128 @@
+//[ FutureGroup
+// Copyright 2008 Eric Niebler. Distributed under the Boost
+// Software License, Version 1.0. (See accompanying file
+// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+// This is an example of using Proto transforms to implement
+// Howard Hinnant's future group proposal.
+
+#include <boost/fusion/tuple.hpp>
+#include <boost/fusion/include/as_vector.hpp>
+#include <boost/fusion/include/joint_view.hpp>
+#include <boost/fusion/include/single_view.hpp>
+#include <boost/proto/core.hpp>
+#include <boost/proto/transform.hpp>
+namespace mpl = boost::mpl;
+namespace proto = boost::proto;
+namespace fusion = boost::fusion;
+using proto::_;
+
+template<class L,class R>
+struct pick_left
+{
+ BOOST_MPL_ASSERT((boost::is_same<L, R>));
+ typedef L type;
+};
+
+// Define the grammar of future group expression, as well as a
+// transform to turn them into a Fusion sequence of the correct
+// type.
+struct FutureGroup
+ : proto::or_<
+ // terminals become a single-element Fusion sequence
+ proto::when<
+ proto::terminal<_>
+ , fusion::single_view<proto::_value>(proto::_value)
+ >
+ // (a && b) becomes a concatenation of the sequence
+ // from 'a' and the one from 'b':
+ , proto::when<
+ proto::logical_and<FutureGroup, FutureGroup>
+ , fusion::joint_view<
+ boost::add_const<FutureGroup(proto::_left)>,
+ boost::add_const<FutureGroup(proto::_right)>
+ >(FutureGroup(proto::_left), FutureGroup(proto::_right))
+ >
+ // (a || b) becomes the sequence for 'a', so long
+ // as it is the same as the sequence for 'b'.
+ , proto::when<
+ proto::logical_or<FutureGroup, FutureGroup>
+ , pick_left<
+ FutureGroup(proto::_left)
+ , FutureGroup(proto::_right)
+ >(FutureGroup(proto::_left))
+ >
+ >
+{};
+
+template<class E>
+struct future_expr;
+
+struct future_dom
+ : proto::domain<proto::generator<future_expr>, FutureGroup>
+{};
+
+// Expressions in the future group domain have a .get()
+// member function that (ostensibly) blocks for the futures
+// to complete and returns the results in an appropriate
+// tuple.
+template<class E>
+struct future_expr
+ : proto::extends<E, future_expr<E>, future_dom>
+{
+ explicit future_expr(E const &e)
+ : proto::extends<E, future_expr<E>, future_dom>(e)
+ {}
+
+ typename fusion::result_of::as_vector<
+ typename boost::result_of<FutureGroup(E,int,int)>::type
+ >::type
+ get() const
+ {
+ int i = 0;
+ return fusion::as_vector(FutureGroup()(*this, i, i));
+ }
+};
+
+// The future<> type has an even simpler .get()
+// member function.
+template<class T>
+struct future
+ : future_expr<typename proto::terminal<T>::type>
+{
+ future(T const &t = T())
+ : future_expr<typename proto::terminal<T>::type>(
+ proto::terminal<T>::type::make(t)
+ )
+ {}
+
+ T get() const
+ {
+ return proto::value(*this);
+ }
+};
+
+// TEST CASES
+struct A {};
+struct B {};
+struct C {};
+
+int main()
+{
+ using fusion::tuple;
+ future<A> a;
+ future<B> b;
+ future<C> c;
+ future<tuple<A,B> > ab;
+
+ // Verify that various future groups have the
+ // correct return types.
+ A t0 = a.get();
+ tuple<A, B, C> t1 = (a && b && c).get();
+ tuple<A, C> t2 = ((a || a) && c).get();
+ tuple<A, B, C> t3 = ((a && b || a && b) && c).get();
+ tuple<tuple<A, B>, C> t4 = ((ab || ab) && c).get();
+
+ return 0;
+}
+//]

Added: branches/proto/v4/libs/proto/example/hello.cpp
==============================================================================
--- (empty file)
+++ branches/proto/v4/libs/proto/example/hello.cpp 2008-04-06 02:19:35 EDT (Sun, 06 Apr 2008)
@@ -0,0 +1,27 @@
+//[ HelloWorld
+////////////////////////////////////////////////////////////////////
+// Copyright 2008 Eric Niebler. Distributed under the Boost
+// Software License, Version 1.0. (See accompanying file
+// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#include <iostream>
+#include <boost/proto/core.hpp>
+#include <boost/proto/context.hpp>
+#include <boost/typeof/std/ostream.hpp>
+namespace proto = boost::proto;
+
+proto::terminal< std::ostream & >::type cout_ = {std::cout};
+
+template< typename Expr >
+void evaluate( Expr const & expr )
+{
+ proto::default_context ctx;
+ proto::eval(expr, ctx);
+}
+
+int main()
+{
+ evaluate( cout_ << "hello" << ',' << " world" );
+ return 0;
+}
+//]

Added: branches/proto/v4/libs/proto/example/lambda.cpp
==============================================================================
--- (empty file)
+++ branches/proto/v4/libs/proto/example/lambda.cpp 2008-04-06 02:19:35 EDT (Sun, 06 Apr 2008)
@@ -0,0 +1,232 @@
+//[ Lambda
+///////////////////////////////////////////////////////////////////////////////
+// Copyright 2008 Eric Niebler. Distributed under the Boost
+// Software License, Version 1.0. (See accompanying file
+// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+// This example builds a simple but functor lambda library using Proto.
+
+#include <iostream>
+#include <algorithm>
+#include <boost/mpl/int.hpp>
+#include <boost/mpl/min_max.hpp>
+#include <boost/mpl/eval_if.hpp>
+#include <boost/mpl/identity.hpp>
+#include <boost/mpl/next_prior.hpp>
+#include <boost/fusion/tuple.hpp>
+#include <boost/typeof/typeof.hpp>
+#include <boost/typeof/std/ostream.hpp>
+#include <boost/typeof/std/iostream.hpp>
+#include <boost/proto/core.hpp>
+#include <boost/proto/context.hpp>
+#include <boost/proto/transform.hpp>
+namespace mpl = boost::mpl;
+namespace proto = boost::proto;
+namespace fusion = boost::fusion;
+using proto::_;
+
+// Forward declaration of the lambda expression wrapper
+template<typename T>
+struct lambda;
+
+struct lambda_domain
+ : proto::domain<proto::pod_generator<lambda> >
+{};
+
+template<typename I>
+struct placeholder
+{
+ typedef I arity;
+};
+
+template<typename T>
+struct placeholder_arity
+{
+ typedef typename T::arity type;
+};
+
+// The lambda grammar, with the transforms for calculating the max arity
+struct Lambda
+ : proto::or_<
+ proto::when<
+ proto::terminal< placeholder<_> >
+ , mpl::next<placeholder_arity<proto::_value> >()
+ >
+ , proto::when< proto::terminal<_>
+ , mpl::int_<0>()
+ >
+ , proto::when<
+ proto::nary_expr<_, proto::vararg<_> >
+ , proto::fold<_, mpl::int_<0>(), mpl::max<Lambda,proto::_state>()>
+ >
+ >
+{};
+
+// simple wrapper for calculating a lambda expression's arity.
+template<typename Expr>
+struct lambda_arity
+ : boost::result_of<Lambda(Expr, mpl::void_, mpl::void_)>
+{};
+
+// The lambda context is the same as the default context
+// with the addition of special handling for lambda placeholders
+template<typename Tuple>
+struct lambda_context
+ : proto::callable_context<lambda_context<Tuple> const>
+{
+ lambda_context(Tuple const &args)
+ : args_(args)
+ {}
+
+ template<typename Sig>
+ struct result;
+
+ template<typename This, typename I>
+ struct result<This(proto::tag::terminal, placeholder<I> const &)>
+ : fusion::result_of::at<Tuple, I>
+ {};
+
+ template<typename I>
+ typename fusion::result_of::at<Tuple, I>::type
+ operator ()(proto::tag::terminal, placeholder<I> const &) const
+ {
+ return fusion::at<I>(this->args_);
+ }
+
+ Tuple args_;
+};
+
+// The lambda<> expression wrapper makes expressions polymorphic
+// function objects
+template<typename T>
+struct lambda
+{
+ BOOST_PROTO_BASIC_EXTENDS(T, lambda<T>, lambda_domain)
+ BOOST_PROTO_EXTENDS_ASSIGN()
+ BOOST_PROTO_EXTENDS_SUBSCRIPT()
+
+ // Careful not to evaluate the return type of the nullary function
+ // unless we have a nullary lambda!
+ typedef typename mpl::eval_if<
+ typename lambda_arity<T>::type
+ , mpl::identity<void>
+ , proto::result_of::eval<T const, lambda_context<fusion::tuple<> > >
+ >::type nullary_type;
+
+ // Define our operator () that evaluates the lambda expression.
+ nullary_type operator ()() const
+ {
+ fusion::tuple<> args;
+ lambda_context<fusion::tuple<> > ctx(args);
+ return proto::eval(*this, ctx);
+ }
+
+ template<typename A0>
+ typename proto::result_of::eval<T const, lambda_context<fusion::tuple<A0 const &> > >::type
+ operator ()(A0 const &a0) const
+ {
+ fusion::tuple<A0 const &> args(a0);
+ lambda_context<fusion::tuple<A0 const &> > ctx(args);
+ return proto::eval(*this, ctx);
+ }
+
+ template<typename A0, typename A1>
+ typename proto::result_of::eval<T const, lambda_context<fusion::tuple<A0 const &, A1 const &> > >::type
+ operator ()(A0 const &a0, A1 const &a1) const
+ {
+ fusion::tuple<A0 const &, A1 const &> args(a0, a1);
+ lambda_context<fusion::tuple<A0 const &, A1 const &> > ctx(args);
+ return proto::eval(*this, ctx);
+ }
+};
+
+// Define some lambda placeholders
+lambda<proto::terminal<placeholder<mpl::int_<0> > >::type> const _1 = {{}};
+lambda<proto::terminal<placeholder<mpl::int_<1> > >::type> const _2 = {{}};
+
+template<typename T>
+lambda<typename proto::terminal<T>::type> const val(T const &t)
+{
+ lambda<typename proto::terminal<T>::type> that = {{t}};
+ return that;
+}
+
+template<typename T>
+lambda<typename proto::terminal<T &>::type> const var(T &t)
+{
+ lambda<typename proto::terminal<T &>::type> that = {{t}};
+ return that;
+}
+
+template<typename T>
+struct construct_helper
+{
+ typedef T result_type; // for TR1 result_of
+
+ T operator()() const
+ { return T(); }
+
+ template<typename A0>
+ T operator()(A0 const &a0) const
+ { return T(a0); }
+
+ template<typename A0, typename A1>
+ T operator()(A0 const &a0, A1 const &a1) const
+ { return T(a0, a1); }
+};
+
+// Generate BOOST_PROTO_MAX_ARITY-1 overloads of the
+// construct function template like the one defined above.
+BOOST_PROTO_DEFINE_VARARG_FUNCTION_TEMPLATE( \
+ construct \
+ , lambda_domain \
+ , (proto::tag::function) \
+ , ((construct_helper)(typename)) \
+)
+
+struct S
+{
+ S() {}
+ S(int i, char c)
+ {
+ std::cout << "S(" << i << "," << c << ")\n";
+ }
+};
+
+int main()
+{
+ // Create some lambda objects and immediately
+ // invoke them by applying their operator():
+ int i = ( (_1 + 2) / 4 )(42);
+ std::cout << i << std::endl; // prints 11
+
+ int j = ( (-(_1 + 2)) / 4 )(42);
+ std::cout << j << std::endl; // prints -11
+
+ double d = ( (4 - _2) * 3 )(42, 3.14);
+ std::cout << d << std::endl; // prints 2.58
+
+ // check non-const ref terminals
+ (std::cout << _1 << " -- " << _2 << '\n')(42, "Life, the Universe and Everything!");
+ // prints "42 -- Life, the Universe and Everything!"
+
+ // "Nullary" lambdas work too
+ int k = (val(1) + val(2))();
+ std::cout << k << std::endl; // prints 3
+
+ // check array indexing for kicks
+ int integers[5] = {0};
+ (var(integers)[2] = 2)();
+ (var(integers)[_1] = _1)(3);
+ std::cout << integers[2] << std::endl; // prints 2
+ std::cout << integers[3] << std::endl; // prints 3
+
+ // Now use a lambda with an STL algorithm!
+ int rgi[4] = {1,2,3,4};
+ char rgc[4] = {'a','b','c','d'};
+ S rgs[4];
+
+ std::transform(rgi, rgi+4, rgc, rgs, construct<S>(_1, _2));
+ return 0;
+}
+//]

Added: branches/proto/v4/libs/proto/example/lazy_vector.cpp
==============================================================================
--- (empty file)
+++ branches/proto/v4/libs/proto/example/lazy_vector.cpp 2008-04-06 02:19:35 EDT (Sun, 06 Apr 2008)
@@ -0,0 +1,144 @@
+//[ LazyVector
+///////////////////////////////////////////////////////////////////////////////
+// Copyright 2008 Eric Niebler. Distributed under the Boost
+// Software License, Version 1.0. (See accompanying file
+// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+// This example constructs a mini-library for linear algebra, using
+// expression templates to eliminate the need for temporaries when
+// adding vectors of numbers.
+//
+// This example uses a domain with a grammar to prune the set
+// of overloaded operators. Only those operators that produce
+// valid lazy vector expressions are allowed.
+
+#include <vector>
+#include <iostream>
+#include <boost/mpl/int.hpp>
+#include <boost/proto/core.hpp>
+#include <boost/proto/context.hpp>
+namespace mpl = boost::mpl;
+namespace proto = boost::proto;
+using proto::_;
+
+// This grammar describes which lazy vector expressions
+// are allowed; namely, vector terminals and addition
+// and subtraction of lazy vector expressions.
+struct LazyVectorGrammar
+ : proto::or_<
+ proto::terminal< std::vector<_> >
+ , proto::plus< LazyVectorGrammar, LazyVectorGrammar >
+ , proto::minus< LazyVectorGrammar, LazyVectorGrammar >
+ >
+{};
+
+// Expressions in the lazy vector domain must conform
+// to the lazy vector grammar
+struct lazy_vector_domain;
+
+// Here is an evaluation context that indexes into a lazy vector
+// expression, and combines the result.
+template<typename Size = std::size_t>
+struct lazy_subscript_context
+{
+ lazy_subscript_context(Size subscript)
+ : subscript_(subscript)
+ {}
+
+ // Use default_eval for all the operations ...
+ template<typename Expr, typename Tag = typename Expr::proto_tag>
+ struct eval
+ : proto::default_eval<Expr, lazy_subscript_context>
+ {};
+
+ // ... except for terminals, which we index with our subscript
+ template<typename Expr>
+ struct eval<Expr, proto::tag::terminal>
+ {
+ typedef typename proto::result_of::value<Expr>::type::value_type result_type;
+
+ result_type operator ()( Expr const & expr, lazy_subscript_context & ctx ) const
+ {
+ return proto::value( expr )[ ctx.subscript_ ];
+ }
+ };
+
+ Size subscript_;
+};
+
+// Here is the domain-specific expression wrapper, which overrides
+// operator [] to evaluate the expression using the lazy_subscript_context.
+template<typename Expr>
+struct lazy_vector_expr
+ : proto::extends<Expr, lazy_vector_expr<Expr>, lazy_vector_domain>
+{
+ typedef proto::extends<Expr, lazy_vector_expr<Expr>, lazy_vector_domain> base_type;
+
+ lazy_vector_expr( Expr const & expr = Expr() )
+ : base_type( expr )
+ {}
+
+ // Use the lazy_subscript_context<> to implement subscripting
+ // of a lazy vector expression tree.
+ template< typename Size >
+ typename proto::result_of::eval< Expr, lazy_subscript_context<Size> >::type
+ operator []( Size subscript ) const
+ {
+ lazy_subscript_context<Size> ctx(subscript);
+ return proto::eval(*this, ctx);
+ }
+};
+
+// Here is our lazy_vector terminal, implemented in terms of lazy_vector_expr
+template< typename T >
+struct lazy_vector
+ : lazy_vector_expr< typename proto::terminal< std::vector<T> >::type >
+{
+ typedef typename proto::terminal< std::vector<T> >::type expr_type;
+
+ lazy_vector( std::size_t size = 0, T const & value = T() )
+ : lazy_vector_expr<expr_type>( expr_type::make( std::vector<T>( size, value ) ) )
+ {}
+
+ // Here we define a += operator for lazy vector terminals that
+ // takes a lazy vector expression and indexes it. expr[i] here
+ // uses lazy_subscript_context<> under the covers.
+ template< typename Expr >
+ lazy_vector &operator += (Expr const & expr)
+ {
+ std::size_t size = proto::value(*this).size();
+ for(std::size_t i = 0; i < size; ++i)
+ {
+ proto::value(*this)[i] += expr[i];
+ }
+ return *this;
+ }
+};
+
+// Tell proto that in the lazy_vector_domain, all
+// expressions should be wrapped in laxy_vector_expr<>
+struct lazy_vector_domain
+ : proto::domain<proto::generator<lazy_vector_expr>, LazyVectorGrammar>
+{};
+
+int main()
+{
+ // lazy_vectors with 4 elements each.
+ lazy_vector< double > v1( 4, 1.0 ), v2( 4, 2.0 ), v3( 4, 3.0 );
+
+ // Add two vectors lazily and get the 2nd element.
+ double d1 = ( v2 + v3 )[ 2 ]; // Look ma, no temporaries!
+ std::cout << d1 << std::endl;
+
+ // Subtract two vectors and add the result to a third vector.
+ v1 += v2 - v3; // Still no temporaries!
+ std::cout << '{' << v1[0] << ',' << v1[1]
+ << ',' << v1[2] << ',' << v1[3] << '}' << std::endl;
+
+ // This expression is disallowed because it does not conform
+ // to the LazyVectorGrammar
+ //(v2 + v3) += v1;
+
+ return 0;
+}
+//]

Added: branches/proto/v4/libs/proto/example/map_assign.cpp
==============================================================================
--- (empty file)
+++ branches/proto/v4/libs/proto/example/map_assign.cpp 2008-04-06 02:19:35 EDT (Sun, 06 Apr 2008)
@@ -0,0 +1,121 @@
+//[ MapAssign
+// Copyright 2008 Eric Niebler. Distributed under the Boost
+// Software License, Version 1.0. (See accompanying file
+// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+// This is a port of map_list_of() from the Boost.Assign library.
+// It has the advantage of being more efficient at runtime by not
+// building any temporary container that requires dynamic allocation.
+
+#include <map>
+#include <string>
+#include <iostream>
+#include <boost/proto/core.hpp>
+#include <boost/proto/transform.hpp>
+#include <boost/type_traits/add_reference.hpp>
+namespace proto = boost::proto;
+using proto::_;
+
+struct map_list_of_tag
+{};
+
+// A simple callable function object that inserts a
+// (key,value) pair into a map.
+struct insert
+ : proto::callable
+{
+ template<typename Sig>
+ struct result;
+
+ template<typename This, typename Map, typename Key, typename Value>
+ struct result<This(Map, Key, Value)>
+ : boost::add_reference<Map>
+ {};
+
+ template<typename Map, typename Key, typename Value>
+ Map &operator()(Map &map, Key const &key, Value const &value) const
+ {
+ map.insert(typename Map::value_type(key, value));
+ return map;
+ }
+};
+
+// The grammmar for valid map-list expressions, and a
+// transform that populates the map.
+struct MapListOf
+ : proto::or_<
+ proto::when<
+ proto::function<
+ proto::terminal<map_list_of_tag>
+ , proto::terminal<_>
+ , proto::terminal<_>
+ >
+ , insert(
+ proto::_data
+ , proto::_value(proto::_child1)
+ , proto::_value(proto::_child2)
+ )
+ >
+ , proto::when<
+ proto::function<
+ MapListOf
+ , proto::terminal<_>
+ , proto::terminal<_>
+ >
+ , insert(
+ MapListOf(proto::_child0)
+ , proto::_value(proto::_child1)
+ , proto::_value(proto::_child2)
+ )
+ >
+ >
+{};
+
+template<typename Expr>
+struct map_list_of_expr;
+
+struct map_list_of_dom
+ : proto::domain<proto::pod_generator<map_list_of_expr>, MapListOf>
+{};
+
+// An expression wrapper that provides a conversion to a
+// map that uses the MapListOf
+template<typename Expr>
+struct map_list_of_expr
+{
+ BOOST_PROTO_BASIC_EXTENDS(Expr, map_list_of_expr, map_list_of_dom)
+ BOOST_PROTO_EXTENDS_FUNCTION()
+
+ template<typename Map>
+ operator Map() const
+ {
+ Map map;
+ return MapListOf()(*this, 0, map);
+ }
+};
+
+map_list_of_expr<proto::terminal<map_list_of_tag>::type> const map_list_of = {{{}}};
+
+int main()
+{
+ // Initialize a map:
+ std::map<std::string, int> op =
+ map_list_of
+ ("<",1)
+ ("<=",2)
+ (">",3)
+ (">=",4)
+ ("=",5)
+ ("<>",6)
+ ;
+
+ std::cout << "\"<\" --> " << op["<"] << std::endl;
+ std::cout << "\"<=\" --> " << op["<="] << std::endl;
+ std::cout << "\">\" --> " << op[">"] << std::endl;
+ std::cout << "\">=\" --> " << op[">="] << std::endl;
+ std::cout << "\"=\" --> " << op["="] << std::endl;
+ std::cout << "\"<>\" --> " << op["<>"] << std::endl;
+
+ return 0;
+}
+//]

Added: branches/proto/v4/libs/proto/example/mixed.cpp
==============================================================================
--- (empty file)
+++ branches/proto/v4/libs/proto/example/mixed.cpp 2008-04-06 02:19:35 EDT (Sun, 06 Apr 2008)
@@ -0,0 +1,375 @@
+//[ Mixed
+///////////////////////////////////////////////////////////////////////////////
+// Copyright 2008 Eric Niebler. Distributed under the Boost
+// Software License, Version 1.0. (See accompanying file
+// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+// This is an example of using BOOST_PROTO_DEFINE_OPERATORS to proto-ify
+// expressions using std::vector<> and std::list, non-proto types. It is a port
+// of the Mixed example from PETE.
+// (http://www.codesourcery.com/pooma/download.html).
+
+#include <list>
+#include <cmath>
+#include <vector>
+#include <complex>
+#include <iostream>
+#include <stdexcept>
+#include <boost/proto/core.hpp>
+#include <boost/proto/debug.hpp>
+#include <boost/proto/context.hpp>
+#include <boost/proto/transform.hpp>
+#include <boost/utility/enable_if.hpp>
+#include <boost/typeof/std/list.hpp>
+#include <boost/typeof/std/vector.hpp>
+#include <boost/typeof/std/complex.hpp>
+#include <boost/type_traits/remove_reference.hpp>
+namespace proto = boost::proto;
+namespace mpl = boost::mpl;
+using proto::_;
+
+template<typename Expr>
+struct MixedExpr;
+
+template<typename Iter>
+struct iterator_wrapper
+{
+ typedef Iter iterator;
+
+ explicit iterator_wrapper(Iter iter)
+ : it(iter)
+ {}
+
+ Iter it;
+};
+
+struct begin : proto::callable
+{
+ template<class Sig>
+ struct result;
+
+ template<class This, class Cont>
+ struct result<This(Cont)>
+ : proto::result_of::as_expr<
+ iterator_wrapper<typename boost::remove_reference<Cont>::type::const_iterator>
+ >
+ {};
+
+ template<typename Cont>
+ typename result<begin(Cont const &)>::type
+ operator ()(Cont const &cont) const
+ {
+ iterator_wrapper<typename Cont::const_iterator> it(cont.begin());
+ return proto::as_expr(it);
+ }
+};
+
+// Here is a grammar that replaces vector and list terminals with their
+// begin iterators
+struct Begin
+ : proto::or_<
+ proto::when< proto::terminal< std::vector<_, _> >, begin(proto::_value) >
+ , proto::when< proto::terminal< std::list<_, _> >, begin(proto::_value) >
+ , proto::when< proto::terminal<_> >
+ , proto::when< proto::nary_expr<_, proto::vararg<Begin> > >
+ >
+{};
+
+// Here is an evaluation context that dereferences iterator
+// terminals.
+struct DereferenceCtx
+{
+ // Unless this is an iterator terminal, use the
+ // default evaluation context
+ template<typename Expr, typename EnableIf = void>
+ struct eval
+ : proto::default_eval<Expr, DereferenceCtx const>
+ {};
+
+ // Dereference iterator terminals.
+ template<typename Expr>
+ struct eval<
+ Expr
+ , typename boost::enable_if<
+ proto::matches<Expr, proto::terminal<iterator_wrapper<_> > >
+ >::type
+ >
+ {
+ typedef typename proto::result_of::value<Expr>::type IteratorWrapper;
+ typedef typename IteratorWrapper::iterator iterator;
+ typedef typename std::iterator_traits<iterator>::reference result_type;
+
+ result_type operator ()(Expr &expr, DereferenceCtx const &) const
+ {
+ return *proto::value(expr).it;
+ }
+ };
+};
+
+// Here is an evaluation context that increments iterator
+// terminals.
+struct IncrementCtx
+{
+ // Unless this is an iterator terminal, use the
+ // default evaluation context
+ template<typename Expr, typename EnableIf = void>
+ struct eval
+ : proto::null_eval<Expr, IncrementCtx const>
+ {};
+
+ // advance iterator terminals.
+ template<typename Expr>
+ struct eval<
+ Expr
+ , typename boost::enable_if<
+ proto::matches<Expr, proto::terminal<iterator_wrapper<_> > >
+ >::type
+ >
+ {
+ typedef void result_type;
+
+ result_type operator ()(Expr &expr, IncrementCtx const &) const
+ {
+ ++proto::value(expr).it;
+ }
+ };
+};
+
+// A grammar which matches all the assignment operators,
+// so we can easily disable them.
+struct AssignOps
+ : proto::switch_<struct AssignOpsCases>
+{};
+
+// Here are the cases used by the switch_ above.
+struct AssignOpsCases
+{
+ template<typename Tag, int D = 0> struct case_ : proto::not_<_> {};
+
+ template<int D> struct case_< proto::tag::plus_assign, D > : _ {};
+ template<int D> struct case_< proto::tag::minus_assign, D > : _ {};
+ template<int D> struct case_< proto::tag::multiplies_assign, D > : _ {};
+ template<int D> struct case_< proto::tag::divides_assign, D > : _ {};
+ template<int D> struct case_< proto::tag::modulus_assign, D > : _ {};
+ template<int D> struct case_< proto::tag::shift_left_assign, D > : _ {};
+ template<int D> struct case_< proto::tag::shift_right_assign, D > : _ {};
+ template<int D> struct case_< proto::tag::bitwise_and_assign, D > : _ {};
+ template<int D> struct case_< proto::tag::bitwise_or_assign, D > : _ {};
+ template<int D> struct case_< proto::tag::bitwise_xor_assign, D > : _ {};
+};
+
+// A vector grammar is a terminal or some op that is not an
+// assignment op. (Assignment will be handled specially.)
+struct MixedGrammar
+ : proto::or_<
+ proto::terminal<_>
+ , proto::and_<
+ proto::nary_expr<_, proto::vararg<MixedGrammar> >
+ , proto::not_<AssignOps>
+ >
+ >
+{};
+
+// Expressions in the vector domain will be wrapped in VectorExpr<>
+// and must conform to the VectorGrammar
+struct MixedDomain
+ : proto::domain<proto::generator<MixedExpr>, MixedGrammar>
+{};
+
+// Here is MixedExpr, a wrapper for expression types in the MixedDomain.
+template<typename Expr>
+struct MixedExpr
+ : proto::extends<Expr, MixedExpr<Expr>, MixedDomain>
+{
+ explicit MixedExpr(Expr const &expr)
+ : proto::extends<Expr, MixedExpr<Expr>, MixedDomain>(expr)
+ {}
+private:
+ // hide this:
+ using proto::extends<Expr, MixedExpr<Expr>, MixedDomain>::operator [];
+};
+
+// Define a trait type for detecting vector and list terminals, to
+// be used by the BOOST_PROTO_DEFINE_OPERATORS macro below.
+template<typename T>
+struct IsMixed
+ : mpl::false_
+{};
+
+template<typename T, typename A>
+struct IsMixed<std::list<T, A> >
+ : mpl::true_
+{};
+
+template<typename T, typename A>
+struct IsMixed<std::vector<T, A> >
+ : mpl::true_
+{};
+
+namespace MixedOps
+{
+ // This defines all the overloads to make expressions involving
+ // std::vector to build expression templates.
+ BOOST_PROTO_DEFINE_OPERATORS(IsMixed, MixedDomain)
+
+ struct assign_op
+ {
+ template<typename T, typename U>
+ void operator ()(T &t, U const &u) const
+ {
+ t = u;
+ }
+ };
+
+ struct plus_assign_op
+ {
+ template<typename T, typename U>
+ void operator ()(T &t, U const &u) const
+ {
+ t += u;
+ }
+ };
+
+ struct minus_assign_op
+ {
+ template<typename T, typename U>
+ void operator ()(T &t, U const &u) const
+ {
+ t -= u;
+ }
+ };
+
+ struct sin_
+ {
+ template<typename Sig>
+ struct result;
+
+ template<typename This, typename Arg>
+ struct result<This(Arg)>
+ : boost::remove_const<typename boost::remove_reference<Arg>::type>
+ {};
+
+ template<typename Arg>
+ Arg operator ()(Arg const &a) const
+ {
+ return std::sin(a);
+ }
+ };
+
+ template<typename A>
+ typename proto::result_of::make_expr<
+ proto::tag::function
+ , MixedDomain
+ , sin_ const
+ , A const &
+ >::type sin(A const &a)
+ {
+ return proto::make_expr<proto::tag::function, MixedDomain>(sin_(), boost::ref(a));
+ }
+
+ template<typename FwdIter, typename Expr, typename Op>
+ void evaluate(FwdIter begin, FwdIter end, Expr const &expr, Op op)
+ {
+ IncrementCtx const inc = {};
+ DereferenceCtx const deref = {};
+ typename boost::result_of<Begin(Expr const &)>::type expr2 = Begin()(expr);
+ for(; begin != end; ++begin)
+ {
+ op(*begin, proto::eval(expr2, deref));
+ proto::eval(expr2, inc);
+ }
+ }
+
+ // Add-assign to a vector from some expression.
+ template<typename T, typename A, typename Expr>
+ std::vector<T, A> &assign(std::vector<T, A> &arr, Expr const &expr)
+ {
+ evaluate(arr.begin(), arr.end(), proto::as_expr<MixedDomain>(expr), assign_op());
+ return arr;
+ }
+
+ // Add-assign to a list from some expression.
+ template<typename T, typename A, typename Expr>
+ std::list<T, A> &assign(std::list<T, A> &arr, Expr const &expr)
+ {
+ evaluate(arr.begin(), arr.end(), proto::as_expr<MixedDomain>(expr), assign_op());
+ return arr;
+ }
+
+ // Add-assign to a vector from some expression.
+ template<typename T, typename A, typename Expr>
+ std::vector<T, A> &operator +=(std::vector<T, A> &arr, Expr const &expr)
+ {
+ evaluate(arr.begin(), arr.end(), proto::as_expr<MixedDomain>(expr), plus_assign_op());
+ return arr;
+ }
+
+ // Add-assign to a list from some expression.
+ template<typename T, typename A, typename Expr>
+ std::list<T, A> &operator +=(std::list<T, A> &arr, Expr const &expr)
+ {
+ evaluate(arr.begin(), arr.end(), proto::as_expr<MixedDomain>(expr), plus_assign_op());
+ return arr;
+ }
+
+ // Minus-assign to a vector from some expression.
+ template<typename T, typename A, typename Expr>
+ std::vector<T, A> &operator -=(std::vector<T, A> &arr, Expr const &expr)
+ {
+ evaluate(arr.begin(), arr.end(), proto::as_expr<MixedDomain>(expr), minus_assign_op());
+ return arr;
+ }
+
+ // Minus-assign to a list from some expression.
+ template<typename T, typename A, typename Expr>
+ std::list<T, A> &operator -=(std::list<T, A> &arr, Expr const &expr)
+ {
+ evaluate(arr.begin(), arr.end(), proto::as_expr<MixedDomain>(expr), minus_assign_op());
+ return arr;
+ }
+}
+
+int main()
+{
+ using namespace MixedOps;
+
+ int n = 10;
+ std::vector<int> a,b,c,d;
+ std::list<double> e;
+ std::list<std::complex<double> > f;
+
+ int i;
+ for(i = 0;i < n; ++i)
+ {
+ a.push_back(i);
+ b.push_back(2*i);
+ c.push_back(3*i);
+ d.push_back(i);
+ e.push_back(0.0);
+ f.push_back(std::complex<double>(1.0, 1.0));
+ }
+
+ MixedOps::assign(b, 2);
+ MixedOps::assign(d, a + b * c);
+ a += if_else(d < 30, b, c);
+
+ MixedOps::assign(e, c);
+ e += e - 4 / (c + 1);
+
+ f -= sin(0.1 * e * std::complex<double>(0.2, 1.2));
+
+ std::list<double>::const_iterator ei = e.begin();
+ std::list<std::complex<double> >::const_iterator fi = f.begin();
+ for (i = 0; i < n; ++i)
+ {
+ std::cout
+ << "a(" << i << ") = " << a[i]
+ << " b(" << i << ") = " << b[i]
+ << " c(" << i << ") = " << c[i]
+ << " d(" << i << ") = " << d[i]
+ << " e(" << i << ") = " << *ei++
+ << " f(" << i << ") = " << *fi++
+ << std::endl;
+ }
+}
+//]

Added: branches/proto/v4/libs/proto/example/rgb.cpp
==============================================================================
--- (empty file)
+++ branches/proto/v4/libs/proto/example/rgb.cpp 2008-04-06 02:19:35 EDT (Sun, 06 Apr 2008)
@@ -0,0 +1,102 @@
+//[ RGB
+///////////////////////////////////////////////////////////////////////////////
+// Copyright 2008 Eric Niebler. Distributed under the Boost
+// Software License, Version 1.0. (See accompanying file
+// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+// This is a simple example of doing arbitrary type manipulations with proto
+// transforms. It takes some expression involving primiary colors and combines
+// the colors according to arbitrary rules. It is a port of the RGB example
+// from PETE (http://www.codesourcery.com/pooma/download.html).
+
+#include <iostream>
+#include <boost/proto/core.hpp>
+#include <boost/proto/transform.hpp>
+namespace proto = boost::proto;
+
+struct RedTag
+{
+ friend std::ostream &operator <<(std::ostream &sout, RedTag)
+ {
+ return sout << "This expression is red.";
+ }
+};
+
+struct BlueTag
+{
+ friend std::ostream &operator <<(std::ostream &sout, BlueTag)
+ {
+ return sout << "This expression is blue.";
+ }
+};
+
+struct GreenTag
+{
+ friend std::ostream &operator <<(std::ostream &sout, GreenTag)
+ {
+ return sout << "This expression is green.";
+ }
+};
+
+typedef proto::terminal<RedTag>::type RedT;
+typedef proto::terminal<BlueTag>::type BlueT;
+typedef proto::terminal<GreenTag>::type GreenT;
+
+struct Red;
+struct Blue;
+struct Green;
+
+///////////////////////////////////////////////////////////////////////////////
+// A transform that produces new colors according to some arbitrary rules:
+// red & green give blue, red & blue give green, blue and green give red.
+struct Red
+ : proto::or_<
+ proto::plus<Green, Blue>
+ , proto::plus<Blue, Green>
+ , proto::plus<Red, Red>
+ , proto::terminal<RedTag>
+ >
+{};
+
+struct Green
+ : proto::or_<
+ proto::plus<Red, Blue>
+ , proto::plus<Blue, Red>
+ , proto::plus<Green, Green>
+ , proto::terminal<GreenTag>
+ >
+{};
+
+struct Blue
+ : proto::or_<
+ proto::plus<Red, Green>
+ , proto::plus<Green, Red>
+ , proto::plus<Blue, Blue>
+ , proto::terminal<BlueTag>
+ >
+{};
+
+struct RGB
+ : proto::or_<
+ proto::when< Red, RedTag() >
+ , proto::when< Blue, BlueTag() >
+ , proto::when< Green, GreenTag() >
+ >
+{};
+
+template<typename Expr>
+void printColor(Expr const & expr)
+{
+ int i = 0; // dummy state and data parameter, not used
+ std::cout << RGB()(expr, i, i) << std::endl;
+}
+
+int main()
+{
+ printColor(RedT() + GreenT());
+ printColor(RedT() + GreenT() + BlueT());
+ printColor(RedT() + (GreenT() + BlueT()));
+
+ return 0;
+}
+//]

Added: branches/proto/v4/libs/proto/example/tarray.cpp
==============================================================================
--- (empty file)
+++ branches/proto/v4/libs/proto/example/tarray.cpp 2008-04-06 02:19:35 EDT (Sun, 06 Apr 2008)
@@ -0,0 +1,222 @@
+//[ TArray
+///////////////////////////////////////////////////////////////////////////////
+// Copyright 2008 Eric Niebler. Distributed under the Boost
+// Software License, Version 1.0. (See accompanying file
+// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+// This example constructs a mini-library for linear algebra, using
+// expression templates to eliminate the need for temporaries when
+// adding arrays of numbers. It duplicates the TArray example from
+// PETE (http://www.codesourcery.com/pooma/download.html)
+
+#include <iostream>
+#include <boost/mpl/int.hpp>
+#include <boost/proto/core.hpp>
+#include <boost/proto/context.hpp>
+namespace mpl = boost::mpl;
+namespace proto = boost::proto;
+using proto::_;
+
+// This grammar describes which TArray expressions
+// are allowed; namely, int and array terminals
+// plus, minus, multiplies and divides of TArray expressions.
+struct TArrayGrammar
+ : proto::or_<
+ proto::terminal< int >
+ , proto::terminal< int[3] >
+ , proto::plus< TArrayGrammar, TArrayGrammar >
+ , proto::minus< TArrayGrammar, TArrayGrammar >
+ , proto::multiplies< TArrayGrammar, TArrayGrammar >
+ , proto::divides< TArrayGrammar, TArrayGrammar >
+ >
+{};
+
+template<typename Expr>
+struct TArrayExpr;
+
+// Tell proto that in the TArrayDomain, all
+// expressions should be wrapped in TArrayExpr<> and
+// must conform to the TArrayGrammar
+struct TArrayDomain
+ : proto::domain<proto::generator<TArrayExpr>, TArrayGrammar>
+{};
+
+// Here is an evaluation context that indexes into a TArray
+// expression, and combines the result.
+struct TArraySubscriptCtx
+ : proto::callable_context< TArraySubscriptCtx const >
+{
+ typedef int result_type;
+
+ TArraySubscriptCtx(std::ptrdiff_t i)
+ : i_(i)
+ {}
+
+ // Index array terminals with our subscript. Everything
+ // else will be handled by the default evaluation context.
+ int operator ()(proto::tag::terminal, int const (&data)[3]) const
+ {
+ return data[this->i_];
+ }
+
+ std::ptrdiff_t i_;
+};
+
+// Here is an evaluation context that prints a TArray expression.
+struct TArrayPrintCtx
+ : proto::callable_context< TArrayPrintCtx const >
+{
+ typedef std::ostream &result_type;
+
+ TArrayPrintCtx() {}
+
+ std::ostream &operator ()(proto::tag::terminal, int i) const
+ {
+ return std::cout << i;
+ }
+
+ std::ostream &operator ()(proto::tag::terminal, int const (&arr)[3]) const
+ {
+ return std::cout << '{' << arr[0] << ", " << arr[1] << ", " << arr[2] << '}';
+ }
+
+ template<typename L, typename R>
+ std::ostream &operator ()(proto::tag::plus, L const &l, R const &r) const
+ {
+ return std::cout << '(' << l << " + " << r << ')';
+ }
+
+ template<typename L, typename R>
+ std::ostream &operator ()(proto::tag::minus, L const &l, R const &r) const
+ {
+ return std::cout << '(' << l << " - " << r << ')';
+ }
+
+ template<typename L, typename R>
+ std::ostream &operator ()(proto::tag::multiplies, L const &l, R const &r) const
+ {
+ return std::cout << l << " * " << r;
+ }
+
+ template<typename L, typename R>
+ std::ostream &operator ()(proto::tag::divides, L const &l, R const &r) const
+ {
+ return std::cout << l << " / " << r;
+ }
+};
+
+// Here is the domain-specific expression wrapper, which overrides
+// operator [] to evaluate the expression using the TArraySubscriptCtx.
+template<typename Expr>
+struct TArrayExpr
+ : proto::extends<Expr, TArrayExpr<Expr>, TArrayDomain>
+{
+ typedef proto::extends<Expr, TArrayExpr<Expr>, TArrayDomain> base_type;
+
+ TArrayExpr( Expr const & expr = Expr() )
+ : base_type( expr )
+ {}
+
+ // Use the TArraySubscriptCtx to implement subscripting
+ // of a TArray expression tree.
+ int operator []( std::ptrdiff_t i ) const
+ {
+ TArraySubscriptCtx const ctx(i);
+ return proto::eval(*this, ctx);
+ }
+
+ // Use the TArrayPrintCtx to display a TArray expression tree.
+ friend std::ostream &operator <<(std::ostream &sout, TArrayExpr<Expr> const &expr)
+ {
+ TArrayPrintCtx const ctx;
+ return proto::eval(expr, ctx);
+ }
+};
+
+// Here is our TArray terminal, implemented in terms of TArrayExpr
+// It is basically just an array of 3 integers.
+struct TArray
+ : TArrayExpr< proto::terminal< int[3] >::type >
+{
+ explicit TArray( int i = 0, int j = 0, int k = 0 )
+ {
+ (*this)[0] = i;
+ (*this)[1] = j;
+ (*this)[2] = k;
+ }
+
+ // Here we override operator [] to give read/write access to
+ // the elements of the array. (We could use the TArrayExpr
+ // operator [] if we made the subscript context smarter about
+ // returning non-const reference when appropriate.)
+ int &operator [](std::ptrdiff_t i)
+ {
+ return proto::value(*this)[i];
+ }
+
+ int const &operator [](std::ptrdiff_t i) const
+ {
+ return proto::value(*this)[i];
+ }
+
+ // Here we define a operator = for TArray terminals that
+ // takes a TArray expression.
+ template< typename Expr >
+ TArray &operator =(Expr const & expr)
+ {
+ // proto::as_expr<TArrayDomain>(expr) is the same as
+ // expr unless expr is an integer, in which case it
+ // is made into a TArrayExpr terminal first.
+ return this->assign(proto::as_expr<TArrayDomain>(expr));
+ }
+
+ template< typename Expr >
+ TArray &printAssign(Expr const & expr)
+ {
+ *this = expr;
+ std::cout << *this << " = " << expr << std::endl;
+ return *this;
+ }
+
+private:
+ template< typename Expr >
+ TArray &assign(Expr const & expr)
+ {
+ // expr[i] here uses TArraySubscriptCtx under the covers.
+ (*this)[0] = expr[0];
+ (*this)[1] = expr[1];
+ (*this)[2] = expr[2];
+ return *this;
+ }
+};
+
+int main()
+{
+ TArray a(3,1,2);
+
+ TArray b;
+
+ std::cout << a << std::endl;
+ std::cout << b << std::endl;
+
+ b[0] = 7; b[1] = 33; b[2] = -99;
+
+ TArray c(a);
+
+ std::cout << c << std::endl;
+
+ a = 0;
+
+ std::cout << a << std::endl;
+ std::cout << b << std::endl;
+ std::cout << c << std::endl;
+
+ a = b + c;
+
+ std::cout << a << std::endl;
+
+ a.printAssign(b+c*(b + 3*c));
+
+ return 0;
+}
+//]

Added: branches/proto/v4/libs/proto/example/vec3.cpp
==============================================================================
--- (empty file)
+++ branches/proto/v4/libs/proto/example/vec3.cpp 2008-04-06 02:19:35 EDT (Sun, 06 Apr 2008)
@@ -0,0 +1,174 @@
+//[ Vec3
+///////////////////////////////////////////////////////////////////////////////
+// Copyright 2008 Eric Niebler. Distributed under the Boost
+// Software License, Version 1.0. (See accompanying file
+// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+// This is a simple example using proto::extends to extend a terminal type with
+// additional behaviors, and using custom contexts and proto::eval for
+// evaluating expressions. It is a port of the Vec3 example
+// from PETE (http://www.codesourcery.com/pooma/download.html).
+
+#include <iostream>
+#include <functional>
+#include <boost/assert.hpp>
+#include <boost/mpl/int.hpp>
+#include <boost/proto/core.hpp>
+#include <boost/proto/context.hpp>
+#include <boost/proto/proto_typeof.hpp>
+#include <boost/proto/transform.hpp>
+namespace mpl = boost::mpl;
+namespace proto = boost::proto;
+using proto::_;
+
+// Here is an evaluation context that indexes into a Vec3
+// expression, and combines the result.
+struct Vec3SubscriptCtx
+ : proto::callable_context< Vec3SubscriptCtx const >
+{
+ typedef int result_type;
+
+ Vec3SubscriptCtx(int i)
+ : i_(i)
+ {}
+
+ // Index array terminals with our subscript. Everything
+ // else will be handled by the default evaluation context.
+ int operator ()(proto::tag::terminal, int const (&arr)[3]) const
+ {
+ return arr[this->i_];
+ }
+
+ int i_;
+};
+
+// Here is an evaluation context that counts the number
+// of Vec3 terminals in an expression.
+struct CountLeavesCtx
+ : proto::callable_context< CountLeavesCtx, proto::null_context >
+{
+ CountLeavesCtx()
+ : count(0)
+ {}
+
+ typedef void result_type;
+
+ void operator ()(proto::tag::terminal, int const(&)[3])
+ {
+ ++this->count;
+ }
+
+ int count;
+};
+
+struct iplus : std::plus<int>, proto::callable {};
+
+// Here is a transform that does the same thing as the above context.
+// It demonstrates the use of the std::plus<> function object
+// with the fold transform. With minor modifications, this
+// transform could be used to calculate the leaf count at compile
+// time, rather than at runtime.
+struct CountLeaves
+ : proto::or_<
+ // match a Vec3 terminal, return 1
+ proto::when<proto::terminal<int[3]>, mpl::int_<1>() >
+ // match a terminal, return int() (which is 0)
+ , proto::when<proto::terminal<_>, int() >
+ // fold everything else, using std::plus<> to add
+ // the leaf count of each child to the accumulated state.
+ , proto::otherwise< proto::fold<_, int(), iplus(CountLeaves, proto::_state) > >
+ >
+{};
+
+// Here is the Vec3 struct, which is a vector of 3 integers.
+struct Vec3
+ : proto::extends<proto::terminal<int[3]>::type, Vec3>
+{
+ explicit Vec3(int i=0, int j=0, int k=0)
+ {
+ (*this)[0] = i;
+ (*this)[1] = j;
+ (*this)[2] = k;
+ }
+
+ int &operator [](int i)
+ {
+ return proto::value(*this)[i];
+ }
+
+ int const &operator [](int i) const
+ {
+ return proto::value(*this)[i];
+ }
+
+ // Here we define a operator = for Vec3 terminals that
+ // takes a Vec3 expression.
+ template< typename Expr >
+ Vec3 &operator =(Expr const & expr)
+ {
+ typedef Vec3SubscriptCtx const CVec3SubscriptCtx;
+ (*this)[0] = proto::eval(proto::as_expr(expr), CVec3SubscriptCtx(0));
+ (*this)[1] = proto::eval(proto::as_expr(expr), CVec3SubscriptCtx(1));
+ (*this)[2] = proto::eval(proto::as_expr(expr), CVec3SubscriptCtx(2));
+ return *this;
+ }
+
+ void print() const
+ {
+ std::cout << '{' << (*this)[0]
+ << ", " << (*this)[1]
+ << ", " << (*this)[2]
+ << '}' << std::endl;
+ }
+};
+
+// The count_leaves() function uses the CountLeaves transform and
+// to count the number of leaves in an expression.
+template<typename Expr>
+int count_leaves(Expr const &expr)
+{
+ // Count the number of Vec3 terminals using the
+ // CountLeavesCtx evaluation context.
+ CountLeavesCtx ctx;
+ proto::eval(expr, ctx);
+
+ // This is another way to count the leaves using a transform.
+ int i = 0;
+ BOOST_ASSERT( CountLeaves()(expr, i, i) == ctx.count );
+
+ return ctx.count;
+}
+
+int main()
+{
+ Vec3 a, b, c;
+
+ c = 4;
+
+ b[0] = -1;
+ b[1] = -2;
+ b[2] = -3;
+
+ a = b + c;
+
+ a.print();
+
+ Vec3 d;
+ BOOST_PROTO_AUTO(expr1, b + c);
+ d = expr1;
+ d.print();
+
+ int num = count_leaves(expr1);
+ std::cout << num << std::endl;
+
+ BOOST_PROTO_AUTO(expr2, b + 3 * c);
+ num = count_leaves(expr2);
+ std::cout << num << std::endl;
+
+ BOOST_PROTO_AUTO(expr3, b + c * d);
+ num = count_leaves(expr3);
+ std::cout << num << std::endl;
+
+ return 0;
+}
+//]

Added: branches/proto/v4/libs/proto/example/vector.cpp
==============================================================================
--- (empty file)
+++ branches/proto/v4/libs/proto/example/vector.cpp 2008-04-06 02:19:35 EDT (Sun, 06 Apr 2008)
@@ -0,0 +1,241 @@
+//[ Vector
+///////////////////////////////////////////////////////////////////////////////
+// Copyright 2008 Eric Niebler. Distributed under the Boost
+// Software License, Version 1.0. (See accompanying file
+// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+// This is an example of using BOOST_PROTO_DEFINE_OPERATORS to proto-ify
+// expressions using std::vector<>, a non-proto type. It is a port of the
+// Vector example from PETE (http://www.codesourcery.com/pooma/download.html).
+
+#include <vector>
+#include <iostream>
+#include <stdexcept>
+#include <boost/mpl/bool.hpp>
+#include <boost/proto/core.hpp>
+#include <boost/proto/debug.hpp>
+#include <boost/proto/context.hpp>
+#include <boost/utility/enable_if.hpp>
+namespace mpl = boost::mpl;
+namespace proto = boost::proto;
+using proto::_;
+
+template<typename Expr>
+struct VectorExpr;
+
+// Here is an evaluation context that indexes into a std::vector
+// expression and combines the result.
+struct VectorSubscriptCtx
+{
+ VectorSubscriptCtx(std::size_t i)
+ : i_(i)
+ {}
+
+ // Unless this is a vector terminal, use the
+ // default evaluation context
+ template<typename Expr, typename EnableIf = void>
+ struct eval
+ : proto::default_eval<Expr, VectorSubscriptCtx const>
+ {};
+
+ // Index vector terminals with our subscript.
+ template<typename Expr>
+ struct eval<
+ Expr
+ , typename boost::enable_if<
+ proto::matches<Expr, proto::terminal<std::vector<_, _> > >
+ >::type
+ >
+ {
+ typedef typename proto::result_of::value<Expr>::type::value_type result_type;
+
+ result_type operator ()(Expr &expr, VectorSubscriptCtx const &ctx) const
+ {
+ return proto::value(expr)[ctx.i_];
+ }
+ };
+
+ std::size_t i_;
+};
+
+// Here is an evaluation context that verifies that all the
+// vectors in an expression have the same size.
+struct VectorSizeCtx
+{
+ VectorSizeCtx(std::size_t size)
+ : size_(size)
+ {}
+
+ // Unless this is a vector terminal, use the
+ // null evaluation context
+ template<typename Expr, typename EnableIf = void>
+ struct eval
+ : proto::null_eval<Expr, VectorSizeCtx const>
+ {};
+
+ // Index array terminals with our subscript. Everything
+ // else will be handled by the default evaluation context.
+ template<typename Expr>
+ struct eval<
+ Expr
+ , typename boost::enable_if<
+ proto::matches<Expr, proto::terminal<std::vector<_, _> > >
+ >::type
+ >
+ {
+ typedef void result_type;
+
+ result_type operator ()(Expr &expr, VectorSizeCtx const &ctx) const
+ {
+ if(ctx.size_ != proto::value(expr).size())
+ {
+ throw std::runtime_error("LHS and RHS are not compatible");
+ }
+ }
+ };
+
+ std::size_t size_;
+};
+
+// A grammar which matches all the assignment operators,
+// so we can easily disable them.
+struct AssignOps
+ : proto::switch_<struct AssignOpsCases>
+{};
+
+// Here are the cases used by the switch_ above.
+struct AssignOpsCases
+{
+ template<typename Tag, int D = 0> struct case_ : proto::not_<_> {};
+
+ template<int D> struct case_< proto::tag::plus_assign, D > : _ {};
+ template<int D> struct case_< proto::tag::minus_assign, D > : _ {};
+ template<int D> struct case_< proto::tag::multiplies_assign, D > : _ {};
+ template<int D> struct case_< proto::tag::divides_assign, D > : _ {};
+ template<int D> struct case_< proto::tag::modulus_assign, D > : _ {};
+ template<int D> struct case_< proto::tag::shift_left_assign, D > : _ {};
+ template<int D> struct case_< proto::tag::shift_right_assign, D > : _ {};
+ template<int D> struct case_< proto::tag::bitwise_and_assign, D > : _ {};
+ template<int D> struct case_< proto::tag::bitwise_or_assign, D > : _ {};
+ template<int D> struct case_< proto::tag::bitwise_xor_assign, D > : _ {};
+};
+
+// A vector grammar is a terminal or some op that is not an
+// assignment op. (Assignment will be handled specially.)
+struct VectorGrammar
+ : proto::or_<
+ proto::terminal<_>
+ , proto::and_<proto::nary_expr<_, proto::vararg<VectorGrammar> >, proto::not_<AssignOps> >
+ >
+{};
+
+// Expressions in the vector domain will be wrapped in VectorExpr<>
+// and must conform to the VectorGrammar
+struct VectorDomain
+ : proto::domain<proto::generator<VectorExpr>, VectorGrammar>
+{};
+
+// Here is VectorExpr, which extends a proto expr type by
+// giving it an operator [] which uses the VectorSubscriptCtx
+// to evaluate an expression with a given index.
+template<typename Expr>
+struct VectorExpr
+ : proto::extends<Expr, VectorExpr<Expr>, VectorDomain>
+{
+ explicit VectorExpr(Expr const &expr)
+ : proto::extends<Expr, VectorExpr<Expr>, VectorDomain>(expr)
+ {}
+
+ // Use the VectorSubscriptCtx to implement subscripting
+ // of a Vector expression tree.
+ typename proto::result_of::eval<Expr const, VectorSubscriptCtx const>::type
+ operator []( std::size_t i ) const
+ {
+ VectorSubscriptCtx const ctx(i);
+ return proto::eval(*this, ctx);
+ }
+};
+
+// Define a trait type for detecting vector terminals, to
+// be used by the BOOST_PROTO_DEFINE_OPERATORS macro below.
+template<typename T>
+struct IsVector
+ : mpl::false_
+{};
+
+template<typename T, typename A>
+struct IsVector<std::vector<T, A> >
+ : mpl::true_
+{};
+
+namespace VectorOps
+{
+ // This defines all the overloads to make expressions involving
+ // std::vector to build expression templates.
+ BOOST_PROTO_DEFINE_OPERATORS(IsVector, VectorDomain)
+
+ typedef VectorSubscriptCtx const CVectorSubscriptCtx;
+
+ // Assign to a vector from some expression.
+ template<typename T, typename A, typename Expr>
+ std::vector<T, A> &assign(std::vector<T, A> &arr, Expr const &expr)
+ {
+ VectorSizeCtx const size(arr.size());
+ proto::eval(proto::as_expr<VectorDomain>(expr), size); // will throw if the sizes don't match
+ for(std::size_t i = 0; i < arr.size(); ++i)
+ {
+ arr[i] = proto::as_expr<VectorDomain>(expr)[i];
+ }
+ return arr;
+ }
+
+ // Add-assign to a vector from some expression.
+ template<typename T, typename A, typename Expr>
+ std::vector<T, A> &operator +=(std::vector<T, A> &arr, Expr const &expr)
+ {
+ VectorSizeCtx const size(arr.size());
+ proto::eval(proto::as_expr<VectorDomain>(expr), size); // will throw if the sizes don't match
+ for(std::size_t i = 0; i < arr.size(); ++i)
+ {
+ arr[i] += proto::as_expr<VectorDomain>(expr)[i];
+ }
+ return arr;
+ }
+}
+
+int main()
+{
+ using namespace VectorOps;
+
+ int i;
+ const int n = 10;
+ std::vector<int> a,b,c,d;
+ std::vector<double> e(n);
+
+ for (i = 0; i < n; ++i)
+ {
+ a.push_back(i);
+ b.push_back(2*i);
+ c.push_back(3*i);
+ d.push_back(i);
+ }
+
+ VectorOps::assign(b, 2);
+ VectorOps::assign(d, a + b * c);
+ a += if_else(d < 30, b, c);
+
+ VectorOps::assign(e, c);
+ e += e - 4 / (c + 1);
+
+ for (i = 0; i < n; ++i)
+ {
+ std::cout
+ << " a(" << i << ") = " << a[i]
+ << " b(" << i << ") = " << b[i]
+ << " c(" << i << ") = " << c[i]
+ << " d(" << i << ") = " << d[i]
+ << " e(" << i << ") = " << e[i]
+ << std::endl;
+ }
+}
+//]

Added: branches/proto/v4/libs/proto/test/Jamfile.v2
==============================================================================
--- (empty file)
+++ branches/proto/v4/libs/proto/test/Jamfile.v2 2008-04-06 02:19:35 EDT (Sun, 06 Apr 2008)
@@ -0,0 +1,33 @@
+# (C) Copyright 2004: Eric Niebler
+# Distributed under the Boost Software License, Version 1.0.
+# (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+# bring in rules for testing
+import testing ;
+
+project
+ : requirements
+ <toolset>intel:<debug-symbols>off
+ <toolset>msvc-7.1:<debug-symbols>off
+ <toolset>msvc-8.0:<define>_SCL_SECURE_NO_DEPRECATE
+ <toolset>msvc-8.0:<define>_CRT_SECURE_NO_DEPRECATE
+ <toolset>msvc-9.0:<define>_SCL_SECURE_NO_DEPRECATE
+ <toolset>gcc:<cxxflags>-ftemplate-depth-1024
+ <library>/boost/test//boost_unit_test_framework
+ <link>static
+ ;
+
+test-suite "proto"
+ :
+ [ run calculator.cpp ]
+ [ run deep_copy.cpp ]
+ [ run examples.cpp ]
+ [ run lambda.cpp ]
+ [ run make_expr.cpp ]
+ [ run matches.cpp ]
+ [ run proto_fusion.cpp : : : <toolset>gcc:<cxxflags>-ftemplate-depth-1024 ]
+ [ run proto_fusion_s.cpp ]
+ [ run toy_spirit.cpp ]
+ [ run toy_spirit2.cpp ]
+ ;
+

Added: branches/proto/v4/libs/proto/test/calculator.cpp
==============================================================================
--- (empty file)
+++ branches/proto/v4/libs/proto/test/calculator.cpp 2008-04-06 02:19:35 EDT (Sun, 06 Apr 2008)
@@ -0,0 +1,109 @@
+///////////////////////////////////////////////////////////////////////////////
+// calculator.hpp
+//
+// Copyright 2008 Eric Niebler. Distributed under the Boost
+// Software License, Version 1.0. (See accompanying file
+// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/proto/core.hpp>
+#include <boost/proto/context.hpp>
+#include <boost/test/unit_test.hpp>
+
+using namespace boost;
+
+struct placeholder {};
+proto::terminal<placeholder>::type const _1 = {{}};
+
+struct calculator : proto::callable_context<calculator const>
+{
+ typedef int result_type;
+
+ calculator(int i)
+ : i_(i)
+ {}
+
+ int operator ()(proto::tag::terminal, placeholder) const
+ {
+ return this->i_;
+ }
+
+ int operator ()(proto::tag::terminal, int j) const
+ {
+ return j;
+ }
+
+ template<typename Left, typename Right>
+ int operator ()(proto::tag::plus, Left const &left, Right const &right) const
+ {
+ return proto::eval(left, *this) + proto::eval(right, *this);
+ }
+
+ template<typename Left, typename Right>
+ int operator ()(proto::tag::minus, Left const &left, Right const &right) const
+ {
+ return proto::eval(left, *this) - proto::eval(right, *this);
+ }
+
+ template<typename Left, typename Right>
+ int operator ()(proto::tag::multiplies, Left const &left, Right const &right) const
+ {
+ return proto::eval(left, *this) * proto::eval(right, *this);
+ }
+
+ template<typename Left, typename Right>
+ int operator ()(proto::tag::divides, Left const &left, Right const &right) const
+ {
+ return proto::eval(left, *this) / proto::eval(right, *this);
+ }
+
+private:
+ int i_;
+};
+
+template<typename Fun, typename Expr>
+struct functor
+{
+ typedef typename proto::result_of::eval<Expr, Fun>::type result_type;
+
+ functor(Expr const &expr)
+ : expr_(expr)
+ {}
+
+ template<typename T>
+ result_type operator ()(T const &t) const
+ {
+ Fun fun(t);
+ return proto::eval(this->expr_, fun);
+ }
+
+private:
+ Expr const &expr_;
+};
+
+template<typename Fun, typename Expr>
+functor<Fun, Expr> as(Expr const &expr)
+{
+ return functor<Fun, Expr>(expr);
+}
+
+void test_calculator()
+{
+ BOOST_CHECK_EQUAL(10, proto::eval(((_1 + 42)-3)/4, calculator(1)));
+ BOOST_CHECK_EQUAL(11, proto::eval(((_1 + 42)-3)/4, calculator(5)));
+
+ BOOST_CHECK_EQUAL(10, as<calculator>(((_1 + 42)-3)/4)(1));
+ BOOST_CHECK_EQUAL(11, as<calculator>(((_1 + 42)-3)/4)(5));
+}
+
+using namespace unit_test;
+///////////////////////////////////////////////////////////////////////////////
+// init_unit_test_suite
+//
+test_suite* init_unit_test_suite( int argc, char* argv[] )
+{
+ test_suite *test = BOOST_TEST_SUITE("test immediate evaluation of proto parse trees");
+
+ test->add(BOOST_TEST_CASE(&test_calculator));
+
+ return test;
+}

Added: branches/proto/v4/libs/proto/test/deep_copy.cpp
==============================================================================
--- (empty file)
+++ branches/proto/v4/libs/proto/test/deep_copy.cpp 2008-04-06 02:19:35 EDT (Sun, 06 Apr 2008)
@@ -0,0 +1,49 @@
+///////////////////////////////////////////////////////////////////////////////
+// deep_copy.hpp
+//
+// Copyright 2008 Eric Niebler. Distributed under the Boost
+// Software License, Version 1.0. (See accompanying file
+// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/proto/core.hpp>
+#include <boost/test/unit_test.hpp>
+
+using namespace boost;
+
+void foo() {}
+
+void test1()
+{
+ using namespace proto;
+
+ int i = 42;
+ terminal<int &>::type t1 = {i};
+ terminal<int>::type r1 = deep_copy(t1);
+ BOOST_CHECK_EQUAL(42, value(r1));
+
+ plus<terminal<int>::type, terminal<int>::type>::type r2 = deep_copy(t1 + 24);
+ BOOST_CHECK_EQUAL(42, value(left(r2)));
+ BOOST_CHECK_EQUAL(24, value(right(r2)));
+
+ char buf[16] = {'\0'};
+ terminal<char (&)[16]>::type t3 = {buf};
+ terminal<char[16]>::type r3 = deep_copy(t3);
+
+ terminal<void(&)()>::type t4 = {foo};
+ plus<terminal<void(&)()>::type, terminal<int>::type>::type r4 = deep_copy(t4 + t1);
+ BOOST_CHECK_EQUAL(42, value(right(r4)));
+ BOOST_CHECK_EQUAL(&foo, &value(left(r4)));
+}
+
+using namespace unit_test;
+///////////////////////////////////////////////////////////////////////////////
+// init_unit_test_suite
+//
+test_suite* init_unit_test_suite( int argc, char* argv[] )
+{
+ test_suite *test = BOOST_TEST_SUITE("test deep_copy of proto parse trees");
+
+ test->add(BOOST_TEST_CASE(&test1));
+
+ return test;
+}

Added: branches/proto/v4/libs/proto/test/examples.cpp
==============================================================================
--- (empty file)
+++ branches/proto/v4/libs/proto/test/examples.cpp 2008-04-06 02:19:35 EDT (Sun, 06 Apr 2008)
@@ -0,0 +1,422 @@
+///////////////////////////////////////////////////////////////////////////////
+// examples.hpp
+//
+// Copyright 2008 Eric Niebler. Distributed under the Boost
+// Software License, Version 1.0. (See accompanying file
+// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#include <iostream>
+#include <boost/config.hpp>
+#include <boost/mpl/min_max.hpp>
+#include <boost/proto/core.hpp>
+#include <boost/proto/transform.hpp>
+#include <boost/utility/result_of.hpp>
+#if BOOST_VERSION < 103500
+# include <boost/spirit/fusion/sequence/cons.hpp>
+#else
+# include <boost/fusion/include/cons.hpp>
+# include <boost/fusion/include/pop_front.hpp>
+#endif
+#include <boost/test/unit_test.hpp>
+
+namespace mpl = boost::mpl;
+namespace proto = boost::proto;
+namespace fusion = boost::fusion;
+using proto::_;
+
+struct placeholder1 {};
+struct placeholder2 {};
+
+namespace test1
+{
+//[ CalcGrammar
+ // This is the grammar for calculator expressions,
+ // to which we will attach transforms for computing
+ // the expressions' arity.
+ /*<< A Calculator expression is ... >>*/
+ struct CalcArity
+ : proto::or_<
+ /*<< placeholder1, or ... >>*/
+ proto::terminal< placeholder1 >
+ /*<< placeholder2, or ... >>*/
+ , proto::terminal< placeholder2 >
+ /*<< some other terminal, or ... >>*/
+ , proto::terminal< _ >
+ /*<< a unary expression where the operand is a calculator expression, or ... >>*/
+ , proto::unary_expr< _, CalcArity >
+ /*<< a binary expression where the operands are calculator expressions >>*/
+ , proto::binary_expr< _, CalcArity, CalcArity >
+ >
+ {};
+//]
+}
+
+//[ binary_arity
+/*<< The `CalculatorArity` is a transform for calculating
+the arity of a calculator expression. It will be define in
+terms of `binary_arity`, which is defined in terms of
+`CalculatorArity`; hence, the definition is recursive.>>*/
+struct CalculatorArity;
+
+// A custom transform that returns the arity of a unary
+// calculator expression by finding the arity of the
+// child expression.
+struct unary_arity
+ /*<< Custom transforms should inherit from
+ transform<>. In some cases, (e.g., when the transform
+ is a template), it is also necessary to specialize
+ the proto::is_callable<> trait. >>*/
+ : proto::transform<unary_arity>
+{
+ template<typename Expr, typename State, typename Data>
+ /*<< Transforms have a nested `impl<>` that is
+ a valid TR1 function object. >>*/
+ struct impl
+ : proto::transform_impl<Expr, State, Data>
+ {
+ /*<< Get the child. >>*/
+ typedef typename proto::result_of::child<Expr>::type child_expr;
+
+ /*<< Apply `CalculatorArity` to find the arity of the child. >>*/
+ typedef typename boost::result_of<CalculatorArity(child_expr, State, Data)>::type result_type;
+
+ /*<< The `unary_arity` transform doesn't have an interesting
+ runtime counterpart, so just return a default-constructed object
+ of the correct type. >>*/
+ result_type operator ()(proto::ignore, proto::ignore, proto::ignore) const
+ {
+ return result_type();
+ }
+ };
+};
+
+// A custom transform that returns the arity of a binary
+// calculator expression by finding the maximum of the
+// arities of the mpl::int_<2> child expressions.
+struct binary_arity
+ /*<< All custom transforms should inherit from
+ transform. In some cases, (e.g., when the transform
+ is a template), it is also necessary to specialize
+ the proto::is_callable<> trait. >>*/
+ : proto::transform<binary_arity>
+{
+ template<typename Expr, typename State, typename Data>
+ /*<< Transforms have a nested `impl<>` that is
+ a valid TR1 function object. >>*/
+ struct impl
+ : proto::transform_impl<Expr, State, Data>
+ {
+ /*<< Get the left and right children. >>*/
+ typedef typename proto::result_of::left<Expr>::type left_expr;
+ typedef typename proto::result_of::right<Expr>::type right_expr;
+
+ /*<< Apply `CalculatorArity` to find the arity of the left and right children. >>*/
+ typedef typename boost::result_of<CalculatorArity(left_expr, State, Data)>::type left_arity;
+ typedef typename boost::result_of<CalculatorArity(right_expr, State, Data)>::type right_arity;
+
+ /*<< The return type is the maximum of the children's arities. >>*/
+ typedef typename mpl::max<left_arity, right_arity>::type result_type;
+
+ /*<< The `unary_arity` transform doesn't have an interesting
+ runtime counterpart, so just return a default-constructed object
+ of the correct type. >>*/
+ result_type operator ()(proto::ignore, proto::ignore, proto::ignore) const
+ {
+ return result_type();
+ }
+ };
+};
+//]
+
+proto::terminal< placeholder1 >::type const _1 = {{}};
+proto::terminal< placeholder2 >::type const _2 = {{}};
+
+//[ CalculatorArityGrammar
+struct CalculatorArity
+ : proto::or_<
+ proto::when< proto::terminal< placeholder1 >, mpl::int_<1>() >
+ , proto::when< proto::terminal< placeholder2 >, mpl::int_<2>() >
+ , proto::when< proto::terminal<_>, mpl::int_<0>() >
+ , proto::when< proto::unary_expr<_, _>, unary_arity >
+ , proto::when< proto::binary_expr<_, _, _>, binary_arity >
+ >
+{};
+//]
+
+//[ CalcArity
+struct CalcArity
+ : proto::or_<
+ proto::when< proto::terminal< placeholder1 >,
+ mpl::int_<1>()
+ >
+ , proto::when< proto::terminal< placeholder2 >,
+ mpl::int_<2>()
+ >
+ , proto::when< proto::terminal<_>,
+ mpl::int_<0>()
+ >
+ , proto::when< proto::unary_expr<_, CalcArity>,
+ CalcArity(proto::_child)
+ >
+ , proto::when< proto::binary_expr<_, CalcArity, CalcArity>,
+ mpl::max<CalcArity(proto::_left),
+ CalcArity(proto::_right)>()
+ >
+ >
+{};
+//]
+
+// BUGBUG find workaround for this
+#if BOOST_WORKAROUND(BOOST_MSVC, == 1310)
+#define _pop_front(x) call<proto::_pop_front(x)>
+#define _value(x) call<proto::_value(x)>
+#endif
+
+//[ AsArgList
+// This transform matches function invocations such as foo(1,'a',"b")
+// and transforms them into Fusion cons lists of their arguments. In this
+// case, the result would be cons(1, cons('a', cons("b", nil()))).
+struct ArgsAsList
+ : proto::when<
+ proto::function<proto::terminal<_>, proto::vararg<proto::terminal<_> > >
+ /*<< Use a `reverse_fold<>` transform to iterate over the children
+ of this node in reverse order, building a fusion list from back to
+ front. >>*/
+ , proto::reverse_fold<
+ /*<< The first child expression of a `function<>` node is the
+ function being invoked. We don't want that in our list, so use
+ `pop_front()` to remove it. >>*/
+ proto::_pop_front(_)
+ /*<< `nil` is the initial state used by the `reverse_fold<>`
+ transform. >>*/
+ , fusion::nil()
+ /*<< Put the rest of the function arguments in a fusion cons
+ list. >>*/
+ , fusion::cons<proto::_value, proto::_state>(proto::_value, proto::_state)
+ >
+ >
+{};
+//]
+
+//[ FoldTreeToList
+// This transform matches expressions of the form (_1=1,'a',"b")
+// (note the use of the comma operator) and transforms it into a
+// Fusion cons list of their arguments. In this case, the result
+// would be cons(1, cons('a', cons("b", nil()))).
+struct FoldTreeToList
+ : proto::or_<
+ // This grammar describes what counts as the terminals in expressions
+ // of the form (_1=1,'a',"b"), which will be flattened using
+ // reverse_fold_tree<> below.
+ proto::when< proto::assign<_, proto::terminal<_> >
+ , proto::_value(proto::_right)
+ >
+ , proto::when< proto::terminal<_>
+ , proto::_value
+ >
+ , proto::when<
+ proto::comma<FoldTreeToList, FoldTreeToList>
+ /*<< Fold all terminals that are separated by commas into a Fusion cons list. >>*/
+ , proto::reverse_fold_tree<
+ _
+ , fusion::nil()
+ , fusion::cons<FoldTreeToList, proto::_state>(FoldTreeToList, proto::_state)
+ >
+ >
+ >
+{};
+//]
+
+//[ Promote
+// This transform finds all float terminals in an expression and promotes
+// them to doubles.
+struct Promote
+ : proto::or_<
+ /*<< Match a `terminal<float>`, then construct a
+ `terminal<double>::type` with the `float`. >>*/
+ proto::when<proto::terminal<float>, proto::terminal<double>::type(proto::_value) >
+ , proto::when<proto::terminal<_> >
+ /*<< `nary_expr<>` has a pass-through transform which
+ will transform each child sub-expression using the
+ `Promote` transform. >>*/
+ , proto::when<proto::nary_expr<_, proto::vararg<Promote> > >
+ >
+{};
+//]
+
+//[ LazyMakePair
+struct make_pair_tag {};
+proto::terminal<make_pair_tag>::type const make_pair_ = {{}};
+
+// This transform matches lazy function invocations like
+// `make_pair_(1, 3.14)` and actually builds a `std::pair<>`
+// from the arguments.
+struct MakePair
+ : proto::when<
+ /*<< Match expressions like `make_pair_(1, 3.14)` >>*/
+ proto::function<
+ proto::terminal<make_pair_tag>
+ , proto::terminal<_>
+ , proto::terminal<_>
+ >
+ /*<< Return `std::pair<F,S>(f,s)` where `f` and `s` are the
+ first and second arguments to the lazy `make_pair_()` function.
+ (This uses `proto::make<>` under the covers to evaluate the
+ transform.)>>*/
+ , std::pair<
+ proto::_value(proto::_child1)
+ , proto::_value(proto::_child2)
+ >(
+ proto::_value(proto::_child1)
+ , proto::_value(proto::_child2)
+ )
+ >
+{};
+//]
+
+namespace lazy_make_pair2
+{
+ //[ LazyMakePair2
+ struct make_pair_tag {};
+ proto::terminal<make_pair_tag>::type const make_pair_ = {{}};
+
+ // Like std::make_pair(), only as a function object.
+ /*<<Inheriting from `proto::callable` lets Proto know
+ that this is a callable transform, so we can use it
+ without having to wrap it in `proto::call<>`.>>*/
+ struct make_pair : proto::callable
+ {
+ template<typename Sig> struct result;
+
+ template<typename This, typename First, typename Second>
+ struct result<This(First, Second)>
+ {
+ typedef std::pair<First, Second> type;
+ };
+
+ template<typename First, typename Second>
+ std::pair<First, Second>
+ operator()(First const &first, Second const &second) const
+ {
+ return std::make_pair(first, second);
+ }
+ };
+
+ // This transform matches lazy function invocations like
+ // `make_pair_(1, 3.14)` and actually builds a `std::pair<>`
+ // from the arguments.
+ struct MakePair
+ : proto::when<
+ /*<< Match expressions like `make_pair_(1, 3.14)` >>*/
+ proto::function<
+ proto::terminal<make_pair_tag>
+ , proto::terminal<_>
+ , proto::terminal<_>
+ >
+ /*<< Return `make_pair()(f,s)` where `f` and `s` are the
+ first and second arguments to the lazy `make_pair_()` function.
+ (This uses `proto::call<>` under the covers to evaluate the
+ transform.)>>*/
+ , make_pair(
+ proto::_value(proto::_child1)
+ , proto::_value(proto::_child2)
+ )
+ >
+ {};
+ //]
+}
+
+
+//[ NegateInt
+struct NegateInt
+ : proto::when<proto::terminal<int>, proto::negate<_>(_)>
+{};
+//]
+
+#ifndef BOOST_MSVC
+//[ SquareAndPromoteInt
+struct SquareAndPromoteInt
+ : proto::when<
+ proto::terminal<int>
+ , proto::_make_multiplies(
+ proto::terminal<long>::type(proto::_value)
+ , proto::terminal<long>::type(proto::_value)
+ )
+ >
+{};
+//]
+#endif
+
+void test_examples()
+{
+ //[ CalculatorArityTest
+ int i = 0; // not used, dummy state and data parameter
+
+ std::cout << CalculatorArity()( proto::lit(100) * 200, i, i) << '\n';
+ std::cout << CalculatorArity()( (_1 - _1) / _1 * 100, i, i) << '\n';
+ std::cout << CalculatorArity()( (_2 - _1) / _2 * 100, i, i) << '\n';
+ //]
+
+ BOOST_CHECK_EQUAL(0, CalculatorArity()( proto::lit(100) * 200, i, i));
+ BOOST_CHECK_EQUAL(1, CalculatorArity()( (_1 - _1) / _1 * 100, i, i));
+ BOOST_CHECK_EQUAL(2, CalculatorArity()( (_2 - _1) / _2 * 100, i, i));
+
+ BOOST_CHECK_EQUAL(0, CalcArity()( proto::lit(100) * 200, i, i));
+ BOOST_CHECK_EQUAL(1, CalcArity()( (_1 - _1) / _1 * 100, i, i));
+ BOOST_CHECK_EQUAL(2, CalcArity()( (_2 - _1) / _2 * 100, i, i));
+
+ using boost::fusion::cons;
+ using boost::fusion::nil;
+ cons<int, cons<char, cons<std::string> > > args(ArgsAsList()( _1(1, 'a', std::string("b")), i, i ));
+ BOOST_CHECK_EQUAL(args.car, 1);
+ BOOST_CHECK_EQUAL(args.cdr.car, 'a');
+ BOOST_CHECK_EQUAL(args.cdr.cdr.car, std::string("b"));
+
+ cons<int, cons<char, cons<std::string> > > lst(FoldTreeToList()( (_1 = 1, 'a', std::string("b")), i, i ));
+ BOOST_CHECK_EQUAL(lst.car, 1);
+ BOOST_CHECK_EQUAL(lst.cdr.car, 'a');
+ BOOST_CHECK_EQUAL(lst.cdr.cdr.car, std::string("b"));
+
+ proto::plus<
+ proto::terminal<double>::type
+ , proto::terminal<double>::type
+ >::type p = Promote()( proto::lit(1.f) + 2.f, i, i );
+
+ //[ LazyMakePairTest
+ int j = 0; // not used, dummy state and data parameter
+
+ std::pair<int, double> p2 = MakePair()( make_pair_(1, 3.14), j, j );
+
+ std::cout << p2.first << std::endl;
+ std::cout << p2.second << std::endl;
+ //]
+
+ BOOST_CHECK_EQUAL(p2.first, 1);
+ BOOST_CHECK_EQUAL(p2.second, 3.14);
+
+ std::pair<int, double> p3 = lazy_make_pair2::MakePair()( lazy_make_pair2::make_pair_(1, 3.14), j, j );
+
+ std::cout << p3.first << std::endl;
+ std::cout << p3.second << std::endl;
+
+ BOOST_CHECK_EQUAL(p3.first, 1);
+ BOOST_CHECK_EQUAL(p3.second, 3.14);
+
+ NegateInt()(proto::lit(1), i, i);
+ #ifndef BOOST_MSVC
+ SquareAndPromoteInt()(proto::lit(1), i, i);
+ #endif
+}
+
+using namespace boost::unit_test;
+///////////////////////////////////////////////////////////////////////////////
+// init_unit_test_suite
+//
+test_suite* init_unit_test_suite( int argc, char* argv[] )
+{
+ test_suite *test = BOOST_TEST_SUITE("test examples from the documentation");
+
+ test->add(BOOST_TEST_CASE(&test_examples));
+
+ return test;
+}

Added: branches/proto/v4/libs/proto/test/lambda.cpp
==============================================================================
--- (empty file)
+++ branches/proto/v4/libs/proto/test/lambda.cpp 2008-04-06 02:19:35 EDT (Sun, 06 Apr 2008)
@@ -0,0 +1,203 @@
+///////////////////////////////////////////////////////////////////////////////
+// lambda.hpp
+//
+// Copyright 2008 Eric Niebler. Distributed under the Boost
+// Software License, Version 1.0. (See accompanying file
+// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#include <sstream>
+#include <boost/version.hpp>
+#include <boost/mpl/int.hpp>
+#include <boost/mpl/min_max.hpp>
+#include <boost/mpl/eval_if.hpp>
+#include <boost/mpl/identity.hpp>
+#include <boost/mpl/next_prior.hpp>
+#if BOOST_VERSION < 103500
+# include <boost/spirit/fusion/sequence/at.hpp>
+# include <boost/spirit/fusion/sequence/tuple.hpp>
+namespace boost { namespace fusion { namespace result_of { using namespace meta; }}}
+#else
+# include <boost/fusion/tuple.hpp>
+#endif
+#include <boost/typeof/typeof.hpp>
+#include <boost/typeof/std/sstream.hpp>
+#include <boost/typeof/std/ostream.hpp>
+#include <boost/typeof/std/iostream.hpp>
+#include <boost/type_traits/add_const.hpp>
+#include <boost/type_traits/add_reference.hpp>
+#include <boost/proto/core.hpp>
+#include <boost/proto/context.hpp>
+#include <boost/proto/transform.hpp>
+#include <boost/test/unit_test.hpp>
+#include <boost/test/floating_point_comparison.hpp>
+
+using namespace boost;
+
+// Forward declaration of the lambda expression wrapper
+template<typename T>
+struct lambda;
+
+struct lambda_domain
+ : proto::domain<proto::pod_generator<lambda> >
+{};
+
+template<typename I>
+struct placeholder
+{
+ typedef I arity;
+};
+
+template<typename T>
+struct placeholder_arity
+{
+ typedef typename T::arity type;
+};
+
+namespace grammar
+{
+ using namespace proto;
+
+ // The lambda grammar, with the transforms for calculating the max arity
+ struct Lambda
+ : or_<
+ when< terminal< placeholder<_> >, mpl::next<placeholder_arity<_value> >() >
+ , when< terminal<_>, mpl::int_<0>() >
+ , when< nary_expr<_, vararg<_> >, fold<_, mpl::int_<0>(), mpl::max<Lambda,_state>()> >
+ >
+ {};
+}
+
+// simple wrapper for calculating a lambda expression's arity.
+template<typename Expr>
+struct lambda_arity
+ : boost::result_of<grammar::Lambda(Expr, mpl::void_, mpl::void_)>
+{};
+
+// The lambda context is the same as the default context
+// with the addition of special handling for lambda placeholders
+template<typename Tuple>
+struct lambda_context
+ : proto::callable_context<lambda_context<Tuple> const>
+{
+ lambda_context(Tuple const &args)
+ : args_(args)
+ {}
+
+ template<typename Sig>
+ struct result;
+
+ template<typename This, typename I>
+ struct result<This(proto::tag::terminal, placeholder<I> const &)>
+ : fusion::result_of::at<Tuple, I>
+ {};
+
+ template<typename I>
+ typename fusion::result_of::at<Tuple, I>::type
+ operator ()(proto::tag::terminal, placeholder<I> const &) const
+ {
+ #if BOOST_VERSION < 103500
+ return fusion::at<I::value>(this->args_);
+ #else
+ return fusion::at<I>(this->args_);
+ #endif
+ }
+
+ Tuple args_;
+};
+
+// The lambda<> expression wrapper makes expressions polymorphic
+// function objects
+template<typename T>
+struct lambda
+{
+ BOOST_PROTO_BASIC_EXTENDS(T, lambda<T>, lambda_domain)
+ BOOST_PROTO_EXTENDS_ASSIGN()
+ BOOST_PROTO_EXTENDS_SUBSCRIPT()
+
+ // Careful not to evaluate the return type of the nullary function
+ // unless we have a nullary lambda!
+ typedef typename mpl::eval_if<
+ typename lambda_arity<T>::type
+ , mpl::identity<void>
+ , proto::result_of::eval<T const, lambda_context<fusion::tuple<> > >
+ >::type nullary_type;
+
+ // Define our operator () that evaluates the lambda expression.
+ nullary_type operator ()() const
+ {
+ fusion::tuple<> args;
+ lambda_context<fusion::tuple<> > ctx(args);
+ return proto::eval(*this, ctx);
+ }
+
+ template<typename A0>
+ typename proto::result_of::eval<T const, lambda_context<fusion::tuple<A0 const &> > >::type
+ operator ()(A0 const &a0) const
+ {
+ fusion::tuple<A0 const &> args(a0);
+ lambda_context<fusion::tuple<A0 const &> > ctx(args);
+ return proto::eval(*this, ctx);
+ }
+
+ template<typename A0, typename A1>
+ typename proto::result_of::eval<T const, lambda_context<fusion::tuple<A0 const &, A1 const &> > >::type
+ operator ()(A0 const &a0, A1 const &a1) const
+ {
+ fusion::tuple<A0 const &, A1 const &> args(a0, a1);
+ lambda_context<fusion::tuple<A0 const &, A1 const &> > ctx(args);
+ return proto::eval(*this, ctx);
+ }
+};
+
+// Define some lambda placeholders
+lambda<proto::terminal<placeholder<mpl::int_<0> > >::type> const _1 = {{}};
+lambda<proto::terminal<placeholder<mpl::int_<1> > >::type> const _2 = {{}};
+
+template<typename T>
+lambda<typename proto::terminal<T>::type> const val(T const &t)
+{
+ lambda<typename proto::terminal<T>::type> that = {{t}};
+ return that;
+}
+
+template<typename T>
+lambda<typename proto::terminal<T &>::type> const var(T &t)
+{
+ lambda<typename proto::terminal<T &>::type> that = {{t}};
+ return that;
+}
+
+void test_lambda()
+{
+ BOOST_CHECK_EQUAL(11, ( (_1 + 2) / 4 )(42));
+ BOOST_CHECK_EQUAL(-11, ( (-(_1 + 2)) / 4 )(42));
+ BOOST_CHECK_CLOSE(2.58, ( (4 - _2) * 3 )(42, 3.14), 0.1);
+
+ // check non-const ref terminals
+ std::stringstream sout;
+ (sout << _1 << " -- " << _2)(42, "Life, the Universe and Everything!");
+ BOOST_CHECK_EQUAL("42 -- Life, the Universe and Everything!", sout.str());
+
+ // check nullary lambdas
+ BOOST_CHECK_EQUAL(3, (val(1) + val(2))());
+
+ // check array indexing for kicks
+ int integers[5] = {0};
+ (var(integers)[2] = 2)();
+ (var(integers)[_1] = _1)(3);
+ BOOST_CHECK_EQUAL(2, integers[2]);
+ BOOST_CHECK_EQUAL(3, integers[3]);
+}
+
+using namespace unit_test;
+///////////////////////////////////////////////////////////////////////////////
+// init_unit_test_suite
+//
+test_suite* init_unit_test_suite( int argc, char* argv[] )
+{
+ test_suite *test = BOOST_TEST_SUITE("test expression template domains");
+
+ test->add(BOOST_TEST_CASE(&test_lambda));
+
+ return test;
+}

Added: branches/proto/v4/libs/proto/test/make_expr.cpp
==============================================================================
--- (empty file)
+++ branches/proto/v4/libs/proto/test/make_expr.cpp 2008-04-06 02:19:35 EDT (Sun, 06 Apr 2008)
@@ -0,0 +1,235 @@
+///////////////////////////////////////////////////////////////////////////////
+// make_expr.hpp
+//
+// Copyright 2008 Eric Niebler. Distributed under the Boost
+// Software License, Version 1.0. (See accompanying file
+// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#include <sstream>
+#include <boost/version.hpp>
+#include <boost/proto/core.hpp>
+#include <boost/proto/transform.hpp>
+#if BOOST_VERSION >= 103500
+#include <boost/fusion/tuple.hpp>
+#else
+#include <boost/spirit/fusion/sequence/make_tuple.hpp>
+#endif
+#include <boost/test/unit_test.hpp>
+
+using namespace boost;
+using namespace proto;
+
+template<typename E> struct ewrap;
+
+struct mydomain
+ : domain<generator<ewrap> >
+{};
+
+template<typename E> struct ewrap
+ : extends<E, ewrap<E>, mydomain>
+{
+ explicit ewrap(E const &e = E())
+ : extends<E, ewrap<E>, mydomain>(e)
+ {}
+};
+
+void test_make_expr()
+{
+ int i = 42;
+ terminal<int>::type t1 = make_expr<tag::terminal>(1);
+ terminal<int>::type t2 = make_expr<tag::terminal>(i);
+ unary_plus<terminal<int>::type>::type p1 = make_expr<tag::unary_plus>(1);
+ unary_plus<terminal<int>::type>::type p2 = make_expr<tag::unary_plus>(i);
+ BOOST_CHECK_EQUAL(proto::value(proto::child(p2)), 42);
+
+ ewrap<unary_plus<ewrap<terminal<int>::type> >::type> p3 = make_expr<tag::unary_plus, mydomain>(i);
+ BOOST_CHECK_EQUAL(proto::value(proto::child(p3)), 42);
+
+ ewrap<plus<
+ ewrap<unary_plus<ewrap<terminal<int>::type> >::type>
+ , ewrap<terminal<int>::type>
+ >::type> p4 = make_expr<tag::plus>(p3, 0);
+ BOOST_CHECK_EQUAL(proto::value(proto::child(proto::left(p4))), 42);
+}
+
+void test_make_expr_ref()
+{
+ int i = 42;
+ terminal<int const &>::type t1 = make_expr<tag::terminal>(boost::cref(1)); // DANGEROUS
+ terminal<int &>::type t2 = make_expr<tag::terminal>(boost::ref(i));
+ BOOST_CHECK_EQUAL(&i, &proto::value(t2));
+ unary_plus<terminal<int const &>::type>::type p1 = make_expr<tag::unary_plus>(boost::cref(1)); // DANGEROUS
+ unary_plus<terminal<int &>::type>::type p2 = make_expr<tag::unary_plus>(boost::ref(i));
+ BOOST_CHECK_EQUAL(proto::value(proto::child(p2)), 42);
+
+ ewrap<unary_plus<ewrap<terminal<int &>::type> >::type> p3 = make_expr<tag::unary_plus, mydomain>(boost::ref(i));
+ BOOST_CHECK_EQUAL(proto::value(proto::child(p3)), 42);
+
+ ewrap<plus<
+ ewrap<unary_plus<ewrap<terminal<int &>::type> >::type> &
+ , ewrap<terminal<int>::type>
+ >::type> p4 = make_expr<tag::plus>(boost::ref(p3), 0);
+ BOOST_CHECK_EQUAL(proto::value(proto::child(proto::left(p4))), 42);
+}
+
+void test_make_expr_functional()
+{
+ int i = 42;
+ terminal<int>::type t1 = functor::make_expr<tag::terminal>()(1);
+ terminal<int>::type t2 = functor::make_expr<tag::terminal>()(i);
+ unary_plus<terminal<int>::type>::type p1 = functor::make_expr<tag::unary_plus>()(1);
+ unary_plus<terminal<int>::type>::type p2 = functor::make_expr<tag::unary_plus>()(i);
+ BOOST_CHECK_EQUAL(proto::value(proto::child(p2)), 42);
+
+ ewrap<unary_plus<ewrap<terminal<int>::type> >::type> p3 = functor::make_expr<tag::unary_plus, mydomain>()(i);
+ BOOST_CHECK_EQUAL(proto::value(proto::child(p3)), 42);
+
+ ewrap<plus<
+ ewrap<unary_plus<ewrap<terminal<int>::type> >::type>
+ , ewrap<terminal<int>::type>
+ >::type> p4 = functor::make_expr<tag::plus, mydomain>()(p3, 0);
+ BOOST_CHECK_EQUAL(proto::value(proto::child(proto::left(p4))), 42);
+}
+
+void test_make_expr_functional_ref()
+{
+ int i = 42;
+ terminal<int const &>::type t1 = functor::make_expr<tag::terminal>()(boost::cref(1)); // DANGEROUS
+ terminal<int &>::type t2 = functor::make_expr<tag::terminal>()(boost::ref(i));
+ BOOST_CHECK_EQUAL(&i, &proto::value(t2));
+ unary_plus<terminal<int const &>::type>::type p1 = functor::make_expr<tag::unary_plus>()(boost::cref(1)); // DANGEROUS
+ unary_plus<terminal<int &>::type>::type p2 = functor::make_expr<tag::unary_plus>()(boost::ref(i));
+ BOOST_CHECK_EQUAL(proto::value(proto::child(p2)), 42);
+
+ ewrap<unary_plus<ewrap<terminal<int &>::type> >::type> p3 = functor::make_expr<tag::unary_plus, mydomain>()(boost::ref(i));
+ BOOST_CHECK_EQUAL(proto::value(proto::child(p3)), 42);
+
+ ewrap<plus<
+ ewrap<unary_plus<ewrap<terminal<int &>::type> >::type> &
+ , ewrap<terminal<int>::type>
+ >::type> p4 = functor::make_expr<tag::plus, mydomain>()(boost::ref(p3), 0);
+ BOOST_CHECK_EQUAL(proto::value(proto::child(proto::left(p4))), 42);
+}
+
+void test_unpack_expr()
+{
+ int i = 42;
+ terminal<int>::type t1 = unpack_expr<tag::terminal>(fusion::make_tuple(1));
+ terminal<int &>::type t2 = unpack_expr<tag::terminal>(fusion::make_tuple(boost::ref(i)));
+ unary_plus<terminal<int>::type>::type p1 = unpack_expr<tag::unary_plus>(fusion::make_tuple(1));
+ unary_plus<terminal<int &>::type>::type p2 = unpack_expr<tag::unary_plus>(fusion::make_tuple(boost::ref(i)));
+ BOOST_CHECK_EQUAL(proto::value(proto::child(p2)), 42);
+
+ ewrap<unary_plus<ewrap<terminal<int &>::type> >::type> p3 = unpack_expr<tag::unary_plus, mydomain>(fusion::make_tuple(boost::ref(i)));
+ BOOST_CHECK_EQUAL(proto::value(proto::child(p3)), 42);
+
+ ewrap<plus<
+ ewrap<unary_plus<ewrap<terminal<int &>::type> >::type> &
+ , ewrap<terminal<int>::type>
+ >::type> p4 = unpack_expr<tag::plus>(fusion::make_tuple(boost::ref(p3), 0));
+ BOOST_CHECK_EQUAL(proto::value(proto::child(proto::left(p4))), 42);
+}
+
+void test_unpack_expr_functional()
+{
+ int i = 42;
+ terminal<int>::type t1 = functor::unpack_expr<tag::terminal>()(fusion::make_tuple(1));
+ terminal<int &>::type t2 = functor::unpack_expr<tag::terminal>()(fusion::make_tuple(boost::ref(i)));
+ unary_plus<terminal<int>::type>::type p1 = functor::unpack_expr<tag::unary_plus>()(fusion::make_tuple(1));
+ unary_plus<terminal<int &>::type>::type p2 = functor::unpack_expr<tag::unary_plus>()(fusion::make_tuple(boost::ref(i)));
+ BOOST_CHECK_EQUAL(proto::value(proto::child(p2)), 42);
+
+ ewrap<unary_plus<ewrap<terminal<int &>::type> >::type> p3 = functor::unpack_expr<tag::unary_plus, mydomain>()(fusion::make_tuple(boost::ref(i)));
+ BOOST_CHECK_EQUAL(proto::value(proto::child(p3)), 42);
+
+ ewrap<plus<
+ ewrap<unary_plus<ewrap<terminal<int &>::type> >::type> &
+ , ewrap<terminal<int>::type>
+ >::type> p4 = functor::unpack_expr<tag::plus>()(fusion::make_tuple(boost::ref(p3), 0));
+ BOOST_CHECK_EQUAL(proto::value(proto::child(proto::left(p4))), 42);
+}
+
+#if BOOST_WORKAROUND(BOOST_MSVC, == 1310)
+#define _ref(x) call<_ref(x)>
+#define Minus(x) call<Minus(x)>
+#endif
+
+// Turn all terminals held by reference into ones held by value
+struct ByVal
+ : or_<
+ when<terminal<_>, _make_terminal(_value)>
+ , when<nary_expr<_, vararg<ByVal> > >
+ >
+{};
+
+// Turn all terminals held by value into ones held by reference (not safe in general)
+struct ByRef
+ : or_<
+ when<terminal<_>, _make_terminal(_ref(_value))>
+ , when<nary_expr<_, vararg<ByRef> > >
+ >
+{};
+
+// turn all plus nodes to minus nodes:
+struct Minus
+ : or_<
+ when<terminal<_> >
+ , when<plus<Minus, Minus>, _make_minus(Minus(_left), Minus(_right)) >
+ >
+{};
+
+struct Square
+ : or_<
+ // Not creating new terminal nodes here,
+ // so hold the existing terminals by reference:
+ when<terminal<_>, _make_multiplies(_ref(_), _ref(_))>
+ , when<plus<Square, Square> >
+ >
+{};
+
+#if BOOST_WORKAROUND(BOOST_MSVC, == 1310)
+#undef _ref
+#undef Minus
+#endif
+
+void test_make_expr_transform()
+{
+ plus<
+ terminal<int>::type
+ , terminal<int>::type
+ >::type t1 = ByVal()(as_expr(1) + 1);
+
+ plus<
+ terminal<int const &>::type
+ , terminal<int const &>::type
+ >::type t2 = ByRef()(as_expr(1) + 1);
+
+ minus<
+ terminal<int>::type
+ , terminal<int const &>::type
+ >::type t3 = Minus()(as_expr(1) + 1);
+
+ plus<
+ multiplies<terminal<int>::type const &, terminal<int>::type const &>::type
+ , multiplies<terminal<int const &>::type const &, terminal<int const &>::type const &>::type
+ >::type t4 = Square()(as_expr(1) + 1);
+}
+
+using namespace unit_test;
+///////////////////////////////////////////////////////////////////////////////
+// init_unit_test_suite
+//
+test_suite* init_unit_test_suite( int argc, char* argv[] )
+{
+ test_suite *test = BOOST_TEST_SUITE("test make_expr, unpack_expr and friends");
+
+ test->add(BOOST_TEST_CASE(&test_make_expr));
+ test->add(BOOST_TEST_CASE(&test_make_expr_ref));
+ test->add(BOOST_TEST_CASE(&test_make_expr_functional));
+ test->add(BOOST_TEST_CASE(&test_make_expr_functional_ref));
+ test->add(BOOST_TEST_CASE(&test_unpack_expr));
+ test->add(BOOST_TEST_CASE(&test_unpack_expr_functional));
+ test->add(BOOST_TEST_CASE(&test_make_expr_transform));
+
+ return test;
+}

Added: branches/proto/v4/libs/proto/test/matches.cpp
==============================================================================
--- (empty file)
+++ branches/proto/v4/libs/proto/test/matches.cpp 2008-04-06 02:19:35 EDT (Sun, 06 Apr 2008)
@@ -0,0 +1,256 @@
+///////////////////////////////////////////////////////////////////////////////
+// matches.hpp
+//
+// Copyright 2008 Eric Niebler. Distributed under the Boost
+// Software License, Version 1.0. (See accompanying file
+// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#include <string>
+#include <iostream>
+#include <boost/mpl/assert.hpp>
+#include <boost/mpl/placeholders.hpp>
+#include <boost/type_traits/is_same.hpp>
+#include <boost/proto/core.hpp>
+#include <boost/proto/transform.hpp>
+#include <boost/test/unit_test.hpp>
+
+using namespace boost;
+using namespace proto;
+
+template<typename Grammar, typename Expr>
+void assert_matches(Expr const &expr)
+{
+ BOOST_MPL_ASSERT((matches<Expr, Grammar>));
+}
+
+template<typename Grammar, typename Expr>
+void assert_not_matches(Expr const &expr)
+{
+ BOOST_MPL_ASSERT_NOT((matches<Expr, Grammar>));
+}
+
+struct int_convertible
+{
+ int_convertible() {}
+ operator int() const { return 0; }
+};
+
+struct Input
+ : or_<
+ shift_right< terminal< std::istream & >, _ >
+ , shift_right< Input, _ >
+ >
+{};
+
+struct Output
+ : or_<
+ shift_left< terminal< std::ostream & >, _ >
+ , shift_left< Output, _ >
+ >
+{};
+
+terminal< std::istream & >::type const cin_ = {std::cin};
+terminal< std::ostream & >::type const cout_ = {std::cout};
+
+struct Anything
+ : or_<
+ terminal<_>
+ , nary_expr<_, vararg<Anything> >
+ >
+{};
+
+void a_function() {}
+
+struct MyCases
+{
+ template<typename Tag>
+ struct case_
+ : proto::not_<proto::_>
+ {};
+};
+
+template<>
+struct MyCases::case_<proto::tag::shift_right>
+ : proto::_
+{};
+
+template<>
+struct MyCases::case_<proto::tag::plus>
+ : proto::_
+{};
+
+enum binary_representation_enum
+{
+ magnitude
+ , two_complement
+};
+
+typedef
+ mpl::integral_c<binary_representation_enum, magnitude>
+magnitude_c;
+
+typedef
+ mpl::integral_c<binary_representation_enum, two_complement>
+two_complement_c;
+
+template<typename Type, typename Representation>
+struct number
+{};
+
+struct NumberGrammar
+ : proto::or_ <
+ proto::terminal<number<proto::_, two_complement_c> >
+ , proto::terminal<number<proto::_, magnitude_c> >
+ >
+{};
+
+
+void test_matches()
+{
+ assert_matches< _ >( lit(1) );
+ assert_matches< _ >( as_child(1) );
+ assert_matches< _ >( as_expr(1) );
+
+ assert_matches< terminal<int> >( lit(1) );
+ assert_matches< terminal<int> >( as_child(1) );
+ assert_matches< terminal<int> >( as_expr(1) );
+
+ assert_not_matches< terminal<int> >( lit('a') );
+ assert_not_matches< terminal<int> >( as_child('a') );
+ assert_not_matches< terminal<int> >( as_expr('a') );
+
+ assert_matches< terminal<convertible_to<int> > >( lit('a') );
+ assert_matches< terminal<convertible_to<int> > >( as_child('a') );
+ assert_matches< terminal<convertible_to<int> > >( as_expr('a') );
+
+ assert_not_matches< terminal<int> >( lit((int_convertible())) );
+ assert_not_matches< terminal<int> >( as_child((int_convertible())) );
+ assert_not_matches< terminal<int> >( as_expr((int_convertible())) );
+
+ assert_matches< terminal<convertible_to<int> > >( lit((int_convertible())) );
+ assert_matches< terminal<convertible_to<int> > >( as_child((int_convertible())) );
+ assert_matches< terminal<convertible_to<int> > >( as_expr((int_convertible())) );
+
+ assert_matches< if_<is_same<_value, int>() > >( lit(1) );
+ assert_not_matches< if_<is_same<_value, int>() > >( lit('a') );
+
+ assert_matches<
+ and_<
+ terminal<_>
+ , if_<is_same<_value, int>() >
+ >
+ >( lit(1) );
+
+ assert_not_matches<
+ and_<
+ terminal<_>
+ , if_<is_same<_value, int>() >
+ >
+ >( lit('a') );
+
+ assert_matches< terminal<char const *> >( lit("hello") );
+ assert_matches< terminal<char const *> >( as_child("hello") );
+ assert_matches< terminal<char const *> >( as_expr("hello") );
+
+ assert_matches< terminal<char const[6]> >( lit("hello") );
+ assert_matches< terminal<char const (&)[6]> >( as_child("hello") );
+ assert_matches< terminal<char const[6]> >( as_expr("hello") );
+
+ assert_matches< terminal<char [6]> >( lit("hello") );
+ assert_matches< terminal<char [6]> >( as_child("hello") );
+ assert_matches< terminal<char [6]> >( as_expr("hello") );
+
+ assert_matches< terminal<char const[N]> >( lit("hello") );
+ assert_matches< terminal<char const (&)[N]> >( as_child("hello") );
+ assert_matches< terminal<char const[N]> >( as_expr("hello") );
+
+ assert_matches< terminal<char [N]> >( lit("hello") );
+ assert_matches< terminal<char [N]> >( as_child("hello") );
+ assert_matches< terminal<char [N]> >( as_expr("hello") );
+
+ assert_matches< terminal<std::string> >( lit(std::string("hello")) );
+ assert_matches< terminal<std::string> >( as_child(std::string("hello")) );
+ assert_matches< terminal<std::string> >( as_expr(std::string("hello")) );
+
+ assert_matches< terminal<std::basic_string<_> > >( lit(std::string("hello")) );
+ assert_matches< terminal<std::basic_string<_> > >( as_child(std::string("hello")) );
+ assert_matches< terminal<std::basic_string<_> > >( as_expr(std::string("hello")) );
+
+ assert_not_matches< terminal<std::basic_string<_> > >( lit(1) );
+ assert_not_matches< terminal<std::basic_string<_> > >( as_child(1) );
+ assert_not_matches< terminal<std::basic_string<_> > >( as_expr(1) );
+
+ assert_not_matches< terminal<std::basic_string<_,_,_> > >( lit(1) );
+ assert_not_matches< terminal<std::basic_string<_,_,_> > >( as_child(1) );
+ assert_not_matches< terminal<std::basic_string<_,_,_> > >( as_expr(1) );
+
+ assert_matches< terminal<std::basic_string<_> const & > >( lit(std::string("hello")) );
+ assert_matches< terminal<std::basic_string<_> const & > >( as_child(std::string("hello")) );
+ assert_not_matches< terminal<std::basic_string<_> const & > >( as_expr(std::string("hello")) );
+
+ assert_matches< terminal< void(&)() > >( lit(a_function) );
+ assert_matches< terminal< void(&)() > >( as_child(a_function) );
+ assert_matches< terminal< void(&)() > >( as_expr(a_function) );
+
+ assert_not_matches< terminal< void(*)() > >( lit(a_function) );
+ assert_not_matches< terminal< void(*)() > >( as_child(a_function) );
+ assert_not_matches< terminal< void(*)() > >( as_expr(a_function) );
+
+ assert_matches< terminal< convertible_to<void(*)()> > >( lit(a_function) );
+ assert_matches< terminal< convertible_to<void(*)()> > >( as_child(a_function) );
+ assert_matches< terminal< convertible_to<void(*)()> > >( as_expr(a_function) );
+
+ assert_matches< terminal< void(*)() > >( lit(&a_function) );
+ assert_matches< terminal< void(*)() > >( as_child(&a_function) );
+ assert_matches< terminal< void(*)() > >( as_expr(&a_function) );
+
+ assert_matches< terminal< void(* const &)() > >( lit(&a_function) );
+ assert_matches< terminal< void(* const &)() > >( as_child(&a_function) );
+ assert_not_matches< terminal< void(* const &)() > >( as_expr(&a_function) );
+
+ assert_matches<
+ or_<
+ if_<is_same<_value, char>() >
+ , if_<is_same<_value, int>() >
+ >
+ >( lit(1) );
+
+ assert_not_matches<
+ or_<
+ if_<is_same<_value, char>() >
+ , if_<is_same<_value, int>() >
+ >
+ >( lit(1u) );
+
+ assert_matches< Input >( cin_ >> 1 >> 2 >> 3 );
+ assert_not_matches< Output >( cin_ >> 1 >> 2 >> 3 );
+
+ assert_matches< Output >( cout_ << 1 << 2 << 3 );
+ assert_not_matches< Input >( cout_ << 1 << 2 << 3 );
+
+ assert_matches< function< terminal<int>, vararg< terminal<char> > > >( lit(1)('a','b','c','d') );
+ assert_not_matches< function< terminal<int>, vararg< terminal<char> > > >( lit(1)('a','b','c',"d") );
+
+ assert_matches< Anything >( cout_ << 1 << +lit('a') << lit(1)('a','b','c',"d") );
+
+ assert_matches< proto::switch_<MyCases> >( lit(1) >> 'a' );
+ assert_matches< proto::switch_<MyCases> >( lit(1) + 'a' );
+ assert_not_matches< proto::switch_<MyCases> >( lit(1) << 'a' );
+
+ number<int, two_complement_c> num;
+ assert_matches<NumberGrammar>(proto::as_expr(num));
+}
+
+using namespace unit_test;
+///////////////////////////////////////////////////////////////////////////////
+// init_unit_test_suite
+//
+test_suite* init_unit_test_suite( int argc, char* argv[] )
+{
+ test_suite *test = BOOST_TEST_SUITE("test proto::matches<>");
+
+ test->add(BOOST_TEST_CASE(&test_matches));
+
+ return test;
+}
+

Added: branches/proto/v4/libs/proto/test/proto_fusion.cpp
==============================================================================
--- (empty file)
+++ branches/proto/v4/libs/proto/test/proto_fusion.cpp 2008-04-06 02:19:35 EDT (Sun, 06 Apr 2008)
@@ -0,0 +1,129 @@
+///////////////////////////////////////////////////////////////////////////////
+// proto_fusion.cpp
+//
+// Copyright 2008 Eric Niebler. Distributed under the Boost
+// Software License, Version 1.0. (See accompanying file
+// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/version.hpp>
+#if BOOST_VERSION < 103500
+# error This test only works on Boost v1.35
+#endif
+
+#include <boost/proto/core.hpp>
+#include <boost/proto/fusion.hpp>
+#include <boost/fusion/include/for_each.hpp>
+#include <boost/test/unit_test.hpp>
+#include <boost/utility/addressof.hpp>
+#include <sstream>
+
+boost::proto::terminal<char>::type a_ = {'a'};
+boost::proto::terminal<char>::type b_ = {'b'};
+boost::proto::terminal<char>::type c_ = {'c'};
+boost::proto::terminal<char>::type d_ = {'d'};
+boost::proto::terminal<char>::type e_ = {'e'};
+boost::proto::terminal<char>::type f_ = {'f'};
+boost::proto::terminal<char>::type g_ = {'g'};
+boost::proto::terminal<char>::type h_ = {'h'};
+boost::proto::terminal<char>::type i_ = {'i'};
+
+std::ostream &operator <<(std::ostream &sout, boost::proto::tag::shift_right)
+{
+ return sout << ">>";
+}
+
+std::ostream &operator <<(std::ostream &sout, boost::proto::tag::bitwise_or)
+{
+ return sout << "|";
+}
+
+template<typename Args>
+std::ostream &operator <<(std::ostream &sout, boost::proto::expr<boost::proto::tag::terminal, Args, 0> const *op)
+{
+ return sout << boost::proto::value(*op);
+}
+
+template<typename Tag, typename Args>
+std::ostream &operator <<(std::ostream &sout, boost::proto::expr<Tag, Args, 1> const *op)
+{
+ return sout << Tag() << boost::addressof(boost::proto::child(*op));
+}
+
+template<typename Tag, typename Args>
+std::ostream &operator <<(std::ostream &sout, boost::proto::expr<Tag, Args, 2> const *op)
+{
+ return sout << boost::addressof(boost::proto::left(*op)) << Tag() << boost::addressof(boost::proto::right(*op));
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// to_string
+//
+struct to_string
+{
+ to_string(std::ostream &sout)
+ : sout_(sout)
+ {}
+
+ template<typename Op>
+ void operator ()(Op const &op) const
+ {
+ this->sout_ << '(' << boost::addressof(op) << ')';
+ }
+private:
+ std::ostream &sout_;
+};
+
+void test1()
+{
+ using boost::proto::flatten;
+
+ std::stringstream sout;
+
+ // Test for 1-way branching "tree"
+ sout.str("");
+ boost::fusion::for_each(flatten(!!!!(a_ >> b_)), to_string(sout));
+ BOOST_CHECK_EQUAL("(a>>b)", sout.str());
+
+ // Tests for 2-way branching trees
+ sout.str("");
+ boost::fusion::for_each(flatten(a_ >> b_ >> c_), to_string(sout));
+ BOOST_CHECK_EQUAL("(a)(b)(c)", sout.str());
+
+ sout.str("");
+ boost::fusion::for_each(flatten(a_ | b_ | c_), to_string(sout));
+ BOOST_CHECK_EQUAL("(a)(b)(c)", sout.str());
+
+ sout.str("");
+ boost::fusion::for_each(flatten(a_ >> b_ | c_ >> d_), to_string(sout));
+ BOOST_CHECK_EQUAL("(a>>b)(c>>d)", sout.str());
+
+ sout.str("");
+ boost::fusion::for_each(flatten(a_ | b_ >> c_ | d_), to_string(sout));
+ BOOST_CHECK_EQUAL("(a)(b>>c)(d)", sout.str());
+
+ sout.str("");
+ boost::fusion::for_each(flatten(a_ >> b_ | c_ >> d_ | e_ >> f_ >> g_), to_string(sout));
+ BOOST_CHECK_EQUAL("(a>>b)(c>>d)(e>>f>>g)", sout.str());
+
+ sout.str("");
+ boost::fusion::for_each(flatten(a_ >> b_ | c_ >> d_ | e_ >> (f_ | g_) >> h_), to_string(sout));
+ BOOST_CHECK_EQUAL("(a>>b)(c>>d)(e>>f|g>>h)", sout.str());
+
+ // Test for n-way branching tree
+ sout.str("");
+ boost::fusion::for_each(flatten(a_(b_(c_ >> d_, e_ | f_), g_ >> h_)(i_)), to_string(sout));
+ BOOST_CHECK_EQUAL("(a)(b)(c>>d)(e|f)(g>>h)(i)", sout.str());
+}
+
+using namespace boost::unit_test;
+///////////////////////////////////////////////////////////////////////////////
+// init_unit_test_suite
+//
+test_suite* init_unit_test_suite( int argc, char* argv[] )
+{
+ test_suite *test = BOOST_TEST_SUITE("test proto and fusion integration");
+
+ test->add(BOOST_TEST_CASE(&test1));
+
+ return test;
+}

Added: branches/proto/v4/libs/proto/test/proto_fusion_s.cpp
==============================================================================
--- (empty file)
+++ branches/proto/v4/libs/proto/test/proto_fusion_s.cpp 2008-04-06 02:19:35 EDT (Sun, 06 Apr 2008)
@@ -0,0 +1,198 @@
+///////////////////////////////////////////////////////////////////////////////
+// proto_fusion_s.cpp
+//
+// Copyright 2008 Eric Niebler. Distributed under the Boost
+// Software License, Version 1.0. (See accompanying file
+// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/version.hpp>
+#if BOOST_VERSION < 103500
+# error This test only works on Boost v1.35
+#endif
+
+#include <boost/proto/core.hpp>
+#include <boost/proto/fusion.hpp>
+#include <boost/fusion/algorithm/iteration/ext_/for_each_s.hpp>
+#include <boost/test/unit_test.hpp>
+#include <boost/utility/addressof.hpp>
+#include <sstream>
+
+std::ostream &operator <<(std::ostream &sout, boost::proto::tag::shift_right)
+{
+ return sout << ">>";
+}
+
+std::ostream &operator <<(std::ostream &sout, boost::proto::tag::bitwise_or)
+{
+ return sout << "|";
+}
+
+template<typename Args>
+std::ostream &operator <<(std::ostream &sout, boost::proto::expr<boost::proto::tag::terminal, Args, 0> const *op)
+{
+ return sout << boost::proto::value(*op);
+}
+
+template<typename Tag, typename Args>
+std::ostream &operator <<(std::ostream &sout, boost::proto::expr<Tag, Args, 1> const *op)
+{
+ return sout << Tag() << boost::addressof(boost::proto::child(*op).proto_base());
+}
+
+template<typename Tag, typename Args>
+std::ostream &operator <<(std::ostream &sout, boost::proto::expr<Tag, Args, 2> const *op)
+{
+ return sout << boost::addressof(boost::proto::left(*op).proto_base()) << Tag() << boost::addressof(boost::proto::right(*op).proto_base());
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// to_string
+//
+struct to_string
+{
+ to_string(std::ostream &sout)
+ : sout_(sout)
+ {}
+
+ template<typename Op>
+ void operator ()(Op const &op) const
+ {
+ this->sout_ << '(' << boost::addressof(op.proto_base()) << ')';
+ }
+private:
+ std::ostream &sout_;
+};
+
+void test1()
+{
+ using boost::proto::flatten;
+
+ boost::proto::terminal<char>::type a_ = {'a'};
+ boost::proto::terminal<char>::type b_ = {'b'};
+ boost::proto::terminal<char>::type c_ = {'c'};
+ boost::proto::terminal<char>::type d_ = {'d'};
+ boost::proto::terminal<char>::type e_ = {'e'};
+ boost::proto::terminal<char>::type f_ = {'f'};
+ boost::proto::terminal<char>::type g_ = {'g'};
+ boost::proto::terminal<char>::type h_ = {'h'};
+ boost::proto::terminal<char>::type i_ = {'i'};
+
+ std::stringstream sout;
+
+ // Test for 1-way branching "tree"
+ sout.str("");
+ boost::fusion::for_each_s(flatten(!!!!(a_ >> b_)), to_string(sout));
+ BOOST_CHECK_EQUAL("(a>>b)", sout.str());
+
+ // Tests for 2-way branching trees
+ sout.str("");
+ boost::fusion::for_each_s(flatten(a_ >> b_ >> c_), to_string(sout));
+ BOOST_CHECK_EQUAL("(a)(b)(c)", sout.str());
+
+ sout.str("");
+ boost::fusion::for_each_s(flatten(a_ | b_ | c_), to_string(sout));
+ BOOST_CHECK_EQUAL("(a)(b)(c)", sout.str());
+
+ sout.str("");
+ boost::fusion::for_each_s(flatten(a_ >> b_ | c_ >> d_), to_string(sout));
+ BOOST_CHECK_EQUAL("(a>>b)(c>>d)", sout.str());
+
+ sout.str("");
+ boost::fusion::for_each_s(flatten(a_ | b_ >> c_ | d_), to_string(sout));
+ BOOST_CHECK_EQUAL("(a)(b>>c)(d)", sout.str());
+
+ sout.str("");
+ boost::fusion::for_each_s(flatten(a_ >> b_ | c_ >> d_ | e_ >> f_ >> g_), to_string(sout));
+ BOOST_CHECK_EQUAL("(a>>b)(c>>d)(e>>f>>g)", sout.str());
+
+ sout.str("");
+ boost::fusion::for_each_s(flatten(a_ >> b_ | c_ >> d_ | e_ >> (f_ | g_) >> h_), to_string(sout));
+ BOOST_CHECK_EQUAL("(a>>b)(c>>d)(e>>f|g>>h)", sout.str());
+
+ // Test for n-way branching tree
+ sout.str("");
+ boost::fusion::for_each_s(flatten(a_(b_(c_ >> d_, e_ | f_), g_ >> h_)(i_)), to_string(sout));
+ BOOST_CHECK_EQUAL("(a)(b)(c>>d)(e|f)(g>>h)(i)", sout.str());
+}
+
+////////////////////////////////////////////////////////////////////////
+// Test that EXTENDS expression wrappers are also valid fusion sequences
+
+template<typename Expr>
+struct My;
+
+struct MyDomain
+ : boost::proto::domain<boost::proto::pod_generator<My> >
+{};
+
+template<typename Expr>
+struct My
+{
+ BOOST_PROTO_EXTENDS(Expr, My<Expr>, MyDomain)
+};
+
+void test2()
+{
+ using boost::proto::flatten;
+
+ My<boost::proto::terminal<char>::type> a_ = {{'a'}};
+ My<boost::proto::terminal<char>::type> b_ = {{'b'}};
+ My<boost::proto::terminal<char>::type> c_ = {{'c'}};
+ My<boost::proto::terminal<char>::type> d_ = {{'d'}};
+ My<boost::proto::terminal<char>::type> e_ = {{'e'}};
+ My<boost::proto::terminal<char>::type> f_ = {{'f'}};
+ My<boost::proto::terminal<char>::type> g_ = {{'g'}};
+ My<boost::proto::terminal<char>::type> h_ = {{'h'}};
+ My<boost::proto::terminal<char>::type> i_ = {{'i'}};
+
+ std::stringstream sout;
+
+ // Test for 1-way branching "tree"
+ sout.str("");
+ boost::fusion::for_each_s(flatten(!!!!(a_ >> b_)), to_string(sout));
+ BOOST_CHECK_EQUAL("(a>>b)", sout.str());
+
+ // Tests for 2-way branching trees
+ sout.str("");
+ boost::fusion::for_each_s(flatten(a_ >> b_ >> c_), to_string(sout));
+ BOOST_CHECK_EQUAL("(a)(b)(c)", sout.str());
+
+ sout.str("");
+ boost::fusion::for_each_s(flatten(a_ | b_ | c_), to_string(sout));
+ BOOST_CHECK_EQUAL("(a)(b)(c)", sout.str());
+
+ sout.str("");
+ boost::fusion::for_each_s(flatten(a_ >> b_ | c_ >> d_), to_string(sout));
+ BOOST_CHECK_EQUAL("(a>>b)(c>>d)", sout.str());
+
+ sout.str("");
+ boost::fusion::for_each_s(flatten(a_ | b_ >> c_ | d_), to_string(sout));
+ BOOST_CHECK_EQUAL("(a)(b>>c)(d)", sout.str());
+
+ sout.str("");
+ boost::fusion::for_each_s(flatten(a_ >> b_ | c_ >> d_ | e_ >> f_ >> g_), to_string(sout));
+ BOOST_CHECK_EQUAL("(a>>b)(c>>d)(e>>f>>g)", sout.str());
+
+ sout.str("");
+ boost::fusion::for_each_s(flatten(a_ >> b_ | c_ >> d_ | e_ >> (f_ | g_) >> h_), to_string(sout));
+ BOOST_CHECK_EQUAL("(a>>b)(c>>d)(e>>f|g>>h)", sout.str());
+
+ // Test for n-way branching tree
+ sout.str("");
+ boost::fusion::for_each_s(flatten(a_(b_(c_ >> d_, e_ | f_), g_ >> h_)(i_)), to_string(sout));
+ BOOST_CHECK_EQUAL("(a)(b)(c>>d)(e|f)(g>>h)(i)", sout.str());
+}
+
+using namespace boost::unit_test;
+///////////////////////////////////////////////////////////////////////////////
+// init_unit_test_suite
+//
+test_suite* init_unit_test_suite( int argc, char* argv[] )
+{
+ test_suite *test = BOOST_TEST_SUITE("test proto and segmented fusion integration");
+
+ test->add(BOOST_TEST_CASE(&test1));
+ test->add(BOOST_TEST_CASE(&test2));
+
+ return test;
+}

Added: branches/proto/v4/libs/proto/test/toy_spirit.cpp
==============================================================================
--- (empty file)
+++ branches/proto/v4/libs/proto/test/toy_spirit.cpp 2008-04-06 02:19:35 EDT (Sun, 06 Apr 2008)
@@ -0,0 +1,667 @@
+///////////////////////////////////////////////////////////////////////////////
+// toy_spirit.hpp
+//
+// Copyright 2008 Eric Niebler. Distributed under the Boost
+// Software License, Version 1.0. (See accompanying file
+// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#include <cctype>
+#include <string>
+#include <cstring>
+#include <iostream>
+#include <boost/assert.hpp>
+#include <boost/mpl/assert.hpp>
+#include <boost/proto/core.hpp>
+#include <boost/proto/context.hpp>
+#include <boost/test/unit_test.hpp>
+
+namespace boost
+{
+ // global tags
+ struct char_tag {};
+ struct ichar_tag {};
+ struct istring_tag {};
+ struct ichar_range_tag {};
+ struct never_tag {};
+ struct always_tag {};
+ struct space_tag {};
+
+ // global primitives
+ proto::terminal<char_tag>::type const char_ = {{}};
+ proto::terminal<space_tag>::type const space = {{}};
+
+ using proto::lit;
+ using proto::literal;
+}
+
+namespace boost { namespace spirit2
+{
+
+ // handy typedefs
+ typedef proto::terminal<char_tag>::type anychar_p;
+ typedef proto::terminal<ichar_tag>::type ianychar_p;
+ typedef proto::terminal<istring_tag>::type ianystr_p;
+ typedef proto::terminal<ichar_range_tag>::type ianychar_range_p;
+ typedef proto::terminal<never_tag>::type never_p;
+ typedef proto::terminal<space_tag>::type space_p;
+
+ struct SpiritGrammar;
+ struct SkipperGrammar;
+ struct SpiritPrimitives;
+ template<typename Grammar>
+ struct SpiritComposites;
+
+ struct CharLiteral
+ : proto::terminal<char>
+ {};
+
+ struct NTBSLiteral
+ : proto::terminal<char const *>
+ {};
+
+ struct StdStringLiteral
+ : proto::terminal<std::string>
+ {};
+
+ struct CharParser
+ : proto::function<anychar_p, CharLiteral>
+ {};
+
+ struct ICharParser
+ : proto::function<ianychar_p, CharLiteral, CharLiteral>
+ {};
+
+ struct CharRangeParser
+ : proto::function<anychar_p, CharLiteral, CharLiteral>
+ {};
+
+ struct IStrParser
+ : proto::function<ianystr_p, StdStringLiteral>
+ {};
+
+ struct ICharRangeParser
+ : proto::function<ianychar_range_p, CharLiteral, CharLiteral>
+ {};
+
+ ianychar_p const ichar_ = {{}};
+ ianystr_p const istr_ = {{}};
+ ianychar_range_p const ichar_range_ = {{}};
+
+ namespace utility
+ {
+ inline bool char_icmp(char ch, char lo, char hi)
+ {
+ return ch == lo || ch == hi;
+ }
+
+ template<typename FwdIter>
+ inline bool string_cmp(char const *sz, FwdIter &begin, FwdIter end)
+ {
+ FwdIter tmp = begin;
+ for(; *sz; ++tmp, ++sz)
+ if(tmp == end || *tmp != *sz)
+ return false;
+ begin = tmp;
+ return true;
+ }
+
+ template<typename FwdIter>
+ inline bool string_icmp(std::string const &str, FwdIter &begin, FwdIter end)
+ {
+ BOOST_ASSERT(0 == str.size() % 2);
+ FwdIter tmp = begin;
+ std::string::const_iterator istr = str.begin(), estr = str.end();
+ for(; istr != estr; ++tmp, istr += 2)
+ if(tmp == end || (*tmp != *istr && *tmp != *(istr+1)))
+ return false;
+ begin = tmp;
+ return true;
+ }
+
+ inline bool in_range(char ch, char lo, char hi)
+ {
+ return ch >= lo && ch <= hi;
+ }
+
+ inline bool in_irange(char ch, char lo, char hi)
+ {
+ return in_range(ch, lo, hi)
+ || in_range(std::tolower(ch), lo, hi)
+ || in_range(std::toupper(ch), lo, hi);
+ }
+
+ inline std::string to_istr(char const *sz)
+ {
+ std::string res;
+ res.reserve(std::strlen(sz) * 2);
+ for(; *sz; ++sz)
+ {
+ res.push_back(std::tolower(*sz));
+ res.push_back(std::toupper(*sz));
+ }
+ return res;
+ }
+ } // namespace utility
+
+ template<typename FwdIter, typename Skipper = never_p>
+ struct spirit_context
+ : std::pair<FwdIter, FwdIter>
+ , proto::callable_context<spirit_context<FwdIter, Skipper> >
+ {
+ typedef bool result_type;
+ typedef FwdIter iterator;
+
+ spirit_context(FwdIter first, FwdIter second, Skipper const &skip = Skipper())
+ : std::pair<FwdIter, FwdIter>(first, second)
+ , skip_(skip)
+ , in_skip_(false)
+ {}
+
+ // parse function for anychar_p
+ bool operator()(proto::tag::terminal, char_tag)
+ {
+ this->skip();
+ if(this->first == this->second)
+ return false;
+ ++this->first;
+ return true;
+ }
+
+ // parse function for char_('a')
+ template<typename Expr>
+ bool operator()(proto::tag::function, anychar_p, Expr const &expr)
+ {
+ this->skip();
+ return proto::eval(expr, *this);
+ }
+
+ // parse function for space_p
+ bool operator()(proto::tag::terminal, space_tag)
+ {
+ this->skip();
+ if(this->first == this->second || !std::isspace(*this->first))
+ return false;
+ ++this->first;
+ return true;
+ }
+
+ // parse function for bare character literals
+ bool operator()(proto::tag::terminal, char ch)
+ {
+ this->skip();
+ if(this->first == this->second || *this->first != ch)
+ return false;
+ ++this->first;
+ return true;
+ }
+
+ // case-insensitive character parser
+ template<typename Arg1, typename Arg2>
+ bool operator()(proto::tag::function, ianychar_p, Arg1 const &arg1, Arg2 const &arg2)
+ {
+ this->skip();
+ if(this->first == this->second
+ || !utility::char_icmp(*this->first, proto::value(arg1), proto::value(arg2)))
+ return false;
+ ++this->first;
+ return true;
+ }
+
+ // parse function for NTBS literals
+ bool operator()(proto::tag::terminal, char const *sz)
+ {
+ this->skip();
+ return utility::string_cmp(sz, this->first, this->second);
+ }
+
+ // parse function for istr_("hello")
+ template<typename Expr>
+ bool operator()(proto::tag::function, ianystr_p, Expr const &expr)
+ {
+ this->skip();
+ return utility::string_icmp(proto::value(expr), this->first, this->second);
+ }
+
+ // parse function for char_('a','z')
+ template<typename Arg1, typename Arg2>
+ bool operator()(proto::tag::function, anychar_p, Arg1 const &arg1, Arg2 const &arg2)
+ {
+ BOOST_ASSERT(proto::value(arg1) <= proto::value(arg2));
+ this->skip();
+ if(this->first == this->second
+ || !utility::in_range(*this->first, proto::value(arg1), proto::value(arg2)))
+ return false;
+ ++this->first;
+ return true;
+ }
+
+ // parse function for ichar_range_('a','z')
+ template<typename Arg1, typename Arg2>
+ bool operator()(proto::tag::function, ianychar_range_p, Arg1 const &arg1, Arg2 const &arg2)
+ {
+ BOOST_ASSERT(proto::value(arg1) <= proto::value(arg2));
+ this->skip();
+ if(this->first == this->second
+ || !utility::in_irange(*this->first, proto::value(arg1), proto::value(arg2)))
+ return false;
+ ++this->first;
+ return true;
+ }
+
+ // parse function for complemented thingies (where thingies are assumed
+ // to be 1 character wide).
+ template<typename Expr>
+ bool operator()(proto::tag::complement, Expr const &expr)
+ {
+ this->skip();
+ iterator where = this->first;
+ if(proto::eval(expr, *this))
+ return this->first = where, false;
+ this->first = ++where;
+ return true;
+ }
+
+ // never_p parse function always returns false.
+ bool operator()(proto::tag::terminal, never_tag)
+ {
+ return false;
+ }
+
+ // for A >> B, succeeds if A and B matches.
+ template<typename Left, typename Right>
+ bool operator()(proto::tag::shift_right, Left const &left, Right const &right)
+ {
+ return proto::eval(left, *this) && proto::eval(right, *this);
+ }
+
+ // for A | B, succeeds if either A or B matches at this point.
+ template<typename Left, typename Right>
+ bool operator()(proto::tag::bitwise_or, Left const &left, Right const &right)
+ {
+ iterator where = this->first;
+ return proto::eval(left, *this) || proto::eval(right, this->reset(where));
+ }
+
+ // for *A, greedily match A as many times as possible.
+ template<typename Expr>
+ bool operator()(proto::tag::dereference, Expr const &expr)
+ {
+ iterator where = this->first;
+ while(proto::eval(expr, *this))
+ where = this->first;
+ // make sure that when we return true, the iterator is at the correct position!
+ this->first = where;
+ return true;
+ }
+
+ // for +A, greedily match A one or more times.
+ template<typename Expr>
+ bool operator()(proto::tag::unary_plus, Expr const &expr)
+ {
+ return proto::eval(expr, *this) && proto::eval(*expr, *this);
+ }
+
+ // for !A, optionally match A.
+ template<typename Expr>
+ bool operator()(proto::tag::logical_not, Expr const &expr)
+ {
+ iterator where = this->first;
+ if(!proto::eval(expr, *this))
+ this->first = where;
+ return true;
+ }
+
+ // for (A - B), matches when A but not B matches.
+ template<typename Left, typename Right>
+ bool operator()(proto::tag::minus, Left const &left, Right const &right)
+ {
+ iterator where = this->first;
+ return !proto::eval(right, *this) && proto::eval(left, this->reset(where));
+ }
+ private:
+ spirit_context &reset(iterator where)
+ {
+ this->first = where;
+ return *this;
+ }
+
+ void skip()
+ {
+ if(!this->in_skip_)
+ {
+ this->in_skip_ = true;
+ while(proto::eval(this->skip_, *this))
+ {}
+ this->in_skip_ = false;
+ }
+ }
+
+ Skipper skip_;
+ bool in_skip_;
+ };
+
+ struct as_ichar_parser : proto::callable
+ {
+ typedef proto::function<
+ ianychar_p
+ , proto::terminal<char>::type
+ , proto::terminal<char>::type
+ >::type result_type;
+
+ template<typename Expr>
+ result_type operator()(Expr const &expr) const
+ {
+ char lo = std::tolower(proto::value(proto::child_c<1>(expr)));
+ char hi = std::toupper(proto::value(proto::child_c<1>(expr)));
+ result_type that = {ichar_, {lo}, {hi}};
+ return that;
+ }
+ };
+
+ struct as_ichar_range_parser : proto::callable
+ {
+ typedef proto::function<
+ ianychar_range_p
+ , proto::terminal<char>::type
+ , proto::terminal<char>::type
+ >::type result_type;
+
+ template<typename Expr>
+ result_type operator()(Expr const &expr) const
+ {
+ char lo = proto::value(proto::child_c<1>(expr));
+ char hi = proto::value(proto::child_c<2>(expr));
+ result_type that = {ichar_range_, {lo}, {hi}};
+ return that;
+ }
+ };
+
+ struct as_ichar_literal : proto::callable
+ {
+ typedef proto::function<
+ ianychar_p
+ , proto::terminal<char>::type
+ , proto::terminal<char>::type
+ >::type result_type;
+
+ template<typename Expr>
+ result_type operator()(Expr const &expr) const
+ {
+ char lo = std::tolower(proto::value(expr));
+ char hi = std::toupper(proto::value(expr));
+ result_type that = {ichar_, {lo}, {hi}};
+ return that;
+ }
+ };
+
+ struct as_intbs_literal : proto::callable
+ {
+ typedef proto::function<
+ ianystr_p
+ , proto::terminal<std::string>::type
+ >::type result_type;
+
+ template<typename Expr>
+ result_type operator()(Expr const &expr) const
+ {
+ result_type that = {istr_, {utility::to_istr(proto::value(expr))}};
+ return that;
+ }
+ };
+
+ struct as_istdstring_literal : proto::callable
+ {
+ typedef proto::function<
+ ianystr_p
+ , proto::terminal<std::string>::type
+ >::type result_type;
+
+ template<typename Expr>
+ result_type operator()(Expr const &expr) const
+ {
+ result_type that = {istr_, {utility::to_istr(proto::value(expr).c_str())}};
+ return that;
+ }
+ };
+
+ ///////////////////////////////////////////////////////////////////////////
+ // Transforms
+ ///////////////////////////////////////////////////////////////////////////
+
+ struct skip_primitives : proto::transform<skip_primitives>
+ {
+ template<typename Expr, typename State, typename Data>
+ struct impl : proto::transform_impl<Expr, State, Data>
+ {
+ typedef
+ typename proto::shift_right<
+ typename proto::dereference<State>::type
+ , Expr
+ >::type
+ result_type;
+
+ result_type operator ()(
+ typename impl::expr_param expr
+ , typename impl::state_param state
+ , typename impl::data_param data
+ ) const
+ {
+ result_type that = {{state}, expr};
+ return that;
+ }
+ };
+ };
+
+ ///////////////////////////////////////////////////////////////////////////
+ // Grammar
+ ///////////////////////////////////////////////////////////////////////////
+ using proto::_;
+
+ struct SpiritGrammar;
+
+ struct SpiritCaseSensitivePrimitives
+ : proto::or_<
+ proto::when<CharParser, as_ichar_parser(_)>
+ , proto::when<CharLiteral, as_ichar_literal(_)>
+ , proto::when<NTBSLiteral, as_intbs_literal(_)>
+ , proto::when<CharRangeParser, as_ichar_range_parser(_)>
+ , proto::when<StdStringLiteral, as_istdstring_literal(_)>
+ >
+ {};
+
+ struct SpiritCaseInsensitivePrimitives
+ : proto::or_<
+ anychar_p
+ , IStrParser
+ , ICharParser
+ , ICharRangeParser
+ , proto::complement<SpiritPrimitives>
+ >
+ {};
+
+ struct SpiritPrimitives
+ : proto::or_<
+ SpiritCaseSensitivePrimitives
+ , SpiritCaseInsensitivePrimitives
+ >
+ {};
+
+ template<typename Grammar>
+ struct SpiritComposites
+ : proto::or_<
+ proto::bitwise_or< Grammar, Grammar >
+ , proto::shift_right< Grammar, Grammar >
+ , proto::minus< Grammar, Grammar >
+ , proto::dereference< Grammar >
+ , proto::unary_plus< Grammar >
+ , proto::logical_not< Grammar >
+ >
+ {};
+
+ // Regular Spirit grammar, has no-case transforms
+ struct SpiritGrammar
+ : proto::or_<
+ SpiritComposites<SpiritGrammar>
+ , SpiritPrimitives
+ >
+ {};
+
+ // Spirit grammar with the skipper transform
+ struct SkipperGrammar
+ : proto::or_<
+ SpiritComposites<SkipperGrammar>
+ , proto::when<SpiritPrimitives, skip_primitives>
+ >
+ {};
+
+ ///////////////////////////////////////////////////////////////////////////
+ // Directives
+ ///////////////////////////////////////////////////////////////////////////
+
+ struct no_case_directive
+ {
+ template<typename Expr>
+ typename SpiritGrammar::result<void(Expr, mpl::void_, mpl::void_)>::type const
+ operator [](Expr const &expr) const
+ {
+ mpl::void_ null;
+ return SpiritGrammar()(expr, null, null);
+ }
+ };
+
+ // no_case
+ no_case_directive const no_case = {};
+
+ template<typename Skipper>
+ struct skip_directive
+ {
+ skip_directive(Skipper const &skip)
+ : skip_(skip)
+ {}
+
+ template<typename Expr>
+ typename boost::result_of<SkipperGrammar(Expr const &, Skipper const &, mpl::void_ &)>::type const
+ operator [](Expr const &expr) const
+ {
+ mpl::void_ null;
+ return SkipperGrammar()(expr, this->skip_, null);
+ }
+ private:
+ Skipper skip_;
+ };
+
+ // skip
+ template<typename Skipper>
+ skip_directive<Skipper> skip(Skipper const &skip)
+ {
+ return skip_directive<Skipper>(skip);
+ }
+
+ ///////////////////////////////////////////////////////////////////////////
+ // parse
+ ///////////////////////////////////////////////////////////////////////////
+
+ template<typename FwdIter, typename Rule>
+ bool parse(FwdIter begin, FwdIter end, Rule const &rule)
+ {
+ // make sure the rule corresponds to the Spirit grammar:
+ BOOST_MPL_ASSERT((proto::matches<Rule, SpiritGrammar>));
+
+ spirit_context<FwdIter> ctx(begin, end);
+ return proto::eval(rule, ctx);
+ }
+
+ // parse with a skip parser can be implemented in one of two ways:
+ // Method 1)
+ // The skip parser is passed to all the parsers which invoke it
+ // before they invoke themselves. This is how Spirit-1 does it,
+ // and it is the cause of the Scanner Business. However, it has
+ // the advantage of not needing a parser transformation phase.
+ // Method 2)
+ // Transform the expression template to insert the skip parser
+ // in between all sequenced parsers. That is, transform (A >> B)
+ // to (*skip >> A >> *skip >> B). This has the advantage of making
+ // it unnecessary to pass the scanner to all the parsers, which
+ // means its type doesn't show up in function signatures, avoiding
+ // the Scanner Business.
+ // Recommendation:
+ // Both methods should be supported. Method 1 should be preferred
+ // when calling parse with parsers defined inline. Method 2 should
+ // be preferred when a parser expression is assigned to a rule<>,
+ // thereby making the type of the rule<> independent of the skip
+ // parser used. I imagine a syntax like:
+ // rule<> r = skip(space)[A >> B >> C]
+ template<typename FwdIter, typename Rule, typename Skipper>
+ bool parse(FwdIter begin, FwdIter end, Rule const &rule, Skipper const &skipper)
+ {
+ // make sure the rule corresponds to the Spirit grammar:
+ BOOST_MPL_ASSERT((proto::matches<Rule, SpiritGrammar>));
+
+ //// Method 1: pass skip parser in the context structure.
+ //spirit_context<FwdIter, Skipper> ctx(begin, end, skipper);
+ //return proto::eval(rule, ctx);
+
+ // Method 2: Embed skip parser via tree transformation.
+ spirit_context<FwdIter> ctx(begin, end);
+ return proto::eval(spirit2::skip(skipper)[rule], ctx);
+ }
+
+}}
+
+using namespace boost;
+using namespace spirit2;
+
+void test_toy_spirit()
+{
+ std::string str("abcd");
+
+ // This will fail:
+ BOOST_CHECK(!spirit2::parse(str.begin(), str.end()
+ , char_ >> char_('a')));
+
+ // This will succeed:
+ BOOST_CHECK(spirit2::parse(str.begin(), str.end()
+ , char_ >> char_('b') >> char_ >> 'd'));
+
+ // This will succeed:
+ BOOST_CHECK(spirit2::parse(str.begin(), str.end()
+ , 'a' >> ('c' >> char_ | 'b' >> char_('d') | 'b' >> char_('c')) >> 'd'));
+
+ // This will succeed:
+ BOOST_CHECK(spirit2::parse(str.begin(), str.end()
+ , *(char_ - 'd')));
+
+ // This will succeed:
+ BOOST_CHECK(spirit2::parse(str.begin(), str.end()
+ , no_case[char_('A') >> 'B' >> "CD"]));
+
+ // This will succeed:
+ BOOST_CHECK(spirit2::parse(str.begin(), str.end()
+ , no_case[*char_('A','Z')]));
+
+ literal<char> a = lit('a');
+ literal<char const *> bcd = lit("bcd");
+
+ // This will succeed:
+ BOOST_CHECK(spirit2::parse(str.begin(), str.end()
+ , +~~a >> no_case[bcd]));
+
+ // Scanner Business: R.I.P. :-)
+ str = "a b cd";
+ BOOST_CHECK(spirit2::parse(str.begin(), str.end()
+ , char_('a') >> 'b' >> 'c' >> 'd', space >> space));
+
+}
+
+using namespace boost::unit_test;
+///////////////////////////////////////////////////////////////////////////////
+// init_unit_test_suite
+//
+test_suite* init_unit_test_suite( int argc, char* argv[] )
+{
+ test_suite *test = BOOST_TEST_SUITE("test proto and and toy spirit-2");
+
+ test->add(BOOST_TEST_CASE(&test_toy_spirit));
+
+ return test;
+}

Added: branches/proto/v4/libs/proto/test/toy_spirit2.cpp
==============================================================================
--- (empty file)
+++ branches/proto/v4/libs/proto/test/toy_spirit2.cpp 2008-04-06 02:19:35 EDT (Sun, 06 Apr 2008)
@@ -0,0 +1,482 @@
+///////////////////////////////////////////////////////////////////////////////
+// toy_spirit3.cpp
+//
+// Copyright 2008 Eric Niebler. Distributed under the Boost
+// Software License, Version 1.0. (See accompanying file
+// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#include <cctype>
+#include <string>
+#include <cstring>
+#include <iomanip>
+#include <iostream>
+#include <boost/version.hpp>
+#include <boost/assert.hpp>
+#include <boost/mpl/assert.hpp>
+#include <boost/utility/result_of.hpp>
+#include <boost/type_traits/is_same.hpp>
+#include <boost/proto/core.hpp>
+#include <boost/proto/transform.hpp>
+#if BOOST_VERSION < 103500
+# include <boost/spirit/fusion/algorithm/for_each.hpp>
+# include <boost/spirit/fusion/algorithm/fold.hpp>
+# include <boost/spirit/fusion/algorithm/any.hpp>
+# include <boost/spirit/fusion/sequence/cons.hpp>
+#else
+# include <boost/fusion/include/for_each.hpp>
+# include <boost/fusion/include/fold.hpp>
+# include <boost/fusion/include/cons.hpp>
+# include <boost/fusion/include/any.hpp>
+#endif
+#include <boost/test/unit_test.hpp>
+
+namespace boost
+{
+ // global tags
+ struct char_tag {};
+ struct space_tag {};
+
+ // global primitives
+ proto::terminal<char_tag>::type const char_ = {{}};
+ proto::terminal<space_tag>::type const space = {{}};
+
+ using proto::lit;
+ using proto::literal;
+}
+
+namespace boost { namespace spirit2
+{
+ namespace utility
+ {
+ inline bool char_icmp(char ch, char lo, char hi)
+ {
+ return ch == lo || ch == hi;
+ }
+
+ template<typename FwdIter>
+ inline bool string_cmp(char const *sz, FwdIter &begin, FwdIter end)
+ {
+ FwdIter tmp = begin;
+ for(; *sz; ++tmp, ++sz)
+ if(tmp == end || *tmp != *sz)
+ return false;
+ begin = tmp;
+ return true;
+ }
+
+ template<typename FwdIter>
+ inline bool string_icmp(std::string const &str, FwdIter &begin, FwdIter end)
+ {
+ BOOST_ASSERT(0 == str.size() % 2);
+ FwdIter tmp = begin;
+ std::string::const_iterator istr = str.begin(), estr = str.end();
+ for(; istr != estr; ++tmp, istr += 2)
+ if(tmp == end || (*tmp != *istr && *tmp != *(istr+1)))
+ return false;
+ begin = tmp;
+ return true;
+ }
+
+ inline bool in_range(char ch, char lo, char hi)
+ {
+ return ch >= lo && ch <= hi;
+ }
+
+ inline bool in_irange(char ch, char lo, char hi)
+ {
+ return in_range(ch, lo, hi)
+ || in_range(std::tolower(ch), lo, hi)
+ || in_range(std::toupper(ch), lo, hi);
+ }
+
+ inline std::string to_istr(char const *sz)
+ {
+ std::string res;
+ res.reserve(std::strlen(sz) * 2);
+ for(; *sz; ++sz)
+ {
+ res.push_back(std::tolower(*sz));
+ res.push_back(std::toupper(*sz));
+ }
+ return res;
+ }
+ } // namespace utility
+
+ template<typename List>
+ struct alternate
+ {
+ explicit alternate(List const &list)
+ : elems(list)
+ {}
+ List elems;
+ };
+
+ template<typename List>
+ struct sequence
+ {
+ explicit sequence(List const &list)
+ : elems(list)
+ {}
+ List elems;
+ };
+
+ struct char_range
+ : std::pair<char, char>
+ {
+ char_range(char from, char to)
+ : std::pair<char, char>(from, to)
+ {}
+ };
+
+ struct ichar
+ {
+ ichar(char ch)
+ : lo_(std::tolower(ch))
+ , hi_(std::toupper(ch))
+ {}
+
+ char lo_, hi_;
+ };
+
+ struct istr
+ {
+ istr(char const *sz)
+ : str_(utility::to_istr(sz))
+ {}
+
+ std::string str_;
+ };
+
+ struct ichar_range
+ : std::pair<char, char>
+ {
+ ichar_range(char from, char to)
+ : std::pair<char, char>(from, to)
+ {}
+ };
+
+ // The no-case directive
+ struct no_case_tag {};
+
+ struct True : mpl::true_ {};
+
+ ///////////////////////////////////////////////////////////////////////////////
+ /// Begin Spirit grammar here
+ ///////////////////////////////////////////////////////////////////////////////
+ namespace grammar
+ {
+ using namespace proto;
+ using namespace fusion;
+
+ struct SpiritExpr;
+
+ struct AnyChar
+ : terminal<char_tag>
+ {};
+
+ struct CharLiteral
+ : terminal<char>
+ {};
+
+ struct NTBSLiteral
+ : terminal<char const *>
+ {};
+
+ struct CharParser
+ : proto::function<AnyChar, CharLiteral>
+ {};
+
+ struct CharRangeParser
+ : proto::function<AnyChar, CharLiteral, CharLiteral>
+ {};
+
+ struct NoCase
+ : terminal<no_case_tag>
+ {};
+
+ // The data determines the case-sensitivity of the terminals
+ typedef _data _icase;
+
+ // Ugh, would be nice to find a work-around for this:
+ #if BOOST_WORKAROUND(BOOST_MSVC, == 1310)
+ #define _value(x) call<_value(x)>
+ #define True() make<True()>
+ #endif
+
+ // Extract the child from terminals
+ struct SpiritTerminal
+ : or_<
+ when< AnyChar, _child >
+ , when< CharLiteral, if_<_icase, ichar(_value), _value> >
+ , when< CharParser, if_<_icase, ichar(_value(_child1)), _value(_child1)> > // char_('a')
+ , when< NTBSLiteral, if_<_icase, istr(_value), char const*(_value)> >
+ , when< CharRangeParser, if_<_icase
+ , ichar_range(_value(_child1), _value(_child2))
+ , char_range(_value(_child1), _value(_child2))> > // char_('a','z')
+ >
+ {};
+
+ struct FoldToList
+ : reverse_fold_tree<_, nil(), cons<SpiritExpr, _state>(SpiritExpr, _state)>
+ {};
+
+ // sequence rule folds all >>'s together into a list
+ // and wraps the result in a sequence<> wrapper
+ struct SpiritSequence
+ : when< shift_right<SpiritExpr, SpiritExpr>, sequence<FoldToList>(FoldToList) >
+ {};
+
+ // alternate rule folds all |'s together into a list
+ // and wraps the result in a alternate<> wrapper
+ struct SpiritAlternate
+ : when< bitwise_or<SpiritExpr, SpiritExpr>, alternate<FoldToList>(FoldToList) >
+ {};
+
+ // Directives such as no_case are handled here
+ struct SpiritDirective
+ : when< subscript<NoCase, SpiritExpr>, SpiritExpr(_right, _state, True()) >
+ {};
+
+ // A SpiritExpr is an alternate, a sequence, a directive or a terminal
+ struct SpiritExpr
+ : or_<
+ SpiritSequence
+ , SpiritAlternate
+ , SpiritDirective
+ , SpiritTerminal
+ >
+ {};
+
+ } // namespace grammar
+
+ using grammar::SpiritExpr;
+ using grammar::NoCase;
+
+ ///////////////////////////////////////////////////////////////////////////////
+ /// End SpiritExpr
+ ///////////////////////////////////////////////////////////////////////////////
+
+ // Globals
+ NoCase::type const no_case = {{}};
+
+ template<typename Iterator>
+ struct parser;
+
+ template<typename Iterator>
+ struct fold_alternate
+ {
+ parser<Iterator> const &parse;
+
+ explicit fold_alternate(parser<Iterator> const &p)
+ : parse(p)
+ {}
+
+ template<typename T>
+ bool operator ()(T const &t) const
+ {
+ Iterator tmp = this->parse.first;
+ if(this->parse(t))
+ return true;
+ this->parse.first = tmp;
+ return false;
+ }
+ };
+
+ template<typename Iterator>
+ struct fold_sequence
+ {
+ parser<Iterator> const &parse;
+
+ explicit fold_sequence(parser<Iterator> const &p)
+ : parse(p)
+ {}
+
+ #if BOOST_VERSION < 103500
+ template<typename, typename>
+ struct apply
+ {
+ typedef bool type;
+ };
+ #else
+ typedef bool result_type;
+ #endif
+
+ template<typename T>
+ bool operator ()(T const &t, bool success) const
+ {
+ return success && this->parse(t);
+ }
+ };
+
+ template<typename Iterator>
+ struct parser
+ {
+ mutable Iterator first;
+ Iterator second;
+
+ parser(Iterator begin, Iterator end)
+ : first(begin)
+ , second(end)
+ {}
+
+ bool done() const
+ {
+ return this->first == this->second;
+ }
+
+ template<typename List>
+ bool operator ()(alternate<List> const &alternates) const
+ {
+ return fusion::any(alternates.elems, fold_alternate<Iterator>(*this));
+ }
+
+ template<typename List>
+ bool operator ()(sequence<List> const &sequence) const
+ {
+ return fusion::fold(sequence.elems, true, fold_sequence<Iterator>(*this));
+ }
+
+ bool operator ()(char_tag ch) const
+ {
+ if(this->done())
+ return false;
+ ++this->first;
+ return true;
+ }
+
+ bool operator ()(char ch) const
+ {
+ if(this->done() || ch != *this->first)
+ return false;
+ ++this->first;
+ return true;
+ }
+
+ bool operator ()(ichar ich) const
+ {
+ if(this->done() || !utility::char_icmp(*this->first, ich.lo_, ich.hi_))
+ return false;
+ ++this->first;
+ return true;
+ }
+
+ bool operator ()(char const *sz) const
+ {
+ return utility::string_cmp(sz, this->first, this->second);
+ }
+
+ bool operator ()(istr const &s) const
+ {
+ return utility::string_icmp(s.str_, this->first, this->second);
+ }
+
+ bool operator ()(char_range rng) const
+ {
+ if(this->done() || !utility::in_range(*this->first, rng.first, rng.second))
+ return false;
+ ++this->first;
+ return true;
+ }
+
+ bool operator ()(ichar_range rng) const
+ {
+ if(this->done() || !utility::in_irange(*this->first, rng.first, rng.second))
+ return false;
+ ++this->first;
+ return true;
+ }
+ };
+
+ template<typename Rule, typename Iterator>
+ typename enable_if<proto::matches< Rule, SpiritExpr >, bool >::type
+ parse_impl(Rule const &rule, Iterator begin, Iterator end)
+ {
+ mpl::false_ is_case_sensitive;
+ parser<Iterator> parse_fun(begin, end);
+ return parse_fun(SpiritExpr()(rule, proto::ignore(), is_case_sensitive));
+ }
+
+ // 2nd overload provides a short error message for invalid rules
+ template<typename Rule, typename Iterator>
+ typename disable_if<proto::matches< Rule, SpiritExpr >, bool >::type
+ parse_impl(Rule const &rule, Iterator begin, Iterator end)
+ {
+ BOOST_MPL_ASSERT((proto::matches<Rule, SpiritExpr>));
+ return false;
+ }
+
+ // parse() converts rule literals to proto expressions if necessary
+ // and dispatches to parse_impl
+ template<typename Rule, typename Iterator>
+ bool parse(Rule const &rule, Iterator begin, Iterator end)
+ {
+ return parse_impl(proto::as_expr(rule), begin, end);
+ }
+
+}}
+
+void test_toy_spirit3()
+{
+ using boost::spirit2::no_case;
+ using boost::char_;
+ std::string hello("abcd");
+
+ BOOST_CHECK(
+ boost::spirit2::parse(
+ "abcd"
+ , hello.begin()
+ , hello.end()
+ )
+ );
+
+ BOOST_CHECK(
+ boost::spirit2::parse(
+ char_ >> char_('b') >> 'c' >> char_
+ , hello.begin()
+ , hello.end()
+ )
+ );
+
+ BOOST_CHECK(
+ !boost::spirit2::parse(
+ char_ >> char_('b') >> 'c' >> 'D'
+ , hello.begin()
+ , hello.end()
+ )
+ );
+
+ BOOST_CHECK(
+ boost::spirit2::parse(
+ char_ >> char_('b') >> 'c' >> 'e'
+ | char_ >> no_case[char_('B') >> "C" >> char_('D','Z')]
+ , hello.begin()
+ , hello.end()
+ )
+ );
+
+ std::string nest_alt_input("abd");
+ BOOST_CHECK(
+ boost::spirit2::parse(
+ char_('a')
+ >> ( char_('b')
+ | char_('c')
+ )
+ >> char_('d')
+ , nest_alt_input.begin()
+ , nest_alt_input.end()
+ )
+ );
+}
+
+using namespace boost::unit_test;
+///////////////////////////////////////////////////////////////////////////////
+// init_unit_test_suite
+//
+test_suite* init_unit_test_suite( int argc, char* argv[] )
+{
+ test_suite *test = BOOST_TEST_SUITE("test proto, grammars and tree transforms");
+
+ test->add(BOOST_TEST_CASE(&test_toy_spirit3));
+
+ return test;
+}

Modified: branches/proto/v4/libs/xpressive/doc/acknowledgements.qbk
==============================================================================
--- branches/proto/v4/libs/xpressive/doc/acknowledgements.qbk (original)
+++ branches/proto/v4/libs/xpressive/doc/acknowledgements.qbk 2008-04-06 02:19:35 EDT (Sun, 06 Apr 2008)
@@ -8,15 +8,15 @@
 [section Acknowledgments]
 
 I am indebted to [@http://boost.org/people/joel_de_guzman.htm Joel de Guzman]
-and [@http://boost.org/people/hartmut_kaiser.htm Hartmut Kaiser] for their
+and [@http://boost.org/people/hartmut_kaiser.htm Hartmut Kaiser] for their
 expert advice during the early states of xpressive's development. Much of
 static xpressive's syntax is owes a large debt to _spirit_, including the
-syntax for xpressive's semantic actions. I am thankful for
+syntax for xpressive's semantic actions. I am thankful for
 [@http://boost.org/people/john_maddock.htm John Maddock]'s excellent work on
 his proposal to add regular expressions to the standard library, and for
 various ideas borrowed liberally from his regex implementation. I'd also like
 to thank [@http://moderncppdesign.com/ Andrei Alexandrescu] for his input
-regarding the behavior of nested regex objects, and
+regarding the behavior of nested regex objects, and
 [@http://boost.org/people/dave_abrahams.htm Dave Abrahams] for his suggestions
 regarding the regex domain-specific embedded language. Noel Belcourt helped
 porting xpressive to the Metrowerks CodeWarrior compiler. Markus

Modified: branches/proto/v4/libs/xpressive/doc/actions.qbk
==============================================================================
--- branches/proto/v4/libs/xpressive/doc/actions.qbk (original)
+++ branches/proto/v4/libs/xpressive/doc/actions.qbk 2008-04-06 02:19:35 EDT (Sun, 06 Apr 2008)
@@ -10,7 +10,7 @@
 [h2 Overview]
 
 Imagine you want to parse an input string and build a `std::map<>` from it. For
-something like that, matching a regular expression isn't enough. You want to
+something like that, matching a regular expression isn't enough. You want to
 /do something/ when parts of your regular expression match. Xpressive lets
 you attach semantic actions to parts of your static regular expressions. This
 section shows you how.
@@ -31,12 +31,12 @@
     {
         std::map<std::string, int> result;
         std::string str("aaa=>1 bbb=>23 ccc=>456");
-
+
         // Match a word and an integer, separated by =>,
         // and then stuff the result into a std::map<>
         sregex pair = ( (s1= +_w) >> "=>" >> (s2= +_d) )
             [ ref(result)[s1] = as<int>(s2) ];
-
+
         // Match one or more word/integer pairs, separated
         // by whitespace.
         sregex rx = pair >> *(+_s >> pair);
@@ -47,7 +47,7 @@
             std::cout << result["bbb"] << '\n';
             std::cout << result["ccc"] << '\n';
         }
-
+
         return 0;
     }
 
@@ -59,7 +59,7 @@
 456
 ]
 
-The regular expression `pair` has two parts: the pattern and the action. The
+The regular expression `pair` has two parts: the pattern and the action. The
 pattern says to match a word, capturing it in sub-match 1, and an integer,
 capturing it in sub-match 2, separated by `"=>"`. The action is the part in
 square brackets: `[ ref(result)[s1] = as<int>(s2) ]`. It says to take sub-match
@@ -73,15 +73,15 @@
 between brackets is an expression template. It encodes the action and executes
 it later. The expression `ref(result)` creates a lazy reference to the `result`
 object. The larger expression `ref(result)[s1]` is a lazy map index operation.
-Later, when this action is getting executed, `s1` gets replaced with the
+Later, when this action is getting executed, `s1` gets replaced with the
 first _sub_match_. Likewise, when `as<int>(s2)` gets executed, `s2` is replaced
-with the second _sub_match_. The `as<>` action converts its argument to the
+with the second _sub_match_. The `as<>` action converts its argument to the
 requested type using Boost.Lexical_cast. The effect of the whole action is to
 insert a new word/integer pair into the map.
 
 [note There is an important difference between the function `boost::ref()` in
-`<boost/ref.hpp>` and `boost::xpressive::ref()` in
-`<boost/xpressive/regex_actions.hpp>`. The first returns a plain
+`<boost/ref.hpp>` and `boost::xpressive::ref()` in
+`<boost/xpressive/regex_actions.hpp>`. The first returns a plain
 `reference_wrapper<>` which behaves in many respects like an ordinary
 reference. By contrast, `boost::xpressive::ref()` returns a /lazy/ reference
 that you can use in expressions that are executed lazily. That is why we can
@@ -137,7 +137,7 @@
 operators. But what if you want to be able to call a function from a semantic
 action? Xpressive provides a mechanism to do this.
 
-The first step is to define a function object type. Here, for instance, is a
+The first step is to define a function object type. Here, for instance, is a
 function object type that calls `push()` on its argument:
 
     struct push_impl
@@ -158,7 +158,7 @@
     // Global "push" function object.
     function<push_impl>::type const push = {{}};
 
-The initialization looks a bit odd, but this is because `push` is being
+The initialization looks a bit odd, but this is because `push` is being
 statically initialized. That means it doesn't need to be constructed
 at runtime. We can use `push` in semantic actions as follows:
 
@@ -182,7 +182,7 @@
 `result_type` typedef. Here, for example, is a `first` function object
 that returns the `first` member of a `std::pair<>` or _sub_match_:
 
- // Function object that returns the
+ // Function object that returns the
     // first element of a pair.
     struct first_impl
     {
@@ -204,7 +204,7 @@
     };
 
     // OK, use as first(s1) to get the begin iterator
- // of the sub-match referred to by s1.
+ // of the sub-match referred to by s1.
     function<first_impl>::type const first = {{}};
 
 [h3 Referring to Local Variables]
@@ -238,7 +238,7 @@
     }
 
 In the above code, we use `xpressive::val()` to hold the shared pointer by
-value. That's not normally necessary because local variables appearing in
+value. That's not normally necessary because local variables appearing in
 actions are held by value by default, but in this case, it is necessary. Had
 we written the action as `++*pi`, it would have executed immediately. That's
 because `++*pi` is not an expression template, but `++*val(pi)` is.
@@ -263,7 +263,7 @@
 
 As you can see, when using `reference<>`, you need to first declare a local
 variable and then declare a `reference<>` to it. These two steps can be combined
-into one using `local<>`.
+into one using `local<>`.
 
 [table local<> vs. reference<>
 [[This ...][... is equivalent to this ...]]
@@ -301,15 +301,15 @@
 that in the semantic action instead of the map itself. Later, when we
 call one of the regex algorithms, we can bind the reference to an actual
 map object. The following code shows how.
-
+
     // Define a placeholder for a map object:
     placeholder<std::map<std::string, int> > _map;
-
+
     // Match a word and an integer, separated by =>,
     // and then stuff the result into a std::map<>
     sregex pair = ( (s1= +_w) >> "=>" >> (s2= +_d) )
         [ _map[s1] = as<int>(s2) ];
-
+
     // Match one or more word/integer pairs, separated
     // by whitespace.
     sregex rx = pair >> *(+_s >> pair);
@@ -319,7 +319,7 @@
 
     // Here is the actual map to fill in:
     std::map<std::string, int> result;
-
+
     // Bind the _map placeholder to the actual map
     smatch what;
     what.let( _map = result );
@@ -340,10 +340,10 @@
 456
 ]
 
-We use `placeholder<>` here to define `_map`, which stands in for a
+We use `placeholder<>` here to define `_map`, which stands in for a
 `std::map<>` variable. We can use the placeholder in the semantic action as if
 it were a map. Then, we define a _match_results_ struct and bind an actual map
-to the placeholder with "`what.let( _map = result );`". The _regex_match_ call
+to the placeholder with "`what.let( _map = result );`". The _regex_match_ call
 behaves as if the placeholder in the semantic action had been replaced with a
 reference to `result`.
 
@@ -360,27 +360,27 @@
 
     // Define a placeholder for a map object:
     placeholder<std::map<std::string, int> > _map;
-
+
     // Match a word and an integer, separated by =>,
     // and then stuff the result into a std::map<>
     sregex pair = ( (s1= +_w) >> "=>" >> (s2= +_d) )
         [ _map[s1] = as<int>(s2) ];
-
+
     // The string to parse
     std::string str("aaa=>1 bbb=>23 ccc=>456");
-
+
     // Here is the actual map to fill in:
     std::map<std::string, int> result;
-
+
     // Create a regex_iterator to find all the matches
     sregex_iterator it(str.begin(), str.end(), pair, let(_map=result));
     sregex_iterator end;
-
+
     // step through all the matches, and fill in
     // the result map
     while(it != end)
         ++it;
-
+
     std::cout << result["aaa"] << '\n';
     std::cout << result["bbb"] << '\n';
     std::cout << result["ccc"] << '\n';
@@ -397,7 +397,7 @@
 
 You are probably already familiar with regular expression /assertions/. In
 Perl, some examples are the [^^] and [^$] assertions, which you can use to
-match the beginning and end of a string, respectively. Xpressive lets you
+match the beginning and end of a string, respectively. Xpressive lets you
 define your own assertions. A custom assertion is a contition which must be
 true at a point in the match in order for the match to succeed. You can check
 a custom assertion with xpressive's _check_ function.
@@ -438,7 +438,7 @@
     sregex rx = (bow >> +_w >> eow)[ check(length(_)==3 || length(_)==6) ] ;
 
 In the above, `length()` is a lazy function that calls the `length()` member
-function of its argument, and `_` is a placeholder that receives the
+function of its argument, and `_` is a placeholder that receives the
 `sub_match`.
 
 Once you get the hang of writing custom assertions inline, they can be
@@ -451,7 +451,7 @@
 
     mark_tag month(1), day(2);
     // find a valid date of the form month/day/year.
- sregex date =
+ sregex date =
         (
             // Month must be between 1 and 12 inclusive
             (month= _d >> !_d) [ check(as<int>(_) >= 1

Modified: branches/proto/v4/libs/xpressive/doc/dynamic_regexes.qbk
==============================================================================
--- branches/proto/v4/libs/xpressive/doc/dynamic_regexes.qbk (original)
+++ branches/proto/v4/libs/xpressive/doc/dynamic_regexes.qbk 2008-04-06 02:19:35 EDT (Sun, 06 Apr 2008)
@@ -20,7 +20,7 @@
 There are two ways to create a dynamic regex: with the _regex_compile_
 function or with the _regex_compiler_ class template. Use _regex_compile_
 if you want the default locale. Use _regex_compiler_ if you need to
-specify a different locale. In the section on
+specify a different locale. In the section on
 [link boost_xpressive.user_s_guide.grammars_and_nested_matches regex grammars],
 we'll see another use for _regex_compiler_.
 

Modified: branches/proto/v4/libs/xpressive/doc/history.qbk
==============================================================================
--- branches/proto/v4/libs/xpressive/doc/history.qbk (original)
+++ branches/proto/v4/libs/xpressive/doc/history.qbk 2008-04-06 02:19:35 EDT (Sun, 06 Apr 2008)
@@ -66,7 +66,7 @@
 
 [h2 Version 0.0.1, November 16, 2003]
 
-Announcement of xpressive:
+Announcement of xpressive:
 [@http://lists.boost.org/Archives/boost/2003/11/56312.php]
 
 [endsect]

Modified: branches/proto/v4/libs/xpressive/doc/installation.qbk
==============================================================================
--- branches/proto/v4/libs/xpressive/doc/installation.qbk (original)
+++ branches/proto/v4/libs/xpressive/doc/installation.qbk 2008-04-06 02:19:35 EDT (Sun, 06 Apr 2008)
@@ -16,7 +16,7 @@
 The second way is by downloading xpressive.zip at the
 [@http://www.boost-consulting.com/vault/index.php?directory=Strings%20-%20Text%20Processing
 Boost File Vault] in the ["Strings - Text Processing] directory. In addition to
-the source code and the Boost license, this archive contains a copy of this
+the source code and the Boost license, this archive contains a copy of this
 documentation in PDF format. This version will always be stable and at least as
 current as the version in the latest Boost release. It may be more recent. The
 version in the File Vault is always guaranteed to work with the latest official

Modified: branches/proto/v4/libs/xpressive/doc/introduction.qbk
==============================================================================
--- branches/proto/v4/libs/xpressive/doc/introduction.qbk (original)
+++ branches/proto/v4/libs/xpressive/doc/introduction.qbk 2008-04-06 02:19:35 EDT (Sun, 06 Apr 2008)
@@ -15,7 +15,7 @@
 [@http://www.osl.iu.edu/~tveldhui/papers/Expression-Templates/exprtmpl.html
 Expression Templates]] that are parsed at compile-time (static regexes).
 Dynamic regexes have the advantage that they can be accepted from the user
-as input at runtime or read from an initialization file. Static regexes
+as input at runtime or read from an initialization file. Static regexes
 have several advantages. Since they are C++ expressions instead of
 strings, they can be syntax-checked at compile-time. Also, they can naturally
 refer to code and data elsewhere in your program, giving you the ability to call

Modified: branches/proto/v4/libs/xpressive/doc/matching.qbk
==============================================================================
--- branches/proto/v4/libs/xpressive/doc/matching.qbk (original)
+++ branches/proto/v4/libs/xpressive/doc/matching.qbk 2008-04-06 02:19:35 EDT (Sun, 06 Apr 2008)
@@ -23,8 +23,8 @@
 algorithm.]
 
 The input can be a bidirectional range such as `std::string`, a C-style null-terminated string or a pair of
-iterators. In all cases, the type of the iterator used to traverse the input sequence must match the iterator
-type used to declare the regex object. (You can use the table in the
+iterators. In all cases, the type of the iterator used to traverse the input sequence must match the iterator
+type used to declare the regex object. (You can use the table in the
 [link boost_xpressive.user_s_guide.quick_start.know_your_iterator_type Quick Start] to find the correct regex
 type for your iterator.)
 
@@ -78,8 +78,8 @@
 
 In all other regards, _regex_search_ behaves like _regex_match_ ['(see above)]. In particular, it can operate
 on a bidirectional range such as `std::string`, C-style null-terminated strings or iterator ranges. The same
-care must be taken to ensure that the iterator type of your regex matches the iterator type of your input
-sequence. As with _regex_match_, you can optionally provide a _match_results_ struct to receive the results
+care must be taken to ensure that the iterator type of your regex matches the iterator type of your input
+sequence. As with _regex_match_, you can optionally provide a _match_results_ struct to receive the results
 of the search, and a _match_flag_type_ bitmask to control how the match is evaluated.
 
 Click [link boost_xpressive.user_s_guide.examples.see_if_a_string_contains_a_sub_string_that_matches_a_regex here]

Modified: branches/proto/v4/libs/xpressive/doc/nyi.qbk
==============================================================================
--- branches/proto/v4/libs/xpressive/doc/nyi.qbk (original)
+++ branches/proto/v4/libs/xpressive/doc/nyi.qbk 2008-04-06 02:19:35 EDT (Sun, 06 Apr 2008)
@@ -10,7 +10,7 @@
 The following features are planned for xpressive 2.X:
 
 * `syntax_option_type::collate`
-* Collation sequences such as [^'''[.a.]''']
+* Collation sequences such as [^'''[.a.]''']
 * Equivalence classes like [^'''[=a=]''']
 * Control of nested results generation with `syntax_option_type::nosubs`,
   and a `nosubs()` modifier for static xpressive.

Modified: branches/proto/v4/libs/xpressive/doc/substitutions.qbk
==============================================================================
--- branches/proto/v4/libs/xpressive/doc/substitutions.qbk (original)
+++ branches/proto/v4/libs/xpressive/doc/substitutions.qbk 2008-04-06 02:19:35 EDT (Sun, 06 Apr 2008)
@@ -14,9 +14,10 @@
 [h2 regex_replace()]
 
 Performing search-and-replace using _regex_replace_ is simple. All you need is an input sequence, a regex object,
-and a format string. There are two versions of the _regex_replace_ algorithm. The first accepts the input
-sequence as `std::basic_string<>` and returns the result in a new `std::basic_string<>`. The second accepts
-the input sequence as a pair of iterators, and writes the result into an output iterator. Below are examples of
+and a format string or a formatter object. There are several versions of the _regex_replace_ algorithm. Some accept
+the input sequence as a bidirectional container such as `std::string` and returns the result in a new container
+of the same type. Others accept the input as a null terminated string and return a `std::string`. Still others
+accept the input sequence as a pair of iterators and writes the result into an output iterator. Below are examples of
 each.
 
     std::string input("This is his face");
@@ -67,7 +68,7 @@
 
 [h2 The ECMA-262 Format Sequences]
 
-When you haven't specified a substitution string dialect with one of the format flags above,
+When you haven't specified a substitution string dialect with one of the format flags above,
 you get the dialect defined by ECMA-262, the standard for ECMAScript. The table below shows
 the escape sequences recognized in ECMA-262 mode.
 
@@ -150,4 +151,12 @@
 it is /false-expression/. In this mode, you can use parens [^()] for grouping. If you
 want a literal paren, you must escape it as [^\\(].
 
+[h2 Formatter Objects]
+
+Format strings are not always expressive enough for all your text substitution
+needs. Consider the simple example of wanting to map input strings to output
+strings.
+
+
+
 [endsect]

Modified: branches/proto/v4/libs/xpressive/doc/symbols.qbk
==============================================================================
--- branches/proto/v4/libs/xpressive/doc/symbols.qbk (original)
+++ branches/proto/v4/libs/xpressive/doc/symbols.qbk 2008-04-06 02:19:35 EDT (Sun, 06 Apr 2008)
@@ -9,7 +9,7 @@
 
 [h2 Overview]
 
-Symbol tables can be built into xpressive regular expressions with just a
+Symbol tables can be built into xpressive regular expressions with just a
 `std::map<>`. The map keys are the strings to be matched and the map values are
 the data to be returned to your semantic action. Xpressive attributes, named
 `a1`, `a2`, through `a9`, hold the value corresponding to a matching key so
@@ -83,7 +83,7 @@
 ninety nine million nine hundred ninety nine thousand nine hundred ninety nine"
 along with some special number names like "dozen".
 
-Symbol table matches are case sensitive by default, but they can be made
+Symbol table matches are case sensitive by default, but they can be made
 case-insensitive by enclosing the expression in `icase()`.
 
 [h2 Attributes]


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk