Boost logo

Boost-Commit :

From: eric_at_[hidden]
Date: 2008-04-14 02:24:42


Author: eric_niebler
Date: 2008-04-14 02:24:30 EDT (Mon, 14 Apr 2008)
New Revision: 44402
URL: http://svn.boost.org/trac/boost/changeset/44402

Log:
proto v4
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/child_traits.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/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)
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 | 228 +++++++++++++------------
   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 | 71 ++++---
   branches/proto/v4/boost/xpressive/xpressive_fwd.hpp | 4
   branches/proto/v4/boost/xpressive/xpressive_typeof.hpp | 2
   30 files changed, 967 insertions(+), 815 deletions(-)

Added: branches/proto/v4/boost/proto/args.hpp
==============================================================================
--- (empty file)
+++ branches/proto/v4/boost/proto/args.hpp 2008-04-14 02:24:30 EDT (Mon, 14 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-14 02:24:30 EDT (Mon, 14 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-14 02:24:30 EDT (Mon, 14 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-14 02:24:30 EDT (Mon, 14 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-14 02:24:30 EDT (Mon, 14 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-14 02:24:30 EDT (Mon, 14 Apr 2008)
@@ -0,0 +1,31 @@
+///////////////////////////////////////////////////////////////////////////////
+/// \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/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-14 02:24:30 EDT (Mon, 14 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 functional
+ {
+ /// \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>functional::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)
+ {
+ functional::display_expr(sout, 0)(expr);
+ }
+
+ /// \overload
+ ///
+ template<typename Expr>
+ void display_expr(Expr const &expr)
+ {
+ functional::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-14 02:24:30 EDT (Mon, 14 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 functional
+ {
+ /// \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::functional::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-14 02:24:30 EDT (Mon, 14 Apr 2008)
@@ -0,0 +1,52 @@
+///////////////////////////////////////////////////////////////////////////////
+/// \file as_lvalue.hpp
+/// Contains definition the as_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
+
+#include <boost/proto/detail/prefix.hpp>
+#include <boost/proto/proto_fwd.hpp>
+#include <boost/proto/detail/suffix.hpp>
+
+namespace boost { namespace proto
+{
+ namespace detail
+ {
+ struct int_
+ {
+ int_() {}
+ int_(int) {}
+ };
+
+ template<typename T>
+ T &as_lvalue(T &t, int = 0)
+ {
+ return t;
+ }
+
+ template<typename T>
+ T const &as_lvalue(T const &t, int = 0)
+ {
+ return t;
+ }
+
+ template<typename Ret, typename T>
+ Ret as_lvalue(T &t, int_ = int_() BOOST_PROTO_DISABLE_IF_IS_CONST(T))
+ {
+ return t;
+ }
+
+ template<typename Ret, typename T>
+ Ret as_lvalue(T const &t, int_ = int_())
+ {
+ return t;
+ }
+ }
+}}
+
+#endif

Added: branches/proto/v4/boost/proto/detail/child_traits.hpp
==============================================================================
--- (empty file)
+++ branches/proto/v4/boost/proto/detail/child_traits.hpp 2008-04-14 02:24:30 EDT (Mon, 14 Apr 2008)
@@ -0,0 +1,89 @@
+///////////////////////////////////////////////////////////////////////////////
+/// \file child_traits.hpp
+/// Traits class for calculating properties of expression node children.
+//
+// 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_CHILD_TRAITS_HPP_EAN_04_06_2008
+#define BOOST_PROTO_DETAIL_CHILD_TRAITS_HPP_EAN_04_06_2008
+
+namespace boost { namespace proto
+{
+ namespace detail
+ {
+ /// \brief Trait for stripping top-level references
+ /// and reference wrappers.
+ template<typename T>
+ struct child_traits
+ {
+ typedef T value_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 child_traits<T &>
+ {
+ typedef T value_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 child_traits<T const &>
+ {
+ typedef T value_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 child_traits<T (&)[N]>
+ {
+ typedef T (&value_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 child_traits<T const (&)[N]>
+ {
+ typedef T const (&value_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 child_traits<T[N]>
+ {
+ typedef T (&value_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 child_traits<T const[N]>
+ {
+ typedef T const (&value_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
+ };
+ }
+
+}}
+
+#endif

Added: branches/proto/v4/boost/proto/detail/decltype.hpp
==============================================================================
--- (empty file)
+++ branches/proto/v4/boost/proto/detail/decltype.hpp 2008-04-14 02:24:30 EDT (Mon, 14 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-14 02:24:30 EDT (Mon, 14 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-14 02:24:30 EDT (Mon, 14 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-14 02:24:30 EDT (Mon, 14 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-14 02:24:30 EDT (Mon, 14 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-14 02:24:30 EDT (Mon, 14 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-14 02:24:30 EDT (Mon, 14 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-14 02:24:30 EDT (Mon, 14 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-14 02:24:30 EDT (Mon, 14 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-14 02:24:30 EDT (Mon, 14 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 functional
+ {
+ /// \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-14 02:24:30 EDT (Mon, 14 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/args.hpp>
+ #include <boost/proto/traits.hpp>
+ #include <boost/proto/detail/child_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 detail::child_traits<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-14 02:24:30 EDT (Mon, 14 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-14 02:24:30 EDT (Mon, 14 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 functional
+ {
+ /// \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<functional::flatten>
+ : mpl::true_
+ {};
+
+ /// INTERNAL ONLY
+ ///
+ template<>
+ struct is_callable<functional::pop_front>
+ : mpl::true_
+ {};
+
+ /// INTERNAL ONLY
+ ///
+ template<>
+ struct is_callable<functional::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
+ >::value_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
+ >::value_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-14 02:24:30 EDT (Mon, 14 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 detail::child_traits< \
+ typename expr_traits<Expr>::args::BOOST_PP_CAT(child, N) \
+ >::value_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 detail::child_traits<typename expr_traits<Expr>::args::child0>::value_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-14 02:24:30 EDT (Mon, 14 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::detail::child_traits<T>::value_type value_type;
+ typedef typename proto::detail::child_traits<T>::reference reference;
+ typedef typename proto::detail::child_traits<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-14 02:24:30 EDT (Mon, 14 Apr 2008)
@@ -0,0 +1,1200 @@
+#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>
+ , functional::as_child<Domain>
+ , functional::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 functional::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 functional
+ {
+ /// \brief A callable function object equivalent to the
+ /// \c proto::make_expr() function.
+ ///
+ /// In all cases, <tt>functional::make_expr\<Tag, Domain\>()(a0, ... aN)</tt>
+ /// is equivalent to <tt>proto::make_expr\<Tag, Domain\>(a0, ... aN)</tt>.
+ ///
+ /// <tt>functional::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>functional::unpack_expr\<Tag, Domain\>()(seq)</tt>
+ /// is equivalent to <tt>proto::unpack_expr\<Tag, Domain\>(seq)</tt>.
+ ///
+ /// <tt>functional::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 functional
+
+ /// TODO document me
+ template<typename Tag, typename Domain BOOST_PROTO_WHEN_BUILDING_DOCS(= deduce_domain)>
+ struct _make_expr : callable
+ {
+ template<typename Sig>
+ struct result
+ : functional::make_expr<Tag, Domain>::template result<Sig>
+ {};
+
+ #define M0(Z, N, DATA) \
+ template<BOOST_PP_ENUM_PARAMS_Z(Z, N, typename A)> \
+ BOOST_PP_CAT(detail::implicit_expr_, N)<BOOST_PP_ENUM_PARAMS_Z(Z, N, A)> \
+ operator ()(BOOST_PP_ENUM_BINARY_PARAMS_Z(Z, N, A, &a)) const \
+ { \
+ BOOST_PP_CAT(detail::implicit_expr_, N)<BOOST_PP_ENUM_PARAMS_Z(Z, N, A)> that = { \
+ BOOST_PP_ENUM_PARAMS_Z(Z, N, a) \
+ }; \
+ return that; \
+ } \
+ /**/
+ BOOST_PP_REPEAT_FROM_TO(1, BOOST_PP_INC(BOOST_PROTO_MAX_ARITY), M0, ~)
+ #undef M0
+ };
+
+ /// \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<functional::make_expr<Tag, Domain> >
+ : mpl::true_
+ {};
+
+ /// INTERNAL ONLY
+ ///
+ template<typename Tag, typename Domain>
+ struct is_callable<functional::unpack_expr<Tag, Domain> >
+ : mpl::true_
+ {};
+
+ /// INTERNAL ONLY
+ ///
+ template<typename Tag, typename Domain>
+ struct is_callable<functional::unfused_expr<Tag, Domain> >
+ : mpl::true_
+ {};
+
+ /// INTERNAL ONLY
+ ///
+ template<typename Tag, typename Domain>
+ struct is_callable<_make_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(N, typename A)>
+ struct BOOST_PP_CAT(implicit_expr_, N)
+ {
+ #define M0(Z, N, DATA) BOOST_PP_CAT(A, N) &BOOST_PP_CAT(a, N);
+ BOOST_PP_REPEAT(N, M0, ~)
+ #undef M0
+
+ template<typename Expr>
+ operator Expr() const
+ {
+ typename Expr::proto_base_expr that = {BOOST_PP_ENUM_PARAMS(N, a)};
+ return typename Expr::proto_domain()(that);
+ }
+ };
+
+ 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
+ #define M0(N, F) char (&F)[BOOST_PP_INC(N)]
+ static M0(BOOST_PROTO_MAX_ARITY, deducer(
+ BOOST_PP_ENUM_PARAMS(N, dont_care BOOST_PP_INTERCEPT)));
+ #define M1(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 M0(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, M1, ~)
+ #undef M0
+ #undef M1
+ 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-14 02:24:30 EDT (Mon, 14 Apr 2008)
@@ -0,0 +1,986 @@
+#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_const.hpp>
+ #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-14 02:24:30 EDT (Mon, 14 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-14 02:24:30 EDT (Mon, 14 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-14 02:24:30 EDT (Mon, 14 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 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_expr;
+
+ template<typename T, typename Void = void>
+ struct is_domain;
+
+ template<typename Expr>
+ struct tag_of;
+
+ template<typename Expr>
+ struct arity_of;
+
+ template<typename T, typename Void = void>
+ struct domain_of;
+
+ template<typename Expr, typename Grammar>
+ struct matches;
+ }
+
+ using result_of::is_expr;
+ using result_of::is_domain;
+ using result_of::tag_of;
+ using result_of::arity_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 functional
+ {
+ 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_unary_plus;
+ 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 functional::flatten _flatten;
+ typedef functional::pop_front _pop_front;
+ typedef functional::reverse _reverse;
+ typedef functional::eval _eval;
+ typedef functional::deep_copy _deep_copy;
+
+ template<typename Tag, typename Domain = deduce_domain>
+ struct _make_expr;
+
+ typedef _make_expr<tag::terminal> _make_terminal;
+ typedef _make_expr<tag::unary_plus> _make_unary_plus;
+ 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;
+
+ 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 _child0 _child;
+ typedef _child0 _value;
+ typedef _child0 _left;
+ typedef _child1 _right;
+
+ // _child2, _child3, _child4, ...
+ #define M0(Z, N, DATA) typedef _child_c<N> BOOST_PP_CAT(_child, N);
+ BOOST_PP_REPEAT_FROM_TO(
+ 2
+ , BOOST_PP_DEC(BOOST_PROTO_MAX_ARITY)
+ , M0
+ , ~
+ )
+ #undef M0
+
+ struct _byref;
+ struct _byval;
+
+ 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-14 02:24:30 EDT (Mon, 14 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/tags.hpp
==============================================================================
--- (empty file)
+++ branches/proto/v4/boost/proto/tags.hpp 2008-04-14 02:24:30 EDT (Mon, 14 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-14 02:24:30 EDT (Mon, 14 Apr 2008)
@@ -0,0 +1,2292 @@
+#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/args.hpp>
+ #include <boost/proto/tags.hpp>
+ #include <boost/proto/detail/child_traits.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) || (__GNUC__ == 4 && __GNUC_MINOR__ == 0)
+ // 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;
+ };
+
+ template<typename Expr>
+ struct tag_of<Expr &>
+ {
+ typedef typename Expr::proto_tag type;
+ };
+
+ /// \brief A metafunction that returns the arity of a
+ /// Proto expression.
+ template<typename Expr>
+ struct arity_of
+ : Expr::proto_arity
+ {};
+
+ template<typename Expr>
+ struct arity_of<Expr &>
+ : Expr::proto_arity
+ {};
+
+ /// \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>
+ {};
+
+ // 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>
+ {};
+
+ /// \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>
+ {};
+
+ } // 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_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 functional
+ {
+ /// \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 detail::child_traits<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 detail::child_traits<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<functional::as_expr<Domain> >
+ : mpl::true_
+ {};
+
+ /// INTERNAL ONLY
+ ///
+ template<typename Domain>
+ struct is_callable<functional::as_child<Domain> >
+ : mpl::true_
+ {};
+
+ /// INTERNAL ONLY
+ ///
+ template<long N>
+ struct is_callable<functional::child_c<N> >
+ : mpl::true_
+ {};
+
+ /// INTERNAL ONLY
+ ///
+ template<typename N>
+ struct is_callable<functional::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<
+ 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>
+ {
+ /// The raw type of the Nth child as it is stored within
+ /// \c Expr. This may be a value or a reference
+ typedef typename Expr::BOOST_PP_CAT(proto_child, N) value_type;
+
+ /// The "value" type of the child, suitable for return by value,
+ /// computed as follows:
+ /// \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 detail::child_traits<value_type>::value_type type;
+ };
+
+ template<typename Expr>
+ struct child_c<Expr &, N>
+ {
+ /// The raw type of the Nth child as it is stored within
+ /// \c Expr. This may be a value or a reference
+ typedef typename Expr::BOOST_PP_CAT(proto_child, N) value_type;
+
+ /// The "reference" type of the child, suitable for return by
+ /// reference, computed as follows:
+ /// \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 detail::child_traits<value_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>
+ {
+ /// The raw type of the Nth child as it is stored within
+ /// \c Expr. This may be a value or a reference
+ typedef typename Expr::BOOST_PP_CAT(proto_child, N) value_type;
+
+ /// The "const reference" type of the child, suitable for return by
+ /// const reference, computed as follows:
+ /// \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 detail::child_traits<value_type>::const_reference type;
+
+ /// INTERNAL ONLY
+ ///
+ static type call(Expr const &expr)
+ {
+ return 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-14 02:24:30 EDT (Mon, 14 Apr 2008)
@@ -0,0 +1,24 @@
+///////////////////////////////////////////////////////////////////////////////
+/// \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/call.hpp>
+#include <boost/proto/transform/default.hpp>
+#include <boost/proto/transform/fold.hpp>
+#include <boost/proto/transform/fold_tree.hpp>
+#include <boost/proto/transform/lazy.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-14 02:24:30 EDT (Mon, 14 Apr 2008)
@@ -0,0 +1,239 @@
+///////////////////////////////////////////////////////////////////////////////
+/// \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 _byref : 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);
+ }
+ };
+
+ /// \brief A unary CallableTransform that strips references
+ /// from its argument.
+ struct _byval : callable
+ {
+ template<typename Sig>
+ struct result;
+
+ template<typename This, typename T>
+ struct result<This(T)>
+ {
+ typedef T type;
+ };
+
+ template<typename This, typename T>
+ struct result<This(T &)>
+ : result<This(T)>
+ {};
+
+ template<typename This, typename T>
+ struct result<This(boost::reference_wrapper<T>)>
+ : result<This(T)>
+ {};
+
+ /// \param t The object to unref
+ /// \return <tt>t</tt>
+ /// \throw nothrow
+ template<typename T>
+ T const &operator ()(T const &t) const
+ {
+ return t;
+ }
+
+ /// \overload
+ ///
+ template<typename T>
+ T &operator ()(boost::reference_wrapper<T> const &t) const
+ {
+ return 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<_byref>
+ : mpl::true_
+ {};
+
+ /// INTERNAL ONLY
+ ///
+ template<>
+ struct is_callable<_byval>
+ : mpl::true_
+ {};
+
+}}
+
+#endif

Added: branches/proto/v4/boost/proto/transform/call.hpp
==============================================================================
--- (empty file)
+++ branches/proto/v4/boost/proto/transform/call.hpp 2008-04-14 02:24:30 EDT (Mon, 14 Apr 2008)
@@ -0,0 +1,415 @@
+#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>
+
+ 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(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()(
+ detail::as_lvalue<a0>(typename when<_, A0>::template impl<Expr, State, Data>()(expr, state, data), 0)
+ );
+ }
+ };
+
+ 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(a0, 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()(
+ detail::as_lvalue<a0>(typename when<_, A0>::template impl<Expr, State, Data>()(expr, state, data), 0)
+ , detail::as_lvalue<a1>(typename when<_, A1>::template impl<Expr, State, Data>()(expr, state, data), 0)
+ );
+ }
+ };
+
+ 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(a0, a1, 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()(
+ detail::as_lvalue<a0>(typename when<_, A0>::template impl<Expr, State, Data>()(expr, state, data), 0)
+ , detail::as_lvalue<a1>(typename when<_, A1>::template impl<Expr, State, Data>()(expr, state, data), 0)
+ , detail::as_lvalue<a2>(typename when<_, A2>::template impl<Expr, State, Data>()(expr, state, data), 0)
+ );
+ }
+ };
+
+ 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
+
+ #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_PARAMS(N, a))>::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) \
+ detail::as_lvalue<BOOST_PP_CAT(a, M)>( \
+ typename when<_, BOOST_PP_CAT(A, M)> \
+ ::template impl<Expr, State, Data>()(expr, state, data), 0) \
+ 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-14 02:24:30 EDT (Mon, 14 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-14 02:24:30 EDT (Mon, 14 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 = arity_of<Expr>::value
+ >
+ struct fold_impl
+ {};
+
+ template<
+ typename State0
+ , typename Fun
+ , typename Expr
+ , typename State
+ , typename Data
+ , long Arity = arity_of<Expr>::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-14 02:24:30 EDT (Mon, 14 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-14 02:24:30 EDT (Mon, 14 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-14 02:24:30 EDT (Mon, 14 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-14 02:24:30 EDT (Mon, 14 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) || (__GNUC__ == 4 && __GNUC_MINOR__ == 0)
+ // 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) || (__GNUC__ == 4 && __GNUC_MINOR__ == 0)
+ // 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-14 02:24:30 EDT (Mon, 14 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 = arity_of<Expr>::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-14 02:24:30 EDT (Mon, 14 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-14 02:24:30 EDT (Mon, 14 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-14 02:24:30 EDT (Mon, 14 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-14 02:24:30 EDT (Mon, 14 Apr 2008)
@@ -22,18 +22,19 @@
 #include <boost/assert.hpp>
 #include <boost/mpl/if.hpp>
 #include <boost/throw_exception.hpp>
+#include <boost/utility/result_of.hpp>
 #include <boost/type_traits/is_const.hpp>
 #include <boost/type_traits/remove_reference.hpp>
 #include <boost/xpressive/detail/detail_fwd.hpp>
 #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 +58,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 +74,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 +96,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 +116,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 +125,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 +164,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 +174,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 +184,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 +194,7 @@
                         )
                     );
                 }
- return proto::arg(expr).cast(where_->second);
+ return proto::value(expr).cast(where_->second);
             }
         };
 
@@ -207,7 +206,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 +214,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 +227,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 +270,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
+ , 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 +341,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
+ , typename impl::data_param
+ ) const
+ {
+ return result_type::make(proto::value(expr));
+ }
+ };
     };
 
     ///////////////////////////////////////////////////////////////////////////////
@@ -457,9 +463,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 boost::result_of<BindActionArgs(
+ Actor const &
+ , match_state<BidiIter> &
+ , int const &
+ )>::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-14 02:24:30 EDT (Mon, 14 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-14 02:24:30 EDT (Mon, 14 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-14 02:24:30 EDT (Mon, 14 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-14 02:24:30 EDT (Mon, 14 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-14 02:24:30 EDT (Mon, 14 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-14 02:24:30 EDT (Mon, 14 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-14 02:24:30 EDT (Mon, 14 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-14 02:24:30 EDT (Mon, 14 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-14 02:24:30 EDT (Mon, 14 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-14 02:24:30 EDT (Mon, 14 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-14 02:24:30 EDT (Mon, 14 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-14 02:24:30 EDT (Mon, 14 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-14 02:24:30 EDT (Mon, 14 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-14 02:24:30 EDT (Mon, 14 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-14 02:24:30 EDT (Mon, 14 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-14 02:24:30 EDT (Mon, 14 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-14 02:24:30 EDT (Mon, 14 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-14 02:24:30 EDT (Mon, 14 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-14 02:24:30 EDT (Mon, 14 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-14 02:24:30 EDT (Mon, 14 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-14 02:24:30 EDT (Mon, 14 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-14 02:24:30 EDT (Mon, 14 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-14 02:24:30 EDT (Mon, 14 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-14 02:24:30 EDT (Mon, 14 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-14 02:24:30 EDT (Mon, 14 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:

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-14 02:24:30 EDT (Mon, 14 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-14 02:24:30 EDT (Mon, 14 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-14 02:24:30 EDT (Mon, 14 Apr 2008)
@@ -0,0 +1,110 @@
+# 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/core.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/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/default.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-14 02:24:30 EDT (Mon, 14 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-14 02:24:30 EDT (Mon, 14 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 A Terminal]
+
+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-14 02:24:30 EDT (Mon, 14 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-14 02:24:30 EDT (Mon, 14 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-14 02:24:30 EDT (Mon, 14 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-14 02:24:30 EDT (Mon, 14 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-14 02:24:30 EDT (Mon, 14 Apr 2008)
@@ -0,0 +1,1039 @@
+[/
+ / 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::arity >
+ 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:
+
+ // decltype( -_1 )
+ proto::expr<
+ proto::tag::negate
+ , proto::list1<
+ proto::expr<
+ proto::tag::terminal
+ , proto::term< placeholder1 >
+ , 0
+ > const &
+ >
+ , 1
+ >
+
+ // decltype( _1 + 42 )
+ proto::expr<
+ proto::tag::plus
+ , proto::list2<
+ proto::expr<
+ proto::tag::terminal
+ , proto::term< placeholder1 >
+ , 0
+ > const &
+ , proto::expr<
+ proto::tag::terminal
+ , proto::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 held 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 thenselves held by reference, but the object itself /is/. 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 _child_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 _child_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 [^value()], [^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 _child_, _left_, and _right_ functions. _child_
+and _left_ are synonomous with `child_c<0>()`, and _right_ is synonomous with
+`child_c<1>()`.
+
+Another very common operation is accessing the value stored within a Proto
+terminal. You can use the _value_ function for that.
+
+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 {};
+ proto::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
+ , proto::functional::value()
+ )
+ , 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:
+
+ proto::terminal<int>::type const _1 = {1};
+
+ // ERROR: this doesn't work! Why?
+ fusion::for_each(
+ fusion::transform(
+ _1 + 2 + 3 + 4
+ , proto::functional::value()
+ )
+ , 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)
+ , functional::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 functional
+ {
+ // 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 functional
+ {
+ // 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::functional`
+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::functional::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::functional::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 --- `functional::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-14 02:24:30 EDT (Mon, 14 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-14 02:24:30 EDT (Mon, 14 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 functional
+ {
+ // 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-14 02:24:30 EDT (Mon, 14 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-14 02:24:30 EDT (Mon, 14 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-14 02:24:30 EDT (Mon, 14 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-14 02:24:30 EDT (Mon, 14 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-14 02:24:30 EDT (Mon, 14 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-14 02:24:30 EDT (Mon, 14 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 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>`. Or, you might decide to just
+include the core of Proto (`#include <boost/proto/proto.hpp>`) and whichever
+contexts and transforms you happen to use.
+
+[heading Requirements]
+
+Proto depends on Boost. You must use either Boost version 1.34.1 or higher,
+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-14 02:24:30 EDT (Mon, 14 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-14 02:24:30 EDT (Mon, 14 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-14 02:24:30 EDT (Mon, 14 Apr 2008)
@@ -0,0 +1,138 @@
+
+[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 _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_child_ [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 _child_ [funcref boost::proto::child `child()`]]
+[def _child_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 _value_ [funcref boost::proto::value `value()`]]
+[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-14 02:24:30 EDT (Mon, 14 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-14 02:24:30 EDT (Mon, 14 Apr 2008)
@@ -0,0 +1,3278 @@
+<?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-specialization name="term_ref"><template>
+ <template-type-parameter name="T"/>
+ </template><specialization><template-arg>T const &amp;</template-arg></specialization><typedef name="type"><type>T</type></typedef></struct-specialization><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="child_ref0"><type><classname>term_ref</classname>&lt; Arg0 &gt;</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="child_ref0"><type><classname>expr_ref</classname>&lt; Arg0 &gt;</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="child_ref0"><type><classname>expr_ref</classname>&lt; Arg0 &gt;</type></typedef><typedef name="child1"><type>Arg1</type></typedef><typedef name="child_ref1"><type><classname>expr_ref</classname>&lt; Arg1 &gt;</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="child_ref0"><type><classname>expr_ref</classname>&lt; Arg0 &gt;</type></typedef><typedef name="child1"><type>Arg1</type></typedef><typedef name="child_ref1"><type><classname>expr_ref</classname>&lt; Arg1 &gt;</type></typedef><typedef name="child2"><type>Arg2</type></typedef><typedef name="child_ref2"><type><classname>expr_ref</classname>&lt; Arg2 &gt;</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="child_ref0"><type><classname>expr_ref</classname>&lt; Arg0 &gt;</type></typedef><typedef name="child1"><type>Arg1</type></typedef><typedef name="child_ref1"><type><classname>expr_ref</classname>&lt; Arg1 &gt;</type></typedef><typedef name="child2"><type>Arg2</type></typedef><typedef name="child_ref2"><type><classname>expr_ref</classname>&lt; Arg2 &gt;</type></typedef><typedef name="child3"><type>Arg3</type></typedef><typedef name="child_ref3"><type><classname>expr_ref</classname>
&lt; Arg3 &gt;</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="child_ref0"><type><classname>expr_ref</classname>&lt; Arg0 &gt;</type></typedef><typedef name="child1"><type>Arg1</type></typedef><typedef name="child_ref1"><type><classname>expr_ref</classname>&lt; Arg1 &gt;</type></typedef><typedef name="child2"><type>Arg2</type></typedef><typedef name="child_ref2"><type><classname>expr_ref</classname>&lt; Arg2 &gt;</type></typedef><typedef name="child3"><type>Arg3</type></typedef><typedef name="child_ref3"><type><classname>expr_ref</classname>
&lt; Arg3 &gt;</type></typedef><typedef name="child4"><type>Arg4</type></typedef><typedef name="child_ref4"><type><classname>expr_ref</classname>&lt; Arg4 &gt;</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 const &amp;, 0 &gt;::type</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 const &amp;, 0 &gt;::type</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 const &amp;, 0 &gt;::type</type></typedef><typedef name="child1"><type>proto::result_of::child_c&lt; Expr const &amp;, 1 &gt;::type</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 const &amp;, 0 &gt;::type</type></typedef><typedef name="child1"><type>proto::result_of::child_c&lt; Expr const &amp;, 1 &gt;::type</type></typedef><typedef name="child2"><type>proto::result_of::child_c&lt; Expr const &amp;, 2 &gt;::type</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 const &amp;, 0 &gt;::type</type></typedef><typedef name="child1"><type>proto::result_of::child_c&lt; Expr const &amp;, 1 &gt;::type</type></typedef><typedef name="child2"><type>proto::result_of::child_c&lt; Expr const &amp;, 2 &gt;::type</type></typedef><typedef name="child3"><type>proto::result_of::child_c&lt; Expr const &amp;, 3 &gt;::type</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 const &amp;, 0 &gt;::type</type></typedef><typedef name="child1"><type>proto::result_of::child_c&lt; Expr const &amp;, 1 &gt;::type</type></typedef><typedef name="child2"><type>proto::result_of::child_c&lt; Expr const &amp;, 2 &gt;::type</type></typedef><typedef name="child3"><type>proto::result_of::child_c&lt; Expr const &amp;, 3 &gt;::type</type></typedef><typedef name="child4"><type>proto::result_of::child_c&lt; Expr const &amp;, 4 &gt;::type</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
><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></namespace></namespace></namespace></header><header name="boost/proto/context/default.hpp"><namespace name="boost"><namespace name="proto"><struct name="_default"><template>
+ <template-type-parameter name="Grammar"/>
+ </template><inherit access="public">transform&lt; boost::proto::_default&lt; Grammar &gt; &gt;</inherit><struct name="impl"><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="State"/>
+ <template-type-parameter name="Data"/>
+ </template></struct><struct-specialization name="impl2"><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="State"/>
+ <template-type-parameter name="Dat