|
Boost-Commit : |
From: eric_at_[hidden]
Date: 2007-11-07 17:03:53
Author: eric_niebler
Date: 2007-11-07 17:03:47 EST (Wed, 07 Nov 2007)
New Revision: 40913
URL: http://svn.boost.org/trac/boost/changeset/40913
Log:
preliminary buggy C++0x proto3 implementation
Added:
branches/proto/v3/boost/xpressive/proto3/
branches/proto/v3/boost/xpressive/proto3/args.hpp (contents, props changed)
branches/proto/v3/boost/xpressive/proto3/context/
branches/proto/v3/boost/xpressive/proto3/context.hpp (contents, props changed)
branches/proto/v3/boost/xpressive/proto3/context/callable.hpp (contents, props changed)
branches/proto/v3/boost/xpressive/proto3/context/default.hpp (contents, props changed)
branches/proto/v3/boost/xpressive/proto3/context/null.hpp (contents, props changed)
branches/proto/v3/boost/xpressive/proto3/domain.hpp (contents, props changed)
branches/proto/v3/boost/xpressive/proto3/eval.hpp (contents, props changed)
branches/proto/v3/boost/xpressive/proto3/expr.hpp (contents, props changed)
branches/proto/v3/boost/xpressive/proto3/extends.hpp (contents, props changed)
branches/proto/v3/boost/xpressive/proto3/fusion.hpp (contents, props changed)
branches/proto/v3/boost/xpressive/proto3/generate.hpp (contents, props changed)
branches/proto/v3/boost/xpressive/proto3/literal.hpp (contents, props changed)
branches/proto/v3/boost/xpressive/proto3/matches.hpp (contents, props changed)
branches/proto/v3/boost/xpressive/proto3/operators.hpp (contents, props changed)
branches/proto/v3/boost/xpressive/proto3/proto.hpp (contents, props changed)
branches/proto/v3/boost/xpressive/proto3/proto_fwd.hpp (contents, props changed)
branches/proto/v3/boost/xpressive/proto3/tags.hpp (contents, props changed)
branches/proto/v3/boost/xpressive/proto3/traits.hpp (contents, props changed)
branches/proto/v3/boost/xpressive/proto3/transform/
branches/proto/v3/boost/xpressive/proto3/transform.hpp (contents, props changed)
branches/proto/v3/boost/xpressive/proto3/transform/apply.hpp (contents, props changed)
branches/proto/v3/boost/xpressive/proto3/transform/arg.hpp (contents, props changed)
branches/proto/v3/boost/xpressive/proto3/transform/bind.hpp (contents, props changed)
branches/proto/v3/boost/xpressive/proto3/transform/fold.hpp (contents, props changed)
branches/proto/v3/boost/xpressive/proto3/transform/fold_tree.hpp (contents, props changed)
branches/proto/v3/libs/xpressive/proto3/
branches/proto/v3/libs/xpressive/proto3/doc/
branches/proto/v3/libs/xpressive/proto3/doc/Jamfile.v2 (contents, props changed)
branches/proto/v3/libs/xpressive/proto3/doc/acknowledgements.qbk (contents, props changed)
branches/proto/v3/libs/xpressive/proto3/doc/calculator.qbk (contents, props changed)
branches/proto/v3/libs/xpressive/proto3/doc/construction.qbk (contents, props changed)
branches/proto/v3/libs/xpressive/proto3/doc/evaluation.qbk (contents, props changed)
branches/proto/v3/libs/xpressive/proto3/doc/examples.qbk (contents, props changed)
branches/proto/v3/libs/xpressive/proto3/doc/extensibility.qbk (contents, props changed)
branches/proto/v3/libs/xpressive/proto3/doc/grammars.qbk (contents, props changed)
branches/proto/v3/libs/xpressive/proto3/doc/history.qbk (contents, props changed)
branches/proto/v3/libs/xpressive/proto3/doc/html/
branches/proto/v3/libs/xpressive/proto3/doc/html/boostbook.css (contents, props changed)
branches/proto/v3/libs/xpressive/proto3/doc/html/images/
branches/proto/v3/libs/xpressive/proto3/doc/html/images/alert.png (contents, props changed)
branches/proto/v3/libs/xpressive/proto3/doc/html/images/callouts/
branches/proto/v3/libs/xpressive/proto3/doc/html/images/callouts/1.png (contents, props changed)
branches/proto/v3/libs/xpressive/proto3/doc/html/images/callouts/10.png (contents, props changed)
branches/proto/v3/libs/xpressive/proto3/doc/html/images/callouts/11.png (contents, props changed)
branches/proto/v3/libs/xpressive/proto3/doc/html/images/callouts/12.png (contents, props changed)
branches/proto/v3/libs/xpressive/proto3/doc/html/images/callouts/13.png (contents, props changed)
branches/proto/v3/libs/xpressive/proto3/doc/html/images/callouts/14.png (contents, props changed)
branches/proto/v3/libs/xpressive/proto3/doc/html/images/callouts/15.png (contents, props changed)
branches/proto/v3/libs/xpressive/proto3/doc/html/images/callouts/2.png (contents, props changed)
branches/proto/v3/libs/xpressive/proto3/doc/html/images/callouts/3.png (contents, props changed)
branches/proto/v3/libs/xpressive/proto3/doc/html/images/callouts/4.png (contents, props changed)
branches/proto/v3/libs/xpressive/proto3/doc/html/images/callouts/5.png (contents, props changed)
branches/proto/v3/libs/xpressive/proto3/doc/html/images/callouts/6.png (contents, props changed)
branches/proto/v3/libs/xpressive/proto3/doc/html/images/callouts/7.png (contents, props changed)
branches/proto/v3/libs/xpressive/proto3/doc/html/images/callouts/8.png (contents, props changed)
branches/proto/v3/libs/xpressive/proto3/doc/html/images/callouts/9.png (contents, props changed)
branches/proto/v3/libs/xpressive/proto3/doc/html/images/caution.png (contents, props changed)
branches/proto/v3/libs/xpressive/proto3/doc/html/images/home.png (contents, props changed)
branches/proto/v3/libs/xpressive/proto3/doc/html/images/important.png (contents, props changed)
branches/proto/v3/libs/xpressive/proto3/doc/html/images/next.png (contents, props changed)
branches/proto/v3/libs/xpressive/proto3/doc/html/images/note.png (contents, props changed)
branches/proto/v3/libs/xpressive/proto3/doc/html/images/prev.png (contents, props changed)
branches/proto/v3/libs/xpressive/proto3/doc/html/images/smiley.png (contents, props changed)
branches/proto/v3/libs/xpressive/proto3/doc/html/images/tip.png (contents, props changed)
branches/proto/v3/libs/xpressive/proto3/doc/html/images/up.png (contents, props changed)
branches/proto/v3/libs/xpressive/proto3/doc/html/images/warning.png (contents, props changed)
branches/proto/v3/libs/xpressive/proto3/doc/implementation.qbk (contents, props changed)
branches/proto/v3/libs/xpressive/proto3/doc/installation.qbk (contents, props changed)
branches/proto/v3/libs/xpressive/proto3/doc/preface.qbk (contents, props changed)
branches/proto/v3/libs/xpressive/proto3/doc/proto.qbk (contents, props changed)
branches/proto/v3/libs/xpressive/proto3/doc/protodoc.xml (contents, props changed)
branches/proto/v3/libs/xpressive/proto3/doc/quick_start.qbk (contents, props changed)
branches/proto/v3/libs/xpressive/proto3/doc/rationale.qbk (contents, props changed)
branches/proto/v3/libs/xpressive/proto3/doc/transforms.qbk (contents, props changed)
branches/proto/v3/libs/xpressive/proto3/example/
branches/proto/v3/libs/xpressive/proto3/example/Jamfile.v2 (contents, props changed)
branches/proto/v3/libs/xpressive/proto3/example/calc1.cpp (contents, props changed)
branches/proto/v3/libs/xpressive/proto3/example/calc2.cpp (contents, props changed)
branches/proto/v3/libs/xpressive/proto3/example/calc3.cpp (contents, props changed)
branches/proto/v3/libs/xpressive/proto3/example/hello.cpp (contents, props changed)
branches/proto/v3/libs/xpressive/proto3/example/lazy_vector.cpp (contents, props changed)
branches/proto/v3/libs/xpressive/proto3/example/mixed.cpp (contents, props changed)
branches/proto/v3/libs/xpressive/proto3/example/rgb.cpp (contents, props changed)
branches/proto/v3/libs/xpressive/proto3/example/tarray.cpp (contents, props changed)
branches/proto/v3/libs/xpressive/proto3/example/vec3.cpp (contents, props changed)
branches/proto/v3/libs/xpressive/proto3/example/vector.cpp (contents, props changed)
branches/proto/v3/libs/xpressive/proto3/test/
branches/proto/v3/libs/xpressive/proto3/test/Jamfile.v2 (contents, props changed)
branches/proto/v3/libs/xpressive/proto3/test/calculator.cpp (contents, props changed)
branches/proto/v3/libs/xpressive/proto3/test/examples.cpp (contents, props changed)
branches/proto/v3/libs/xpressive/proto3/test/examples2.cpp (contents, props changed)
branches/proto/v3/libs/xpressive/proto3/test/lambda.cpp (contents, props changed)
branches/proto/v3/libs/xpressive/proto3/test/lambda2.cpp (contents, props changed)
branches/proto/v3/libs/xpressive/proto3/test/main.cpp (contents, props changed)
branches/proto/v3/libs/xpressive/proto3/test/matches.cpp (contents, props changed)
branches/proto/v3/libs/xpressive/proto3/test/proto_fusion.cpp (contents, props changed)
branches/proto/v3/libs/xpressive/proto3/test/proto_fusion_s.cpp (contents, props changed)
branches/proto/v3/libs/xpressive/proto3/test/toy_spirit.cpp (contents, props changed)
branches/proto/v3/libs/xpressive/proto3/test/toy_spirit2.cpp (contents, props changed)
branches/proto/v3/libs/xpressive/proto3/test/toy_spirit3.cpp (contents, props changed)
Added: branches/proto/v3/boost/xpressive/proto3/args.hpp
==============================================================================
--- (empty file)
+++ branches/proto/v3/boost/xpressive/proto3/args.hpp 2007-11-07 17:03:47 EST (Wed, 07 Nov 2007)
@@ -0,0 +1,103 @@
+///////////////////////////////////////////////////////////////////////////////
+/// \file args.hpp
+/// Contains definition of args\<\> and term\<\> class templates.
+//
+// Copyright 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)
+
+#ifndef BOOST_PROTO3_ARGS_HPP_EAN_10_28_2007
+#define BOOST_PROTO3_ARGS_HPP_EAN_10_28_2007
+
+#include <boost/xpressive/proto3/proto_fwd.hpp>
+
+namespace boost { namespace proto
+{
+
+ namespace argsns_
+ {
+
+ template<typename... Args>
+ struct args
+ {
+ static long const size = sizeof...(Args);
+ typedef cons<Args...> cons_type;
+ };
+
+ template<typename Arg>
+ struct term
+ {
+ static long const size = 0;
+ typedef cons<Arg> cons_type;
+ };
+
+ template<typename Args>
+ struct back;
+
+ template<typename Head, typename... Tail>
+ struct back<args<Head, Tail...> >
+ : back<args<Tail...> >
+ {};
+
+ template<typename Head>
+ struct back<args<Head> >
+ {
+ typedef Head type;
+ };
+
+ template<typename Head>
+ struct back<term<Head> >
+ {
+ typedef Head type;
+ };
+
+ template<typename Head, typename... Tail>
+ struct cons<Head, Tail...>
+ {
+ static long const size = 1 + sizeof...(Tail);
+ typedef Head car_type;
+ typedef cons<Tail...> cdr_type;
+ car_type car;
+ cdr_type cdr;
+ };
+
+ template<>
+ struct cons<>
+ {
+ static long const size = 0;
+ typedef void car_type;
+ typedef void cdr_type;
+ };
+
+ template<typename Head>
+ struct cons<Head>
+ {
+ static long const size = 1;
+ typedef Head car_type;
+ typedef cons<> cdr_type;
+ car_type car;
+ static cdr_type const cdr;
+ };
+
+ template<typename Head>
+ cons<> const cons<Head>::cdr = {};
+
+ template<typename Head, typename... Tail>
+ inline cons<Head, Tail...> make_cons(Head &&head, Tail &&... tail)
+ {
+ cons<Head, Tail...> that = {head, make_cons(std::forward<Tail>(tail)...)};
+ return that;
+ }
+
+ template<typename Head>
+ inline cons<Head> make_cons(Head &&head)
+ {
+ cons<Head> that = {head};
+ return that;
+ }
+
+ }
+
+}}
+
+#endif
Added: branches/proto/v3/boost/xpressive/proto3/context.hpp
==============================================================================
--- (empty file)
+++ branches/proto/v3/boost/xpressive/proto3/context.hpp 2007-11-07 17:03:47 EST (Wed, 07 Nov 2007)
@@ -0,0 +1,16 @@
+///////////////////////////////////////////////////////////////////////////////
+/// \file context.hpp
+/// Includes all the context classes in the context/ sub-directory.
+//
+// Copyright 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)
+
+#ifndef BOOST_PROTO3_CONTEXT_HPP_EAN_06_23_2007
+#define BOOST_PROTO3_CONTEXT_HPP_EAN_06_23_2007
+
+#include <boost/xpressive/proto3/context/null.hpp>
+#include <boost/xpressive/proto3/context/default.hpp>
+#include <boost/xpressive/proto3/context/callable.hpp>
+
+#endif
Added: branches/proto/v3/boost/xpressive/proto3/context/callable.hpp
==============================================================================
--- (empty file)
+++ branches/proto/v3/boost/xpressive/proto3/context/callable.hpp 2007-11-07 17:03:47 EST (Wed, 07 Nov 2007)
@@ -0,0 +1,163 @@
+///////////////////////////////////////////////////////////////////////////////
+/// \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 the default_context.
+//
+// Copyright 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)
+
+#ifndef BOOST_PROTO3_CONTEXT_CALLABLE_HPP_EAN_06_23_2007
+#define BOOST_PROTO3_CONTEXT_CALLABLE_HPP_EAN_06_23_2007
+
+#include <boost/config.hpp>
+#include <boost/detail/workaround.hpp>
+#include <boost/mpl/if.hpp>
+#include <boost/mpl/bool.hpp>
+#include <boost/utility/result_of.hpp>
+#include <boost/type_traits.hpp>
+#include <boost/xpressive/proto3/proto_fwd.hpp>
+#include <boost/xpressive/proto3/traits.hpp> // for arg_c
+
+namespace boost { namespace proto
+{
+ namespace detail
+ {
+ typedef char yes_type;
+ typedef char (&no_type)[2];
+
+ struct dont_care
+ {
+ dont_care(...);
+ };
+
+ struct private_type_
+ {
+ private_type_ const &operator,(int) const;
+ };
+
+ template<typename T>
+ yes_type check_is_expr_handled(T const &);
+
+ no_type check_is_expr_handled(private_type_ const &);
+
+ template<typename Context, typename Args>
+ struct callable_context_wrapper;
+
+ template<typename Expr, typename Context, typename Args = typename Expr::proto_args>
+ struct is_expr_handled;
+
+ template<int N, typename Result = args<> >
+ struct make_dont_care;
+
+ template<int N, typename... Result>
+ struct make_dont_care<N, args<Result...> >
+ : make_dont_care<N-1, args<dont_care, Result...> >
+ {};
+
+ template<typename... Result>
+ struct make_dont_care<0, args<Result...> >
+ {
+ typedef args<Result...> type;
+ };
+
+ template<typename Context, typename... DontCare>
+ struct callable_context_wrapper<Context, args<DontCare...> >
+ : remove_cv<Context>::type
+ {
+ callable_context_wrapper();
+ typedef private_type_ const &(*pointer_to_function)(DontCare...);
+ operator pointer_to_function() const;
+ };
+
+ template<typename Expr, typename Context, typename Args, typename Indices>
+ struct is_expr_handled_aux_;
+
+ template<typename Expr, typename Context, typename... Args, int... Indices>
+ struct is_expr_handled_aux_<Expr, Context, args<Args...>, op::detail::indices<Indices...> >
+ {
+ typedef typename make_dont_care<sizeof...(Args)>::type DontCare;
+
+ static callable_context_wrapper<Context, DontCare> &sctx_;
+ static Expr &sexpr_;
+
+ BOOST_STATIC_CONSTANT(bool, value =
+ (
+ sizeof(yes_type) ==
+ sizeof(
+ proto::detail::check_is_expr_handled(
+ (sctx_(
+ typename Expr::proto_tag()
+ , proto::arg_c<Indices>(sexpr_)...
+ ), 0)
+ )
+ )));
+
+ typedef mpl::bool_<value> type;
+ };
+
+ template<typename Expr, typename Context, typename... Args>
+ struct is_expr_handled<Expr, Context, args<Args...> >
+ : is_expr_handled_aux_<Expr, Context, args<Args...>, typename op::detail::make_indices<sizeof...(Args)>::type >
+ {};
+
+ template<typename Expr, typename Context, typename T>
+ struct is_expr_handled<Expr, Context, term<T> >
+ : is_expr_handled_aux_<Expr, Context, args<T>, op::detail::indices<0> >
+ {};
+
+ }
+
+ namespace context
+ {
+ /// callable_eval
+ ///
+ template<typename Expr, typename Context, typename Indices>
+ struct callable_eval
+ {};
+
+ /// callable_context
+ ///
+ template<typename Context, typename DefaultCtx>
+ struct callable_context
+ {
+ /// callable_context::eval
+ ///
+ template<typename Expr, typename ThisContext = Context>
+ struct eval
+ : mpl::if_<
+ proto::detail::is_expr_handled<Expr, Context>
+ , callable_eval<Expr, ThisContext>
+ , typename DefaultCtx::template eval<Expr, Context>
+ >::type
+ {};
+ };
+
+ template<typename Expr, typename Context, int... Indices>
+ struct callable_eval<Expr, Context, op::detail::indices<Indices...> >
+ {
+ typedef
+ typename boost::result_of<
+ Context(
+ typename Expr::proto_tag
+ , typename proto::result_of::arg_c<Expr, Indices>::const_reference...
+ )
+ >::type
+ result_type;
+
+ result_type operator ()(Expr &expr, Context &context) const
+ {
+ return context(
+ typename Expr::proto_tag()
+ , proto::arg_c<Indices>(expr)...
+ );
+ }
+ };
+
+ }
+
+}}
+
+#endif
Added: branches/proto/v3/boost/xpressive/proto3/context/default.hpp
==============================================================================
--- (empty file)
+++ branches/proto/v3/boost/xpressive/proto3/context/default.hpp 2007-11-07 17:03:47 EST (Wed, 07 Nov 2007)
@@ -0,0 +1,388 @@
+#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 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)
+
+ #ifndef BOOST_PROTO_CONTEXT_DEFAULT_HPP_EAN_01_08_2007
+ #define BOOST_PROTO_CONTEXT_DEFAULT_HPP_EAN_01_08_2007
+
+ //#include <boost/xpressive/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/enum_shifted.hpp>
+ #include <boost/preprocessor/repetition/enum_params.hpp>
+ #include <boost/preprocessor/repetition/enum_trailing.hpp>
+ #include <boost/preprocessor/arithmetic/inc.hpp>
+ #include <boost/preprocessor/tuple/elem.hpp>
+ #include <boost/mpl/if.hpp>
+ #include <boost/typeof/typeof.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_cv.hpp>
+ #include <boost/xpressive/proto3/proto_fwd.hpp>
+ #include <boost/xpressive/proto3/tags.hpp>
+ #include <boost/xpressive/proto3/eval.hpp>
+ #include <boost/xpressive/proto3/traits.hpp> // for proto::arg_c()
+ //#include <boost/xpressive/proto/detail/suffix.hpp> // must be last include
+
+ // If we're generating doxygen documentation, hide all the nasty
+ // Boost.Typeof gunk.
+ #ifndef BOOST_PROTO_DOXYGEN_INVOKED
+ #define BOOST_PROTO_DECLTYPE_NESTED_TYPEDEF_TPL_(Nested, Expr)\
+ BOOST_TYPEOF_NESTED_TYPEDEF_TPL(BOOST_PP_CAT(nested_and_hidden_, Nested), Expr)\
+ struct Nested\
+ : mpl::if_c<\
+ 1==sizeof(detail_::check_reference(Expr))\
+ , 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;
+ #else
+ /// INTERNAL ONLY
+ ///
+ #define BOOST_PROTO_DECLTYPE_NESTED_TYPEDEF_TPL_(Nested, Expr)
+ /// 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_((detail_::make<A0>(), 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>));
+
+ #if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
+ template<typename T> T &make_ref_(T &t);
+ template<typename T> T const &make_ref_(T const &t);
+ #define BOOST_PROTO_REF(x) detail_::make_ref_(x)
+ #else
+ #define BOOST_PROTO_REF(x) x
+ #endif
+ }
+
+ namespace context
+ {
+ template<typename Expr, typename Context, typename Tag, long Arity>
+ 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: \
+ static Expr &sexpr; \
+ static Context &sctx; \
+ public: \
+ BOOST_PROTO_DECLTYPE_(Op proto::eval(BOOST_PROTO_REF(proto::arg_c<0>(sexpr)), sctx), result_type)\
+ result_type operator()(Expr &expr, Context &ctx) const \
+ { \
+ return Op proto::eval(proto::arg_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: \
+ static Expr &sexpr; \
+ static Context &sctx; \
+ public: \
+ BOOST_PROTO_DECLTYPE_(proto::eval(BOOST_PROTO_REF(proto::arg_c<0>(sexpr)), sctx) Op proto::eval(BOOST_PROTO_REF(proto::arg_c<1>(sexpr)), sctx), result_type)\
+ result_type operator()(Expr &expr, Context &ctx) const \
+ { \
+ return proto::eval(proto::arg_c<0>(expr), ctx) Op proto::eval(proto::arg_c<1>(expr), ctx);\
+ } \
+ }; \
+ /**/
+
+ BOOST_PROTO_UNARY_OP_RESULT(+, proto::tag::posit)
+ 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)
+
+ template<typename Expr, typename Context>
+ struct default_eval<Expr, Context, proto::tag::terminal, 0>
+ {
+ typedef
+ typename mpl::if_<
+ is_const<Expr>
+ , typename proto::result_of::arg<Expr>::const_reference
+ , typename proto::result_of::arg<Expr>::reference
+ >::type
+ result_type;
+
+ result_type operator()(Expr &expr, Context &) const
+ {
+ return proto::arg(expr);
+ }
+ };
+
+ // Handle post-increment specially.
+ template<typename Expr, typename Context>
+ struct default_eval<Expr, Context, proto::tag::post_inc, 1>
+ {
+ private:
+ static Expr &sexpr;
+ static Context &sctx;
+ public:
+ BOOST_PROTO_DECLTYPE_(proto::eval(BOOST_PROTO_REF(proto::arg_c<0>(sexpr)), sctx) ++, result_type)
+ result_type operator()(Expr &expr, Context &ctx) const
+ {
+ return proto::eval(proto::arg_c<0>(expr), ctx) ++;
+ }
+ };
+
+ // Handle post-decrement specially.
+ template<typename Expr, typename Context>
+ struct default_eval<Expr, Context, proto::tag::post_dec, 1>
+ {
+ private:
+ static Expr &sexpr;
+ static Context &sctx;
+ public:
+ BOOST_PROTO_DECLTYPE_(proto::eval(BOOST_PROTO_REF(proto::arg_c<0>(sexpr)), sctx) --, result_type)
+ result_type operator()(Expr &expr, Context &ctx) const
+ {
+ return proto::eval(proto::arg_c<0>(expr), ctx) --;
+ }
+ };
+
+ // Handle subscript specially.
+ template<typename Expr, typename Context>
+ struct default_eval<Expr, Context, proto::tag::subscript, 2>
+ {
+ private:
+ static Expr &sexpr;
+ static Context &sctx;
+ public:
+ BOOST_PROTO_DECLTYPE_(proto::eval(BOOST_PROTO_REF(proto::arg_c<0>(sexpr)), sctx)[proto::eval(BOOST_PROTO_REF(proto::arg_c<1>(sexpr)), sctx)], result_type)
+ result_type operator()(Expr &expr, Context &ctx) const
+ {
+ return proto::eval(proto::arg_c<0>(expr), ctx)[proto::eval(proto::arg_c<1>(expr), ctx)];
+ }
+ };
+
+ // Handle if_else_ specially.
+ template<typename Expr, typename Context>
+ struct default_eval<Expr, Context, proto::tag::if_else_, 3>
+ {
+ private:
+ static Expr &sexpr;
+ static Context &sctx;
+ public:
+ BOOST_PROTO_DECLTYPE_(
+ proto::eval(BOOST_PROTO_REF(proto::arg_c<0>(sexpr)), sctx)
+ ? proto::eval(BOOST_PROTO_REF(proto::arg_c<1>(sexpr)), sctx)
+ : proto::eval(BOOST_PROTO_REF(proto::arg_c<2>(sexpr)), sctx)
+ , result_type
+ )
+ result_type operator()(Expr &expr, Context &ctx) const
+ {
+ return proto::eval(proto::arg_c<0>(expr), ctx)
+ ? proto::eval(proto::arg_c<1>(expr), ctx)
+ : proto::eval(proto::arg_c<2>(expr), ctx);
+ }
+ };
+
+ // Handle comma specially.
+ template<typename Expr, typename Context>
+ struct default_eval<Expr, Context, proto::tag::comma, 2>
+ {
+ typedef typename proto::result_of::eval<typename proto::result_of::arg_c<Expr, 0>::type, Context>::type proto_arg0;
+ typedef typename proto::result_of::eval<typename proto::result_of::arg_c<Expr, 1>::type, Context>::type proto_arg1;
+ typedef typename detail_::comma_result<proto_arg0, proto_arg1>::type result_type;
+ result_type operator()(Expr &expr, Context &ctx) const
+ {
+ return proto::eval(proto::arg_c<0>(expr), ctx), proto::eval(proto::arg_c<1>(expr), ctx);
+ }
+ };
+
+ #define BOOST_PROTO_EVAL_N_TYPE(Z, N, Data)\
+ typename proto::result_of::eval<\
+ typename proto::result_of::arg_c<BOOST_PP_TUPLE_ELEM(2, 0, Data), N>::type\
+ , BOOST_PP_TUPLE_ELEM(2, 1, Data)\
+ >::type
+
+ #define BOOST_PROTO_EVAL_N(Z, N, Data)\
+ proto::eval(proto::arg_c<N>(BOOST_PP_TUPLE_ELEM(2, 0, Data)), BOOST_PP_TUPLE_ELEM(2, 1, Data))
+
+ #define BOOST_PP_ITERATION_PARAMS_1 (3, (1, BOOST_PROTO_MAX_ARITY, <boost/xpressive/proto/context/default.hpp>))
+ #include BOOST_PP_ITERATE()
+
+ #undef BOOST_PROTO_EVAL_N_TYPE
+ #undef BOOST_PROTO_EVAL_N
+
+ /// 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 BOOST_PROTO_DECLTYPE_NESTED_TYPEDEF_TPL_
+ #undef BOOST_PROTO_DECLTYPE_
+
+ #endif
+
+#else
+
+ #define N BOOST_PP_ITERATION()
+
+ // Handle function specially
+ template<typename Expr, typename Context>
+ struct default_eval<Expr, Context, proto::tag::function, N>
+ {
+ typedef
+ typename detail_::result_of_fixup<
+ BOOST_PROTO_EVAL_N_TYPE(1, 0, (Expr, Context))
+ >::type
+ function_type;
+
+ typedef
+ typename boost::result_of<
+ function_type(
+ BOOST_PP_ENUM_SHIFTED(N, BOOST_PROTO_EVAL_N_TYPE, (Expr, Context))
+ )
+ >::type
+ result_type;
+
+ result_type operator ()(Expr &expr, Context &context) const
+ {
+ return BOOST_PROTO_EVAL_N(1, 0, (expr, context))(
+ BOOST_PP_ENUM_SHIFTED(N, BOOST_PROTO_EVAL_N, (expr, context))
+ );
+ }
+ };
+
+ #undef N
+
+#endif
Added: branches/proto/v3/boost/xpressive/proto3/context/null.hpp
==============================================================================
--- (empty file)
+++ branches/proto/v3/boost/xpressive/proto3/context/null.hpp 2007-11-07 17:03:47 EST (Wed, 07 Nov 2007)
@@ -0,0 +1,83 @@
+#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 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)
+
+ #ifndef BOOST_PROTO_CONTEXT_NULL_HPP_EAN_06_24_2007
+ #define BOOST_PROTO_CONTEXT_NULL_HPP_EAN_06_24_2007
+
+ #include <boost/xpressive/proto/detail/prefix.hpp> // must be first include
+ #include <boost/preprocessor/iteration/iterate.hpp>
+ #include <boost/preprocessor/repetition/repeat.hpp>
+ #include <boost/xpressive/proto/proto_fwd.hpp>
+ #include <boost/xpressive/proto/eval.hpp>
+ #include <boost/xpressive/proto/traits.hpp>
+ #include <boost/xpressive/proto/detail/suffix.hpp> // must be last include
+
+ namespace boost { namespace proto { namespace context
+ {
+
+ template<typename Expr, typename Context, long Arity>
+ 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::arg_c<N>(expr), ctx); \
+ /**/
+
+ #define BOOST_PP_ITERATION_PARAMS_1 \
+ (3, (1, BOOST_PROTO_MAX_ARITY, <boost/xpressive/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/v3/boost/xpressive/proto3/domain.hpp
==============================================================================
--- (empty file)
+++ branches/proto/v3/boost/xpressive/proto3/domain.hpp 2007-11-07 17:03:47 EST (Wed, 07 Nov 2007)
@@ -0,0 +1,83 @@
+///////////////////////////////////////////////////////////////////////////////
+/// \file domain.hpp
+/// Contains definition of domain\<\> class template, for defining domains
+/// with a grammar for controlling operator overloading.
+//
+// Copyright 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)
+
+#ifndef BOOST_PROTO3_DOMAIN_HPP_EAN_02_13_2007
+#define BOOST_PROTO3_DOMAIN_HPP_EAN_02_13_2007
+
+#include <boost/mpl/bool.hpp>
+#include <boost/xpressive/proto3/proto_fwd.hpp>
+#include <boost/xpressive/proto3/generate.hpp>
+
+namespace boost { namespace proto
+{
+
+ namespace detail
+ {
+ struct not_a_generator
+ {};
+
+ struct not_a_grammar
+ {};
+ }
+
+ namespace domainns_
+ {
+ template<typename Generator, typename Grammar>
+ struct domain
+ : Generator
+ {
+ typedef Grammar grammar;
+
+ /// INTERNAL ONLY
+ ///
+ typedef void proto_is_domain_;
+ };
+
+ struct default_domain
+ : domain<>
+ {};
+
+ struct deduce_domain
+ : domain<proto::detail::not_a_generator, proto::detail::not_a_grammar>
+ {};
+ }
+
+ namespace result_of
+ {
+ template<typename T, typename EnableIf>
+ struct is_domain
+ : mpl::false_
+ {};
+
+ template<typename T>
+ struct is_domain<T, typename T::proto_is_domain_>
+ : mpl::true_
+ {};
+
+ template<typename T, typename EnableIf>
+ struct domain_of
+ {
+ typedef default_domain type;
+ };
+
+ template<typename T>
+ struct domain_of<T, typename T::proto_is_expr_>
+ {
+ typedef typename T::proto_domain type;
+ };
+
+ template<typename T>
+ struct domain_of<T &, typename T::proto_is_expr_>
+ {
+ typedef typename T::proto_domain type;
+ };
+ }
+}}
+
+#endif
Added: branches/proto/v3/boost/xpressive/proto3/eval.hpp
==============================================================================
--- (empty file)
+++ branches/proto/v3/boost/xpressive/proto3/eval.hpp 2007-11-07 17:03:47 EST (Wed, 07 Nov 2007)
@@ -0,0 +1,54 @@
+///////////////////////////////////////////////////////////////////////////////
+/// \file eval.hpp
+/// Contains the eval() expression evaluator.
+//
+// Copyright 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)
+
+#ifndef BOOST_PROTO3_EVAL_HPP_EAN_03_29_2007
+#define BOOST_PROTO3_EVAL_HPP_EAN_03_29_2007
+
+#include <boost/type_traits.hpp>
+
+#define UNREF(X) typename remove_reference<X>::type
+
+namespace boost { namespace proto
+{
+
+ namespace result_of
+ {
+ template<typename Expr, typename Context>
+ struct eval
+ {
+ typedef typename Context::template eval<Expr>::result_type type;
+ };
+ }
+
+ namespace functional
+ {
+ struct eval
+ {
+ template<typename Sig>
+ struct result;
+
+ template<typename This, typename Expr, typename Context>
+ struct result<This(Expr, Context)>
+ : proto::result_of::eval<UNREF(Expr), UNREF(Context)>
+ {};
+
+ template<typename Expr, typename Context>
+ typename proto::result_of::eval<UNREF(Expr), UNREF(Context)>::type
+ operator ()(Expr &&expr, Context &&context) const
+ {
+ return UNREF(Context)::template eval<UNREF(Expr)>()(expr, context);
+ }
+ };
+ }
+
+ functional::eval const eval = {};
+}}
+
+#undef UNREF
+
+#endif
Added: branches/proto/v3/boost/xpressive/proto3/expr.hpp
==============================================================================
--- (empty file)
+++ branches/proto/v3/boost/xpressive/proto3/expr.hpp 2007-11-07 17:03:47 EST (Wed, 07 Nov 2007)
@@ -0,0 +1,122 @@
+///////////////////////////////////////////////////////////////////////////////
+/// \file expr.hpp
+/// Contains the definition of the expr\<\> class template
+//
+// Copyright 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)
+
+#ifndef BOOST_PROTO3_EXPR_HPP_EAN_10_28_2007
+#define BOOST_PROTO3_EXPR_HPP_EAN_10_28_2007
+
+#include <boost/xpressive/proto3/proto_fwd.hpp>
+
+namespace boost { namespace proto
+{
+
+ namespace exprns_
+ {
+
+ template<typename Tag, typename Args, long Arity>
+ struct expr
+ {
+ typedef Tag proto_tag;
+ typedef Args proto_args;
+ typedef void proto_is_expr_;
+ static long const proto_arity = Arity;
+ typedef expr proto_base_expr;
+ typedef expr proto_derived_expr;
+ typedef default_domain proto_domain;
+ typedef tag::proto_expr fusion_tag;
+
+ typename Args::cons_type proto_args_;
+
+ template<typename Expr, typename, typename>
+ struct apply
+ {
+ typedef Expr type;
+ };
+
+ template<typename Expr, typename State, typename Visitor>
+ static Expr const &call(Expr const &expr, State const &, Visitor &)
+ {
+ return expr;
+ }
+
+ template<typename... A>
+ static expr make(A &&... a)
+ {
+ expr that = {{a...}};
+ return that;
+ }
+
+ expr &proto_base()
+ {
+ return *this;
+ }
+
+ expr const &proto_base() const
+ {
+ return *this;
+ }
+
+ template<typename A>
+ expr<tag::assign, args<expr &, typename result_of::as_arg<A>::type> >
+ operator=(A &&a)
+ {
+ expr<tag::assign, args<expr &, typename result_of::as_arg<A>::type> > that =
+ {{*this, {proto::result_of::as_arg<A>::call(a)}}};
+ return that;
+ }
+
+ template<typename A>
+ expr<tag::assign, args<expr const &, typename result_of::as_arg<A>::type> >
+ operator=(A &&a) const
+ {
+ expr<tag::assign, args<expr const &, typename result_of::as_arg<A>::type> > that =
+ {{*this, {proto::result_of::as_arg<A>::call(a)}}};
+ return that;
+ }
+
+ template<typename A>
+ expr<tag::subscript, args<expr &, typename result_of::as_arg<A>::type> >
+ operator[](A &&a)
+ {
+ expr<tag::subscript, args<expr &, typename result_of::as_arg<A>::type> > that =
+ {{*this, {proto::result_of::as_arg<A>::call(a)}}};
+ return that;
+ }
+
+ template<typename A>
+ expr<tag::subscript, args<expr const &, typename result_of::as_arg<A>::type> >
+ operator[](A &&a) const
+ {
+ expr<tag::subscript, args<expr const &, typename result_of::as_arg<A>::type> > that =
+ {{*this, {proto::result_of::as_arg<A>::call(a)}}};
+ return that;
+ }
+
+ template<typename... A>
+ expr<tag::function, args<expr &, typename result_of::as_arg<A>::type...> >
+ operator()(A &&... a)
+ {
+ expr<tag::function, args<expr &, typename result_of::as_arg<A>::type...> > that =
+ {argsns_::make_cons(*this, proto::result_of::as_arg<A>::call(a)...)};
+ return that;
+ }
+
+ template<typename... A>
+ expr<tag::function, args<expr const &, typename result_of::as_arg<A>::type...> >
+ operator()(A &&... a) const
+ {
+ expr<tag::function, args<expr const &, typename result_of::as_arg<A>::type...> > that =
+ {argsns_::make_cons(*this, proto::result_of::as_arg<A>::call(a)...)};
+ return that;
+ }
+ };
+
+ }
+
+}}
+
+#endif
Added: branches/proto/v3/boost/xpressive/proto3/extends.hpp
==============================================================================
--- (empty file)
+++ branches/proto/v3/boost/xpressive/proto3/extends.hpp 2007-11-07 17:03:47 EST (Wed, 07 Nov 2007)
@@ -0,0 +1,200 @@
+///////////////////////////////////////////////////////////////////////////////
+/// \file extends.hpp
+/// Macros and a base class for defining end-user expression types
+//
+// Copyright 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)
+
+#ifndef BOOST_PROTO3_EXTENDS_HPP_EAN_11_1_2006
+#define BOOST_PROTO3_EXTENDS_HPP_EAN_11_1_2006
+
+#include <boost/mpl/apply_wrap.hpp>
+#include <boost/xpressive/proto3/proto_fwd.hpp>
+#include <boost/xpressive/proto3/traits.hpp>
+#include <boost/xpressive/proto3/expr.hpp>
+#include <boost/xpressive/proto3/args.hpp>
+#include <boost/xpressive/proto3/traits.hpp>
+#include <boost/xpressive/proto3/generate.hpp>
+
+namespace boost { namespace proto
+{
+ /// INTERNAL ONLY
+ ///
+ #define BOOST_PROTO_CONST0
+
+ /// INTERNAL ONLY
+ ///
+ #define BOOST_PROTO_CONST1 const
+
+ #define BOOST_PROTO_EXTENDS(Expr, Derived, Domain)\
+ Expr expr;\
+ \
+ typedef Expr proto_base_expr;\
+ typedef Domain proto_domain;\
+ typedef Derived proto_derived_expr;\
+ typedef typename Expr::proto_tag proto_tag;\
+ typedef typename Expr::proto_args proto_args;\
+ static long const proto_arity = Expr::proto_arity;\
+ typedef void proto_is_expr_;\
+ typedef boost::proto::tag::proto_expr fusion_tag;\
+ \
+ template<typename Expr_, typename, typename>\
+ struct apply\
+ {\
+ typedef Expr_ type;\
+ };\
+ \
+ template<typename Expr_, typename State, typename Visitor>\
+ static Expr_ const &call(Expr_ const &expr, State const &, Visitor &)\
+ {\
+ return expr;\
+ }\
+ \
+ static Derived make(Expr const &expr)\
+ {\
+ Derived that = {expr};\
+ return that;\
+ }\
+ \
+ Expr &proto_base()\
+ {\
+ return this->expr;\
+ }\
+ \
+ Expr const &proto_base() const\
+ {\
+ return this->expr;\
+ }\
+ /**/
+
+ /// INTERNAL ONLY
+ ///
+ #define BOOST_PROTO_EXTENDS_ASSIGN_IMPL_(Expr, Derived, Domain, Const)\
+ template<typename A>\
+ typename boost::mpl::apply_wrap1<Domain, boost::proto::expr<boost::proto::tag::assign, boost::proto::args<Derived BOOST_PROTO_CONST ## Const &, typename boost::proto::result_of::as_arg<A>::type> > >::type\
+ operator =(A &&a) BOOST_PROTO_CONST ## Const\
+ {\
+ typedef boost::proto::expr<boost::proto::tag::assign, boost::proto::args<Derived BOOST_PROTO_CONST ## Const &, typename boost::proto::result_of::as_arg<A>::type> > that_type;\
+ that_type that = {{*static_cast<Derived BOOST_PROTO_CONST ## Const *>(this), {boost::proto::result_of::as_arg<A>::call(a)}}};\
+ return Domain::make(that);\
+ }\
+ /**/
+
+ #define BOOST_PROTO_EXTENDS_ASSIGN_CONST(Expr, Derived, Domain)\
+ BOOST_PROTO_EXTENDS_ASSIGN_IMPL_(Expr, Derived, Domain, 1)
+
+ #define BOOST_PROTO_EXTENDS_ASSIGN_NON_CONST(Expr, Derived, Domain)\
+ BOOST_PROTO_EXTENDS_ASSIGN_IMPL_(Expr, Derived, Domain, 0)
+
+ #define BOOST_PROTO_EXTENDS_ASSIGN(Expr, Derived, Domain)\
+ BOOST_PROTO_EXTENDS_ASSIGN_CONST(Expr, Derived, Domain)\
+ BOOST_PROTO_EXTENDS_ASSIGN_NON_CONST(Expr, Derived, Domain)\
+ /**/
+
+ /// INTERNAL ONLY
+ ///
+ #define BOOST_PROTO_EXTENDS_SUBSCRIPT_IMPL_(Expr, Derived, Domain, Const)\
+ template<typename A>\
+ typename boost::mpl::apply_wrap1<Domain, boost::proto::expr<boost::proto::tag::subscript, boost::proto::args<Derived BOOST_PROTO_CONST ## Const &, typename boost::proto::result_of::as_arg<A>::type> > >::type\
+ operator [](A &&a) BOOST_PROTO_CONST ## Const\
+ {\
+ typedef boost::proto::expr<boost::proto::tag::subscript, boost::proto::args<Derived BOOST_PROTO_CONST ## Const &, typename boost::proto::result_of::as_arg<A>::type> > that_type;\
+ that_type that = {{*static_cast<Derived BOOST_PROTO_CONST ## Const *>(this), {boost::proto::result_of::as_arg<A>::call(a)}}};\
+ return Domain::make(that);\
+ }\
+ /**/
+
+ #define BOOST_PROTO_EXTENDS_SUBSCRIPT_CONST(Expr, Derived, Domain)\
+ BOOST_PROTO_EXTENDS_SUBSCRIPT_IMPL_(Expr, Derived, Domain, 1)
+
+ #define BOOST_PROTO_EXTENDS_SUBSCRIPT_NON_CONST(Expr, Derived, Domain)\
+ BOOST_PROTO_EXTENDS_SUBSCRIPT_IMPL_(Expr, Derived, Domain, 0)
+
+ #define BOOST_PROTO_EXTENDS_SUBSCRIPT(Expr, Derived, Domain)\
+ BOOST_PROTO_EXTENDS_SUBSCRIPT_CONST(Expr, Derived, Domain)\
+ BOOST_PROTO_EXTENDS_SUBSCRIPT_NON_CONST(Expr, Derived, Domain)\
+ /**/
+
+ /// INTERNAL ONLY
+ ///
+ #define BOOST_PROTO_EXTENDS_FUNCTION_IMPL_(Expr, Derived, Domain, Const)\
+ template<typename... A>\
+ typename boost::mpl::apply_wrap1<Domain, boost::proto::expr<boost::proto::tag::function, boost::proto::args<Derived BOOST_PROTO_CONST ## Const &, typename boost::proto::result_of::as_arg<A>::type...> > >::type\
+ operator ()(A &&... a) BOOST_PROTO_CONST ## Const\
+ {\
+ typedef boost::proto::expr<boost::proto::tag::function, boost::proto::args<Derived BOOST_PROTO_CONST ## Const &, typename boost::proto::result_of::as_arg<A>::type...> > that_type;\
+ that_type that = {boost::proto::argsns_::make_cons(*static_cast<Derived BOOST_PROTO_CONST ## Const *>(this), boost::proto::result_of::as_arg<A>::call(a)...)};\
+ return Domain::make(that);\
+ }\
+ /**/
+
+ #define BOOST_PROTO_EXTENDS_FUNCTION_CONST(Expr, Derived, Domain)\
+ BOOST_PROTO_EXTENDS_FUNCTION_IMPL_(Expr, Derived, Domain, 1)
+
+ #define BOOST_PROTO_EXTENDS_FUNCTION_NON_CONST(Expr, Derived, Domain)\
+ BOOST_PROTO_EXTENDS_FUNCTION_IMPL_(Expr, Derived, Domain, 0)
+
+ #define BOOST_PROTO_EXTENDS_FUNCTION(Expr, Derived, Domain)\
+ BOOST_PROTO_EXTENDS_FUNCTION_CONST(Expr, Derived, Domain)\
+ BOOST_PROTO_EXTENDS_FUNCTION_NON_CONST(Expr, Derived, Domain)\
+ /**/
+
+ 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_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>
+ struct extends
+ {
+ extends()
+ : expr()
+ {}
+
+ extends(extends const &that)
+ : expr(that.expr)
+ {}
+
+ extends(Expr const &expr_)
+ : expr(expr_)
+ {}
+
+ BOOST_PROTO_EXTENDS(Expr, Derived, Domain)
+ BOOST_PROTO_EXTENDS_ASSIGN(Expr, Derived, Domain)
+ BOOST_PROTO_EXTENDS_SUBSCRIPT(Expr, Derived, Domain)
+ BOOST_PROTO_EXTENDS_FUNCTION(Expr, Derived, Domain)
+ };
+
+ } // namespace exprns_
+
+}}
+
+#endif
Added: branches/proto/v3/boost/xpressive/proto3/fusion.hpp
==============================================================================
--- (empty file)
+++ branches/proto/v3/boost/xpressive/proto3/fusion.hpp 2007-11-07 17:03:47 EST (Wed, 07 Nov 2007)
@@ -0,0 +1,232 @@
+///////////////////////////////////////////////////////////////////////////////
+/// \file fusion.hpp
+/// Make any Proto parse tree a valid Fusion sequence
+//
+// Copyright 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)
+
+#ifndef BOOST_PROTO3_FUSION_HPP_EAN_11_04_2006
+#define BOOST_PROTO3_FUSION_HPP_EAN_11_04_2006
+
+#include <boost/mpl/long.hpp>
+#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/xpressive/proto3/proto_fwd.hpp>
+#include <boost/xpressive/proto3/traits.hpp>
+
+namespace boost { namespace proto
+{
+
+ namespace detail
+ {
+
+ template<typename Expr, long Pos>
+ struct expr_iterator
+ : fusion::iterator_base<expr_iterator<Expr, Pos> >
+ {
+ typedef Expr expr_type;
+ static long const index = Pos;
+ typedef fusion::random_access_traversal_tag category;
+ typedef tag::proto_expr_iterator fusion_tag;
+
+ expr_iterator(Expr const &e)
+ : expr(e)
+ {}
+
+ Expr const &expr;
+ };
+
+ }
+
+}}
+
+namespace boost { namespace fusion
+{
+
+ namespace extension
+ {
+
+ template<typename Tag>
+ struct is_view_impl;
+
+ template<>
+ struct is_view_impl<proto::tag::proto_expr>
+ {
+ template<typename Iterator>
+ 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
+ : proto::result_of::arg_c<
+ typename Iterator::expr_type
+ , Iterator::index
+ >
+ {};
+ };
+
+ 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::arg_c<
+ typename Iterator::expr_type
+ , Iterator::index
+ >::const_reference
+ type;
+
+ static type call(Iterator const &iter)
+ {
+ return proto::arg_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> >
+ {};
+ };
+
+ 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;
+ };
+ };
+
+ 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 ? 1 : Sequence::proto_arity>
+ {};
+ };
+
+ 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 ? 1 : Sequence::proto_arity
+ >
+ type;
+
+ static type call(Sequence const &seq)
+ {
+ return type(seq);
+ }
+ };
+ };
+
+ }
+
+}}
+
+#endif
Added: branches/proto/v3/boost/xpressive/proto3/generate.hpp
==============================================================================
--- (empty file)
+++ branches/proto/v3/boost/xpressive/proto3/generate.hpp 2007-11-07 17:03:47 EST (Wed, 07 Nov 2007)
@@ -0,0 +1,158 @@
+///////////////////////////////////////////////////////////////////////////////
+/// \file generate.hpp
+/// Contains definition of generate\<\> class template, which end users can
+/// specialize for generating domain-specific expression wrappers.
+//
+// Copyright 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)
+
+#ifndef BOOST_PROTO3_GENERATE_HPP_EAN_02_13_2007
+#define BOOST_PROTO3_GENERATE_HPP_EAN_02_13_2007
+
+#include <boost/mpl/long.hpp>
+#include <boost/utility/enable_if.hpp>
+#include <boost/xpressive/proto3/proto_fwd.hpp>
+#include <boost/xpressive/proto3/matches.hpp>
+
+namespace boost { namespace proto
+{
+
+ namespace detail
+ {
+ template<typename Expr>
+ struct arity_;
+
+ template<typename Tag, typename Args, long N>
+ struct arity_<expr<Tag, Args, N> >
+ : mpl::long_<N>
+ {};
+
+ template<typename Expr>
+ struct tag_;
+
+ template<typename Tag, typename Args, long N>
+ struct tag_<expr<Tag, Args, N> >
+ {
+ typedef Tag type;
+ };
+
+ template<typename Expr>
+ struct args_;
+
+ template<typename Tag, typename Args, long N>
+ struct args_<expr<Tag, Args, N> >
+ {
+ typedef Args type;
+ };
+
+ template<typename Expr, long Arity = arity_<Expr>::value>
+ struct by_value_generator_;
+
+ //#define BOOST_PROTO_DEFINE_BY_VALUE_TYPE(Z, N, Expr)\
+ // typename result_of::unref<typename args_<Expr>::type::BOOST_PP_CAT(arg, N) >::type
+
+ //#define BOOST_PROTO_DEFINE_BY_VALUE(Z, N, expr)\
+ // proto::unref(expr.BOOST_PP_CAT(arg, N))
+
+ //#define BOOST_PP_ITERATION_PARAMS_1 (3, (0, BOOST_PROTO_MAX_ARITY, <boost/xpressive/proto/generate.hpp>))
+ //#include BOOST_PP_ITERATE()
+
+ //#undef BOOST_PROTO_DEFINE_BY_VALUE
+ //#undef BOOST_PROTO_DEFINE_BY_VALUE_TYPE
+
+ // template<typename Expr>
+ // struct by_value_generator_<Expr, N>
+ // {
+ // typedef expr<
+ // typename tag_<Expr>::type
+ // , BOOST_PP_CAT(args, N)<
+ // // typename result_of::unref<typename args_<Expr>::type::arg0>::type, ...
+ // BOOST_PP_ENUM(BOOST_PP_MAX(N, 1), BOOST_PROTO_DEFINE_BY_VALUE_TYPE, Expr)
+ // >
+ // > type;
+
+ // static type const make(Expr const &expr)
+ // {
+ // type that = {
+ // // proto::unref(expr.arg0), ...
+ // BOOST_PP_ENUM(BOOST_PP_MAX(N, 1), BOOST_PROTO_DEFINE_BY_VALUE, expr)
+ // };
+ // return that;
+ // }
+ // };
+
+ }
+
+ namespace generatorns_
+ {
+ struct default_generator
+ {
+ template<typename Expr>
+ struct apply
+ {
+ typedef Expr type;
+ };
+
+ template<typename Expr>
+ static Expr const &make(Expr const &expr)
+ {
+ return expr;
+ }
+ };
+
+ template<template<typename> class Extends>
+ struct generator
+ {
+ template<typename Expr>
+ struct apply
+ {
+ typedef Extends<Expr> type;
+ };
+
+ template<typename Expr>
+ static Extends<Expr> make(Expr const &expr)
+ {
+ return Extends<Expr>(expr);
+ }
+ };
+
+ template<template<typename> class Extends>
+ struct pod_generator
+ {
+ template<typename Expr>
+ struct apply
+ {
+ typedef Extends<Expr> type;
+ };
+
+ template<typename Expr>
+ static Extends<Expr> make(Expr const &expr)
+ {
+ Extends<Expr> that = {expr};
+ return that;
+ }
+ };
+
+ template<typename Generator>
+ struct by_value_generator
+ {
+ template<typename Expr>
+ struct apply
+ : Generator::template apply<
+ typename proto::detail::by_value_generator_<Expr>::type
+ >
+ {};
+
+ template<typename Expr>
+ static typename apply<Expr>::type make(Expr const &expr)
+ {
+ return Generator::make(proto::detail::by_value_generator_<Expr>::make(expr));
+ }
+ };
+
+ }
+
+}}
+
+#endif // BOOST_PROTO3_GENERATE_HPP_EAN_02_13_2007
Added: branches/proto/v3/boost/xpressive/proto3/literal.hpp
==============================================================================
--- (empty file)
+++ branches/proto/v3/boost/xpressive/proto3/literal.hpp 2007-11-07 17:03:47 EST (Wed, 07 Nov 2007)
@@ -0,0 +1,75 @@
+///////////////////////////////////////////////////////////////////////////////
+/// \file literal.hpp
+/// The literal\<\> terminal wrapper, and the proto::lit() function for
+/// creating literal\<\> wrappers.
+//
+// Copyright 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)
+
+#ifndef BOOST_PROTO3_LITERAL_HPP_EAN_01_03_2007
+#define BOOST_PROTO3_LITERAL_HPP_EAN_01_03_2007
+
+#include <boost/xpressive/proto3/proto_fwd.hpp>
+#include <boost/xpressive/proto3/expr.hpp>
+#include <boost/xpressive/proto3/traits.hpp>
+#include <boost/xpressive/proto3/extends.hpp>
+
+namespace boost { namespace proto
+{
+ namespace utility
+ {
+ template<typename T, typename Domain>
+ struct literal
+ : extends<typename terminal<T>::type, literal<T, Domain>, Domain>
+ {
+ typedef typename terminal<T>::type terminal_type;
+ typedef extends<terminal_type, literal<T, Domain>, Domain> base_type;
+
+ 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(proto::arg(u)))
+ {}
+
+ using base_type::operator =;
+ };
+ }
+
+ /// lit
+ ///
+ template<typename T>
+ inline literal<T &> lit(T &t)
+ {
+ return literal<T &>(t);
+ }
+
+ /// \overload
+ ///
+ template<typename T>
+ inline literal<T const &> lit(T const &t)
+ {
+ #ifdef _MSC_VER
+ #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 _MSC_VER
+ #pragma warning(pop)
+ #endif
+ }
+
+}}
+
+#endif
Added: branches/proto/v3/boost/xpressive/proto3/matches.hpp
==============================================================================
--- (empty file)
+++ branches/proto/v3/boost/xpressive/proto3/matches.hpp 2007-11-07 17:03:47 EST (Wed, 07 Nov 2007)
@@ -0,0 +1,552 @@
+///////////////////////////////////////////////////////////////////////////////
+/// \file matches.hpp
+/// Contains definition of the matches\<\> meta-function.
+//
+// Copyright 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)
+
+#ifndef BOOST_PROTO3_MATCHES_HPP_EAN_10_28_2007
+#define BOOST_PROTO3_MATCHES_HPP_EAN_10_28_2007
+
+#include <boost/mpl/if.hpp>
+#include <boost/mpl/bool.hpp>
+#include <boost/mpl/apply.hpp>
+#include <boost/mpl/assert.hpp>
+#include <boost/mpl/identity.hpp>
+#include <boost/type_traits.hpp>
+#include <boost/xpressive/proto3/proto_fwd.hpp>
+#include <boost/xpressive/proto3/transform/arg.hpp>
+
+// BUGBUG
+#include <boost/mpl/aux_/template_arity.hpp>
+#include <boost/mpl/aux_/lambda_arity_param.hpp>
+
+#define UNREF(X) \
+ typename remove_reference<X>::type
+
+#define UNCVREF(X) \
+ typename remove_cv<UNREF(X)>::type
+
+namespace boost { namespace proto
+{
+
+ namespace wildns_
+ {
+ struct _ : _expr
+ {
+ typedef _ proto_base_expr;
+ };
+ }
+
+ namespace result_of
+ {
+
+ namespace detail
+ {
+ template<typename Expr, typename Grammar>
+ struct matches_;
+
+ template<bool Head, typename... Preds>
+ struct and_
+ : mpl::bool_<Head>
+ {};
+
+ template<typename Head, typename... Preds>
+ struct and_<true, Head, Preds...>
+ : and_<Head::value, Preds...>
+ {};
+
+ template<typename Head>
+ struct and_<true, Head>
+ : Head
+ {};
+
+ template<bool Head, typename... Preds>
+ struct or_
+ : mpl::bool_<Head>
+ {};
+
+ template<typename Head, typename... Preds>
+ struct or_<false, Head, Preds...>
+ : or_<Head::value, Preds...>
+ {};
+
+ template<typename Head>
+ struct or_<false, Head>
+ : Head
+ {};
+
+ template<typename T, typename U
+ BOOST_MPL_AUX_LAMBDA_ARITY_PARAM(long Arity = mpl::aux::template_arity<U>::value)
+ >
+ struct lambda_matches;
+
+ template<typename T, typename U>
+ struct lambda_matches_aux_
+ : mpl::false_
+ {};
+
+ template<
+ template<typename, typename...> class T
+ , typename E0, typename... ET
+ , typename G0, typename... GT
+ >
+ struct lambda_matches_aux_<T<E0, ET...>, T<G0, GT...> >
+ : and_<
+ lambda_matches<E0, G0>::value
+ , lambda_matches<ET, GT>...
+ >
+ {};
+
+ template<typename T, typename U BOOST_MPL_AUX_LAMBDA_ARITY_PARAM(long Arity)>
+ struct lambda_matches
+ : lambda_matches_aux_<T, U>
+ {};
+
+ template<typename T, typename U>
+ struct lambda_matches<T, U BOOST_MPL_AUX_LAMBDA_ARITY_PARAM(-1)>
+ : mpl::false_
+ {};
+
+ template<typename T>
+ struct lambda_matches<T, _ 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_
+ {};
+
+ // How terminal_matches<> handles references and cv-qualifiers.
+ // The cv and ref matter *only* if the grammar has a top-level ref.
+ //
+ // Expr | Grammar | Match
+ // ------------------------------
+ // 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>
+ {};
+
+ // terminal_matches
+ template<typename T, typename U>
+ struct terminal_matches
+ : and_<
+ is_cv_ref_compatible<T, U>::value
+ , lambda_matches<UNCVREF(T), 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_
+ {};
+
+ 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, _>
+ : mpl::true_
+ {};
+
+ template<typename T>
+ struct terminal_matches<T, exact<T> >
+ : mpl::true_
+ {};
+
+ template<typename T, typename U>
+ struct terminal_matches<T, convertible_to<U> >
+ : is_convertible<T, U>
+ {};
+
+ template<bool True, typename Cons1, typename Cons2>
+ struct nonterminal_matches;
+
+ template<typename Head1, typename... Tail1, typename Head2, typename... Tail2>
+ struct nonterminal_matches<true, args<Head1, Tail1...>, args<Head2, Tail2...> >
+ : nonterminal_matches<
+ matches_<
+ UNREF(Head1)::proto_base_expr
+ , UNREF(Head2)::proto_base_expr
+ >::value
+ , args<Tail1...>
+ , args<Tail2...>
+ >
+ {};
+
+ template<typename Cons1, typename Cons2>
+ struct nonterminal_matches<false, Cons1, Cons2>
+ : mpl::false_
+ {};
+
+ template<>
+ struct nonterminal_matches<true, args<>, args<> >
+ : mpl::true_
+ {};
+
+ template<
+ typename Args1
+ , typename Args2
+ , bool IsVararg = control::detail::is_vararg<typename back<Args2>::type>::value
+ >
+ struct vararg_matches
+ : mpl::false_
+ {};
+
+ template<typename Head1, typename... Tail1, typename Head2, typename... Tail2>
+ struct vararg_matches<args<Head1, Tail1...>, args<Head2, Tail2...>, true>
+ : and_<
+ matches_<
+ UNREF(Head1)::proto_base_expr
+ , UNREF(Head2)::proto_base_expr
+ >::value
+ , vararg_matches<
+ args<Tail1...>
+ , args<Tail2...>
+ , true
+ >
+ >
+ {};
+
+ template<typename Head1, typename... Tail1, typename Head2>
+ struct vararg_matches<args<Head1, Tail1...>, args<Head2>, true>
+ : and_<
+ matches_<
+ UNREF(Head1)::proto_base_expr
+ , UNREF(Head2)::proto_base_expr
+ >::value
+ , vararg_matches<
+ args<Tail1...>
+ , args<Head2>
+ , true
+ >
+ >
+ {};
+
+ template<typename Head2>
+ struct vararg_matches<args<>, args<Head2>, true>
+ : mpl::true_
+ {};
+
+ template<typename Expr, typename Grammar>
+ struct matches_
+ : mpl::false_
+ {};
+
+ template<typename Expr>
+ struct matches_<Expr, _>
+ : mpl::true_
+ {};
+
+ template<
+ typename Tag1
+ , typename Head1
+ , typename... Tail1
+ , long N
+ , typename Head2
+ , typename... Tail2
+ >
+ struct matches_<expr<Tag1, args<Head1, Tail1...>, N>, expr<Tag1, args<Head2, Tail2...>, N> >
+ : nonterminal_matches<
+ matches_<
+ UNREF(Head1)::proto_base_expr
+ , UNREF(Head2)::proto_base_expr
+ >::value
+ , args<Tail1...>
+ , args<Tail2...>
+ >
+ {};
+
+ template<
+ typename Tag1
+ , typename Head1
+ , typename... Tail1
+ , long N
+ , typename Head2
+ , typename... Tail2
+ >
+ struct matches_<expr<Tag1, args<Head1, Tail1...>, N>, expr<_, args<Head2, Tail2...>, N> >
+ : nonterminal_matches<
+ matches_<
+ UNREF(Head1)::proto_base_expr
+ , UNREF(Head2)::proto_base_expr
+ >::value
+ , args<Tail1...>
+ , args<Tail2...>
+ >
+ {};
+
+ template<typename Arg1, typename Arg2>
+ struct matches_<expr<tag::terminal, term<Arg1>, 0>, expr<tag::terminal, term<Arg2>, 0> >
+ : terminal_matches<Arg1, Arg2>
+ {};
+
+ template<typename Tag1, typename Args1, long N1, typename Args2, long N2>
+ struct matches_<expr<Tag1, Args1, N1>, expr<Tag1, Args2, N2> >
+ : vararg_matches<Args1, Args2>
+ {};
+
+ template<typename Tag1, typename Args1, long N1, typename Args2, long N2>
+ struct matches_<expr<Tag1, Args1, N1>, expr<_, Args2, N2> >
+ : vararg_matches<Args1, Args2>
+ {};
+
+ // handle proto::or_
+ template<typename Expr, typename Head, typename... Tail>
+ struct matches_<Expr, proto::or_<Head, Tail...> >
+ : or_<
+ matches_<
+ typename Expr::proto_base_expr
+ , typename Head::proto_base_expr
+ >::value
+ , matches_<
+ typename Expr::proto_base_expr
+ , typename Tail::proto_base_expr
+ >...
+ >
+ {};
+
+ // handle proto::and_
+ template<typename Expr, typename Head, typename... Tail>
+ struct matches_<Expr, proto::and_<Head, Tail...> >
+ : and_<
+ matches_<
+ typename Expr::proto_base_expr
+ , typename Head::proto_base_expr
+ >::value
+ , matches_<
+ typename Expr::proto_base_expr
+ , typename Tail::proto_base_expr
+ >...
+ >
+ {};
+
+ // handle proto::if_
+ template<typename Expr, typename Condition>
+ struct matches_<Expr, proto::if_<Condition> >
+ : mpl::apply1<Condition, Expr>::type
+ {};
+
+ // handle proto::not_
+ template<typename Expr, typename Grammar>
+ struct matches_<Expr, proto::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
+ >
+ {};
+
+ }
+
+ template<typename Expr, typename Grammar>
+ struct matches
+ : detail::matches_<
+ typename Expr::proto_base_expr
+ , typename Grammar::proto_base_expr
+ >
+ {};
+
+ }
+
+ namespace control
+ {
+ namespace detail
+ {
+ template<typename T, typename EnableIf>
+ struct is_vararg
+ : mpl::false_
+ {};
+
+ template<typename T>
+ struct is_vararg<T, typename T::proto_is_vararg_>
+ : mpl::true_
+ {};
+
+ template<typename Expr, typename... Alts>
+ struct which;
+
+ template<typename Expr, typename Head, typename... Tail>
+ struct which<Expr, Head, Tail...>
+ : mpl::if_<
+ matches<Expr, Head>
+ , mpl::identity<Head>
+ , which<Expr, Tail...>
+ >::type
+ {};
+
+ } // namespace detail
+
+ template<typename... Alts>
+ struct or_ : raw_transform
+ {
+ typedef or_ proto_base_expr;
+
+ template<typename Expr, typename State, typename Visitor>
+ struct apply
+ {
+ typedef typename detail::which<Expr, Alts...>::type
+ ::template apply<Expr, State, Visitor>::type type;
+ };
+
+ template<typename Expr, typename State, typename Visitor>
+ static typename apply<Expr, State, Visitor>::type
+ call(Expr const &expr, State const &state, Visitor &visitor)
+ {
+ return detail::which<Expr, Alts...>::type::call(expr, state, visitor);
+ }
+ };
+
+ template<typename... Alts>
+ struct and_ : back<args<Alts...> >::type
+ {
+ typedef and_ proto_base_expr;
+ };
+
+ // if_
+ template<typename Condition, typename Then, typename Else>
+ struct if_
+ : or_<
+ and_<if_<Condition>, Then>
+ , and_<not_<if_<Condition> >, Else>
+ >
+ {};
+
+ template<typename Condition, typename Then>
+ struct if_<Condition, Then, void>
+ : and_<if_<Condition>, Then>
+ {};
+
+ template<typename Condition>
+ struct if_<Condition, void, void> : _expr
+ {
+ typedef if_ proto_base_expr;
+ };
+
+ template<typename Grammar>
+ struct not_ : _expr
+ {
+ typedef not_ proto_base_expr;
+ };
+
+ template<typename Cases>
+ struct switch_
+ {
+ typedef switch_ proto_base_expr;
+
+ template<typename Expr, typename State, typename Visitor>
+ struct apply
+ : Cases::template case_<typename Expr::proto_tag>::template apply<Expr, State, Visitor>
+ {};
+
+ template<typename Expr, typename State, typename Visitor>
+ static typename apply<Expr, State, Visitor>::type
+ call(Expr const &expr, State const &state, Visitor &visitor)
+ {
+ return Cases::template case_<typename Expr::proto_tag>::call(expr, state, visitor);
+ }
+ };
+
+ template<typename T>
+ struct exact
+ {};
+
+ template<typename T>
+ struct convertible_to
+ {};
+
+ template<typename Grammar>
+ struct vararg
+ : Grammar
+ {
+ typedef void proto_is_vararg_;
+ };
+
+ }
+
+ template<typename... Args>
+ struct transform_category<or_<Args...> >
+ {
+ typedef raw_transform type;
+ };
+
+ template<typename... Args>
+ struct transform_category<and_<Args...> >
+ {
+ typedef raw_transform type;
+ };
+
+ template<typename Grammar>
+ struct transform_category<not_<Grammar> >
+ {
+ typedef raw_transform type;
+ };
+
+ template<typename If, typename Then, typename Else>
+ struct transform_category<if_<If, Then, Else> >
+ {
+ typedef raw_transform type;
+ };
+
+ template<typename Grammar>
+ struct transform_category<vararg<Grammar> >
+ {
+ typedef raw_transform type;
+ };
+
+ template<>
+ struct transform_category<_>
+ {
+ typedef raw_transform type;
+ };
+
+}}
+
+#undef UNREF
+#undef UNCVREF
+
+#endif
Added: branches/proto/v3/boost/xpressive/proto3/operators.hpp
==============================================================================
--- (empty file)
+++ branches/proto/v3/boost/xpressive/proto3/operators.hpp 2007-11-07 17:03:47 EST (Wed, 07 Nov 2007)
@@ -0,0 +1,180 @@
+///////////////////////////////////////////////////////////////////////////////
+/// \file operators.hpp
+/// Contains the definition of proto's operator overloads
+//
+// Copyright 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)
+
+#ifndef BOOST_PROTO3_OPERATORS_HPP_EAN_10_28_2007
+#define BOOST_PROTO3_OPERATORS_HPP_EAN_10_28_2007
+
+#include <boost/mpl/logical.hpp>
+#include <boost/utility/enable_if.hpp>
+#include <boost/preprocessor/punctuation/comma.hpp>
+#include <boost/xpressive/proto3/proto_fwd.hpp>
+
+#define UNREF(X) typename remove_reference<X>::type
+
+namespace boost { namespace proto
+{
+
+ namespace exprns_
+ {
+ namespace detail
+ {
+ template<bool Pred, typename Domain, typename Expr>
+ struct generate_if
+ {};
+
+ template<typename Domain, typename Expr>
+ struct generate_if<true, Domain, Expr>
+ : lazy_enable_if<
+ matches<Expr, typename Domain::grammar>
+ , typename Domain::template apply<Expr>
+ >
+ {};
+
+ template<typename Expr>
+ struct generate_if<true, default_domain, Expr>
+ {
+ typedef Expr type;
+ };
+
+ template<
+ typename A
+ , typename B
+ , typename DA = typename domain_of<A>::type
+ , typename DB = typename domain_of<B>::type
+ >
+ struct unify_domain
+ {};
+
+ template<typename A, typename B, typename D>
+ struct unify_domain<A, B, D, D>
+ {
+ typedef D type;
+ };
+
+ template<typename A, typename B, typename D>
+ struct unify_domain<A, B, default_domain, D>
+ {
+ typedef D type;
+ };
+
+ template<typename A, typename B, typename D>
+ struct unify_domain<A, B, D, default_domain>
+ {
+ typedef D type;
+ };
+
+ template<typename A, typename B>
+ struct unify_domain<A, B, default_domain, default_domain>
+ {
+ typedef default_domain type;
+ };
+
+ }
+
+ #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 A> \
+ typename detail::generate_if< \
+ true \
+ , UNREF(A)::proto_domain \
+ , expr<TAG, args< \
+ typename result_of::as_arg<A, UNREF(A)::proto_domain>::type \
+ > > \
+ >::type \
+ operator OP(A &&a BOOST_PROTO_UNARY_OP_IS_POSTFIX_ ## POST) \
+ { \
+ typedef UNREF(A)::proto_domain D; \
+ expr<TAG, args< \
+ typename result_of::as_arg<A, D>::type \
+ > > that = {{proto::as_arg<D>(std::forward<A>(a))}}; \
+ return that; \
+ } \
+ /**/
+
+ #define BOOST_PROTO_DEFINE_BINARY_OPERATOR(OP, TAG) \
+ template<typename A, typename B> \
+ typename detail::generate_if< \
+ result_of::is_expr<A>::value || result_of::is_expr<B>::value \
+ , typename detail::unify_domain<A, B>::type \
+ , expr<TAG, args< \
+ typename result_of::as_arg<A, typename detail::unify_domain<A, B>::type>::type\
+ , typename result_of::as_arg<B, typename detail::unify_domain<A, B>::type>::type\
+ > > \
+ >::type \
+ operator OP(A &&a, B &&b) \
+ { \
+ typedef typename detail::unify_domain<A, B>::type D; \
+ expr<TAG, args< \
+ typename result_of::as_arg<A, D>::type \
+ , typename result_of::as_arg<B, D>::type \
+ > > that = {{ \
+ proto::as_arg<D>(std::forward<A>(a)) \
+ , {proto::as_arg<D>(std::forward<B>(b))} \
+ }}; \
+ return that; \
+ } \
+ /**/
+
+ BOOST_PROTO_DEFINE_UNARY_OPERATOR(+, tag::posit, 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)
+
+ #undef BOOST_PROTO_UNARY_OP_IS_POSTFIX_0
+ #undef BOOST_PROTO_UNARY_OP_IS_POSTFIX_1
+
+ #undef BOOST_PROTO_DEFINE_UNARY_OPERATOR
+ #undef BOOST_PROTO_DEFINE_BINARY_OPERATOR
+
+ }
+
+}}
+
+#undef UNREF
+
+#endif
Added: branches/proto/v3/boost/xpressive/proto3/proto.hpp
==============================================================================
--- (empty file)
+++ branches/proto/v3/boost/xpressive/proto3/proto.hpp 2007-11-07 17:03:47 EST (Wed, 07 Nov 2007)
@@ -0,0 +1,27 @@
+///////////////////////////////////////////////////////////////////////////////
+/// \file proto.hpp
+/// Includes all of proto.
+//
+// Copyright 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)
+
+#ifndef BOOST_PROTO3_PROTO_EAN_10_28_2007
+#define BOOST_PROTO3_PROTO_EAN_10_28_2007
+
+#include <boost/xpressive/proto3/proto_fwd.hpp>
+#include <boost/xpressive/proto3/args.hpp>
+#include <boost/xpressive/proto3/tags.hpp>
+#include <boost/xpressive/proto3/eval.hpp>
+#include <boost/xpressive/proto3/expr.hpp>
+#include <boost/xpressive/proto3/traits.hpp>
+#include <boost/xpressive/proto3/domain.hpp>
+#include <boost/xpressive/proto3/extends.hpp>
+#include <boost/xpressive/proto3/literal.hpp>
+#include <boost/xpressive/proto3/generate.hpp>
+#include <boost/xpressive/proto3/operators.hpp>
+#include <boost/xpressive/proto3/matches.hpp>
+#include <boost/xpressive/proto3/transform.hpp>
+#include <boost/xpressive/proto3/fusion.hpp>
+
+#endif
Added: branches/proto/v3/boost/xpressive/proto3/proto_fwd.hpp
==============================================================================
--- (empty file)
+++ branches/proto/v3/boost/xpressive/proto3/proto_fwd.hpp 2007-11-07 17:03:47 EST (Wed, 07 Nov 2007)
@@ -0,0 +1,416 @@
+///////////////////////////////////////////////////////////////////////////////
+/// \file proto_fwd.hpp
+/// Contains proto's forward declarations
+//
+// Copyright 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)
+
+#ifndef BOOST_PROTO3_PROTO_FWD_EAN_10_28_2007
+#define BOOST_PROTO3_PROTO_FWD_EAN_10_28_2007
+
+#include <climits> // for INT_MAX
+
+// BUGBUG
+#define BOOST_PROTO_MAX_ARITY 5
+
+namespace boost { namespace proto
+{
+ namespace wildns_
+ {
+ struct _;
+ }
+
+ using wildns_::_;
+
+ namespace generatorns_
+ {
+ struct default_generator;
+
+ template<template<typename> class Extends>
+ struct generator;
+
+ template<template<typename> class Extends>
+ struct pod_generator;
+
+ template<typename Generator = default_generator>
+ struct by_value_generator;
+ }
+
+ using generatorns_::default_generator;
+ using generatorns_::generator;
+ using generatorns_::pod_generator;
+ using generatorns_::by_value_generator;
+
+ namespace domainns_
+ {
+ template<typename Generator = default_generator, typename Grammar = proto::_>
+ struct domain;
+
+ struct default_domain;
+
+ struct deduce_domain;
+ }
+
+ using domainns_::domain;
+ using domainns_::default_domain;
+ using domainns_::deduce_domain;
+
+ namespace argsns_
+ {
+ template<typename... Args>
+ struct cons;
+
+ template<typename... Args>
+ struct args;
+
+ template<typename Arg>
+ struct term;
+
+ template<typename Args>
+ struct back;
+ }
+
+ using argsns_::args;
+ using argsns_::term;
+ using argsns_::back;
+
+ namespace exprns_
+ {
+ template<typename Tag, typename Args, long Arity = Args::size>
+ struct expr;
+
+ template<typename Expr, typename Derived, typename Domain = default_domain>
+ struct extends;
+
+ struct is_proto_expr;
+ }
+
+ using exprns_::expr;
+ using exprns_::extends;
+ using exprns_::is_proto_expr;
+
+ namespace tag
+ {
+ struct terminal;
+ struct posit;
+ 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;
+
+ struct proto_expr;
+ struct proto_expr_iterator;
+ }
+
+ namespace utility
+ {
+ template<typename T, typename Domain = default_domain>
+ struct literal;
+ }
+
+ using utility::literal;
+
+ namespace result_of
+ {
+ namespace detail
+ {
+ template<typename Args, long N>
+ struct arg_c;
+ }
+
+ template<typename Expr>
+ struct tag_of
+ {
+ typedef typename Expr::proto_tag type;
+ };
+
+ template<typename Expr, long N>
+ struct arg_c;
+
+ template<typename Expr>
+ struct left;
+
+ template<typename Expr>
+ struct right;
+
+ template<typename T, typename Domain = default_domain, typename EnableIf = void>
+ struct as_expr;
+
+ template<typename T, typename Domain = default_domain, typename EnableIf = void>
+ struct as_arg;
+
+ template<typename T, typename EnableIf = void>
+ struct is_expr;
+
+ template<typename Expr, typename Grammar>
+ struct matches;
+
+ template<typename T, typename EnableIf = void>
+ struct is_domain;
+
+ template<typename T, typename EnableIf = void>
+ struct domain_of;
+ }
+
+ using result_of::matches;
+ using result_of::tag_of;
+ using result_of::is_domain;
+ using result_of::domain_of;
+
+ template<long N, typename Expr>
+ typename result_of::arg_c<Expr, N>::reference
+ arg_c(Expr &expr);
+
+ template<long N, typename Expr>
+ typename result_of::arg_c<Expr, N>::const_reference
+ arg_c(Expr const &expr);
+
+ template<typename T>
+ typename result_of::as_arg<T>::type
+ as_arg(T &&t);
+
+ namespace op
+ {
+ // BUGBUG move this elsewhere
+ namespace detail
+ {
+ template<int... I>
+ struct indices;
+
+ template<int N, typename T = indices<> >
+ struct make_indices;
+ }
+
+ template<typename T> struct terminal;
+ template<typename T> struct posit;
+ 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<typename... Args> struct function;
+ template<typename Tag, typename T> struct unary_expr;
+ template<typename Tag, typename T, typename U> struct binary_expr;
+ template<typename Tag, typename... Args> struct nary_expr;
+ }
+
+ using namespace op;
+
+ namespace control
+ {
+ namespace detail
+ {
+ template<typename T, typename EnableIf = void>
+ struct is_vararg;
+ }
+
+ template<typename... Alts>
+ struct or_;
+
+ template<typename... Alts>
+ struct and_;
+
+ template<typename Condition, typename Then = void, typename Else = void>
+ struct if_;
+
+ template<typename Cases>
+ struct switch_;
+
+ template<typename Grammar>
+ struct not_;
+
+ template<typename T>
+ struct exact;
+
+ template<typename T>
+ struct convertible_to;
+
+ template<typename Grammar>
+ struct vararg;
+
+ int const N = INT_MAX;
+ }
+
+ using control::or_;
+ using control::and_;
+ using control::if_;
+ using control::not_;
+ using control::switch_;
+ using control::exact;
+ using control::convertible_to;
+ using control::vararg;
+ using control::N;
+
+ template<typename T>
+ struct transform_category;
+
+ namespace transform
+ {
+ // Transforms can be of these 3 types
+ struct no_transform
+ {};
+
+ struct raw_transform
+ {
+ typedef void proto_raw_transform_;
+ };
+
+ struct function_transform
+ {
+ typedef void proto_function_transform_;
+ };
+
+ template<typename Fun, typename... Args>
+ struct bind;
+
+ template<typename Trans, typename... Args>
+ struct apply_;
+
+ 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, typename Fun = Grammar>
+ struct case_;
+
+ template<typename Trans>
+ struct typeof_;
+
+ struct _expr;
+ struct _state;
+ struct _visitor;
+ }
+
+ using transform::case_;
+ using transform::typeof_;
+ using transform::_expr;
+ using transform::_state;
+ using transform::_visitor;
+ using transform::bind;
+ using transform::fold;
+ using transform::reverse_fold;
+ using transform::fold_tree;
+ using transform::reverse_fold_tree;
+ using transform::no_transform;
+ using transform::raw_transform;
+ using transform::function_transform;
+
+ 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>
+ struct default_eval;
+
+ template<typename Derived, typename DefaultCtx = default_context>
+ struct callable_context;
+
+ template<typename Expr, typename Context,
+ typename Indices = typename op::detail::make_indices<
+ Expr::proto_arity == 0 ? 1 : Expr::proto_arity
+ >::type
+ >
+ 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;
+
+}}
+
+#endif
Added: branches/proto/v3/boost/xpressive/proto3/tags.hpp
==============================================================================
--- (empty file)
+++ branches/proto/v3/boost/xpressive/proto3/tags.hpp 2007-11-07 17:03:47 EST (Wed, 07 Nov 2007)
@@ -0,0 +1,73 @@
+///////////////////////////////////////////////////////////////////////////////
+/// \file tags.hpp
+/// Contains definition of operator tag types.
+//
+// Copyright 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)
+
+#ifndef BOOST_PROTO3_TAGS_HPP_EAN_10_28_2007
+#define BOOST_PROTO3_TAGS_HPP_EAN_10_28_2007
+
+#include <boost/xpressive/proto3/proto_fwd.hpp>
+
+namespace boost { namespace proto
+{
+
+ namespace tags
+ {
+
+ struct terminal {};
+ struct posit {};
+ 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 {};
+
+ // For fusion
+ struct proto_expr {};
+ struct proto_expr_iterator {};
+ }
+
+}}
+
+#endif
Added: branches/proto/v3/boost/xpressive/proto3/traits.hpp
==============================================================================
--- (empty file)
+++ branches/proto/v3/boost/xpressive/proto3/traits.hpp 2007-11-07 17:03:47 EST (Wed, 07 Nov 2007)
@@ -0,0 +1,492 @@
+///////////////////////////////////////////////////////////////////////////////
+/// \file traits.hpp
+/// Definition of the (meta-)functions for querying for expression tree properties.
+//
+// Copyright 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)
+
+#ifndef BOOST_PROTO3_TRAITS_HPP_EAN_10_28_2007
+#define BOOST_PROTO3_TRAITS_HPP_EAN_10_28_2007
+
+#include <boost/type_traits.hpp>
+#include <boost/mpl/logical.hpp>
+#include <boost/xpressive/proto3/proto_fwd.hpp>
+
+#define CV(T)\
+ typename add_const<T>::type
+
+#define REF(T)\
+ typename add_reference<T>::type
+
+#define CVREF(T)\
+ REF(CV(T))
+
+#define UNREF(T)\
+ typename remove_reference<T>::type
+
+#define UNCVREF(T)\
+ typename remove_cv<UNREF(T)>::type
+
+namespace boost { namespace proto
+{
+
+ namespace op
+ {
+
+ namespace detail
+ {
+
+ template<typename Args, int N, typename Result = args<>, bool Done = (N == 0) >
+ struct resize;
+
+ template<typename Head, typename... Tail, int N, typename... Result>
+ struct resize<args<Head, Tail...>, N, args<Result...>, false>
+ : resize<args<Tail...>, N-1, args<Result..., Head> >
+ {};
+
+ template<typename... Args, typename... Result>
+ struct resize<args<Args...>, 0, args<Result...>, true>
+ {
+ typedef args<Result...> type;
+ };
+
+ template<int... I>
+ struct indices
+ {};
+
+ template<int N, int... I>
+ struct make_indices<N, indices<I...> >
+ : make_indices<N-1, indices<N-1, I...> >
+ {};
+
+ template<int... I>
+ struct make_indices<0, indices<I...> >
+ {
+ typedef indices<I...> type;
+ };
+
+ template<typename G, typename E, typename S, typename V
+ , long GN = G::size, long EN = E::size, bool B = (GN > EN)>
+ struct apply_args;
+
+ template<typename... G, typename... E, typename S, typename V, long GN, long EN>
+ struct apply_args<args<G...>, args<E...>, S, V, GN, EN, false>
+ : apply_args<args<G..., typename back<args<G...> >::type>, args<E...>, S, V>
+ {};
+
+ template<typename... G, typename... E, typename S, typename V, long GN, long EN>
+ struct apply_args<args<G...>, args<E...>, S, V, GN, EN, true>
+ : apply_args<typename resize<args<G...>, EN>::type, args<E...>, S, V>
+ {};
+
+ template<typename... G, typename... E, typename S, typename V, long N>
+ struct apply_args<args<G...>, args<E...>, S, V, N, N, false>
+ {
+ typedef args<
+ typename G::template apply<UNCVREF(E), S, V>::type...
+ > type;
+
+ static typename type::cons_type
+ call(argsns_::cons<E...> const &a, S const &s, V &v)
+ {
+ return apply_args::call_(a, s, v, typename make_indices<sizeof...(E)>::type());
+ }
+
+ template<int... I>
+ static typename type::cons_type
+ call_(argsns_::cons<E...> const &a, S const &s, V &v, indices<I...>)
+ {
+ using result_of::detail::arg_c;
+ typename type::cons_type that = {
+ G::call(arg_c<argsns_::cons<E...>, I>::call(a), s, v)...
+ };
+ return that;
+ }
+ };
+ }
+
+ template<typename T>
+ struct terminal
+ {
+ typedef expr<tag::terminal, term<T> > type;
+ typedef type proto_base_expr;
+
+ template<typename Expr, typename, typename>
+ struct apply
+ {
+ typedef Expr type;
+ };
+
+ template<typename Expr, typename State, typename Visitor>
+ static Expr const &
+ call(Expr const &expr, State const &, Visitor &)
+ {
+ return expr;
+ }
+ };
+
+ template<typename Tag, typename T>
+ struct unary_expr
+ {
+ typedef expr<Tag, args<T> > type;
+ typedef type proto_base_expr;
+
+ template<typename Expr, typename State, typename Visitor>
+ struct apply
+ {
+ typedef expr<typename Expr::proto_tag, args<
+ typename T::template apply<
+ typename result_of::arg_c<Expr, 0>::type, State, Visitor
+ >::type
+ > > type;
+ };
+
+ template<typename Expr, typename State, typename Visitor>
+ static typename apply<Expr, State, Visitor>::type
+ call(Expr const &expr, State const &state, Visitor &visitor)
+ {
+ typename apply<Expr, State, Visitor>::type that = {
+ T::call(proto::arg_c<0>(expr), state, visitor)
+ };
+ return that;
+ }
+ };
+
+ template<typename Tag, typename T, typename U>
+ struct binary_expr
+ {
+ typedef expr<Tag, args<T, U> > type;
+ typedef type proto_base_expr;
+
+ template<typename Expr, typename State, typename Visitor>
+ struct apply
+ {
+ typedef expr<typename Expr::proto_tag, args<
+ typename T::template apply<typename result_of::arg_c<Expr, 0>::type, State, Visitor>::type
+ , typename U::template apply<typename result_of::arg_c<Expr, 1>::type, State, Visitor>::type
+ > > type;
+ };
+
+ template<typename Expr, typename State, typename Visitor>
+ static typename apply<Expr, State, Visitor>::type
+ call(Expr const &expr, State const &state, Visitor &visitor)
+ {
+ typename apply<Expr, State, Visitor>::type that = {
+ T::call(proto::arg_c<0>(expr), state, visitor)
+ , U::call(proto::arg_c<1>(expr), state, visitor)
+ };
+ return that;
+ }
+ };
+
+ template<typename T> struct posit : unary_expr<tag::posit, T> {};
+ template<typename T> struct negate : unary_expr<tag::negate, T> {};
+ template<typename T> struct dereference : unary_expr<tag::dereference, T> {};
+ template<typename T> struct complement : unary_expr<tag::complement, T> {};
+ template<typename T> struct address_of : unary_expr<tag::address_of, T> {};
+ template<typename T> struct logical_not : unary_expr<tag::logical_not, T> {};
+ template<typename T> struct pre_inc : unary_expr<tag::pre_inc, T> {};
+ template<typename T> struct pre_dec : unary_expr<tag::pre_dec, T> {};
+ template<typename T> struct post_inc : unary_expr<tag::post_inc, T> {};
+ template<typename T> struct post_dec : unary_expr<tag::post_dec, T> {};
+
+ template<typename T, typename U> struct shift_left : binary_expr<tag::shift_left, T, U> {};
+ template<typename T, typename U> struct shift_right : binary_expr<tag::shift_right, T, U> {};
+ template<typename T, typename U> struct multiplies : binary_expr<tag::multiplies, T, U> {};
+ template<typename T, typename U> struct divides : binary_expr<tag::divides, T, U> {};
+ template<typename T, typename U> struct modulus : binary_expr<tag::modulus, T, U> {};
+ template<typename T, typename U> struct plus : binary_expr<tag::plus, T, U> {};
+ template<typename T, typename U> struct minus : binary_expr<tag::minus, T, U> {};
+ template<typename T, typename U> struct less : binary_expr<tag::less, T, U> {};
+ template<typename T, typename U> struct greater : binary_expr<tag::greater, T, U> {};
+ template<typename T, typename U> struct less_equal : binary_expr<tag::less_equal, T, U> {};
+ template<typename T, typename U> struct greater_equal : binary_expr<tag::greater_equal, T, U> {};
+ template<typename T, typename U> struct equal_to : binary_expr<tag::equal_to, T, U> {};
+ template<typename T, typename U> struct not_equal_to : binary_expr<tag::not_equal_to, T, U> {};
+ template<typename T, typename U> struct logical_or : binary_expr<tag::logical_or, T, U> {};
+ template<typename T, typename U> struct logical_and : binary_expr<tag::logical_and, T, U> {};
+ template<typename T, typename U> struct bitwise_and : binary_expr<tag::bitwise_and, T, U> {};
+ template<typename T, typename U> struct bitwise_or : binary_expr<tag::bitwise_or, T, U> {};
+ template<typename T, typename U> struct bitwise_xor : binary_expr<tag::bitwise_xor, T, U> {};
+ template<typename T, typename U> struct comma : binary_expr<tag::comma, T, U> {};
+ template<typename T, typename U> struct mem_ptr : binary_expr<tag::mem_ptr, T, U> {};
+
+ template<typename T, typename U> struct assign : binary_expr<tag::assign, T, U> {};
+ template<typename T, typename U> struct shift_left_assign : binary_expr<tag::shift_left_assign, T, U> {};
+ template<typename T, typename U> struct shift_right_assign : binary_expr<tag::shift_right_assign, T, U> {};
+ template<typename T, typename U> struct multiplies_assign : binary_expr<tag::multiplies_assign, T, U> {};
+ template<typename T, typename U> struct divides_assign : binary_expr<tag::divides_assign, T, U> {};
+ template<typename T, typename U> struct modulus_assign : binary_expr<tag::modulus_assign, T, U> {};
+ template<typename T, typename U> struct plus_assign : binary_expr<tag::plus_assign, T, U> {};
+ template<typename T, typename U> struct minus_assign : binary_expr<tag::minus_assign, T, U> {};
+ template<typename T, typename U> struct bitwise_and_assign : binary_expr<tag::bitwise_and_assign, T, U> {};
+ template<typename T, typename U> struct bitwise_or_assign : binary_expr<tag::bitwise_or_assign, T, U> {};
+ template<typename T, typename U> struct bitwise_xor_assign : binary_expr<tag::bitwise_xor_assign, T, U> {};
+ template<typename T, typename U> struct subscript : binary_expr<tag::subscript, T, U> {};
+
+ template<typename Tag, typename... Args>
+ struct nary_expr
+ {
+ typedef expr<Tag, args<Args...> > type;
+ typedef type proto_base_expr;
+
+ template<typename Expr, typename State, typename Visitor>
+ struct apply
+ {
+ typedef detail::apply_args<args<Args...>, typename Expr::proto_args, State, Visitor> apply_;
+ typedef expr<typename Expr::proto_tag, typename apply_::type> type;
+ };
+
+ template<typename Expr, typename State, typename Visitor>
+ static typename apply<Expr, State, Visitor>::type
+ call(Expr const &expr, State const &state, Visitor &visitor)
+ {
+ typename apply<Expr, State, Visitor>::type that =
+ {apply<Expr, State, Visitor>::apply_::call(expr.proto_args_, state, visitor)};
+ return that;
+ }
+ };
+
+ template<typename... Args>
+ struct function
+ : nary_expr<tag::function, Args...>
+ {};
+
+ }
+
+ namespace result_of
+ {
+
+ namespace detail
+ {
+ // TODO unroll this loop with a few extra specializations
+ template<typename Head, typename... Tail, long N>
+ struct arg_c<argsns_::cons<Head, Tail...>, N>
+ {
+ typedef arg_c<argsns_::cons<Tail...>, N-1> base_type;
+ typedef typename base_type::type type;
+ typedef typename base_type::reference reference;
+ typedef typename base_type::const_reference const_reference;
+
+ static reference call(argsns_::cons<Head, Tail...> &args)
+ {
+ return base_type::call(args.cdr);
+ }
+
+ static const_reference call(argsns_::cons<Head, Tail...> const &args)
+ {
+ return base_type::call(args.cdr);
+ }
+ };
+
+ template<typename Head, typename... Tail>
+ struct arg_c<argsns_::cons<Head, Tail...>, 0>
+ {
+ typedef UNCVREF(Head) type;
+ typedef REF(Head) reference;
+ typedef CVREF(Head) const_reference;
+
+ static reference call(argsns_::cons<Head, Tail...> &args)
+ {
+ return args.car;
+ }
+
+ static const_reference call(argsns_::cons<Head, Tail...> const &args)
+ {
+ return args.car;
+ }
+ };
+
+ } // namespace detail
+
+ template<typename Expr, long N>
+ struct arg_c
+ : detail::arg_c<typename Expr::proto_args::cons_type, N>
+ {};
+
+ template<typename Expr>
+ struct arg
+ : detail::arg_c<typename Expr::proto_args::cons_type, 0>
+ {};
+
+ template<typename Expr>
+ struct left
+ : detail::arg_c<typename Expr::proto_args::cons_type, 0>
+ {};
+
+ template<typename Expr>
+ struct right
+ : detail::arg_c<typename Expr::proto_args::cons_type, 1>
+ {};
+
+ // as_expr
+ template<typename T, typename Domain, typename EnableIf>
+ struct as_expr
+ {
+ typedef typename mpl::if_<
+ mpl::or_<is_array<UNCVREF(T)>, is_function<UNCVREF(T)> >
+ , REF(T)
+ , UNCVREF(T)
+ >::type value_type;
+
+ typedef expr<tag::terminal, term<value_type> > expr_type;
+ typedef typename Domain::template apply<expr_type>::type type;
+ typedef type const result_type;
+
+ template<typename T2>
+ static result_type call(T2 &&t)
+ {
+ return Domain::make(expr_type::make(t));
+ }
+ };
+
+ template<typename T, typename Domain>
+ struct as_expr<T, Domain, typename T::proto_is_expr_>
+ {
+ typedef typename T::proto_derived_expr type;
+ typedef T &result_type;
+
+ template<typename T2>
+ static result_type call(T2 &&t)
+ {
+ return t;
+ }
+ };
+
+ template<typename T, typename Domain, typename EnableIf>
+ struct as_arg
+ {
+ typedef expr<tag::terminal, term<CVREF(T) > > expr_type;
+ typedef typename Domain::template apply<expr_type>::type type;
+ static type call(T &&t)
+ {
+ return Domain::make(expr_type::make(t));
+ }
+ };
+
+ template<typename T, typename Domain>
+ struct as_arg<T, Domain, typename T::proto_is_expr_>
+ {
+ typedef T const &type;
+ static T const &call(T const &t)
+ {
+ return t;
+ }
+ };
+
+ template<typename T, typename Domain>
+ struct as_arg<T &, Domain, typename T::proto_is_expr_>
+ {
+ typedef T &type;
+ static T &call(T &t)
+ {
+ return t;
+ }
+ };
+
+ template<typename T, typename _>
+ struct is_expr
+ : mpl::false_
+ {};
+
+ template<typename T>
+ struct is_expr<T, typename T::proto_is_expr_>
+ : mpl::true_
+ {};
+
+ template<typename T>
+ struct is_expr<T &, typename T::proto_is_expr_>
+ : mpl::true_
+ {};
+
+ }
+
+ namespace functional
+ {
+
+ // TODOD
+
+ }
+
+ template<typename Expr>
+ typename result_of::arg<Expr>::reference arg(Expr &expr)
+ {
+ return result_of::arg<Expr>::call(expr.proto_args_);
+ }
+
+ template<typename Expr>
+ typename result_of::arg<Expr>::const_reference arg(Expr const &expr)
+ {
+ return result_of::arg<Expr>::call(expr.proto_args_);
+ }
+
+ template<typename Expr>
+ typename result_of::left<Expr>::reference left(Expr &expr)
+ {
+ return result_of::left<Expr>::call(expr.proto_args_);
+ }
+
+ template<typename Expr>
+ typename result_of::left<Expr>::const_reference left(Expr const &expr)
+ {
+ return result_of::left<Expr>::call(expr.proto_args_);
+ }
+
+ template<typename Expr>
+ typename result_of::right<Expr>::reference right(Expr &expr)
+ {
+ return result_of::right<Expr>::call(expr.proto_args_);
+ }
+
+ template<typename Expr>
+ typename result_of::right<Expr>::const_reference right(Expr const &expr)
+ {
+ return result_of::right<Expr>::call(expr.proto_args_);
+ }
+
+ template<long N, typename Expr>
+ typename result_of::arg_c<Expr, N>::reference arg_c(Expr &expr)
+ {
+ return result_of::arg_c<Expr, N>::call(expr.proto_args_);
+ }
+
+ template<long N, typename Expr>
+ typename result_of::arg_c<Expr, N>::const_reference arg_c(Expr const &expr)
+ {
+ return result_of::arg_c<Expr, N>::call(expr.proto_args_);
+ }
+
+ template<typename T>
+ typename result_of::as_expr<T>::result_type as_expr(T &&t)
+ {
+ return result_of::as_expr<T>::call(t);
+ }
+
+ template<typename Domain, typename T>
+ typename result_of::as_expr<T, Domain>::result_type as_expr(T &&t)
+ {
+ return result_of::as_expr<T, Domain>::call(t);
+ }
+
+ template<typename T>
+ typename result_of::as_arg<T>::type as_arg(T &&t)
+ {
+ return result_of::as_arg<T>::call(std::forward<T>(t));
+ }
+
+ template<typename Domain, typename T>
+ typename result_of::as_arg<T, Domain>::type as_arg(T &&t)
+ {
+ return result_of::as_arg<T, Domain>::call(t);
+ }
+
+}}
+
+#undef CV
+#undef REF
+#undef CVREF
+#undef UNREF
+#undef UNCVREF
+
+#endif
Added: branches/proto/v3/boost/xpressive/proto3/transform.hpp
==============================================================================
--- (empty file)
+++ branches/proto/v3/boost/xpressive/proto3/transform.hpp 2007-11-07 17:03:47 EST (Wed, 07 Nov 2007)
@@ -0,0 +1,233 @@
+///////////////////////////////////////////////////////////////////////////////
+/// \file transform.hpp
+/// Definition of case_ transform.
+//
+// Copyright 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)
+
+#ifndef BOOST_PROTO3_TRANSFORM_HPP_EAN_10_29_2007
+#define BOOST_PROTO3_TRANSFORM_HPP_EAN_10_29_2007
+
+#include <boost/mpl/bool.hpp>
+#include <boost/mpl/aux_/has_type.hpp>
+#include <boost/type_traits.hpp>
+#include <boost/xpressive/proto3/proto_fwd.hpp>
+#include <boost/xpressive/proto3/transform/bind.hpp>
+#include <boost/xpressive/proto3/transform/apply.hpp>
+
+namespace boost { namespace proto
+{
+ namespace transform
+ {
+ namespace detail
+ {
+ template<typename... T>
+ struct typelist
+ {
+ typedef void type;
+ };
+
+ template<typename T>
+ struct is_aggregate
+ : is_pod<T>
+ {};
+
+ template<typename Tag, typename Args, long N>
+ struct is_aggregate<expr<Tag, Args, N> >
+ : mpl::true_
+ {};
+
+ 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 EnableIf = void>
+ struct nested_type_if
+ : nested_type<T>
+ {};
+
+ template<typename T, typename... Args>
+ struct nested_type_if<T, typelist<Args...>, typename typelist<typename Args::not_applied_...>::type>
+ {
+ typedef T type;
+ typedef void not_applied_;
+ };
+
+ template<typename R, typename Expr, typename State, typename Visitor
+ , typename Category = typename transform_category<R>::type
+ >
+ struct apply_lambda_; // function-style transforms cannot be part of lambdas
+
+ template<typename R, typename Expr, typename State, typename Visitor>
+ struct apply_lambda_aux_
+ {
+ typedef R type;
+ typedef void not_applied_;
+ };
+
+ template<template<typename...> class R, typename... Args, typename Expr, typename State, typename Visitor>
+ struct apply_lambda_aux_<R<Args...>, Expr, State, Visitor>
+ : nested_type_if<
+ R<typename apply_lambda_<Args, Expr, State, Visitor>::type...>
+ , typelist<apply_lambda_<Args, Expr, State, Visitor>...>
+ >
+ {};
+
+ template<typename R, typename Expr, typename State, typename Visitor>
+ struct apply_lambda_<R, Expr, State, Visitor, no_transform>
+ : apply_lambda_aux_<R, Expr, State, Visitor>
+ {};
+
+ template<typename R, typename Expr, typename State, typename Visitor>
+ struct apply_lambda_<R, Expr, State, Visitor, raw_transform>
+ : R::template apply<Expr, State, Visitor>
+ {};
+
+ // work around GCC bug
+ template<typename Tag, typename Args, long N, typename Expr, typename State, typename Visitor>
+ struct apply_lambda_<expr<Tag, Args, N>, Expr, State, Visitor, no_transform>
+ {
+ typedef expr<Tag, Args, N> type;
+ typedef void not_applied_;
+ };
+
+ template<typename Type, typename... Args>
+ typename enable_if<is_aggregate<Type>, Type>::type
+ construct_(Args &&... args)
+ {
+ Type that = { args... };
+ return that;
+ }
+
+ template<typename Type, typename... Args>
+ typename disable_if<is_aggregate<Type>, Type>::type
+ construct_(Args &&... args)
+ {
+ return Type(args...);
+ }
+
+ template<typename TransformCategory, typename Return, typename... Args>
+ struct case_impl
+ : raw_transform
+ {
+ template<typename Expr, typename State, typename Visitor>
+ struct apply
+ : apply_lambda_<Return, Expr, State, Visitor>
+ {};
+
+ template<typename Expr, typename State, typename Visitor>
+ static typename apply<Expr, State, Visitor>::type
+ call(Expr const &expr, State const &state, Visitor &visitor)
+ {
+ typedef typename apply<Expr, State, Visitor>::type type;
+ return detail::construct_<type>(case_<_, Args>::call(expr, state, visitor)...);
+ }
+ };
+
+ template<typename Return, typename... Args>
+ struct case_impl<function_transform, Return, Args...>
+ : bind<Return, Args...>
+ {};
+
+ template<typename Return, typename... Args>
+ struct case_impl<raw_transform, Return, Args...>
+ : apply_<Return, Args...>
+ {};
+
+ }
+
+ // Simple transform, takes a raw transform and
+ // applies it directly.
+ template<typename Grammar, typename Fun>
+ struct case_
+ : Fun
+ {
+ typedef typename Grammar::proto_base_expr proto_base_expr;
+ };
+
+ // Lambda-style transform, takes a raw or function-style
+ // transform with arguments and applies it, OR takes a
+ // (possibly lambda) type and constructor arguments.
+ template<typename Grammar, typename Return, typename... Args>
+ struct case_<Grammar, Return(Args...)>
+ : detail::case_impl<typename transform_category<Return>::type, Return, Args...>
+ {
+ typedef typename Grammar::proto_base_expr proto_base_expr;
+ };
+
+ template<typename Grammar, typename Return, typename... Args>
+ struct case_<Grammar, Return(*)(Args...)>
+ : detail::case_impl<typename transform_category<Return>::type, Return, Args...>
+ {
+ typedef typename Grammar::proto_base_expr proto_base_expr;
+ };
+
+ template<typename Trans>
+ struct typeof_
+ : case_<_, Trans>
+ {};
+
+ }
+
+ namespace detail
+ {
+ template<typename T, typename EnableIf = void>
+ struct transform_category2_
+ {
+ typedef no_transform type;
+ };
+
+ template<typename T>
+ struct transform_category2_<T, typename T::proto_raw_transform_>
+ {
+ typedef raw_transform type;
+ };
+
+ template<typename T>
+ struct transform_category2_<T, typename T::proto_function_transform_>
+ {
+ typedef function_transform type;
+ };
+
+ template<typename T>
+ struct transform_category_
+ : transform_category2_<T>
+ {};
+
+ template<template<typename...> class T, typename... Args>
+ struct transform_category_<T<Args...> >
+ {
+ typedef no_transform type;
+ };
+ }
+
+ template<typename T>
+ struct transform_category
+ : proto::detail::transform_category_<T>
+ {};
+
+ // work around GCC bug
+ template<typename Tag, typename Args, long N>
+ struct transform_category<expr<Tag, Args, N> >
+ {
+ typedef no_transform type;
+ };
+
+ template<typename Trans>
+ struct transform_category<typeof_<Trans> >
+ {
+ typedef raw_transform type;
+ };
+
+}}
+
+#endif
Added: branches/proto/v3/boost/xpressive/proto3/transform/apply.hpp
==============================================================================
--- (empty file)
+++ branches/proto/v3/boost/xpressive/proto3/transform/apply.hpp 2007-11-07 17:03:47 EST (Wed, 07 Nov 2007)
@@ -0,0 +1,109 @@
+///////////////////////////////////////////////////////////////////////////////
+/// \file apply.hpp
+/// Contains definition of the apply_<> transform.
+//
+// Copyright 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)
+
+#ifndef BOOST_PROTO3_TRANSFORM_APPLY_HPP_EAN_11_02_2007
+#define BOOST_PROTO3_TRANSFORM_APPLY_HPP_EAN_11_02_2007
+
+#include <boost/utility/result_of.hpp>
+#include <boost/xpressive/proto3/proto_fwd.hpp>
+#include <boost/xpressive/proto3/traits.hpp>
+
+namespace boost { namespace proto
+{
+
+ namespace transform
+ {
+
+ template<typename Trans>
+ struct apply_<Trans>
+ : Trans
+ {};
+
+ template<typename Trans, typename ExprTfx>
+ struct apply_<Trans, ExprTfx> : raw_transform
+ {
+ template<typename Expr, typename State, typename Visitor>
+ struct apply
+ : Trans::template apply<
+ typename case_<_, ExprTfx>::template apply<Expr, State, Visitor>::type
+ , State
+ , Visitor
+ >
+ {};
+
+ template<typename Expr, typename State, typename Visitor>
+ static typename apply<Expr, State, Visitor>::type
+ call(Expr const &expr, State const &state, Visitor &visitor)
+ {
+ return Trans::call(
+ case_<_, ExprTfx>::call(expr, state, visitor)
+ , state
+ , visitor
+ );
+ }
+ };
+
+ template<typename Trans, typename ExprTfx, typename StateTfx>
+ struct apply_<Trans, ExprTfx, StateTfx>
+ {
+ template<typename Expr, typename State, typename Visitor>
+ struct apply
+ : Trans::template apply<
+ typename case_<_, ExprTfx>::template apply<Expr, State, Visitor>::type
+ , typename case_<_, StateTfx>::template apply<Expr, State, Visitor>::type
+ , Visitor
+ >
+ {};
+
+ template<typename Expr, typename State, typename Visitor>
+ static typename apply<Expr, State, Visitor>::type
+ call(Expr const &expr, State const &state, Visitor &visitor)
+ {
+ return Trans::call(
+ case_<_, ExprTfx>::call(expr, state, visitor)
+ , case_<_, StateTfx>::call(expr, state, visitor)
+ , visitor
+ );
+ }
+ };
+
+ template<typename Trans, typename ExprTfx, typename StateTfx, typename VisitorTfx>
+ struct apply_<Trans, ExprTfx, StateTfx, VisitorTfx>
+ {
+ template<typename Expr, typename State, typename Visitor>
+ struct apply
+ : Trans::template apply<
+ typename case_<_, ExprTfx>::template apply<Expr, State, Visitor>::type
+ , typename case_<_, StateTfx>::template apply<Expr, State, Visitor>::type
+ , typename case_<_, VisitorTfx>::template apply<Expr, State, Visitor>::type
+ >
+ {};
+
+ template<typename Expr, typename State, typename Visitor>
+ static typename apply<Expr, State, Visitor>::type
+ call(Expr const &expr, State const &state, Visitor &visitor)
+ {
+ return Trans::call(
+ case_<_, ExprTfx>::call(expr, state, visitor)
+ , case_<_, StateTfx>::call(expr, state, visitor)
+ , case_<_, VisitorTfx>::call(expr, state, visitor)
+ );
+ }
+ };
+
+ }
+
+ template<typename Trans, typename... Args>
+ struct transform_category<transform::apply_<Trans, Args...> >
+ {
+ typedef raw_transform type;
+ };
+
+}}
+
+#endif
Added: branches/proto/v3/boost/xpressive/proto3/transform/arg.hpp
==============================================================================
--- (empty file)
+++ branches/proto/v3/boost/xpressive/proto3/transform/arg.hpp 2007-11-07 17:03:47 EST (Wed, 07 Nov 2007)
@@ -0,0 +1,104 @@
+///////////////////////////////////////////////////////////////////////////////
+/// \file arg.hpp
+/// Contains definition of the argN transforms.
+//
+// Copyright 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)
+
+#ifndef BOOST_PROTO3_TRANSFORM_ARG_HPP_EAN_11_01_2007
+#define BOOST_PROTO3_TRANSFORM_ARG_HPP_EAN_11_01_2007
+
+#include <boost/xpressive/proto3/proto_fwd.hpp>
+#include <boost/xpressive/proto3/traits.hpp>
+
+namespace boost { namespace proto
+{
+
+ namespace transform
+ {
+
+ struct _expr : raw_transform
+ {
+ template<typename Expr, typename, typename>
+ struct apply
+ {
+ typedef Expr type;
+ };
+
+ template<typename Expr, typename State, typename Visitor>
+ static Expr const &
+ call(Expr const &expr, State const &, Visitor &)
+ {
+ return expr;
+ }
+ };
+
+ struct _state : raw_transform
+ {
+ template<typename, typename State, typename>
+ struct apply
+ {
+ typedef State type;
+ };
+
+ template<typename Expr, typename State, typename Visitor>
+ static State const &
+ call(Expr const &, State const &state, Visitor &)
+ {
+ return state;
+ }
+ };
+
+ struct _visitor : raw_transform
+ {
+ template<typename, typename, typename Visitor>
+ struct apply
+ {
+ typedef Visitor type;
+ };
+
+ template<typename Expr, typename State, typename Visitor>
+ static Visitor &
+ call(Expr const &, State const &, Visitor &visitor)
+ {
+ return visitor;
+ }
+ };
+
+ template<int I>
+ struct _arg_c : raw_transform
+ {
+ template<typename Expr, typename, typename>
+ struct apply
+ : proto::result_of::arg_c<Expr, I>
+ {};
+
+ template<typename Expr, typename State, typename Visitor>
+ static typename boost::proto::result_of::arg_c<Expr, I>::const_reference
+ call(Expr const &expr, State const &, Visitor &)
+ {
+ return proto::arg_c<I>(expr);
+ }
+ };
+
+ struct _arg0 : _arg_c<0> {};
+ struct _arg1 : _arg_c<1> {};
+ struct _arg2 : _arg_c<2> {};
+ struct _arg3 : _arg_c<3> {};
+ struct _arg4 : _arg_c<4> {};
+ struct _arg5 : _arg_c<5> {};
+ struct _arg6 : _arg_c<6> {};
+ struct _arg7 : _arg_c<7> {};
+ struct _arg8 : _arg_c<8> {};
+ struct _arg9 : _arg_c<9> {};
+
+ typedef _arg0 _arg;
+ typedef _arg0 _left;
+ typedef _arg1 _right;
+
+ }
+
+}}
+
+#endif
Added: branches/proto/v3/boost/xpressive/proto3/transform/bind.hpp
==============================================================================
--- (empty file)
+++ branches/proto/v3/boost/xpressive/proto3/transform/bind.hpp 2007-11-07 17:03:47 EST (Wed, 07 Nov 2007)
@@ -0,0 +1,61 @@
+///////////////////////////////////////////////////////////////////////////////
+/// \file bind.hpp
+/// Contains definition of the bind<> transform.
+//
+// Copyright 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)
+
+#ifndef BOOST_PROTO3_TRANSFORM_BIND_HPP_EAN_11_02_2007
+#define BOOST_PROTO3_TRANSFORM_BIND_HPP_EAN_11_02_2007
+
+#include <boost/utility/result_of.hpp>
+#include <boost/xpressive/proto3/proto_fwd.hpp>
+#include <boost/xpressive/proto3/traits.hpp>
+
+namespace boost { namespace proto
+{
+
+ namespace transform
+ {
+
+ template<typename Fun, typename... Args>
+ struct bind : raw_transform
+ {
+ template<typename Expr, typename State, typename Visitor>
+ struct apply
+ : boost::result_of<
+ Fun(typename case_<_, Args>::template apply<Expr, State, Visitor>::type...)
+ >
+ {};
+
+ template<typename Expr, typename State, typename Visitor>
+ static typename apply<Expr, State, Visitor>::type
+ call(Expr const &expr, State const &state, Visitor &visitor)
+ {
+ Fun f;
+ return f(case_<_, Args>::call(expr, state, visitor)...);
+ }
+ };
+
+ template<typename Fun>
+ struct bind<Fun> : Fun, function_transform
+ {};
+
+ }
+
+ template<typename Fun>
+ struct transform_category<transform::bind<Fun> >
+ {
+ typedef function_transform type;
+ };
+
+ template<typename Fun, typename... Args>
+ struct transform_category<transform::bind<Fun, Args...> >
+ {
+ typedef raw_transform type;
+ };
+
+}}
+
+#endif
Added: branches/proto/v3/boost/xpressive/proto3/transform/fold.hpp
==============================================================================
--- (empty file)
+++ branches/proto/v3/boost/xpressive/proto3/transform/fold.hpp 2007-11-07 17:03:47 EST (Wed, 07 Nov 2007)
@@ -0,0 +1,129 @@
+///////////////////////////////////////////////////////////////////////////////
+/// \file fold.hpp
+/// Contains definition of the fold<> and reverse_fold<> transforms.
+//
+// Copyright 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)
+
+#ifndef BOOST_PROTO3_TRANSFORM_FOLD_HPP_EAN_11_04_2007
+#define BOOST_PROTO3_TRANSFORM_FOLD_HPP_EAN_11_04_2007
+
+#include <boost/fusion/include/fold.hpp>
+#include <boost/fusion/include/reverse.hpp>
+#include <boost/xpressive/proto3/proto_fwd.hpp>
+#include <boost/xpressive/proto3/fusion.hpp>
+#include <boost/xpressive/proto3/traits.hpp>
+
+#define UNREF(T)\
+ typename remove_reference<T>::type
+
+#define UNCVREF(T)\
+ typename remove_cv<UNREF(T)>::type
+
+namespace boost { namespace proto
+{
+
+ namespace transform
+ {
+
+ namespace detail
+ {
+
+ template<typename Transform, typename Visitor>
+ struct as_callable
+ {
+ as_callable(Visitor &v)
+ : v_(v)
+ {}
+
+ typedef case_<_, Transform> Tfx;
+
+ template<typename Sig>
+ struct result;
+
+ template<typename This, typename Expr, typename State>
+ struct result<This(Expr, State)>
+ : Tfx::template apply<UNCVREF(Expr), UNCVREF(State), Visitor>
+ {};
+
+ template<typename Expr, typename State>
+ typename Tfx::template apply<Expr, State, Visitor>::type
+ operator()(Expr const &expr, State const &state) const
+ {
+ return Tfx::call(expr, state, this->v_);
+ }
+
+ private:
+ Visitor &v_;
+ };
+
+ struct reverse : function_transform
+ {
+ template<typename Sig> struct result;
+
+ template<typename This, typename T>
+ struct result<This(T)>
+ : fusion::result_of::reverse<T const>
+ {};
+
+ template<typename T>
+ typename fusion::result_of::reverse<T const>::type
+ operator()(T const &t) const
+ {
+ return fusion::reverse(t);
+ }
+ };
+
+ } // namespace detail
+
+ template<typename Sequence, typename State0, typename Fun>
+ struct fold : raw_transform
+ {
+ template<typename Expr, typename State, typename Visitor>
+ struct apply
+ : fusion::result_of::fold<
+ typename case_<_, Sequence>::template apply<Expr, State, Visitor>::type
+ , typename case_<_, State0>::template apply<Expr, State, Visitor>::type
+ , detail::as_callable<Fun, Visitor>
+ >
+ {};
+
+ template<typename Expr, typename State, typename Visitor>
+ static typename apply<Expr, State, Visitor>::type
+ call(Expr const &expr, State const &state, Visitor &visitor)
+ {
+ detail::as_callable<Fun, Visitor> fun(visitor);
+ return fusion::fold(
+ case_<_, Sequence>::call(expr, state, visitor)
+ , case_<_, State0>::call(expr, state, visitor)
+ , fun
+ );
+ }
+ };
+
+ template<typename Sequence, typename State, typename Fun>
+ struct reverse_fold
+ : fold<detail::reverse(Sequence), State, Fun>
+ {};
+
+ }
+
+ template<typename Sequence, typename State, typename Fun>
+ struct transform_category<transform::fold<Sequence, State, Fun> >
+ {
+ typedef raw_transform type;
+ };
+
+ template<typename Sequence, typename State, typename Fun>
+ struct transform_category<transform::reverse_fold<Sequence, State, Fun> >
+ {
+ typedef raw_transform type;
+ };
+
+}}
+
+#undef UNREF
+#undef UNCVREF
+
+#endif
Added: branches/proto/v3/boost/xpressive/proto3/transform/fold_tree.hpp
==============================================================================
--- (empty file)
+++ branches/proto/v3/boost/xpressive/proto3/transform/fold_tree.hpp 2007-11-07 17:03:47 EST (Wed, 07 Nov 2007)
@@ -0,0 +1,114 @@
+///////////////////////////////////////////////////////////////////////////////
+/// \file fold.hpp
+/// Contains definition of the fold_tree<> and reverse_fold_tree<> transforms.
+//
+// Copyright 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)
+
+#ifndef BOOST_PROTO3_TRANSFORM_FOLD_TREE_HPP_EAN_11_05_2007
+#define BOOST_PROTO3_TRANSFORM_FOLD_TREE_HPP_EAN_11_05_2007
+
+#include <boost/mpl/placeholders.hpp>
+#include <boost/type_traits.hpp>
+#include <boost/xpressive/proto3/proto_fwd.hpp>
+#include <boost/xpressive/proto3/traits.hpp>
+#include <boost/xpressive/proto3/transform/fold.hpp>
+
+namespace boost { namespace proto
+{
+
+ namespace transform
+ {
+
+ namespace detail
+ {
+
+ template<typename Grammar, typename Fun>
+ struct fold_tree_
+ : or_<
+ case_<Grammar, fold<_, _state, fold_tree_<Grammar, Fun> > >
+ , case_<_, Fun>
+ >
+ {};
+
+ template<typename Grammar, typename Fun>
+ struct reverse_fold_tree_
+ : or_<
+ case_<Grammar, reverse_fold<_, _state, reverse_fold_tree_<Grammar, Fun> > >
+ , case_<_, Fun>
+ >
+ {};
+
+ }
+
+ template<typename Sequence, typename State0, typename Fun>
+ struct fold_tree
+ : raw_transform
+ {
+ template<typename Expr, typename State, typename Visitor>
+ struct apply
+ {
+ typedef fold<
+ Sequence
+ , State0
+ , detail::fold_tree_<
+ nary_expr<typename Expr::proto_tag, vararg<_> >
+ , Fun
+ >
+ > impl;
+
+ typedef typename impl::template apply<Expr, State, Visitor>::type type;
+ };
+
+ template<typename Expr, typename State, typename Visitor>
+ static typename apply<Expr, State, Visitor>::type
+ call(Expr const &expr, State const &state, Visitor &visitor)
+ {
+ return apply<Expr, State, Visitor>::impl::call(expr, state, visitor);
+ }
+ };
+
+ template<typename Sequence, typename State0, typename Fun>
+ struct reverse_fold_tree
+ : raw_transform
+ {
+ template<typename Expr, typename State, typename Visitor>
+ struct apply
+ {
+ typedef reverse_fold<
+ Sequence
+ , State0
+ , detail::reverse_fold_tree_<
+ nary_expr<typename Expr::proto_tag, vararg<_> >
+ , Fun
+ >
+ > impl;
+
+ typedef typename impl::template apply<Expr, State, Visitor>::type type;
+ };
+
+ template<typename Expr, typename State, typename Visitor>
+ static typename apply<Expr, State, Visitor>::type
+ call(Expr const &expr, State const &state, Visitor &visitor)
+ {
+ return apply<Expr, State, Visitor>::impl::call(expr, state, visitor);
+ }
+ };
+ }
+
+ template<typename Sequence, typename State0, typename Fun>
+ struct transform_category<transform::fold_tree<Sequence, State0, Fun> >
+ {
+ typedef raw_transform type;
+ };
+
+ template<typename Sequence, typename State0, typename Fun>
+ struct transform_category<transform::reverse_fold_tree<Sequence, State0, Fun> >
+ {
+ typedef raw_transform type;
+ };
+
+}}
+
+#endif
Added: branches/proto/v3/libs/xpressive/proto3/doc/Jamfile.v2
==============================================================================
--- (empty file)
+++ branches/proto/v3/libs/xpressive/proto3/doc/Jamfile.v2 2007-11-07 17:03:47 EST (Wed, 07 Nov 2007)
@@ -0,0 +1,109 @@
+# Copyright Eric Niebler 2007. Use, modification, and distribution are
+# subject to the Boost Software License, Version 1.0. (See accompanying
+# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+import path ;
+import doxygen ;
+import quickbook ;
+
+wave-command = [ path.native ../../../../dist/bin/wave ] ;
+
+## Generate reference section using Doxygen
+#doxygen protodoc
+# :
+# ../../../../boost/xpressive/proto/args.hpp
+# ../../../../boost/xpressive/proto/context.hpp
+# ../../../../boost/xpressive/proto/debug.hpp
+# ../../../../boost/xpressive/proto/deep_copy.hpp
+# ../../../../boost/xpressive/proto/domain.hpp
+# ../../../../boost/xpressive/proto/eval.hpp
+# ../../../../boost/xpressive/proto/expr.hpp
+# ../../../../boost/xpressive/proto/extends.hpp
+# ../../../../boost/xpressive/proto/fusion.hpp
+# ../../../../boost/xpressive/proto/generate.hpp
+# ../../../../boost/xpressive/proto/literal.hpp
+# ../../../../boost/xpressive/proto/make_expr.hpp
+# ../../../../boost/xpressive/proto/matches.hpp
+# ../../../../boost/xpressive/proto/operators.hpp
+# ../../../../boost/xpressive/proto/proto.hpp
+# ../../../../boost/xpressive/proto/proto_fwd.hpp
+## ../../../../boost/xpressive/proto/proto_typeof.hpp
+# ../../../../boost/xpressive/proto/ref.hpp
+# ../../../../boost/xpressive/proto/tags.hpp
+# ../../../../boost/xpressive/proto/traits.hpp
+# ../../../../boost/xpressive/proto/transform.hpp
+# ../../../../boost/xpressive/proto/context/callable.hpp
+# ../../../../boost/xpressive/proto/context/default.hpp
+# ../../../../boost/xpressive/proto/context/null.hpp
+# ../../../../boost/xpressive/proto/transform/arg.hpp
+# ../../../../boost/xpressive/proto/transform/apply.hpp
+# ../../../../boost/xpressive/proto/transform/branch.hpp
+# ../../../../boost/xpressive/proto/transform/compose.hpp
+# ../../../../boost/xpressive/proto/transform/construct.hpp
+# ../../../../boost/xpressive/proto/transform/fold.hpp
+# ../../../../boost/xpressive/proto/transform/fold_tree.hpp
+# ../../../../boost/xpressive/proto/transform/function.hpp
+# ../../../../boost/xpressive/proto/transform/list.hpp
+# ../../../../boost/xpressive/proto/transform/pass_through.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-command) \\
+# -S ../../../.. \\
+# -S \\\"C:\\Program Files\\Microsoft Visual Studio .NET 2003\\vc7\\include\\\" \\
+# -D _WIN32 \\
+# -D BOOST_PROTO_DOXYGEN_INVOKED \\
+# -p 1 \""
+# # This ensures that Wave is actually built before we try to execute it
+# <dependency>../../../../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=../../../../..
+ # location of the main index file so our links work:
+ #<xsl:param>boost.libraries=../../../../../libs/libraries.htm
+
+ # PDF Options:
+ # TOC Generation: this is needed for FOP-0.9 and later:
+ # <xsl:param>fop1.extensions=1
+ <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!
+ <xsl:param>fop.extensions=0
+ # No indent on body text:
+ <xsl:param>body.start.indent=0pt
+ # Margin size:
+ <xsl:param>page.margin.inner=0.5in
+ # Margin size:
+ <xsl:param>page.margin.outer=0.5in
+ # Yes, we want graphics for admonishments:
+ <xsl:param>admon.graphics=1
+ # Set this one for PDF generation *only*:
+ # default pnd graphics are awful in PDF form,
+ # better use SVG's instead:
+ # <xsl:param>admon.graphics.extension=".svg"
+
+# <dependency>protodoc
+ ;
Added: branches/proto/v3/libs/xpressive/proto3/doc/acknowledgements.qbk
==============================================================================
--- (empty file)
+++ branches/proto/v3/libs/xpressive/proto3/doc/acknowledgements.qbk 2007-11-07 17:03:47 EST (Wed, 07 Nov 2007)
@@ -0,0 +1,15 @@
+[/
+ / Copyright (c) 2006 Eric Niebler
+ /
+ / Distributed under the Boost Software License, Version 1.0. (See accompanying
+ / file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+ /]
+
+[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.
+
+[endsect]
Added: branches/proto/v3/libs/xpressive/proto3/doc/calculator.qbk
==============================================================================
--- (empty file)
+++ branches/proto/v3/libs/xpressive/proto3/doc/calculator.qbk 2007-11-07 17:03:47 EST (Wed, 07 Nov 2007)
@@ -0,0 +1,176 @@
+[/
+ / Copyright (c) 2006 Eric Niebler
+ /
+ / Distributed under the Boost Software License, Version 1.0. (See accompanying
+ / file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+ /]
+
+[section Hello Calculator]
+
+"Hello, world" is nice, but it doesn't get you very far. Let's use Proto to
+build a Domain Specific Embedded Language for a lazily-evaluated calculator.
+We'll see how to define the terminals in your mini-language, how Proto combines
+the terminals into larger expressions, and how to define an evaluation context
+so that your expressions can do useful work. When we're done, we'll have a
+mini-language that will allow us to declare a lazily-evaluated arithmetic
+expression, such as `(_2 - _1) / _2 * 100`, where `_1` and `_2` are
+placeholders for values to be passed in when the expression is evaluated.
+
+[heading Defining Terminals]
+
+The first order of business is to define the placeholders `_1` and `_2`. For
+that, we'll use the _terminal_ expression generator.
+
+ // 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,
+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/v3/libs/xpressive/proto3/doc/construction.qbk
==============================================================================
--- (empty file)
+++ branches/proto/v3/libs/xpressive/proto3/doc/construction.qbk 2007-11-07 17:03:47 EST (Wed, 07 Nov 2007)
@@ -0,0 +1,336 @@
+[/
+ / 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_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, args0< 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 -- braches, 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 children types. Terminals will always have only one type in the
+type list. The last parameter is the arity of the expression. Terminals have
+arity 0, unary expressions have arity 1, etc.
+
+The _expr_ struct is defined as follows:
+
+ template< typename Tag, typename Args, long Arity = Args::size >
+ struct expr;
+
+ template< typename Tag, typename Args >
+ struct expr< Tag, Args, 1 >
+ {
+ typename Args::arg0 arg0;
+ // ...
+ };
+
+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.arg0` which
+is of type `placeholder1`. Note that we use braces to initialize `_1.arg0`
+because `placeholder1` is also an aggregate.
+
+[section:operator_overloads Proto's Operator Overloads]
+
+Once we have some Proto terminals, expressions involving those terminals build
+expression trees for us, as if by magic. It's not magic; Proto defines
+overloads for each of C++'s overloadable operators to make it happen. As long
+as one operand is a Proto expression, the result of the operation is a tree
+node representing that operation.[footnote There are a couple of exceptions to
+this. In ["`int x; x = _1`], the assignment isn't a Proto expression, even
+though the right hand operand /is/ a Proto expression. That's just how C++ works.
+The same is also true for the subscript operator and the function call
+operator, as in ["`int *x; x[_1];`] and ["`std::sin(_1);`]. Them's the breaks,
+as they say.]
+
+[note The _expr_ struct lives in the `boost::proto` namespace, as do all of
+Proto's operator overloads. The overloads are found via ADL (Argument-Dependent
+Lookup). That is why expressions must be "tainted" with Proto-ness for Proto to
+be able to build trees out of expressions.]
+
+As a result of Proto's operator overloads, we can say:
+
+ -_1; // OK, build a unary-negate tree node
+ _1 + 42; // OK, build a binary-plus tree node
+
+[endsect]
+
+[section:expression_trees Building Expression Trees]
+
+The `_1` node is an _expr_ type, and new nodes created with this type are
+also _expr_ types. They look like this:
+
+ // typeof( -_1 )
+ expr<
+ tag::negate
+ , args1<
+ ref_< expr< tag::terminal, args0< placeholder1 >, 0 > >
+ >
+ , 1
+ >
+
+ // typeof( _1 + 42 )
+ expr<
+ tag::plus
+ , args2<
+ ref_< expr< tag::terminal, args0< placeholder1 >, 0 > >
+ , expr< tag::terminal, args0< int const & >, 0 >
+ >
+ , 2
+ >
+
+There are a few things to note about these types:
+
+# Terminals have arity 0, unary expressions have arity 1 and binary expressions
+ have arity 2.
+# When one Proto expression is made a child node of another Proto expression,
+ it is wrapped in _ref_, which is a simple reference wrapper. That is, Proto
+ expressions hold their children by reference ['even if they are temporary
+ objects]. This last point becomes important later.
+# Non-Proto expressions, such as the integer literal, are turned into Proto
+ expressions by making them Proto terminals. These terminal expressions
+ are /not/ wrapped in _ref_, but the object itself /is/ held by reference.
+ Notice that the type of the Proto-ified `42` literal is `int const &` -- held
+ by reference.
+
+The types make it clear: everything in a Proto expression tree is held by
+reference. That means that building an expression tree is exceptionally cheap.
+It involves no copying at all.
+
+[note To use Proto effectively, you won't have to bother yourself with the
+actual types that Proto generates. These are details, but you're likely to
+encounter these types in compiler error messages, so it's helpful to be familiar
+with them.]
+
+[endsect]
+
+[section:left_right_arg Accessing Children Nodes]
+
+// TODO describe tag_of, arg, arg_c, left and right. Maybe also children_of and Fusion.
+
+[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::posit`]
+ [`posit<>`]]
+
+ [[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_<>`]]
+
+ [[nary function call]
+ [`tag::function`]
+ [`function<>`]]
+]
+
+[endsect]
+
+[section:construction_utils Expression Construction Utilities]
+
+// TODO describe make_expr, unpack_expr and BOOST_PROTO_DEFINE_VARARG_FUNCTION_TEMPLATE
+
+[endsect]
+
+[endsect]
Added: branches/proto/v3/libs/xpressive/proto3/doc/evaluation.qbk
==============================================================================
--- (empty file)
+++ branches/proto/v3/libs/xpressive/proto3/doc/evaluation.qbk 2007-11-07 17:03:47 EST (Wed, 07 Nov 2007)
@@ -0,0 +1,44 @@
+[/
+ / 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]
+
+[section:proto_eval Evaluating An Expression with [^proto::eval()]]
+
+TODO
+
+[endsect]
+
+[section:contexts Defining an Evaluation Context]
+
+TODO
+
+[endsect]
+
+[section:canned_contexts Canned Contexts]
+
+[section:default_context [^default_context]]
+
+TODO
+
+[endsect]
+
+[section:null_context [^null_context]]
+
+TODO
+
+[endsect]
+
+[section:callable_context [^callable_context<>]]
+
+TODO
+
+[endsect]
+
+[endsect]
+
+[endsect]
Added: branches/proto/v3/libs/xpressive/proto3/doc/examples.qbk
==============================================================================
--- (empty file)
+++ branches/proto/v3/libs/xpressive/proto3/doc/examples.qbk 2007-11-07 17:03:47 EST (Wed, 07 Nov 2007)
@@ -0,0 +1,85 @@
+[/
+ / Copyright (c) 2006 Eric Niebler
+ /
+ / Distributed under the Boost Software License, Version 1.0. (See accompanying
+ / file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+ /]
+
+[import ../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]
+
+[section Examples]
+
+[section Hello World]
+
+blah blah blah
+
+[HelloWorld]
+
+blah blah blah
+
+[endsect]
+
+[section Calc1]
+
+[Calc1]
+
+[endsect]
+
+[section Calc2]
+
+[Calc2]
+
+[endsect]
+
+[section Calc3]
+
+[Calc3]
+
+[endsect]
+
+[section Lazy Vector]
+
+[LazyVector]
+
+[endsect]
+
+[section RGB]
+
+[RGB]
+
+[endsect]
+
+[section TArray]
+
+[TArray]
+
+[endsect]
+
+[section Vec3]
+
+[Vec3]
+
+[endsect]
+
+[section Vector]
+
+[Vector]
+
+[endsect]
+
+[section Mixed]
+
+[Mixed]
+
+[endsect]
+
+[endsect]
Added: branches/proto/v3/libs/xpressive/proto3/doc/extensibility.qbk
==============================================================================
--- (empty file)
+++ branches/proto/v3/libs/xpressive/proto3/doc/extensibility.qbk 2007-11-07 17:03:47 EST (Wed, 07 Nov 2007)
@@ -0,0 +1,329 @@
+[/
+ / Copyright (c) 2006 Eric Niebler
+ /
+ / Distributed under the Boost Software License, Version 1.0. (See accompanying
+ / file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+ /]
+
+[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 children 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::arg<Expr>::type::value_type result_type;
+
+ result_type operator()( Expr const & expr, lazy_subscript_context & ctx ) const
+ {
+ return proto::arg( 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::arg(*this).size();
+ for(std::size_t i = 0; i < size; ++i)
+ {
+ proto::arg(*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/v3/libs/xpressive/proto3/doc/grammars.qbk
==============================================================================
--- (empty file)
+++ branches/proto/v3/libs/xpressive/proto3/doc/grammars.qbk 2007-11-07 17:03:47 EST (Wed, 07 Nov 2007)
@@ -0,0 +1,495 @@
+[/
+ / Copyright (c) 2006 Eric Niebler
+ /
+ / Distributed under the Boost Software License, Version 1.0. (See accompanying
+ / file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+ /]
+
+[/============================================================================]
+[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 simiple 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
+reference to 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 an MPL lambda expression, which is
+evaluated against expression types to find matches.
+
+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< result_of::arg< mpl::_ >, 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< result_of::arg< mpl::_ >, char const * >`. This is an MPL lambda
+expression because it has the MPL placeholder `mpl::_` in it.
+
+[warning Do not confuse `mpl::_` with `proto::_`. The first is only useful in
+MPL lambda expressions. The second is Proto's grammar wildcard. The only place
+`mpl::_` should appear in your grammars is in an _if_, or in tranform::applyN<>,
+as we'll see later. Elsewhere in your grammars you should be using `proto::_`.]
+
+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`. The following table shows their
+equivalencies:
+
+[table If-Then-Else Equivalencies
+[[Short-Cut Grammar][Equivalent Grammar]]
+[[`if_<Condition, ThenGrammar>`][`and_<if_<Condition>, ThenGrammar>`]]
+[[`if_<Condition, ThenGrammar, ElseGrammar>`][``or_<
+ and_<if_<Condition>, ThenGrammar>
+ , and_<not_<if_<Condition> >, ElseGrammar>
+>``]]
+]
+
+[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 children 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/v3/libs/xpressive/proto3/doc/history.qbk
==============================================================================
--- (empty file)
+++ branches/proto/v3/libs/xpressive/proto3/doc/history.qbk 2007-11-07 17:03:47 EST (Wed, 07 Nov 2007)
@@ -0,0 +1,47 @@
+[/
+ / Copyright (c) 2006 Eric Niebler
+ /
+ / Distributed under the Boost Software License, Version 1.0. (See accompanying
+ / file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+ /]
+
+[section:history Appendix A: History]
+
+[variablelist
+[
+ [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/v3/libs/xpressive/proto3/doc/html/boostbook.css
==============================================================================
--- (empty file)
+++ branches/proto/v3/libs/xpressive/proto3/doc/html/boostbook.css 2007-11-07 17:03:47 EST (Wed, 07 Nov 2007)
@@ -0,0 +1,528 @@
+/*=============================================================================
+ Copyright (c) 2004 Joel de Guzman
+ http://spirit.sourceforge.net/
+
+ Use, modification and distribution is 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)
+=============================================================================*/
+
+/*=============================================================================
+ Body defaults
+=============================================================================*/
+
+ body
+ {
+ margin: 1em;
+ font-family: sans-serif;
+ }
+
+/*=============================================================================
+ Paragraphs
+=============================================================================*/
+
+ p
+ {
+ text-align: left;
+ font-size: 10pt;
+ line-height: 1.15;
+ }
+
+/*=============================================================================
+ Program listings
+=============================================================================*/
+
+ /* Code on paragraphs */
+ p tt.computeroutput
+ {
+ font-size: 9pt;
+ }
+
+ pre.synopsis
+ {
+ font-size: 90%;
+ margin: 1pc 4% 0pc 4%;
+ padding: 0.5pc 0.5pc 0.5pc 0.5pc;
+ }
+
+ .programlisting,
+ .screen
+ {
+ font-size: 9pt;
+ display: block;
+ margin: 1pc 4% 0pc 4%;
+ padding: 0.5pc 0.5pc 0.5pc 0.5pc;
+ }
+
+ /* Program listings in tables don't get borders */
+ td .programlisting,
+ td .screen
+ {
+ margin: 0pc 0pc 0pc 0pc;
+ padding: 0pc 0pc 0pc 0pc;
+ }
+
+/*=============================================================================
+ Headings
+=============================================================================*/
+
+ h1, h2, h3, h4, h5, h6
+ {
+ text-align: left;
+ margin: 1em 0em 0.5em 0em;
+ font-weight: bold;
+ }
+
+ h1 { font: 140% }
+ h2 { font: bold 140% }
+ h3 { font: bold 130% }
+ h4 { font: bold 120% }
+ h5 { font: italic 110% }
+ h6 { font: italic 100% }
+
+ /* Top page titles */
+ title,
+ h1.title,
+ h2.title
+ h3.title,
+ h4.title,
+ h5.title,
+ h6.title,
+ .refentrytitle
+ {
+ font-weight: bold;
+ margin-bottom: 1pc;
+ }
+
+ h1.title { font-size: 140% }
+ h2.title { font-size: 140% }
+ h3.title { font-size: 130% }
+ h4.title { font-size: 120% }
+ h5.title { font-size: 110% }
+ h6.title { font-size: 100% }
+
+ .section h1
+ {
+ margin: 0em 0em 0.5em 0em;
+ font-size: 140%;
+ }
+
+ .section h2 { font-size: 140% }
+ .section h3 { font-size: 130% }
+ .section h4 { font-size: 120% }
+ .section h5 { font-size: 110% }
+ .section h6 { font-size: 100% }
+
+ /* Code on titles */
+ h1 tt.computeroutput { font-size: 140% }
+ h2 tt.computeroutput { font-size: 140% }
+ h3 tt.computeroutput { font-size: 130% }
+ h4 tt.computeroutput { font-size: 120% }
+ h5 tt.computeroutput { font-size: 110% }
+ h6 tt.computeroutput { font-size: 100% }
+
+/*=============================================================================
+ Author
+=============================================================================*/
+
+ h3.author
+ {
+ font-size: 100%
+ }
+
+/*=============================================================================
+ Lists
+=============================================================================*/
+
+ li
+ {
+ font-size: 10pt;
+ line-height: 1.3;
+ }
+
+ /* Unordered lists */
+ ul
+ {
+ text-align: left;
+ }
+
+ /* Ordered lists */
+ ol
+ {
+ text-align: left;
+ }
+
+/*=============================================================================
+ Links
+=============================================================================*/
+
+ a
+ {
+ text-decoration: none; /* no underline */
+ }
+
+ a:hover
+ {
+ text-decoration: underline;
+ }
+
+/*=============================================================================
+ Spirit style navigation
+=============================================================================*/
+
+ .spirit-nav
+ {
+ text-align: right;
+ }
+
+ .spirit-nav a
+ {
+ color: white;
+ padding-left: 0.5em;
+ }
+
+ .spirit-nav img
+ {
+ border-width: 0px;
+ }
+
+/*=============================================================================
+ Table of contents
+=============================================================================*/
+
+ .toc
+ {
+ margin: 1pc 4% 0pc 4%;
+ padding: 0.1pc 1pc 0.1pc 1pc;
+ font-size: 80%;
+ line-height: 1.15;
+ }
+
+ .boost-toc
+ {
+ float: right;
+ padding: 0.5pc;
+ }
+
+/*=============================================================================
+ Tables
+=============================================================================*/
+
+ .table-title,
+ div.table p.title
+ {
+ margin-left: 4%;
+ padding-right: 0.5em;
+ padding-left: 0.5em;
+ }
+
+ .informaltable table,
+ .table table
+ {
+ width: 92%;
+ margin-left: 4%;
+ margin-right: 4%;
+ }
+
+ div.informaltable table,
+ div.table table
+ {
+ padding: 4px;
+ }
+
+ /* Table Cells */
+ div.informaltable table tr td,
+ div.table table tr td
+ {
+ padding: 0.5em;
+ text-align: left;
+ font-size: 9pt;
+ }
+
+ div.informaltable table tr th,
+ div.table table tr th
+ {
+ padding: 0.5em 0.5em 0.5em 0.5em;
+ border: 1pt solid white;
+ font-size: 80%;
+ }
+
+/*=============================================================================
+ Blurbs
+=============================================================================*/
+
+ div.note,
+ div.tip,
+ div.important,
+ div.caution,
+ div.warning,
+ div.sidebar
+ {
+ font-size: 9pt; /* A little bit smaller than the main text */
+ line-height: 1.2;
+ display: block;
+ margin: 1pc 4% 0pc 4%;
+ padding: 0.5pc 0.5pc 0.0pc 0.5pc;
+ }
+
+ div.sidebar img
+ {
+ padding: 1pt;
+ }
+
+/*=============================================================================
+ Callouts
+=============================================================================*/
+ .line_callout_bug img
+ {
+ float: left;
+ position:relative;
+ left: 4px;
+ top: -12px;
+ clear: left;
+ margin-left:-22px;
+ }
+
+ .callout_bug img
+ {
+ }
+
+/*=============================================================================
+ Variable Lists
+=============================================================================*/
+
+ /* Make the terms in definition lists bold */
+ div.variablelist dl dt,
+ span.term
+ {
+ font-weight: bold;
+ font-size: 10pt;
+ }
+
+ div.variablelist table tbody tr td
+ {
+ text-align: left;
+ vertical-align: top;
+ padding: 0em 2em 0em 0em;
+ font-size: 10pt;
+ margin: 0em 0em 0.5em 0em;
+ line-height: 1;
+ }
+
+ div.variablelist dl dt
+ {
+ margin-bottom: 0.2em;
+ }
+
+ div.variablelist dl dd
+ {
+ margin: 0em 0em 0.5em 2em;
+ font-size: 10pt;
+ }
+
+ div.variablelist table tbody tr td p,
+ div.variablelist dl dd p
+ {
+ margin: 0em 0em 0.5em 0em;
+ line-height: 1;
+ }
+
+/*=============================================================================
+ Misc
+=============================================================================*/
+
+ /* Title of books and articles in bibliographies */
+ span.title
+ {
+ font-style: italic;
+ }
+
+ span.underline
+ {
+ text-decoration: underline;
+ }
+
+ span.strikethrough
+ {
+ text-decoration: line-through;
+ }
+
+ /* Copyright, Legal Notice */
+ div div.legalnotice p
+ {
+ text-align: left
+ }
+
+/*=============================================================================
+ Colors
+=============================================================================*/
+
+ @media screen
+ {
+ /* Links */
+ a
+ {
+ color: #005a9c;
+ }
+
+ a:visited
+ {
+ color: #9c5a9c;
+ }
+
+ h1 a, h2 a, h3 a, h4 a, h5 a, h6 a,
+ h1 a:hover, h2 a:hover, h3 a:hover, h4 a:hover, h5 a:hover, h6 a:hover,
+ h1 a:visited, h2 a:visited, h3 a:visited, h4 a:visited, h5 a:visited, h6 a:visited
+ {
+ text-decoration: none; /* no underline */
+ color: #000000;
+ }
+
+ /* Syntax Highlighting */
+ .keyword { color: #0000AA; }
+ .identifier { color: #000000; }
+ .special { color: #707070; }
+ .preprocessor { color: #402080; }
+ .char { color: teal; }
+ .comment { color: #800000; }
+ .string { color: teal; }
+ .number { color: teal; }
+ .white_bkd { background-color: #FFFFFF; }
+ .dk_grey_bkd { background-color: #999999; }
+
+ /* Copyright, Legal Notice */
+ .copyright
+ {
+ color: #666666;
+ font-size: small;
+ }
+
+ div div.legalnotice p
+ {
+ color: #666666;
+ }
+
+ /* Program listing */
+ pre.synopsis
+ {
+ border: 1px solid #DCDCDC;
+ }
+
+ .programlisting,
+ .screen
+ {
+ border: 1px solid #DCDCDC;
+ }
+
+ td .programlisting,
+ td .screen
+ {
+ border: 0px solid #DCDCDC;
+ }
+
+ /* Blurbs */
+ div.note,
+ div.tip,
+ div.important,
+ div.caution,
+ div.warning,
+ div.sidebar
+ {
+ border: 1px solid #DCDCDC;
+ }
+
+ /* Table of contents */
+ .toc
+ {
+ border: 1px solid #DCDCDC;
+ }
+
+ /* Tables */
+ div.informaltable table tr td,
+ div.table table tr td
+ {
+ border: 1px solid #DCDCDC;
+ }
+
+ div.informaltable table tr th,
+ div.table table tr th
+ {
+ background-color: #F0F0F0;
+ border: 1px solid #DCDCDC;
+ }
+
+ /* Misc */
+ span.highlight
+ {
+ color: #00A000;
+ }
+ }
+
+ @media print
+ {
+ /* Links */
+ a
+ {
+ color: black;
+ }
+
+ a:visited
+ {
+ color: black;
+ }
+
+ .spirit-nav
+ {
+ display: none;
+ }
+
+ /* Program listing */
+ pre.synopsis
+ {
+ border: 1px solid gray;
+ }
+
+ .programlisting,
+ .screen
+ {
+ border: 1px solid gray;
+ }
+
+ td .programlisting,
+ td .screen
+ {
+ border: 0px solid #DCDCDC;
+ }
+
+ /* Table of contents */
+ .toc
+ {
+ border: 1px solid gray;
+ }
+
+ .informaltable table,
+ .table table
+ {
+ border: 1px solid gray;
+ border-collapse: collapse;
+ }
+
+ /* Tables */
+ div.informaltable table tr td,
+ div.table table tr td
+ {
+ border: 1px solid gray;
+ }
+
+ div.informaltable table tr th,
+ div.table table tr th
+ {
+ border: 1px solid gray;
+ }
+
+ /* Misc */
+ span.highlight
+ {
+ font-weight: bold;
+ }
+ }
Added: branches/proto/v3/libs/xpressive/proto3/doc/html/images/alert.png
==============================================================================
Binary file. No diff available.
Added: branches/proto/v3/libs/xpressive/proto3/doc/html/images/callouts/1.png
==============================================================================
Binary file. No diff available.
Added: branches/proto/v3/libs/xpressive/proto3/doc/html/images/callouts/10.png
==============================================================================
Binary file. No diff available.
Added: branches/proto/v3/libs/xpressive/proto3/doc/html/images/callouts/11.png
==============================================================================
Binary file. No diff available.
Added: branches/proto/v3/libs/xpressive/proto3/doc/html/images/callouts/12.png
==============================================================================
Binary file. No diff available.
Added: branches/proto/v3/libs/xpressive/proto3/doc/html/images/callouts/13.png
==============================================================================
Binary file. No diff available.
Added: branches/proto/v3/libs/xpressive/proto3/doc/html/images/callouts/14.png
==============================================================================
Binary file. No diff available.
Added: branches/proto/v3/libs/xpressive/proto3/doc/html/images/callouts/15.png
==============================================================================
Binary file. No diff available.
Added: branches/proto/v3/libs/xpressive/proto3/doc/html/images/callouts/2.png
==============================================================================
Binary file. No diff available.
Added: branches/proto/v3/libs/xpressive/proto3/doc/html/images/callouts/3.png
==============================================================================
Binary file. No diff available.
Added: branches/proto/v3/libs/xpressive/proto3/doc/html/images/callouts/4.png
==============================================================================
Binary file. No diff available.
Added: branches/proto/v3/libs/xpressive/proto3/doc/html/images/callouts/5.png
==============================================================================
Binary file. No diff available.
Added: branches/proto/v3/libs/xpressive/proto3/doc/html/images/callouts/6.png
==============================================================================
Binary file. No diff available.
Added: branches/proto/v3/libs/xpressive/proto3/doc/html/images/callouts/7.png
==============================================================================
Binary file. No diff available.
Added: branches/proto/v3/libs/xpressive/proto3/doc/html/images/callouts/8.png
==============================================================================
Binary file. No diff available.
Added: branches/proto/v3/libs/xpressive/proto3/doc/html/images/callouts/9.png
==============================================================================
Binary file. No diff available.
Added: branches/proto/v3/libs/xpressive/proto3/doc/html/images/caution.png
==============================================================================
Binary file. No diff available.
Added: branches/proto/v3/libs/xpressive/proto3/doc/html/images/home.png
==============================================================================
Binary file. No diff available.
Added: branches/proto/v3/libs/xpressive/proto3/doc/html/images/important.png
==============================================================================
Binary file. No diff available.
Added: branches/proto/v3/libs/xpressive/proto3/doc/html/images/next.png
==============================================================================
Binary file. No diff available.
Added: branches/proto/v3/libs/xpressive/proto3/doc/html/images/note.png
==============================================================================
Binary file. No diff available.
Added: branches/proto/v3/libs/xpressive/proto3/doc/html/images/prev.png
==============================================================================
Binary file. No diff available.
Added: branches/proto/v3/libs/xpressive/proto3/doc/html/images/smiley.png
==============================================================================
Binary file. No diff available.
Added: branches/proto/v3/libs/xpressive/proto3/doc/html/images/tip.png
==============================================================================
Binary file. No diff available.
Added: branches/proto/v3/libs/xpressive/proto3/doc/html/images/up.png
==============================================================================
Binary file. No diff available.
Added: branches/proto/v3/libs/xpressive/proto3/doc/html/images/warning.png
==============================================================================
Binary file. No diff available.
Added: branches/proto/v3/libs/xpressive/proto3/doc/implementation.qbk
==============================================================================
--- (empty file)
+++ branches/proto/v3/libs/xpressive/proto3/doc/implementation.qbk 2007-11-07 17:03:47 EST (Wed, 07 Nov 2007)
@@ -0,0 +1,12 @@
+[/
+ / Copyright (c) 2006 Eric Niebler
+ /
+ / Distributed under the Boost Software License, Version 1.0. (See accompanying
+ / file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+ /]
+
+[section:implementation Appendix C: Implementation Notes]
+
+TODO
+
+[endsect]
Added: branches/proto/v3/libs/xpressive/proto3/doc/installation.qbk
==============================================================================
--- (empty file)
+++ branches/proto/v3/libs/xpressive/proto3/doc/installation.qbk 2007-11-07 17:03:47 EST (Wed, 07 Nov 2007)
@@ -0,0 +1,39 @@
+[/
+ / Copyright (c) 2006 Eric Niebler
+ /
+ / Distributed under the Boost Software License, Version 1.0. (See accompanying
+ / file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+ /]
+
+[section Installing Proto]
+
+[heading Getting Proto]
+
+Currently the only way to get Proto is through CVS via the boost project on
+SourceForge.net. Just go to [@http://sf.net/projects/boost] and follow the
+instructions there for anonymous CVS 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/xpressive/proto/proto.hpp>`. This will include the
+core of Proto. If you want to use any transforms, you must include the
+appropriate header from the [^boost\/xpressive\/proto\/transform\/] directory.
+
+[heading Requirements]
+
+Proto depends on Boost. You must use the version in CVS HEAD.
+
+[heading Supported Compilers]
+
+Currently, Boost.Proto is known to work on the following compilers:
+
+* Visual C++ 7.1 and higher
+* GNU C++ 3.2 and higher
+* Intel on Linun 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/v3/libs/xpressive/proto3/doc/preface.qbk
==============================================================================
--- (empty file)
+++ branches/proto/v3/libs/xpressive/proto3/doc/preface.qbk 2007-11-07 17:03:47 EST (Wed, 07 Nov 2007)
@@ -0,0 +1,66 @@
+[/
+ / Copyright (c) 2006 Eric Niebler
+ /
+ / Distributed under the Boost Software License, Version 1.0. (See accompanying
+ / file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+ /]
+
+[section Preface]
+
+[:Something witty.]
+[:[*['-- Someone Famous]]]
+
+[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.
+
+[endsect]
Added: branches/proto/v3/libs/xpressive/proto3/doc/proto.qbk
==============================================================================
--- (empty file)
+++ branches/proto/v3/libs/xpressive/proto3/doc/proto.qbk 2007-11-07 17:03:47 EST (Wed, 07 Nov 2007)
@@ -0,0 +1,133 @@
+
+[library Boost.Proto
+ [quickbook 1.3]
+ [authors [Niebler, Eric]]
+ [copyright 2006 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) 2006 Eric Niebler
+ /
+ / Distributed under the Boost Software License, Version 1.0. (See accompanying
+ / file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+ /]
+
+[/ 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 _spirit_fx_ [@http://spirit.sourceforge.net Spirit Parser Framework]]
+[def _spirit_ [@http://spirit.sourceforge.net Spirit]]
+[def _xpressive_ [@../../../libs/xpressive/doc/index.html Boost.Xpressive]]
+[def _expr_ [classref boost::proto::exprns_::expr<Tag,Args,1> `expr<>`]]
+[def _ref_ [classref boost::proto::refns_::ref_ `ref_<>`]]
+[def _unref_ [classref boost::proto::functional::unref `unref()`]]
+[def _deep_copy_ [classref boost::proto::functional::deep_copy `deep_copy()`]]
+[def _extends_ [classref boost::proto::exprns_::extends `extends<>`]]
+[def _as_expr_ [classref boost::proto::functional::as_expr `as_expr()`]]
+[def _as_arg_ [classref boost::proto::functional::as_arg `as_arg()`]]
+[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_if::is_expr `is_expr<>`]]
+[def _tag_of_ [classref boost::proto::result_if::tag_of `tag_of<>`]]
+[def _arg_ [funcref boost::proto::arg `arg()`]]
+[def _arg_c_ [funcref boost::proto::arg_c `arg_c()`]]
+[def _eval_ [classref boost::proto::functional::eval `eval()`]]
+[def _left_ [classref boost::proto::functional::left `left()`]]
+[def _right_ [classref boost::proto::functional::right `right()`]]
+[def _terminal_ [classref boost::proto::op::terminal `terminal<>`]]
+[def _unary_expr_ [classref boost::proto::op::unary_expr `unary_expr<>`]]
+[def _binary_expr_ [classref boost::proto::op::binary_expr `binary_expr<>`]]
+[def _literal_ [classref boost::proto::utility::literal `literal<>`]]
+[def _lit_ [funcref boost::proto::lit `lit()`]]
+[def _vararg_ [classref boost::proto::control::vararg `vararg<>`]]
+[def _default_context_ [classref boost::proto::context::default_context `default_context`]]
+[def _callable_context_ [classref boost::proto::context::callable_context `callable_context<>`]]
+
+[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 faciities, 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 protodoc.xml]
+
+[section Appendices]
+
+[include history.qbk]
+
+[include rationale.qbk]
+
+[include implementation.qbk]
+
+[include acknowledgements.qbk]
+
+[endsect]
Added: branches/proto/v3/libs/xpressive/proto3/doc/protodoc.xml
==============================================================================
--- (empty file)
+++ branches/proto/v3/libs/xpressive/proto3/doc/protodoc.xml 2007-11-07 17:03:47 EST (Wed, 07 Nov 2007)
@@ -0,0 +1,2216 @@
+<?xml version="1.0" standalone="yes"?>
+<library-reference><header name="boost/xpressive/proto/args.hpp"><para>Contains definition of args<> class template. </para><namespace name="boost"><namespace name="proto"><namespace name="argsns_"><struct name="args0"><template>
+ <template-type-parameter name="Arg0"/>
+ </template><purpose>A type sequence, for use as the 2nd parameter to the <computeroutput>expr<></computeroutput> class template. </purpose><description><para>A type sequence, for use as the 2nd parameter to the <computeroutput>expr<></computeroutput> class template. The types in the sequence correspond to the children of a node in an expression tree. </para></description><typedef name="arg0"><type>Arg0</type></typedef><typedef name="arg1"><type>mpl::void_</type></typedef><typedef name="arg2"><type>mpl::void_</type></typedef><typedef name="arg3"><type>mpl::void_</type></typedef><typedef name="arg4"><type>mpl::void_</type></typedef><data-member name="size" specifiers="static"><type>const long</type></data-member></struct><struct name="args1"><template>
+ <template-type-parameter name="Arg0"/>
+ </template><purpose>A type sequence, for use as the 2nd parameter to the <computeroutput>expr<></computeroutput> class template. </purpose><description><para>A type sequence, for use as the 2nd parameter to the <computeroutput>expr<></computeroutput> class template. The types in the sequence correspond to the children of a node in an expression tree. </para></description><typedef name="arg0"><type>Arg0</type></typedef><typedef name="arg1"><type>mpl::void_</type></typedef><typedef name="arg2"><type>mpl::void_</type></typedef><typedef name="arg3"><type>mpl::void_</type></typedef><typedef name="arg4"><type>mpl::void_</type></typedef><data-member name="size" specifiers="static"><type>const long</type></data-member></struct><struct name="args2"><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<></computeroutput> class template. </purpose><description><para>A type sequence, for use as the 2nd parameter to the <computeroutput>expr<></computeroutput> class template. The types in the sequence correspond to the children of a node in an expression tree. </para></description><typedef name="arg0"><type>Arg0</type></typedef><typedef name="arg1"><type>Arg1</type></typedef><typedef name="arg2"><type>mpl::void_</type></typedef><typedef name="arg3"><type>mpl::void_</type></typedef><typedef name="arg4"><type>mpl::void_</type></typedef><data-member name="size" specifiers="static"><type>const long</type></data-member></struct><struct name="args3"><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<></computeroutput> class template. </purpose><description><para>A type sequence, for use as the 2nd parameter to the <computeroutput>expr<></computeroutput> class template. The types in the sequence correspond to the children of a node in an expression tree. </para></description><typedef name="arg0"><type>Arg0</type></typedef><typedef name="arg1"><type>Arg1</type></typedef><typedef name="arg2"><type>Arg2</type></typedef><typedef name="arg3"><type>mpl::void_</type></typedef><typedef name="arg4"><type>mpl::void_</type></typedef><data-member name="size" specifiers="static"><type>const long</type></data-member></struct><struct name="args4"><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<></computeroutput> class template. </purpose><description><para>A type sequence, for use as the 2nd parameter to the <computeroutput>expr<></computeroutput> class template. The types in the sequence correspond to the children of a node in an expression tree. </para></description><typedef name="arg0"><type>Arg0</type></typedef><typedef name="arg1"><type>Arg1</type></typedef><typedef name="arg2"><type>Arg2</type></typedef><typedef name="arg3"><type>Arg3</type></typedef><typedef name="arg4"><type>mpl::void_</type></typedef><data-member name="size" specifiers="static"><type>const long</type></data-member></struct><struct name="args5"><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<></computeroutput> class template. </purpose><description><para>A type sequence, for use as the 2nd parameter to the <computeroutput>expr<></computeroutput> class template. The types in the sequence correspond to the children of a node in an expression tree. </para></description><typedef name="arg0"><type>Arg0</type></typedef><typedef name="arg1"><type>Arg1</type></typedef><typedef name="arg2"><type>Arg2</type></typedef><typedef name="arg3"><type>Arg3</type></typedef><typedef name="arg4"><type>Arg4</type></typedef><data-member name="size" specifiers="static"><type>const long</type></data-member></struct></namespace></namespace></namespace></header><header name="boost/xpressive/proto/context.hpp"><para>Includes all the context classes in the context/ sub-directory. </para></header><header name="boost/xpressive/proto/context/callable.hpp"><para>Definintion of callable_context<>, an evaluation co
ntext 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 the default_context. TODO: make the fall-back configurable! </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></template-nontype-parameter>
+ </template><description><para>callable_eval </para></description></struct><struct name="callable_context"><template>
+ <template-type-parameter name="Context"/>
+ <template-type-parameter name="DefaultCtx"/>
+ </template><description><para>callable_context </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>callable_context::eval </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><typedef name="result_type"><type>boost::result_of< Context(typename Expr::proto_tag, typename proto::result_of::arg_c< Expr, 0 >::const_reference)>::type</type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type>result_type</type><parameter name="expr"><paramtype>Expr &</paramtype></parameter><parameter name="context"><paramtype>Context &</paramtype></parameter></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><typedef name="result_type"><type>boost::result_of< Context(typename Expr::proto_tag, typename proto::result_of::arg_c< Expr, 0 >::const_reference)>::type</type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type>result_type</type><parameter name="expr"><paramtype>Expr &</paramtype></parameter><parameter name="context"><paramtype>Context &</paramtype></parameter></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><typedef name="result_type"><type>boost::result_of< Context(typename Expr::proto_tag, typename proto::result_of::arg_c< Expr, 0 >::const_reference, typename proto::result_of::arg_c< Expr, 1 >::const_reference)>::type</type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type>result_type</type><parameter name="expr"><paramtype>Expr &</paramtype></parameter><parameter name="context"><paramtype>Context &</paramtype></parameter></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><typedef name="result_type"><type>boost::result_of< Context(typename Expr::proto_tag, typename proto::result_of::arg_c< Expr, 0 >::const_reference, typename proto::result_of::arg_c< Expr, 1 >::const_reference, typename proto::result_of::arg_c< Expr, 2 >::const_reference)>::type</type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type>result_type</type><parameter name="expr"><paramtype>Expr &</paramtype></parameter><parameter name="context"><paramtype>Context &</paramtype></parameter></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><typedef name="result_type"><type>boost::result_of< Context(typename Expr::proto_tag, typename proto::result_of::arg_c< Expr, 0 >::const_reference, typename proto::result_of::arg_c< Expr, 1 >::const_reference, typename proto::result_of::arg_c< Expr, 2 >::const_reference, typename proto::result_of::arg_c< Expr, 3 >::const_reference)>::type</type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type>result_type</type><parameter name="expr"><paramtype>Expr &</paramtype></parameter><parameter name="context"><paramtype>Context &</paramtype></parameter></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><typedef name="result_type"><type>boost::result_of< Context(typename Expr::proto_tag, typename proto::result_of::arg_c< Expr, 0 >::const_reference, typename proto::result_of::arg_c< Expr, 1 >::const_reference, typename proto::result_of::arg_c< Expr, 2 >::const_reference, typename proto::result_of::arg_c< Expr, 3 >::const_reference, typename proto::result_of::arg_c< Expr, 4 >::const_reference)>::type</type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type>result_type</type><parameter name="expr"><paramtype>Expr &</paramtype></parameter><parameter name="context"><paramtype>Context &</paramtype></parameter></method></method-group></struct-specialization></namespace></namespace></namespace></header><header name="boost/xpressive/proto/context/default.hpp"><para>Definintion of d
efault_context, a default evaluation context for proto::eval() that uses Boost.Typeof to deduce return types of the built-in operators. </para><namespace name="boost"><namespace name="proto"><namespace name="context"><struct name="default_eval"><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="Context"/>
+ <template-type-parameter name="Tag"/>
+ <template-nontype-parameter name="Arity"><type>long</type></template-nontype-parameter>
+ </template></struct><struct name="default_context"><description><para>default_context </para></description><struct name="eval"><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="ThisContext"><default>default_context const</default></template-type-parameter>
+ </template><inherit access="public">boost::proto::context::default_eval< Expr, ThisContext ></inherit><description><para>default_context::eval </para></description></struct></struct><struct-specialization name="default_eval"><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="Context"/>
+ </template><specialization><template-arg>Expr</template-arg><template-arg>Context</template-arg><template-arg>proto::tag::posit</template-arg><template-arg>1</template-arg></specialization><typedef name="result_type"><type><emphasis>unspecified</emphasis></type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type>result_type</type><parameter name="expr"><paramtype>Expr &</paramtype></parameter><parameter name="ctx"><paramtype>Context &</paramtype></parameter></method></method-group></struct-specialization><struct-specialization name="default_eval"><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="Context"/>
+ </template><specialization><template-arg>Expr</template-arg><template-arg>Context</template-arg><template-arg>proto::tag::negate</template-arg><template-arg>1</template-arg></specialization><typedef name="result_type"><type><emphasis>unspecified</emphasis></type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type>result_type</type><parameter name="expr"><paramtype>Expr &</paramtype></parameter><parameter name="ctx"><paramtype>Context &</paramtype></parameter></method></method-group></struct-specialization><struct-specialization name="default_eval"><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="Context"/>
+ </template><specialization><template-arg>Expr</template-arg><template-arg>Context</template-arg><template-arg>proto::tag::dereference</template-arg><template-arg>1</template-arg></specialization><typedef name="result_type"><type><emphasis>unspecified</emphasis></type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type>result_type</type><parameter name="expr"><paramtype>Expr &</paramtype></parameter><parameter name="ctx"><paramtype>Context &</paramtype></parameter></method></method-group></struct-specialization><struct-specialization name="default_eval"><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="Context"/>
+ </template><specialization><template-arg>Expr</template-arg><template-arg>Context</template-arg><template-arg>proto::tag::complement</template-arg><template-arg>1</template-arg></specialization><typedef name="result_type"><type><emphasis>unspecified</emphasis></type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type>result_type</type><parameter name="expr"><paramtype>Expr &</paramtype></parameter><parameter name="ctx"><paramtype>Context &</paramtype></parameter></method></method-group></struct-specialization><struct-specialization name="default_eval"><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="Context"/>
+ </template><specialization><template-arg>Expr</template-arg><template-arg>Context</template-arg><template-arg>proto::tag::address_of</template-arg><template-arg>1</template-arg></specialization><typedef name="result_type"><type><emphasis>unspecified</emphasis></type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type>result_type</type><parameter name="expr"><paramtype>Expr &</paramtype></parameter><parameter name="ctx"><paramtype>Context &</paramtype></parameter></method></method-group></struct-specialization><struct-specialization name="default_eval"><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="Context"/>
+ </template><specialization><template-arg>Expr</template-arg><template-arg>Context</template-arg><template-arg>proto::tag::logical_not</template-arg><template-arg>1</template-arg></specialization><typedef name="result_type"><type><emphasis>unspecified</emphasis></type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type>result_type</type><parameter name="expr"><paramtype>Expr &</paramtype></parameter><parameter name="ctx"><paramtype>Context &</paramtype></parameter></method></method-group></struct-specialization><struct-specialization name="default_eval"><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="Context"/>
+ </template><specialization><template-arg>Expr</template-arg><template-arg>Context</template-arg><template-arg>proto::tag::pre_inc</template-arg><template-arg>1</template-arg></specialization><typedef name="result_type"><type><emphasis>unspecified</emphasis></type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type>result_type</type><parameter name="expr"><paramtype>Expr &</paramtype></parameter><parameter name="ctx"><paramtype>Context &</paramtype></parameter></method></method-group></struct-specialization><struct-specialization name="default_eval"><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="Context"/>
+ </template><specialization><template-arg>Expr</template-arg><template-arg>Context</template-arg><template-arg>proto::tag::pre_dec</template-arg><template-arg>1</template-arg></specialization><typedef name="result_type"><type><emphasis>unspecified</emphasis></type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type>result_type</type><parameter name="expr"><paramtype>Expr &</paramtype></parameter><parameter name="ctx"><paramtype>Context &</paramtype></parameter></method></method-group></struct-specialization><struct-specialization name="default_eval"><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="Context"/>
+ </template><specialization><template-arg>Expr</template-arg><template-arg>Context</template-arg><template-arg>proto::tag::shift_left</template-arg><template-arg>2</template-arg></specialization><typedef name="result_type"><type><emphasis>unspecified</emphasis></type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type>result_type</type><parameter name="expr"><paramtype>Expr &</paramtype></parameter><parameter name="ctx"><paramtype>Context &</paramtype></parameter></method></method-group></struct-specialization><struct-specialization name="default_eval"><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="Context"/>
+ </template><specialization><template-arg>Expr</template-arg><template-arg>Context</template-arg><template-arg>proto::tag::shift_right</template-arg><template-arg>2</template-arg></specialization><typedef name="result_type"><type><emphasis>unspecified</emphasis></type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type>result_type</type><parameter name="expr"><paramtype>Expr &</paramtype></parameter><parameter name="ctx"><paramtype>Context &</paramtype></parameter></method></method-group></struct-specialization><struct-specialization name="default_eval"><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="Context"/>
+ </template><specialization><template-arg>Expr</template-arg><template-arg>Context</template-arg><template-arg>proto::tag::multiplies</template-arg><template-arg>2</template-arg></specialization><typedef name="result_type"><type><emphasis>unspecified</emphasis></type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type>result_type</type><parameter name="expr"><paramtype>Expr &</paramtype></parameter><parameter name="ctx"><paramtype>Context &</paramtype></parameter></method></method-group></struct-specialization><struct-specialization name="default_eval"><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="Context"/>
+ </template><specialization><template-arg>Expr</template-arg><template-arg>Context</template-arg><template-arg>proto::tag::divides</template-arg><template-arg>2</template-arg></specialization><typedef name="result_type"><type><emphasis>unspecified</emphasis></type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type>result_type</type><parameter name="expr"><paramtype>Expr &</paramtype></parameter><parameter name="ctx"><paramtype>Context &</paramtype></parameter></method></method-group></struct-specialization><struct-specialization name="default_eval"><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="Context"/>
+ </template><specialization><template-arg>Expr</template-arg><template-arg>Context</template-arg><template-arg>proto::tag::modulus</template-arg><template-arg>2</template-arg></specialization><typedef name="result_type"><type><emphasis>unspecified</emphasis></type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type>result_type</type><parameter name="expr"><paramtype>Expr &</paramtype></parameter><parameter name="ctx"><paramtype>Context &</paramtype></parameter></method></method-group></struct-specialization><struct-specialization name="default_eval"><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="Context"/>
+ </template><specialization><template-arg>Expr</template-arg><template-arg>Context</template-arg><template-arg>proto::tag::plus</template-arg><template-arg>2</template-arg></specialization><typedef name="result_type"><type><emphasis>unspecified</emphasis></type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type>result_type</type><parameter name="expr"><paramtype>Expr &</paramtype></parameter><parameter name="ctx"><paramtype>Context &</paramtype></parameter></method></method-group></struct-specialization><struct-specialization name="default_eval"><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="Context"/>
+ </template><specialization><template-arg>Expr</template-arg><template-arg>Context</template-arg><template-arg>proto::tag::minus</template-arg><template-arg>2</template-arg></specialization><typedef name="result_type"><type><emphasis>unspecified</emphasis></type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type>result_type</type><parameter name="expr"><paramtype>Expr &</paramtype></parameter><parameter name="ctx"><paramtype>Context &</paramtype></parameter></method></method-group></struct-specialization><struct-specialization name="default_eval"><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="Context"/>
+ </template><specialization><template-arg>Expr</template-arg><template-arg>Context</template-arg><template-arg>proto::tag::less</template-arg><template-arg>2</template-arg></specialization><typedef name="result_type"><type><emphasis>unspecified</emphasis></type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type>result_type</type><parameter name="expr"><paramtype>Expr &</paramtype></parameter><parameter name="ctx"><paramtype>Context &</paramtype></parameter></method></method-group></struct-specialization><struct-specialization name="default_eval"><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="Context"/>
+ </template><specialization><template-arg>Expr</template-arg><template-arg>Context</template-arg><template-arg>proto::tag::greater</template-arg><template-arg>2</template-arg></specialization><typedef name="result_type"><type><emphasis>unspecified</emphasis></type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type>result_type</type><parameter name="expr"><paramtype>Expr &</paramtype></parameter><parameter name="ctx"><paramtype>Context &</paramtype></parameter></method></method-group></struct-specialization><struct-specialization name="default_eval"><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="Context"/>
+ </template><specialization><template-arg>Expr</template-arg><template-arg>Context</template-arg><template-arg>proto::tag::less_equal</template-arg><template-arg>2</template-arg></specialization><typedef name="result_type"><type><emphasis>unspecified</emphasis></type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type>result_type</type><parameter name="expr"><paramtype>Expr &</paramtype></parameter><parameter name="ctx"><paramtype>Context &</paramtype></parameter></method></method-group></struct-specialization><struct-specialization name="default_eval"><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="Context"/>
+ </template><specialization><template-arg>Expr</template-arg><template-arg>Context</template-arg><template-arg>proto::tag::greater_equal</template-arg><template-arg>2</template-arg></specialization><typedef name="result_type"><type><emphasis>unspecified</emphasis></type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type>result_type</type><parameter name="expr"><paramtype>Expr &</paramtype></parameter><parameter name="ctx"><paramtype>Context &</paramtype></parameter></method></method-group></struct-specialization><struct-specialization name="default_eval"><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="Context"/>
+ </template><specialization><template-arg>Expr</template-arg><template-arg>Context</template-arg><template-arg>proto::tag::equal_to</template-arg><template-arg>2</template-arg></specialization><typedef name="result_type"><type><emphasis>unspecified</emphasis></type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type>result_type</type><parameter name="expr"><paramtype>Expr &</paramtype></parameter><parameter name="ctx"><paramtype>Context &</paramtype></parameter></method></method-group></struct-specialization><struct-specialization name="default_eval"><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="Context"/>
+ </template><specialization><template-arg>Expr</template-arg><template-arg>Context</template-arg><template-arg>proto::tag::not_equal_to</template-arg><template-arg>2</template-arg></specialization><typedef name="result_type"><type><emphasis>unspecified</emphasis></type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type>result_type</type><parameter name="expr"><paramtype>Expr &</paramtype></parameter><parameter name="ctx"><paramtype>Context &</paramtype></parameter></method></method-group></struct-specialization><struct-specialization name="default_eval"><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="Context"/>
+ </template><specialization><template-arg>Expr</template-arg><template-arg>Context</template-arg><template-arg>proto::tag::logical_or</template-arg><template-arg>2</template-arg></specialization><typedef name="result_type"><type><emphasis>unspecified</emphasis></type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type>result_type</type><parameter name="expr"><paramtype>Expr &</paramtype></parameter><parameter name="ctx"><paramtype>Context &</paramtype></parameter></method></method-group></struct-specialization><struct-specialization name="default_eval"><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="Context"/>
+ </template><specialization><template-arg>Expr</template-arg><template-arg>Context</template-arg><template-arg>proto::tag::logical_and</template-arg><template-arg>2</template-arg></specialization><typedef name="result_type"><type><emphasis>unspecified</emphasis></type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type>result_type</type><parameter name="expr"><paramtype>Expr &</paramtype></parameter><parameter name="ctx"><paramtype>Context &</paramtype></parameter></method></method-group></struct-specialization><struct-specialization name="default_eval"><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="Context"/>
+ </template><specialization><template-arg>Expr</template-arg><template-arg>Context</template-arg><template-arg>proto::tag::bitwise_and</template-arg><template-arg>2</template-arg></specialization><typedef name="result_type"><type><emphasis>unspecified</emphasis></type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type>result_type</type><parameter name="expr"><paramtype>Expr &</paramtype></parameter><parameter name="ctx"><paramtype>Context &</paramtype></parameter></method></method-group></struct-specialization><struct-specialization name="default_eval"><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="Context"/>
+ </template><specialization><template-arg>Expr</template-arg><template-arg>Context</template-arg><template-arg>proto::tag::bitwise_or</template-arg><template-arg>2</template-arg></specialization><typedef name="result_type"><type><emphasis>unspecified</emphasis></type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type>result_type</type><parameter name="expr"><paramtype>Expr &</paramtype></parameter><parameter name="ctx"><paramtype>Context &</paramtype></parameter></method></method-group></struct-specialization><struct-specialization name="default_eval"><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="Context"/>
+ </template><specialization><template-arg>Expr</template-arg><template-arg>Context</template-arg><template-arg>proto::tag::bitwise_xor</template-arg><template-arg>2</template-arg></specialization><typedef name="result_type"><type><emphasis>unspecified</emphasis></type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type>result_type</type><parameter name="expr"><paramtype>Expr &</paramtype></parameter><parameter name="ctx"><paramtype>Context &</paramtype></parameter></method></method-group></struct-specialization><struct-specialization name="default_eval"><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="Context"/>
+ </template><specialization><template-arg>Expr</template-arg><template-arg>Context</template-arg><template-arg>proto::tag::mem_ptr</template-arg><template-arg>2</template-arg></specialization><typedef name="result_type"><type><emphasis>unspecified</emphasis></type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type>result_type</type><parameter name="expr"><paramtype>Expr &</paramtype></parameter><parameter name="ctx"><paramtype>Context &</paramtype></parameter></method></method-group></struct-specialization><struct-specialization name="default_eval"><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="Context"/>
+ </template><specialization><template-arg>Expr</template-arg><template-arg>Context</template-arg><template-arg>proto::tag::assign</template-arg><template-arg>2</template-arg></specialization><typedef name="result_type"><type><emphasis>unspecified</emphasis></type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type>result_type</type><parameter name="expr"><paramtype>Expr &</paramtype></parameter><parameter name="ctx"><paramtype>Context &</paramtype></parameter></method></method-group></struct-specialization><struct-specialization name="default_eval"><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="Context"/>
+ </template><specialization><template-arg>Expr</template-arg><template-arg>Context</template-arg><template-arg>proto::tag::shift_left_assign</template-arg><template-arg>2</template-arg></specialization><typedef name="result_type"><type><emphasis>unspecified</emphasis></type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type>result_type</type><parameter name="expr"><paramtype>Expr &</paramtype></parameter><parameter name="ctx"><paramtype>Context &</paramtype></parameter></method></method-group></struct-specialization><struct-specialization name="default_eval"><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="Context"/>
+ </template><specialization><template-arg>Expr</template-arg><template-arg>Context</template-arg><template-arg>proto::tag::shift_right_assign</template-arg><template-arg>2</template-arg></specialization><typedef name="result_type"><type><emphasis>unspecified</emphasis></type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type>result_type</type><parameter name="expr"><paramtype>Expr &</paramtype></parameter><parameter name="ctx"><paramtype>Context &</paramtype></parameter></method></method-group></struct-specialization><struct-specialization name="default_eval"><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="Context"/>
+ </template><specialization><template-arg>Expr</template-arg><template-arg>Context</template-arg><template-arg>proto::tag::multilpies_assign</template-arg><template-arg>2</template-arg></specialization><typedef name="result_type"><type><emphasis>unspecified</emphasis></type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type>result_type</type><parameter name="expr"><paramtype>Expr &</paramtype></parameter><parameter name="ctx"><paramtype>Context &</paramtype></parameter></method></method-group></struct-specialization><struct-specialization name="default_eval"><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="Context"/>
+ </template><specialization><template-arg>Expr</template-arg><template-arg>Context</template-arg><template-arg>proto::tag::divides_assign</template-arg><template-arg>2</template-arg></specialization><typedef name="result_type"><type><emphasis>unspecified</emphasis></type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type>result_type</type><parameter name="expr"><paramtype>Expr &</paramtype></parameter><parameter name="ctx"><paramtype>Context &</paramtype></parameter></method></method-group></struct-specialization><struct-specialization name="default_eval"><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="Context"/>
+ </template><specialization><template-arg>Expr</template-arg><template-arg>Context</template-arg><template-arg>proto::tag::modulus_assign</template-arg><template-arg>2</template-arg></specialization><typedef name="result_type"><type><emphasis>unspecified</emphasis></type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type>result_type</type><parameter name="expr"><paramtype>Expr &</paramtype></parameter><parameter name="ctx"><paramtype>Context &</paramtype></parameter></method></method-group></struct-specialization><struct-specialization name="default_eval"><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="Context"/>
+ </template><specialization><template-arg>Expr</template-arg><template-arg>Context</template-arg><template-arg>proto::tag::plus_assign</template-arg><template-arg>2</template-arg></specialization><typedef name="result_type"><type><emphasis>unspecified</emphasis></type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type>result_type</type><parameter name="expr"><paramtype>Expr &</paramtype></parameter><parameter name="ctx"><paramtype>Context &</paramtype></parameter></method></method-group></struct-specialization><struct-specialization name="default_eval"><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="Context"/>
+ </template><specialization><template-arg>Expr</template-arg><template-arg>Context</template-arg><template-arg>proto::tag::minus_assign</template-arg><template-arg>2</template-arg></specialization><typedef name="result_type"><type><emphasis>unspecified</emphasis></type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type>result_type</type><parameter name="expr"><paramtype>Expr &</paramtype></parameter><parameter name="ctx"><paramtype>Context &</paramtype></parameter></method></method-group></struct-specialization><struct-specialization name="default_eval"><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="Context"/>
+ </template><specialization><template-arg>Expr</template-arg><template-arg>Context</template-arg><template-arg>proto::tag::bitwise_and_assign</template-arg><template-arg>2</template-arg></specialization><typedef name="result_type"><type><emphasis>unspecified</emphasis></type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type>result_type</type><parameter name="expr"><paramtype>Expr &</paramtype></parameter><parameter name="ctx"><paramtype>Context &</paramtype></parameter></method></method-group></struct-specialization><struct-specialization name="default_eval"><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="Context"/>
+ </template><specialization><template-arg>Expr</template-arg><template-arg>Context</template-arg><template-arg>proto::tag::bitwise_or_assign</template-arg><template-arg>2</template-arg></specialization><typedef name="result_type"><type><emphasis>unspecified</emphasis></type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type>result_type</type><parameter name="expr"><paramtype>Expr &</paramtype></parameter><parameter name="ctx"><paramtype>Context &</paramtype></parameter></method></method-group></struct-specialization><struct-specialization name="default_eval"><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="Context"/>
+ </template><specialization><template-arg>Expr</template-arg><template-arg>Context</template-arg><template-arg>proto::tag::bitwise_xor_assign</template-arg><template-arg>2</template-arg></specialization><typedef name="result_type"><type><emphasis>unspecified</emphasis></type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type>result_type</type><parameter name="expr"><paramtype>Expr &</paramtype></parameter><parameter name="ctx"><paramtype>Context &</paramtype></parameter></method></method-group></struct-specialization><struct-specialization name="default_eval"><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="Context"/>
+ </template><specialization><template-arg>Expr</template-arg><template-arg>Context</template-arg><template-arg>proto::tag::terminal</template-arg><template-arg>0</template-arg></specialization><typedef name="result_type"><type>mpl::if_< is_const < Expr >, typename <classname>proto::result_of::arg</classname>< Expr >::const_reference, typename <classname>proto::result_of::arg</classname>< Expr >::reference >::type</type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type>result_type</type><parameter name="expr"><paramtype>Expr &</paramtype></parameter><parameter name=""><paramtype>Context &</paramtype></parameter></method></method-group></struct-specialization><struct-specialization name="default_eval"><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="Context"/>
+ </template><specialization><template-arg>Expr</template-arg><template-arg>Context</template-arg><template-arg>proto::tag::post_inc</template-arg><template-arg>1</template-arg></specialization><typedef name="result_type"><type><emphasis>unspecified</emphasis></type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type>result_type</type><parameter name="expr"><paramtype>Expr &</paramtype></parameter><parameter name="ctx"><paramtype>Context &</paramtype></parameter></method></method-group></struct-specialization><struct-specialization name="default_eval"><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="Context"/>
+ </template><specialization><template-arg>Expr</template-arg><template-arg>Context</template-arg><template-arg>proto::tag::post_dec</template-arg><template-arg>1</template-arg></specialization><typedef name="result_type"><type><emphasis>unspecified</emphasis></type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type>result_type</type><parameter name="expr"><paramtype>Expr &</paramtype></parameter><parameter name="ctx"><paramtype>Context &</paramtype></parameter></method></method-group></struct-specialization><struct-specialization name="default_eval"><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="Context"/>
+ </template><specialization><template-arg>Expr</template-arg><template-arg>Context</template-arg><template-arg>proto::tag::subscript</template-arg><template-arg>2</template-arg></specialization><typedef name="result_type"><type><emphasis>unspecified</emphasis></type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type>result_type</type><parameter name="expr"><paramtype>Expr &</paramtype></parameter><parameter name="ctx"><paramtype>Context &</paramtype></parameter></method></method-group></struct-specialization><struct-specialization name="default_eval"><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="Context"/>
+ </template><specialization><template-arg>Expr</template-arg><template-arg>Context</template-arg><template-arg>proto::tag::if_else_</template-arg><template-arg>3</template-arg></specialization><typedef name="result_type"><type><emphasis>unspecified</emphasis></type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type>result_type</type><parameter name="expr"><paramtype>Expr &</paramtype></parameter><parameter name="ctx"><paramtype>Context &</paramtype></parameter></method></method-group></struct-specialization><struct-specialization name="default_eval"><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="Context"/>
+ </template><specialization><template-arg>Expr</template-arg><template-arg>Context</template-arg><template-arg>proto::tag::comma</template-arg><template-arg>2</template-arg></specialization><typedef name="proto_arg0"><type><classname>proto::result_of::eval</classname>< typename proto::result_of::arg_c< Expr, 0 >::type, Context >::type</type></typedef><typedef name="proto_arg1"><type><classname>proto::result_of::eval</classname>< typename proto::result_of::arg_c< Expr, 1 >::type, Context >::type</type></typedef><typedef name="result_type"><type><emphasis>unspecified</emphasis></type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type>result_type</type><parameter name="expr"><paramtype>Expr &</paramtype></parameter><parameter name="ctx"><paramtype>Context &</paramtype></parameter></method></method-group></struct-specialization><struct-specialization name="default_eval"><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="Context"/>
+ </template><specialization><template-arg>Expr</template-arg><template-arg>Context</template-arg><template-arg>proto::tag::function</template-arg><template-arg>1</template-arg></specialization><typedef name="function_type"><type><emphasis>unspecified</emphasis></type></typedef><typedef name="result_type"><type>boost::result_of< function_type()>::type</type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type>result_type</type><parameter name="expr"><paramtype>Expr &</paramtype></parameter><parameter name="context"><paramtype>Context &</paramtype></parameter></method></method-group></struct-specialization><struct-specialization name="default_eval"><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="Context"/>
+ </template><specialization><template-arg>Expr</template-arg><template-arg>Context</template-arg><template-arg>proto::tag::function</template-arg><template-arg>2</template-arg></specialization><typedef name="function_type"><type><emphasis>unspecified</emphasis></type></typedef><typedef name="result_type"><type>boost::result_of< function_type(typename <classname>proto::result_of::eval</classname>< typename proto::result_of::arg_c< Expr, 1 >::type, Context >::type)>::type</type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type>result_type</type><parameter name="expr"><paramtype>Expr &</paramtype></parameter><parameter name="context"><paramtype>Context &</paramtype></parameter></method></method-group></struct-specialization><struct-specialization name="default_eval"><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="Context"/>
+ </template><specialization><template-arg>Expr</template-arg><template-arg>Context</template-arg><template-arg>proto::tag::function</template-arg><template-arg>3</template-arg></specialization><typedef name="function_type"><type><emphasis>unspecified</emphasis></type></typedef><typedef name="result_type"><type>boost::result_of< function_type(typename <classname>proto::result_of::eval</classname>< typename proto::result_of::arg_c< Expr, 1 >::type, Context >::type, typename <classname>proto::result_of::eval</classname>< typename proto::result_of::arg_c< Expr, 2 >::type, Context >::type)>::type</type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type>result_type</type><parameter name="expr"><paramtype>Expr &</paramtype></parameter><parameter name="context"><paramtype>Context &</paramtype></parameter></method></method-group></struct-specialization><struct-specialization name="default_eval"><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="Context"/>
+ </template><specialization><template-arg>Expr</template-arg><template-arg>Context</template-arg><template-arg>proto::tag::function</template-arg><template-arg>4</template-arg></specialization><typedef name="function_type"><type><emphasis>unspecified</emphasis></type></typedef><typedef name="result_type"><type>boost::result_of< function_type(typename <classname>proto::result_of::eval</classname>< typename proto::result_of::arg_c< Expr, 1 >::type, Context >::type, typename <classname>proto::result_of::eval</classname>< typename proto::result_of::arg_c< Expr, 2 >::type, Context >::type, typename <classname>proto::result_of::eval</classname>< typename proto::result_of::arg_c< Expr, 3 >::type, Context >::type)>::type</type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type>result_type</type><parameter name="expr"><paramtype>Expr &</paramtype></parameter><parameter name="context"><paramtype>Context &</paramtype></
parameter></method></method-group></struct-specialization><struct-specialization name="default_eval"><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="Context"/>
+ </template><specialization><template-arg>Expr</template-arg><template-arg>Context</template-arg><template-arg>proto::tag::function</template-arg><template-arg>5</template-arg></specialization><typedef name="function_type"><type><emphasis>unspecified</emphasis></type></typedef><typedef name="result_type"><type>boost::result_of< function_type(typename <classname>proto::result_of::eval</classname>< typename proto::result_of::arg_c< Expr, 1 >::type, Context >::type, typename <classname>proto::result_of::eval</classname>< typename proto::result_of::arg_c< Expr, 2 >::type, Context >::type, typename <classname>proto::result_of::eval</classname>< typename proto::result_of::arg_c< Expr, 3 >::type, Context >::type, typename <classname>proto::result_of::eval</classname>< typename proto::result_of::arg_c< Expr, 4 >::type, Context >::type)>::type</type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type>result_type</t
ype><parameter name="expr"><paramtype>Expr &</paramtype></parameter><parameter name="context"><paramtype>Context &</paramtype></parameter></method></method-group></struct-specialization></namespace></namespace></namespace></header><header name="boost/xpressive/proto/context/null.hpp"><para>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. </para><namespace name="boost"><namespace name="proto"><namespace name="context"><struct name="null_eval"><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="Context"/>
+ <template-nontype-parameter name="Arity"><type>long</type></template-nontype-parameter>
+ </template></struct><struct-specialization name="null_eval"><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="Context"/>
+ </template><specialization><template-arg>Expr</template-arg><template-arg>Context</template-arg><template-arg>0</template-arg></specialization><typedef name="result_type"><type>void</type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type>void</type><parameter name=""><paramtype>Expr &</paramtype></parameter><parameter name=""><paramtype>Context &</paramtype></parameter></method></method-group></struct-specialization><struct-specialization name="null_eval"><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="Context"/>
+ </template><specialization><template-arg>Expr</template-arg><template-arg>Context</template-arg><template-arg>1</template-arg></specialization><typedef name="result_type"><type>void</type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type>void</type><parameter name="expr"><paramtype>Expr &</paramtype></parameter><parameter name="ctx"><paramtype>Context &</paramtype></parameter></method></method-group></struct-specialization><struct-specialization name="null_eval"><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="Context"/>
+ </template><specialization><template-arg>Expr</template-arg><template-arg>Context</template-arg><template-arg>2</template-arg></specialization><typedef name="result_type"><type>void</type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type>void</type><parameter name="expr"><paramtype>Expr &</paramtype></parameter><parameter name="ctx"><paramtype>Context &</paramtype></parameter></method></method-group></struct-specialization><struct-specialization name="null_eval"><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="Context"/>
+ </template><specialization><template-arg>Expr</template-arg><template-arg>Context</template-arg><template-arg>3</template-arg></specialization><typedef name="result_type"><type>void</type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type>void</type><parameter name="expr"><paramtype>Expr &</paramtype></parameter><parameter name="ctx"><paramtype>Context &</paramtype></parameter></method></method-group></struct-specialization><struct-specialization name="null_eval"><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="Context"/>
+ </template><specialization><template-arg>Expr</template-arg><template-arg>Context</template-arg><template-arg>4</template-arg></specialization><typedef name="result_type"><type>void</type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type>void</type><parameter name="expr"><paramtype>Expr &</paramtype></parameter><parameter name="ctx"><paramtype>Context &</paramtype></parameter></method></method-group></struct-specialization><struct-specialization name="null_eval"><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="Context"/>
+ </template><specialization><template-arg>Expr</template-arg><template-arg>Context</template-arg><template-arg>5</template-arg></specialization><typedef name="result_type"><type>void</type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type>void</type><parameter name="expr"><paramtype>Expr &</paramtype></parameter><parameter name="ctx"><paramtype>Context &</paramtype></parameter></method></method-group></struct-specialization><struct name="null_context"><description><para>null_context </para></description><struct name="eval"><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="ThisContext"><default>null_context const</default></template-type-parameter>
+ </template><inherit access="public">boost::proto::context::null_eval< Expr, ThisContext ></inherit><description><para>null_context::eval </para></description></struct></struct></namespace></namespace></namespace></header><header name="boost/xpressive/proto/debug.hpp"><para>Utilities for debugging proto expression trees </para><namespace name="boost"><namespace name="proto"><namespace name="functional"><struct name="display_expr"><method-group name="public member functions"><method name="operator()" cv="const"><type>void</type><template>
+ <template-type-parameter name="Args"/>
+ </template><parameter name="expr"><paramtype>expr< <classname>tag::terminal</classname>, Args, 0 > const &</paramtype></parameter></method><method name="operator()" cv="const"><type>void</type><template>
+ <template-type-parameter name="Tag"/>
+ <template-type-parameter name="Args"/>
+ </template><parameter name="expr"><paramtype>expr< Tag, Args, 1 > const &</paramtype></parameter></method><method name="operator()" cv="const"><type>void</type><template>
+ <template-type-parameter name="Tag"/>
+ <template-type-parameter name="Args"/>
+ </template><parameter name="expr"><paramtype>expr< Tag, Args, 0 > const &</paramtype></parameter></method><method name="operator()" cv="const"><type>void</type><template>
+ <template-type-parameter name="T"/>
+ </template><parameter name="t"><paramtype>T const &</paramtype></parameter></method></method-group><constructor><parameter name="depth"><paramtype>int</paramtype><default>0</default></parameter><parameter name="sout"><paramtype>std::ostream &</paramtype><default>std::cout</default></parameter></constructor></struct></namespace><namespace name="tag"><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::posit</classname></paramtype></parameter></function><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::negate</classname></paramtype></parameter></function><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::dereference</classname></paramtype></parameter></function><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::complement</classname></paramtype></parameter></function><function name="proto_t
ag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::address_of</classname></paramtype></parameter></function><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::logical_not</classname></paramtype></parameter></function><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::pre_inc</classname></paramtype></parameter></function><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::pre_dec</classname></paramtype></parameter></function><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::post_inc</classname></paramtype></parameter></function><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::post_dec</classname></paramtype></parameter></function><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classna
me>tag::shift_left</classname></paramtype></parameter></function><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::shift_right</classname></paramtype></parameter></function><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::multiplies</classname></paramtype></parameter></function><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::divides</classname></paramtype></parameter></function><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::modulus</classname></paramtype></parameter></function><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::plus</classname></paramtype></parameter></function><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::minus</classname></paramtype></parameter></function><function name
="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::less</classname></paramtype></parameter></function><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::greater</classname></paramtype></parameter></function><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::less_equal</classname></paramtype></parameter></function><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::greater_equal</classname></paramtype></parameter></function><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::equal_to</classname></paramtype></parameter></function><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::not_equal_to</classname></paramtype></parameter></function><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramt
ype><classname>tag::logical_or</classname></paramtype></parameter></function><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::logical_and</classname></paramtype></parameter></function><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::bitwise_and</classname></paramtype></parameter></function><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::bitwise_or</classname></paramtype></parameter></function><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::bitwise_xor</classname></paramtype></parameter></function><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::comma</classname></paramtype></parameter></function><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::mem_ptr</classname></paramtype></parameter></
function><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::assign</classname></paramtype></parameter></function><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::shift_left_assign</classname></paramtype></parameter></function><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::shift_right_assign</classname></paramtype></parameter></function><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::multilpies_assign</classname></paramtype></parameter></function><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::divides_assign</classname></paramtype></parameter></function><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::modulus_assign</classname></paramtype></parameter></function><function name="proto_tag_na
me"><type>char const *</type><parameter name=""><paramtype><classname>tag::plus_assign</classname></paramtype></parameter></function><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::minus_assign</classname></paramtype></parameter></function><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::bitwise_and_assign</classname></paramtype></parameter></function><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::bitwise_or_assign</classname></paramtype></parameter></function><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::bitwise_xor_assign</classname></paramtype></parameter></function><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::subscript</classname></paramtype></parameter></function><function name="proto_tag_name"><type>char const *</type><paramete
r name=""><paramtype><classname>tag::if_else_</classname></paramtype></parameter></function><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::function</classname></paramtype></parameter></function><data-member name="proto_tag_name"><type><classname>hidden_detail_::printable_tag</classname>< Tag >::type</type></data-member></namespace><function name="display_expr"><type>void</type><template>
+ <template-type-parameter name="Expr"/>
+ </template><parameter name="expr"><paramtype>Expr const &</paramtype></parameter></function><function name="display_expr"><type>void</type><template>
+ <template-type-parameter name="Expr"/>
+ </template><parameter name="expr"><paramtype>Expr const &</paramtype></parameter><parameter name="sout"><paramtype>std::ostream &</paramtype></parameter></function></namespace></namespace></header><header name="boost/xpressive/proto/deep_copy.hpp"><para>Replace all nodes stored by reference by nodes stored by value. </para><namespace name="boost"><namespace name="proto"><namespace name="functional"><struct name="deep_copy"><struct-specialization name="result"><template>
+ <template-type-parameter name="This"/>
+ <template-type-parameter name="Expr"/>
+ </template><specialization><template-arg>This(Expr)</template-arg></specialization></struct-specialization><method-group name="public member functions"><method name="operator()" cv="const"><type><classname>result_of::deep_copy</classname>< Expr >::type</type><template>
+ <template-type-parameter name="Expr"/>
+ </template><parameter name="expr"><paramtype>Expr const &</paramtype></parameter></method></method-group></struct></namespace><namespace name="result_of"><struct name="deep_copy"><template>
+ <template-type-parameter name="Expr"/>
+ </template></struct></namespace><data-member name="deep_copy"><type><classname>functional::deep_copy</classname> const</type></data-member></namespace></namespace></header><header name="boost/xpressive/proto/domain.hpp"><para>Contains definition of domain<> class template, for defining domains with a grammar for controlling operator overloading. </para><namespace name="boost"><namespace name="proto"><namespace name="domainns_"><struct name="domain"><template>
+ <template-type-parameter name="Generator"/>
+ <template-type-parameter name="Grammar"/>
+ </template><inherit access="public">Generator</inherit><typedef name="grammar"><type>Grammar</type></typedef></struct><struct name="default_domain"><inherit access="public">boost::proto::domainns_::domain< ></inherit></struct><struct name="deduce_domain"/></namespace><namespace name="result_of"><struct name="is_domain"><template>
+ <template-type-parameter name="T"/>
+ <template-type-parameter name="EnableIf"/>
+ </template></struct><struct name="domain_of"><template>
+ <template-type-parameter name="T"/>
+ <template-type-parameter name="EnableIf"/>
+ </template><typedef name="type"><type><classname>default_domain</classname></type></typedef></struct><struct-specialization name="is_domain"><template>
+ <template-type-parameter name="T"/>
+ </template><specialization><template-arg>T</template-arg><template-arg>typename T::proto_is_domain_</template-arg></specialization></struct-specialization><struct-specialization name="domain_of"><template>
+ <template-type-parameter name="T"/>
+ </template><specialization><template-arg>T</template-arg><template-arg>typename T::proto_is_expr_</template-arg></specialization><typedef name="type"><type>T::proto_domain</type></typedef></struct-specialization></namespace></namespace></namespace></header><header name="boost/xpressive/proto/eval.hpp"><para>Contains the eval() expression evaluator. </para><namespace name="boost"><namespace name="proto"><namespace name="functional"><struct name="eval"><struct-specialization name="result"><template>
+ <template-type-parameter name="This"/>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="Context"/>
+ </template><specialization><template-arg>This(Expr</template-arg><template-arg>Context)</template-arg></specialization><inherit access="public">boost::proto::result_of::eval< remove_reference< Expr >::type, remove_reference< Context >::type ></inherit></struct-specialization><method-group name="public member functions"><method name="operator()" cv="const"><type><classname>proto::result_of::eval</classname>< Expr, Context >::type</type><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="Context"/>
+ </template><parameter name="expr"><paramtype>Expr &</paramtype></parameter><parameter name="context"><paramtype>Context &</paramtype></parameter></method><method name="operator()" cv="const"><type><classname>proto::result_of::eval</classname>< Expr, Context >::type</type><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="Context"/>
+ </template><parameter name="expr"><paramtype>Expr &</paramtype></parameter><parameter name="context"><paramtype>Context const &</paramtype></parameter></method></method-group></struct></namespace><namespace name="result_of"><struct name="eval"><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="Context"/>
+ </template><typedef name="type"><type>Context::template <classname>eval</classname>< Expr >::result_type</type></typedef></struct></namespace><data-member name="eval"><type><classname>functional::eval</classname> const</type></data-member></namespace></namespace></header><header name="boost/xpressive/proto/expr.hpp"><para>Contains definition of expr<> class template. </para><namespace name="boost"><namespace name="proto"><namespace name="exprns_"><struct-specialization name="expr"><template>
+ <template-type-parameter name="Tag"/>
+ <template-type-parameter name="Args"/>
+ </template><specialization><template-arg>Tag</template-arg><template-arg>Args</template-arg><template-arg>0</template-arg></specialization><purpose>Representation of a node in an expression tree. </purpose><description><para><computeroutput>proto::expr<></computeroutput> is a node in an expression template tree. It is a container for its children sub-trees. It also serves as the terminal nodes of the tree.</para><para><computeroutput>Tag</computeroutput> is type that represents the operation encoded by this expression. It is typically one of the structs in the <computeroutput>boost::proto::tag</computeroutput> namespace, but it doesn't have to be. If the <computeroutput>Tag</computeroutput> type is <computeroutput>boost::proto::tag::terminal</computeroutput> then this <computeroutput>expr<></computeroutput> type represents a leaf in the expression tree.</para><para><computeroutput>Args</computeroutput> is a type list representing the type of the children of this expression. It is an instanti
ation of one of <computeroutput>proto::args1<></computeroutput>, <computeroutput>proto::args2<></computeroutput>, etc. The children types must all themselves be either <computeroutput>expr<></computeroutput> or <computeroutput>proto::ref_<proto::expr<>></computeroutput>, unless the <computeroutput>Tag</computeroutput> type is <computeroutput>boost::proto::tag::terminal</computeroutput>, in which case <computeroutput>Args</computeroutput> must be <computeroutput>proto::args1<T></computeroutput>, where <computeroutput>T</computeroutput> can be any type. </para></description><struct name="apply"><template>
+ <template-type-parameter name="Expr_"/>
+ <template-type-parameter name=""/>
+ <template-type-parameter name=""/>
+ </template><typedef name="type"><type>Expr_</type></typedef></struct><struct name="result"><template>
+ <template-type-parameter name="Sig"/>
+ </template><description><para>Encodes the return type of <computeroutput>expr<>operator()</computeroutput>, for use with <computeroutput>boost::result_of<></computeroutput> </para></description><typedef name="type"><type>result_of::funop< Sig, expr >::type</type></typedef></struct><typedef name="proto_tag"><type>Tag</type></typedef><typedef name="proto_arity"><type>mpl::long_< 0 ></type></typedef><typedef name="proto_base_expr"><type>expr</type></typedef><typedef name="proto_args"><type>Args</type></typedef><typedef name="proto_domain"><type><classname>default_domain</classname></type></typedef><typedef name="fusion_tag"><type>tag::proto_expr</type></typedef><typedef name="proto_is_expr_"><type>void</type></typedef><typedef name="proto_derived_expr"><type>expr</type></typedef><typedef name="proto_arg0"><type>Args::arg0</type></typedef><typedef name="proto_arg1"><type>void</type></typedef><typedef name="proto_arg2"><type>void</type></typedef><typedef name="proto_arg3"><type>void</
type></typedef><typedef name="proto_arg4"><type>void</type></typedef><method-group name="public member functions"><method name="proto_base" cv="const"><type>expr const &</type><description><para>
+</para></description><returns><para>*this </para></returns></method><method name="proto_base" cv=""><type>expr &</type><description><para>This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts. </para></description></method><method name="operator[]" cv="const"><type>expr< <classname>tag::subscript</classname>, <classname>args2</classname>< <classname>ref_</classname>< expr const >, typename <classname>result_of::as_arg</classname>< A >::type > > const</type><template>
+ <template-type-parameter name="A"/>
+ </template><parameter name="a"><paramtype>A &</paramtype><description><para>The rhs. </para></description></parameter><description><para>Subscript</para><para>
+
+</para></description><returns><para>A new <computeroutput>expr<></computeroutput> node representing <computeroutput>*this</computeroutput> subscripted with <computeroutput>a</computeroutput>. </para></returns></method><method name="operator[]" cv="const"><type>expr< <classname>tag::subscript</classname>, <classname>args2</classname>< <classname>ref_</classname>< expr const >, typename <classname>result_of::as_arg</classname>< A const >::type > > const</type><template>
+ <template-type-parameter name="A"/>
+ </template><parameter name="a"><paramtype>A const &</paramtype></parameter><description><para>This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts. </para></description></method><method name="operator[]" cv=""><type>expr< <classname>tag::subscript</classname>, <classname>args2</classname>< <classname>ref_</classname>< expr >, typename <classname>result_of::as_arg</classname>< A >::type > > const</type><template>
+ <template-type-parameter name="A"/>
+ </template><parameter name="a"><paramtype>A &</paramtype></parameter><description><para>This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts. </para></description></method><method name="operator[]" cv=""><type>expr< <classname>tag::subscript</classname>, <classname>args2</classname>< <classname>ref_</classname>< expr >, typename <classname>result_of::as_arg</classname>< A const >::type > > const</type><template>
+ <template-type-parameter name="A"/>
+ </template><parameter name="a"><paramtype>A const &</paramtype></parameter><description><para>This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts. </para></description></method><method name="operator()" cv="const"><type>expr< <classname>tag::function</classname>, <classname>args1</classname>< <classname>ref_</classname>< expr const > > > const</type><description><para>Function call</para><para>
+</para></description><returns><para>A new <computeroutput>expr<></computeroutput> node representing the function invocation of <computeroutput/>(*this)(). </para></returns></method><method name="operator()" cv=""><type>expr< <classname>tag::function</classname>, <classname>args1</classname>< <classname>ref_</classname>< expr > > > const</type><description><para>This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts. </para></description></method><method name="operator()" cv="const"><type><classname>result_of::funop1</classname>< expr const , const A0 >::type const</type><template>
+ <template-type-parameter name="A0"/>
+ </template><parameter name="a0"><paramtype>A0 const &</paramtype></parameter><description><para>This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts. </para></description></method><method name="operator()" cv="const"><type><classname>result_of::funop2</classname>< expr const , const A0, const A1 >::type const</type><template>
+ <template-type-parameter name="A0"/>
+ <template-type-parameter name="A1"/>
+ </template><parameter name="a0"><paramtype>A0 const &</paramtype></parameter><parameter name="a1"><paramtype>A1 const &</paramtype></parameter><description><para>This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts. </para></description></method><method name="operator()" cv="const"><type><classname>result_of::funop3</classname>< expr const , const A0, const A1, const A2 >::type const</type><template>
+ <template-type-parameter name="A0"/>
+ <template-type-parameter name="A1"/>
+ <template-type-parameter name="A2"/>
+ </template><parameter name="a0"><paramtype>A0 const &</paramtype></parameter><parameter name="a1"><paramtype>A1 const &</paramtype></parameter><parameter name="a2"><paramtype>A2 const &</paramtype></parameter><description><para>This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts. </para></description></method><method name="operator()" cv="const"><type><classname>result_of::funop4</classname>< expr const , const A0, const A1, const A2, const A3 >::type const</type><template>
+ <template-type-parameter name="A0"/>
+ <template-type-parameter name="A1"/>
+ <template-type-parameter name="A2"/>
+ <template-type-parameter name="A3"/>
+ </template><parameter name="a0"><paramtype>A0 const &</paramtype></parameter><parameter name="a1"><paramtype>A1 const &</paramtype></parameter><parameter name="a2"><paramtype>A2 const &</paramtype></parameter><parameter name="a3"><paramtype>A3 const &</paramtype></parameter><description><para>This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts. </para></description></method></method-group><copy-assignment><template>
+ <template-type-parameter name="A"/>
+ </template><parameter name="a"><paramtype>A &</paramtype><description><para>The rhs. </para></description></parameter><description><para>Assignment</para><para>
+
+</para></description><returns><para>A new <computeroutput>expr<></computeroutput> node representing an assignment of <computeroutput>a</computeroutput> to <computeroutput>*this</computeroutput>. </para></returns></copy-assignment><copy-assignment><template>
+ <template-type-parameter name="A"/>
+ </template><parameter name="a"><paramtype>A const &</paramtype></parameter><description><para>This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts. </para></description></copy-assignment><copy-assignment><template>
+ <template-type-parameter name="A"/>
+ </template><parameter name="a"><paramtype>A &</paramtype></parameter><description><para>This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts. </para></description></copy-assignment><copy-assignment><template>
+ <template-type-parameter name="A"/>
+ </template><parameter name="a"><paramtype>A const &</paramtype></parameter><description><para>This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts. </para></description></copy-assignment><data-member name="arg0"><type>proto_arg0</type></data-member><method-group name="public static functions"><method name="call" cv=""><type>static Expr_ const &</type><template>
+ <template-type-parameter name="Expr_"/>
+ <template-type-parameter name="State_"/>
+ <template-type-parameter name="Visitor_"/>
+ </template><parameter name="expr_"><paramtype>Expr_ const &</paramtype></parameter><parameter name=""><paramtype>State_ const &</paramtype></parameter><parameter name=""><paramtype>Visitor_ &</paramtype></parameter></method><method name="make" cv=""><type>static expr</type><template>
+ <template-type-parameter name="A0"/>
+ </template><parameter name="a0"><paramtype>A0 const &</paramtype></parameter><description><para>
+</para></description><returns><para>A new <computeroutput>expr<></computeroutput> object initialized with the specified arguments. </para></returns></method><method name="make" cv=""><type>static expr</type><template>
+ <template-type-parameter name="A0"/>
+ </template><parameter name="a0"><paramtype>A0 &</paramtype></parameter><description><para>This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts. </para></description></method><method name="make" cv=""><type>static expr</type><template>
+ <template-type-parameter name="A0"/>
+ <template-nontype-parameter name="N"><type>std::size_t</type></template-nontype-parameter>
+ </template><parameter name="a0"><paramtype>A0 &</paramtype></parameter><parameter name=""><paramtype><emphasis>unspecified</emphasis></paramtype><default>0</default></parameter><description><para>This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts. </para></description></method><method name="make" cv=""><type>static expr</type><template>
+ <template-type-parameter name="A0"/>
+ <template-nontype-parameter name="N"><type>std::size_t</type></template-nontype-parameter>
+ </template><parameter name="a0"><paramtype>A0 const &</paramtype></parameter><parameter name=""><paramtype><emphasis>unspecified</emphasis></paramtype><default>0</default></parameter><description><para>This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts. </para></description></method></method-group></struct-specialization><struct-specialization name="expr"><template>
+ <template-type-parameter name="Tag"/>
+ <template-type-parameter name="Args"/>
+ </template><specialization><template-arg>Tag</template-arg><template-arg>Args</template-arg><template-arg>1</template-arg></specialization><purpose>Representation of a node in an expression tree. </purpose><description><para><computeroutput>proto::expr<></computeroutput> is a node in an expression template tree. It is a container for its children sub-trees. It also serves as the terminal nodes of the tree.</para><para><computeroutput>Tag</computeroutput> is type that represents the operation encoded by this expression. It is typically one of the structs in the <computeroutput>boost::proto::tag</computeroutput> namespace, but it doesn't have to be. If the <computeroutput>Tag</computeroutput> type is <computeroutput>boost::proto::tag::terminal</computeroutput> then this <computeroutput>expr<></computeroutput> type represents a leaf in the expression tree.</para><para><computeroutput>Args</computeroutput> is a type list representing the type of the children of this expression. It is an instanti
ation of one of <computeroutput>proto::args1<></computeroutput>, <computeroutput>proto::args2<></computeroutput>, etc. The children types must all themselves be either <computeroutput>expr<></computeroutput> or <computeroutput>proto::ref_<proto::expr<>></computeroutput>, unless the <computeroutput>Tag</computeroutput> type is <computeroutput>boost::proto::tag::terminal</computeroutput>, in which case <computeroutput>Args</computeroutput> must be <computeroutput>proto::args1<T></computeroutput>, where <computeroutput>T</computeroutput> can be any type. </para></description><struct name="apply"><template>
+ <template-type-parameter name="Expr_"/>
+ <template-type-parameter name=""/>
+ <template-type-parameter name=""/>
+ </template><typedef name="type"><type>Expr_</type></typedef></struct><struct name="result"><template>
+ <template-type-parameter name="Sig"/>
+ </template><description><para>Encodes the return type of <computeroutput>expr<>operator()</computeroutput>, for use with <computeroutput>boost::result_of<></computeroutput> </para></description><typedef name="type"><type>result_of::funop< Sig, expr >::type</type></typedef></struct><typedef name="proto_tag"><type>Tag</type></typedef><typedef name="proto_arity"><type>mpl::long_< 1 ></type></typedef><typedef name="proto_base_expr"><type>expr</type></typedef><typedef name="proto_args"><type>Args</type></typedef><typedef name="proto_domain"><type><classname>default_domain</classname></type></typedef><typedef name="fusion_tag"><type>tag::proto_expr</type></typedef><typedef name="proto_is_expr_"><type>void</type></typedef><typedef name="proto_derived_expr"><type>expr</type></typedef><typedef name="proto_arg0"><type>Args::arg0</type></typedef><typedef name="proto_arg1"><type>void</type></typedef><typedef name="proto_arg2"><type>void</type></typedef><typedef name="proto_arg3"><type>void</
type></typedef><typedef name="proto_arg4"><type>void</type></typedef><typedef name="address_of_hack_type_"><description><para>If <computeroutput>Tag</computeroutput> is <computeroutput>boost::proto::tag::address_of</computeroutput> and <computeroutput>proto_arg0</computeroutput> is <computeroutput>proto::ref_<T></computeroutput>, then <computeroutput>address_of_hack_type_</computeroutput> is <computeroutput>T*</computeroutput>. Otherwise, it is some undefined type. </para></description><type><emphasis>unspecified</emphasis></type></typedef><method-group name="public member functions"><method name="proto_base" cv="const"><type>expr const &</type><description><para>
+</para></description><returns><para>*this </para></returns></method><method name="proto_base" cv=""><type>expr &</type><description><para>This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts. </para></description></method><method name="conversion-operator" cv="const"><type>address_of_hack_type_</type><description><para>
+
+</para></description><returns><para>The address of <computeroutput>this->arg0</computeroutput> if <computeroutput>Tag</computeroutput> is <computeroutput>boost::proto::tag::address_of</computeroutput>. Otherwise, this function will fail to compile.</para></returns><notes><para>Proto overloads <computeroutput>operator&</computeroutput>, which means that proto-ified objects cannot have their addresses taken, unless we use the following hack to make <computeroutput>&x</computeroutput> implicitly convertible to <computeroutput>X*</computeroutput>. </para></notes></method><method name="operator[]" cv="const"><type>expr< <classname>tag::subscript</classname>, <classname>args2</classname>< <classname>ref_</classname>< expr const >, typename <classname>result_of::as_arg</classname>< A >::type > > const</type><template>
+ <template-type-parameter name="A"/>
+ </template><parameter name="a"><paramtype>A &</paramtype><description><para>The rhs. </para></description></parameter><description><para>Subscript</para><para>
+
+</para></description><returns><para>A new <computeroutput>expr<></computeroutput> node representing <computeroutput>*this</computeroutput> subscripted with <computeroutput>a</computeroutput>. </para></returns></method><method name="operator[]" cv="const"><type>expr< <classname>tag::subscript</classname>, <classname>args2</classname>< <classname>ref_</classname>< expr const >, typename <classname>result_of::as_arg</classname>< A const >::type > > const</type><template>
+ <template-type-parameter name="A"/>
+ </template><parameter name="a"><paramtype>A const &</paramtype></parameter><description><para>This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts. </para></description></method><method name="operator()" cv="const"><type>expr< <classname>tag::function</classname>, <classname>args1</classname>< <classname>ref_</classname>< expr const > > > const</type><description><para>Function call</para><para>
+</para></description><returns><para>A new <computeroutput>expr<></computeroutput> node representing the function invocation of <computeroutput/>(*this)(). </para></returns></method><method name="operator()" cv="const"><type><classname>result_of::funop1</classname>< expr const , const A0 >::type const</type><template>
+ <template-type-parameter name="A0"/>
+ </template><parameter name="a0"><paramtype>A0 const &</paramtype></parameter><description><para>This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts. </para></description></method><method name="operator()" cv="const"><type><classname>result_of::funop2</classname>< expr const , const A0, const A1 >::type const</type><template>
+ <template-type-parameter name="A0"/>
+ <template-type-parameter name="A1"/>
+ </template><parameter name="a0"><paramtype>A0 const &</paramtype></parameter><parameter name="a1"><paramtype>A1 const &</paramtype></parameter><description><para>This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts. </para></description></method><method name="operator()" cv="const"><type><classname>result_of::funop3</classname>< expr const , const A0, const A1, const A2 >::type const</type><template>
+ <template-type-parameter name="A0"/>
+ <template-type-parameter name="A1"/>
+ <template-type-parameter name="A2"/>
+ </template><parameter name="a0"><paramtype>A0 const &</paramtype></parameter><parameter name="a1"><paramtype>A1 const &</paramtype></parameter><parameter name="a2"><paramtype>A2 const &</paramtype></parameter><description><para>This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts. </para></description></method><method name="operator()" cv="const"><type><classname>result_of::funop4</classname>< expr const , const A0, const A1, const A2, const A3 >::type const</type><template>
+ <template-type-parameter name="A0"/>
+ <template-type-parameter name="A1"/>
+ <template-type-parameter name="A2"/>
+ <template-type-parameter name="A3"/>
+ </template><parameter name="a0"><paramtype>A0 const &</paramtype></parameter><parameter name="a1"><paramtype>A1 const &</paramtype></parameter><parameter name="a2"><paramtype>A2 const &</paramtype></parameter><parameter name="a3"><paramtype>A3 const &</paramtype></parameter><description><para>This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts. </para></description></method></method-group><copy-assignment><template>
+ <template-type-parameter name="A"/>
+ </template><parameter name="a"><paramtype>A &</paramtype><description><para>The rhs. </para></description></parameter><description><para>Assignment</para><para>
+
+</para></description><returns><para>A new <computeroutput>expr<></computeroutput> node representing an assignment of <computeroutput>a</computeroutput> to <computeroutput>*this</computeroutput>. </para></returns></copy-assignment><copy-assignment><template>
+ <template-type-parameter name="A"/>
+ </template><parameter name="a"><paramtype>A const &</paramtype></parameter><description><para>This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts. </para></description></copy-assignment><data-member name="arg0"><type>proto_arg0</type></data-member><method-group name="public static functions"><method name="call" cv=""><type>static Expr_ const &</type><template>
+ <template-type-parameter name="Expr_"/>
+ <template-type-parameter name="State_"/>
+ <template-type-parameter name="Visitor_"/>
+ </template><parameter name="expr_"><paramtype>Expr_ const &</paramtype></parameter><parameter name=""><paramtype>State_ const &</paramtype></parameter><parameter name=""><paramtype>Visitor_ &</paramtype></parameter></method><method name="make" cv=""><type>static expr</type><template>
+ <template-type-parameter name="A0"/>
+ </template><parameter name="a0"><paramtype>A0 const &</paramtype></parameter><description><para>
+</para></description><returns><para>A new <computeroutput>expr<></computeroutput> object initialized with the specified arguments. </para></returns></method></method-group></struct-specialization><struct-specialization name="expr"><template>
+ <template-type-parameter name="Tag"/>
+ <template-type-parameter name="Args"/>
+ </template><specialization><template-arg>Tag</template-arg><template-arg>Args</template-arg><template-arg>2</template-arg></specialization><purpose>Representation of a node in an expression tree. </purpose><description><para><computeroutput>proto::expr<></computeroutput> is a node in an expression template tree. It is a container for its children sub-trees. It also serves as the terminal nodes of the tree.</para><para><computeroutput>Tag</computeroutput> is type that represents the operation encoded by this expression. It is typically one of the structs in the <computeroutput>boost::proto::tag</computeroutput> namespace, but it doesn't have to be. If the <computeroutput>Tag</computeroutput> type is <computeroutput>boost::proto::tag::terminal</computeroutput> then this <computeroutput>expr<></computeroutput> type represents a leaf in the expression tree.</para><para><computeroutput>Args</computeroutput> is a type list representing the type of the children of this expression. It is an instanti
ation of one of <computeroutput>proto::args1<></computeroutput>, <computeroutput>proto::args2<></computeroutput>, etc. The children types must all themselves be either <computeroutput>expr<></computeroutput> or <computeroutput>proto::ref_<proto::expr<>></computeroutput>, unless the <computeroutput>Tag</computeroutput> type is <computeroutput>boost::proto::tag::terminal</computeroutput>, in which case <computeroutput>Args</computeroutput> must be <computeroutput>proto::args1<T></computeroutput>, where <computeroutput>T</computeroutput> can be any type. </para></description><struct name="apply"><template>
+ <template-type-parameter name="Expr_"/>
+ <template-type-parameter name=""/>
+ <template-type-parameter name=""/>
+ </template><typedef name="type"><type>Expr_</type></typedef></struct><struct name="result"><template>
+ <template-type-parameter name="Sig"/>
+ </template><description><para>Encodes the return type of <computeroutput>expr<>operator()</computeroutput>, for use with <computeroutput>boost::result_of<></computeroutput> </para></description><typedef name="type"><type>result_of::funop< Sig, expr >::type</type></typedef></struct><typedef name="proto_tag"><type>Tag</type></typedef><typedef name="proto_arity"><type>mpl::long_< 2 ></type></typedef><typedef name="proto_base_expr"><type>expr</type></typedef><typedef name="proto_args"><type>Args</type></typedef><typedef name="proto_domain"><type><classname>default_domain</classname></type></typedef><typedef name="fusion_tag"><type>tag::proto_expr</type></typedef><typedef name="proto_is_expr_"><type>void</type></typedef><typedef name="proto_derived_expr"><type>expr</type></typedef><typedef name="proto_arg0"><type>Args::arg0</type></typedef><typedef name="proto_arg1"><type>Args::arg1</type></typedef><typedef name="proto_arg2"><type>void</type></typedef><typedef name="proto_arg3"><type>
void</type></typedef><typedef name="proto_arg4"><type>void</type></typedef><method-group name="public member functions"><method name="proto_base" cv="const"><type>expr const &</type><description><para>
+</para></description><returns><para>*this </para></returns></method><method name="proto_base" cv=""><type>expr &</type><description><para>This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts. </para></description></method><method name="operator[]" cv="const"><type>expr< <classname>tag::subscript</classname>, <classname>args2</classname>< <classname>ref_</classname>< expr const >, typename <classname>result_of::as_arg</classname>< A >::type > > const</type><template>
+ <template-type-parameter name="A"/>
+ </template><parameter name="a"><paramtype>A &</paramtype><description><para>The rhs. </para></description></parameter><description><para>Subscript</para><para>
+
+</para></description><returns><para>A new <computeroutput>expr<></computeroutput> node representing <computeroutput>*this</computeroutput> subscripted with <computeroutput>a</computeroutput>. </para></returns></method><method name="operator[]" cv="const"><type>expr< <classname>tag::subscript</classname>, <classname>args2</classname>< <classname>ref_</classname>< expr const >, typename <classname>result_of::as_arg</classname>< A const >::type > > const</type><template>
+ <template-type-parameter name="A"/>
+ </template><parameter name="a"><paramtype>A const &</paramtype></parameter><description><para>This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts. </para></description></method><method name="operator()" cv="const"><type>expr< <classname>tag::function</classname>, <classname>args1</classname>< <classname>ref_</classname>< expr const > > > const</type><description><para>Function call</para><para>
+</para></description><returns><para>A new <computeroutput>expr<></computeroutput> node representing the function invocation of <computeroutput/>(*this)(). </para></returns></method><method name="operator()" cv="const"><type><classname>result_of::funop1</classname>< expr const , const A0 >::type const</type><template>
+ <template-type-parameter name="A0"/>
+ </template><parameter name="a0"><paramtype>A0 const &</paramtype></parameter><description><para>This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts. </para></description></method><method name="operator()" cv="const"><type><classname>result_of::funop2</classname>< expr const , const A0, const A1 >::type const</type><template>
+ <template-type-parameter name="A0"/>
+ <template-type-parameter name="A1"/>
+ </template><parameter name="a0"><paramtype>A0 const &</paramtype></parameter><parameter name="a1"><paramtype>A1 const &</paramtype></parameter><description><para>This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts. </para></description></method><method name="operator()" cv="const"><type><classname>result_of::funop3</classname>< expr const , const A0, const A1, const A2 >::type const</type><template>
+ <template-type-parameter name="A0"/>
+ <template-type-parameter name="A1"/>
+ <template-type-parameter name="A2"/>
+ </template><parameter name="a0"><paramtype>A0 const &</paramtype></parameter><parameter name="a1"><paramtype>A1 const &</paramtype></parameter><parameter name="a2"><paramtype>A2 const &</paramtype></parameter><description><para>This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts. </para></description></method><method name="operator()" cv="const"><type><classname>result_of::funop4</classname>< expr const , const A0, const A1, const A2, const A3 >::type const</type><template>
+ <template-type-parameter name="A0"/>
+ <template-type-parameter name="A1"/>
+ <template-type-parameter name="A2"/>
+ <template-type-parameter name="A3"/>
+ </template><parameter name="a0"><paramtype>A0 const &</paramtype></parameter><parameter name="a1"><paramtype>A1 const &</paramtype></parameter><parameter name="a2"><paramtype>A2 const &</paramtype></parameter><parameter name="a3"><paramtype>A3 const &</paramtype></parameter><description><para>This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts. </para></description></method></method-group><copy-assignment><template>
+ <template-type-parameter name="A"/>
+ </template><parameter name="a"><paramtype>A &</paramtype><description><para>The rhs. </para></description></parameter><description><para>Assignment</para><para>
+
+</para></description><returns><para>A new <computeroutput>expr<></computeroutput> node representing an assignment of <computeroutput>a</computeroutput> to <computeroutput>*this</computeroutput>. </para></returns></copy-assignment><copy-assignment><template>
+ <template-type-parameter name="A"/>
+ </template><parameter name="a"><paramtype>A const &</paramtype></parameter><description><para>This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts. </para></description></copy-assignment><data-member name="arg0"><type>proto_arg0</type></data-member><data-member name="arg1"><type>proto_arg1</type></data-member><method-group name="public static functions"><method name="call" cv=""><type>static Expr_ const &</type><template>
+ <template-type-parameter name="Expr_"/>
+ <template-type-parameter name="State_"/>
+ <template-type-parameter name="Visitor_"/>
+ </template><parameter name="expr_"><paramtype>Expr_ const &</paramtype></parameter><parameter name=""><paramtype>State_ const &</paramtype></parameter><parameter name=""><paramtype>Visitor_ &</paramtype></parameter></method><method name="make" cv=""><type>static expr</type><template>
+ <template-type-parameter name="A0"/>
+ <template-type-parameter name="A1"/>
+ </template><parameter name="a0"><paramtype>A0 const &</paramtype></parameter><parameter name="a1"><paramtype>A1 const &</paramtype></parameter><description><para>
+</para></description><returns><para>A new <computeroutput>expr<></computeroutput> object initialized with the specified arguments. </para></returns></method></method-group></struct-specialization><struct-specialization name="expr"><template>
+ <template-type-parameter name="Tag"/>
+ <template-type-parameter name="Args"/>
+ </template><specialization><template-arg>Tag</template-arg><template-arg>Args</template-arg><template-arg>3</template-arg></specialization><purpose>Representation of a node in an expression tree. </purpose><description><para><computeroutput>proto::expr<></computeroutput> is a node in an expression template tree. It is a container for its children sub-trees. It also serves as the terminal nodes of the tree.</para><para><computeroutput>Tag</computeroutput> is type that represents the operation encoded by this expression. It is typically one of the structs in the <computeroutput>boost::proto::tag</computeroutput> namespace, but it doesn't have to be. If the <computeroutput>Tag</computeroutput> type is <computeroutput>boost::proto::tag::terminal</computeroutput> then this <computeroutput>expr<></computeroutput> type represents a leaf in the expression tree.</para><para><computeroutput>Args</computeroutput> is a type list representing the type of the children of this expression. It is an instanti
ation of one of <computeroutput>proto::args1<></computeroutput>, <computeroutput>proto::args2<></computeroutput>, etc. The children types must all themselves be either <computeroutput>expr<></computeroutput> or <computeroutput>proto::ref_<proto::expr<>></computeroutput>, unless the <computeroutput>Tag</computeroutput> type is <computeroutput>boost::proto::tag::terminal</computeroutput>, in which case <computeroutput>Args</computeroutput> must be <computeroutput>proto::args1<T></computeroutput>, where <computeroutput>T</computeroutput> can be any type. </para></description><struct name="apply"><template>
+ <template-type-parameter name="Expr_"/>
+ <template-type-parameter name=""/>
+ <template-type-parameter name=""/>
+ </template><typedef name="type"><type>Expr_</type></typedef></struct><struct name="result"><template>
+ <template-type-parameter name="Sig"/>
+ </template><description><para>Encodes the return type of <computeroutput>expr<>operator()</computeroutput>, for use with <computeroutput>boost::result_of<></computeroutput> </para></description><typedef name="type"><type>result_of::funop< Sig, expr >::type</type></typedef></struct><typedef name="proto_tag"><type>Tag</type></typedef><typedef name="proto_arity"><type>mpl::long_< 3 ></type></typedef><typedef name="proto_base_expr"><type>expr</type></typedef><typedef name="proto_args"><type>Args</type></typedef><typedef name="proto_domain"><type><classname>default_domain</classname></type></typedef><typedef name="fusion_tag"><type>tag::proto_expr</type></typedef><typedef name="proto_is_expr_"><type>void</type></typedef><typedef name="proto_derived_expr"><type>expr</type></typedef><typedef name="proto_arg0"><type>Args::arg0</type></typedef><typedef name="proto_arg1"><type>Args::arg1</type></typedef><typedef name="proto_arg2"><type>Args::arg2</type></typedef><typedef name="proto_arg3">
<type>void</type></typedef><typedef name="proto_arg4"><type>void</type></typedef><method-group name="public member functions"><method name="proto_base" cv="const"><type>expr const &</type><description><para>
+</para></description><returns><para>*this </para></returns></method><method name="proto_base" cv=""><type>expr &</type><description><para>This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts. </para></description></method><method name="operator[]" cv="const"><type>expr< <classname>tag::subscript</classname>, <classname>args2</classname>< <classname>ref_</classname>< expr const >, typename <classname>result_of::as_arg</classname>< A >::type > > const</type><template>
+ <template-type-parameter name="A"/>
+ </template><parameter name="a"><paramtype>A &</paramtype><description><para>The rhs. </para></description></parameter><description><para>Subscript</para><para>
+
+</para></description><returns><para>A new <computeroutput>expr<></computeroutput> node representing <computeroutput>*this</computeroutput> subscripted with <computeroutput>a</computeroutput>. </para></returns></method><method name="operator[]" cv="const"><type>expr< <classname>tag::subscript</classname>, <classname>args2</classname>< <classname>ref_</classname>< expr const >, typename <classname>result_of::as_arg</classname>< A const >::type > > const</type><template>
+ <template-type-parameter name="A"/>
+ </template><parameter name="a"><paramtype>A const &</paramtype></parameter><description><para>This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts. </para></description></method><method name="operator()" cv="const"><type>expr< <classname>tag::function</classname>, <classname>args1</classname>< <classname>ref_</classname>< expr const > > > const</type><description><para>Function call</para><para>
+</para></description><returns><para>A new <computeroutput>expr<></computeroutput> node representing the function invocation of <computeroutput/>(*this)(). </para></returns></method><method name="operator()" cv="const"><type><classname>result_of::funop1</classname>< expr const , const A0 >::type const</type><template>
+ <template-type-parameter name="A0"/>
+ </template><parameter name="a0"><paramtype>A0 const &</paramtype></parameter><description><para>This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts. </para></description></method><method name="operator()" cv="const"><type><classname>result_of::funop2</classname>< expr const , const A0, const A1 >::type const</type><template>
+ <template-type-parameter name="A0"/>
+ <template-type-parameter name="A1"/>
+ </template><parameter name="a0"><paramtype>A0 const &</paramtype></parameter><parameter name="a1"><paramtype>A1 const &</paramtype></parameter><description><para>This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts. </para></description></method><method name="operator()" cv="const"><type><classname>result_of::funop3</classname>< expr const , const A0, const A1, const A2 >::type const</type><template>
+ <template-type-parameter name="A0"/>
+ <template-type-parameter name="A1"/>
+ <template-type-parameter name="A2"/>
+ </template><parameter name="a0"><paramtype>A0 const &</paramtype></parameter><parameter name="a1"><paramtype>A1 const &</paramtype></parameter><parameter name="a2"><paramtype>A2 const &</paramtype></parameter><description><para>This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts. </para></description></method><method name="operator()" cv="const"><type><classname>result_of::funop4</classname>< expr const , const A0, const A1, const A2, const A3 >::type const</type><template>
+ <template-type-parameter name="A0"/>
+ <template-type-parameter name="A1"/>
+ <template-type-parameter name="A2"/>
+ <template-type-parameter name="A3"/>
+ </template><parameter name="a0"><paramtype>A0 const &</paramtype></parameter><parameter name="a1"><paramtype>A1 const &</paramtype></parameter><parameter name="a2"><paramtype>A2 const &</paramtype></parameter><parameter name="a3"><paramtype>A3 const &</paramtype></parameter><description><para>This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts. </para></description></method></method-group><copy-assignment><template>
+ <template-type-parameter name="A"/>
+ </template><parameter name="a"><paramtype>A &</paramtype><description><para>The rhs. </para></description></parameter><description><para>Assignment</para><para>
+
+</para></description><returns><para>A new <computeroutput>expr<></computeroutput> node representing an assignment of <computeroutput>a</computeroutput> to <computeroutput>*this</computeroutput>. </para></returns></copy-assignment><copy-assignment><template>
+ <template-type-parameter name="A"/>
+ </template><parameter name="a"><paramtype>A const &</paramtype></parameter><description><para>This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts. </para></description></copy-assignment><data-member name="arg0"><type>proto_arg0</type></data-member><data-member name="arg1"><type>proto_arg1</type></data-member><data-member name="arg2"><type>proto_arg2</type></data-member><method-group name="public static functions"><method name="call" cv=""><type>static Expr_ const &</type><template>
+ <template-type-parameter name="Expr_"/>
+ <template-type-parameter name="State_"/>
+ <template-type-parameter name="Visitor_"/>
+ </template><parameter name="expr_"><paramtype>Expr_ const &</paramtype></parameter><parameter name=""><paramtype>State_ const &</paramtype></parameter><parameter name=""><paramtype>Visitor_ &</paramtype></parameter></method><method name="make" cv=""><type>static expr</type><template>
+ <template-type-parameter name="A0"/>
+ <template-type-parameter name="A1"/>
+ <template-type-parameter name="A2"/>
+ </template><parameter name="a0"><paramtype>A0 const &</paramtype></parameter><parameter name="a1"><paramtype>A1 const &</paramtype></parameter><parameter name="a2"><paramtype>A2 const &</paramtype></parameter><description><para>
+</para></description><returns><para>A new <computeroutput>expr<></computeroutput> object initialized with the specified arguments. </para></returns></method></method-group></struct-specialization><struct-specialization name="expr"><template>
+ <template-type-parameter name="Tag"/>
+ <template-type-parameter name="Args"/>
+ </template><specialization><template-arg>Tag</template-arg><template-arg>Args</template-arg><template-arg>4</template-arg></specialization><purpose>Representation of a node in an expression tree. </purpose><description><para><computeroutput>proto::expr<></computeroutput> is a node in an expression template tree. It is a container for its children sub-trees. It also serves as the terminal nodes of the tree.</para><para><computeroutput>Tag</computeroutput> is type that represents the operation encoded by this expression. It is typically one of the structs in the <computeroutput>boost::proto::tag</computeroutput> namespace, but it doesn't have to be. If the <computeroutput>Tag</computeroutput> type is <computeroutput>boost::proto::tag::terminal</computeroutput> then this <computeroutput>expr<></computeroutput> type represents a leaf in the expression tree.</para><para><computeroutput>Args</computeroutput> is a type list representing the type of the children of this expression. It is an instanti
ation of one of <computeroutput>proto::args1<></computeroutput>, <computeroutput>proto::args2<></computeroutput>, etc. The children types must all themselves be either <computeroutput>expr<></computeroutput> or <computeroutput>proto::ref_<proto::expr<>></computeroutput>, unless the <computeroutput>Tag</computeroutput> type is <computeroutput>boost::proto::tag::terminal</computeroutput>, in which case <computeroutput>Args</computeroutput> must be <computeroutput>proto::args1<T></computeroutput>, where <computeroutput>T</computeroutput> can be any type. </para></description><struct name="apply"><template>
+ <template-type-parameter name="Expr_"/>
+ <template-type-parameter name=""/>
+ <template-type-parameter name=""/>
+ </template><typedef name="type"><type>Expr_</type></typedef></struct><struct name="result"><template>
+ <template-type-parameter name="Sig"/>
+ </template><description><para>Encodes the return type of <computeroutput>expr<>operator()</computeroutput>, for use with <computeroutput>boost::result_of<></computeroutput> </para></description><typedef name="type"><type>result_of::funop< Sig, expr >::type</type></typedef></struct><typedef name="proto_tag"><type>Tag</type></typedef><typedef name="proto_arity"><type>mpl::long_< 4 ></type></typedef><typedef name="proto_base_expr"><type>expr</type></typedef><typedef name="proto_args"><type>Args</type></typedef><typedef name="proto_domain"><type><classname>default_domain</classname></type></typedef><typedef name="fusion_tag"><type>tag::proto_expr</type></typedef><typedef name="proto_is_expr_"><type>void</type></typedef><typedef name="proto_derived_expr"><type>expr</type></typedef><typedef name="proto_arg0"><type>Args::arg0</type></typedef><typedef name="proto_arg1"><type>Args::arg1</type></typedef><typedef name="proto_arg2"><type>Args::arg2</type></typedef><typedef name="proto_arg3">
<type>Args::arg3</type></typedef><typedef name="proto_arg4"><type>void</type></typedef><method-group name="public member functions"><method name="proto_base" cv="const"><type>expr const &</type><description><para>
+</para></description><returns><para>*this </para></returns></method><method name="proto_base" cv=""><type>expr &</type><description><para>This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts. </para></description></method><method name="operator[]" cv="const"><type>expr< <classname>tag::subscript</classname>, <classname>args2</classname>< <classname>ref_</classname>< expr const >, typename <classname>result_of::as_arg</classname>< A >::type > > const</type><template>
+ <template-type-parameter name="A"/>
+ </template><parameter name="a"><paramtype>A &</paramtype><description><para>The rhs. </para></description></parameter><description><para>Subscript</para><para>
+
+</para></description><returns><para>A new <computeroutput>expr<></computeroutput> node representing <computeroutput>*this</computeroutput> subscripted with <computeroutput>a</computeroutput>. </para></returns></method><method name="operator[]" cv="const"><type>expr< <classname>tag::subscript</classname>, <classname>args2</classname>< <classname>ref_</classname>< expr const >, typename <classname>result_of::as_arg</classname>< A const >::type > > const</type><template>
+ <template-type-parameter name="A"/>
+ </template><parameter name="a"><paramtype>A const &</paramtype></parameter><description><para>This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts. </para></description></method><method name="operator()" cv="const"><type>expr< <classname>tag::function</classname>, <classname>args1</classname>< <classname>ref_</classname>< expr const > > > const</type><description><para>Function call</para><para>
+</para></description><returns><para>A new <computeroutput>expr<></computeroutput> node representing the function invocation of <computeroutput/>(*this)(). </para></returns></method><method name="operator()" cv="const"><type><classname>result_of::funop1</classname>< expr const , const A0 >::type const</type><template>
+ <template-type-parameter name="A0"/>
+ </template><parameter name="a0"><paramtype>A0 const &</paramtype></parameter><description><para>This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts. </para></description></method><method name="operator()" cv="const"><type><classname>result_of::funop2</classname>< expr const , const A0, const A1 >::type const</type><template>
+ <template-type-parameter name="A0"/>
+ <template-type-parameter name="A1"/>
+ </template><parameter name="a0"><paramtype>A0 const &</paramtype></parameter><parameter name="a1"><paramtype>A1 const &</paramtype></parameter><description><para>This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts. </para></description></method><method name="operator()" cv="const"><type><classname>result_of::funop3</classname>< expr const , const A0, const A1, const A2 >::type const</type><template>
+ <template-type-parameter name="A0"/>
+ <template-type-parameter name="A1"/>
+ <template-type-parameter name="A2"/>
+ </template><parameter name="a0"><paramtype>A0 const &</paramtype></parameter><parameter name="a1"><paramtype>A1 const &</paramtype></parameter><parameter name="a2"><paramtype>A2 const &</paramtype></parameter><description><para>This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts. </para></description></method><method name="operator()" cv="const"><type><classname>result_of::funop4</classname>< expr const , const A0, const A1, const A2, const A3 >::type const</type><template>
+ <template-type-parameter name="A0"/>
+ <template-type-parameter name="A1"/>
+ <template-type-parameter name="A2"/>
+ <template-type-parameter name="A3"/>
+ </template><parameter name="a0"><paramtype>A0 const &</paramtype></parameter><parameter name="a1"><paramtype>A1 const &</paramtype></parameter><parameter name="a2"><paramtype>A2 const &</paramtype></parameter><parameter name="a3"><paramtype>A3 const &</paramtype></parameter><description><para>This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts. </para></description></method></method-group><copy-assignment><template>
+ <template-type-parameter name="A"/>
+ </template><parameter name="a"><paramtype>A &</paramtype><description><para>The rhs. </para></description></parameter><description><para>Assignment</para><para>
+
+</para></description><returns><para>A new <computeroutput>expr<></computeroutput> node representing an assignment of <computeroutput>a</computeroutput> to <computeroutput>*this</computeroutput>. </para></returns></copy-assignment><copy-assignment><template>
+ <template-type-parameter name="A"/>
+ </template><parameter name="a"><paramtype>A const &</paramtype></parameter><description><para>This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts. </para></description></copy-assignment><data-member name="arg0"><type>proto_arg0</type></data-member><data-member name="arg1"><type>proto_arg1</type></data-member><data-member name="arg2"><type>proto_arg2</type></data-member><data-member name="arg3"><type>proto_arg3</type></data-member><method-group name="public static functions"><method name="call" cv=""><type>static Expr_ const &</type><template>
+ <template-type-parameter name="Expr_"/>
+ <template-type-parameter name="State_"/>
+ <template-type-parameter name="Visitor_"/>
+ </template><parameter name="expr_"><paramtype>Expr_ const &</paramtype></parameter><parameter name=""><paramtype>State_ const &</paramtype></parameter><parameter name=""><paramtype>Visitor_ &</paramtype></parameter></method><method name="make" cv=""><type>static expr</type><template>
+ <template-type-parameter name="A0"/>
+ <template-type-parameter name="A1"/>
+ <template-type-parameter name="A2"/>
+ <template-type-parameter name="A3"/>
+ </template><parameter name="a0"><paramtype>A0 const &</paramtype></parameter><parameter name="a1"><paramtype>A1 const &</paramtype></parameter><parameter name="a2"><paramtype>A2 const &</paramtype></parameter><parameter name="a3"><paramtype>A3 const &</paramtype></parameter><description><para>
+</para></description><returns><para>A new <computeroutput>expr<></computeroutput> object initialized with the specified arguments. </para></returns></method></method-group></struct-specialization><struct-specialization name="expr"><template>
+ <template-type-parameter name="Tag"/>
+ <template-type-parameter name="Args"/>
+ </template><specialization><template-arg>Tag</template-arg><template-arg>Args</template-arg><template-arg>5</template-arg></specialization><purpose>Representation of a node in an expression tree. </purpose><description><para><computeroutput>proto::expr<></computeroutput> is a node in an expression template tree. It is a container for its children sub-trees. It also serves as the terminal nodes of the tree.</para><para><computeroutput>Tag</computeroutput> is type that represents the operation encoded by this expression. It is typically one of the structs in the <computeroutput>boost::proto::tag</computeroutput> namespace, but it doesn't have to be. If the <computeroutput>Tag</computeroutput> type is <computeroutput>boost::proto::tag::terminal</computeroutput> then this <computeroutput>expr<></computeroutput> type represents a leaf in the expression tree.</para><para><computeroutput>Args</computeroutput> is a type list representing the type of the children of this expression. It is an instanti
ation of one of <computeroutput>proto::args1<></computeroutput>, <computeroutput>proto::args2<></computeroutput>, etc. The children types must all themselves be either <computeroutput>expr<></computeroutput> or <computeroutput>proto::ref_<proto::expr<>></computeroutput>, unless the <computeroutput>Tag</computeroutput> type is <computeroutput>boost::proto::tag::terminal</computeroutput>, in which case <computeroutput>Args</computeroutput> must be <computeroutput>proto::args1<T></computeroutput>, where <computeroutput>T</computeroutput> can be any type. </para></description><struct name="apply"><template>
+ <template-type-parameter name="Expr_"/>
+ <template-type-parameter name=""/>
+ <template-type-parameter name=""/>
+ </template><typedef name="type"><type>Expr_</type></typedef></struct><struct name="result"><template>
+ <template-type-parameter name="Sig"/>
+ </template><description><para>Encodes the return type of <computeroutput>expr<>operator()</computeroutput>, for use with <computeroutput>boost::result_of<></computeroutput> </para></description><typedef name="type"><type>result_of::funop< Sig, expr >::type</type></typedef></struct><typedef name="proto_tag"><type>Tag</type></typedef><typedef name="proto_arity"><type>mpl::long_< 5 ></type></typedef><typedef name="proto_base_expr"><type>expr</type></typedef><typedef name="proto_args"><type>Args</type></typedef><typedef name="proto_domain"><type><classname>default_domain</classname></type></typedef><typedef name="fusion_tag"><type>tag::proto_expr</type></typedef><typedef name="proto_is_expr_"><type>void</type></typedef><typedef name="proto_derived_expr"><type>expr</type></typedef><typedef name="proto_arg0"><type>Args::arg0</type></typedef><typedef name="proto_arg1"><type>Args::arg1</type></typedef><typedef name="proto_arg2"><type>Args::arg2</type></typedef><typedef name="proto_arg3">
<type>Args::arg3</type></typedef><typedef name="proto_arg4"><type>Args::arg4</type></typedef><method-group name="public member functions"><method name="proto_base" cv="const"><type>expr const &</type><description><para>
+</para></description><returns><para>*this </para></returns></method><method name="proto_base" cv=""><type>expr &</type><description><para>This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts. </para></description></method><method name="operator[]" cv="const"><type>expr< <classname>tag::subscript</classname>, <classname>args2</classname>< <classname>ref_</classname>< expr const >, typename <classname>result_of::as_arg</classname>< A >::type > > const</type><template>
+ <template-type-parameter name="A"/>
+ </template><parameter name="a"><paramtype>A &</paramtype><description><para>The rhs. </para></description></parameter><description><para>Subscript</para><para>
+
+</para></description><returns><para>A new <computeroutput>expr<></computeroutput> node representing <computeroutput>*this</computeroutput> subscripted with <computeroutput>a</computeroutput>. </para></returns></method><method name="operator[]" cv="const"><type>expr< <classname>tag::subscript</classname>, <classname>args2</classname>< <classname>ref_</classname>< expr const >, typename <classname>result_of::as_arg</classname>< A const >::type > > const</type><template>
+ <template-type-parameter name="A"/>
+ </template><parameter name="a"><paramtype>A const &</paramtype></parameter><description><para>This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts. </para></description></method><method name="operator()" cv="const"><type>expr< <classname>tag::function</classname>, <classname>args1</classname>< <classname>ref_</classname>< expr const > > > const</type><description><para>Function call</para><para>
+</para></description><returns><para>A new <computeroutput>expr<></computeroutput> node representing the function invocation of <computeroutput/>(*this)(). </para></returns></method><method name="operator()" cv="const"><type><classname>result_of::funop1</classname>< expr const , const A0 >::type const</type><template>
+ <template-type-parameter name="A0"/>
+ </template><parameter name="a0"><paramtype>A0 const &</paramtype></parameter><description><para>This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts. </para></description></method><method name="operator()" cv="const"><type><classname>result_of::funop2</classname>< expr const , const A0, const A1 >::type const</type><template>
+ <template-type-parameter name="A0"/>
+ <template-type-parameter name="A1"/>
+ </template><parameter name="a0"><paramtype>A0 const &</paramtype></parameter><parameter name="a1"><paramtype>A1 const &</paramtype></parameter><description><para>This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts. </para></description></method><method name="operator()" cv="const"><type><classname>result_of::funop3</classname>< expr const , const A0, const A1, const A2 >::type const</type><template>
+ <template-type-parameter name="A0"/>
+ <template-type-parameter name="A1"/>
+ <template-type-parameter name="A2"/>
+ </template><parameter name="a0"><paramtype>A0 const &</paramtype></parameter><parameter name="a1"><paramtype>A1 const &</paramtype></parameter><parameter name="a2"><paramtype>A2 const &</paramtype></parameter><description><para>This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts. </para></description></method><method name="operator()" cv="const"><type><classname>result_of::funop4</classname>< expr const , const A0, const A1, const A2, const A3 >::type const</type><template>
+ <template-type-parameter name="A0"/>
+ <template-type-parameter name="A1"/>
+ <template-type-parameter name="A2"/>
+ <template-type-parameter name="A3"/>
+ </template><parameter name="a0"><paramtype>A0 const &</paramtype></parameter><parameter name="a1"><paramtype>A1 const &</paramtype></parameter><parameter name="a2"><paramtype>A2 const &</paramtype></parameter><parameter name="a3"><paramtype>A3 const &</paramtype></parameter><description><para>This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts. </para></description></method></method-group><copy-assignment><template>
+ <template-type-parameter name="A"/>
+ </template><parameter name="a"><paramtype>A &</paramtype><description><para>The rhs. </para></description></parameter><description><para>Assignment</para><para>
+
+</para></description><returns><para>A new <computeroutput>expr<></computeroutput> node representing an assignment of <computeroutput>a</computeroutput> to <computeroutput>*this</computeroutput>. </para></returns></copy-assignment><copy-assignment><template>
+ <template-type-parameter name="A"/>
+ </template><parameter name="a"><paramtype>A const &</paramtype></parameter><description><para>This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts. </para></description></copy-assignment><data-member name="arg0"><type>proto_arg0</type></data-member><data-member name="arg1"><type>proto_arg1</type></data-member><data-member name="arg2"><type>proto_arg2</type></data-member><data-member name="arg3"><type>proto_arg3</type></data-member><data-member name="arg4"><type>proto_arg4</type></data-member><method-group name="public static functions"><method name="call" cv=""><type>static Expr_ const &</type><template>
+ <template-type-parameter name="Expr_"/>
+ <template-type-parameter name="State_"/>
+ <template-type-parameter name="Visitor_"/>
+ </template><parameter name="expr_"><paramtype>Expr_ const &</paramtype></parameter><parameter name=""><paramtype>State_ const &</paramtype></parameter><parameter name=""><paramtype>Visitor_ &</paramtype></parameter></method><method name="make" cv=""><type>static expr</type><template>
+ <template-type-parameter name="A0"/>
+ <template-type-parameter name="A1"/>
+ <template-type-parameter name="A2"/>
+ <template-type-parameter name="A3"/>
+ <template-type-parameter name="A4"/>
+ </template><parameter name="a0"><paramtype>A0 const &</paramtype></parameter><parameter name="a1"><paramtype>A1 const &</paramtype></parameter><parameter name="a2"><paramtype>A2 const &</paramtype></parameter><parameter name="a3"><paramtype>A3 const &</paramtype></parameter><parameter name="a4"><paramtype>A4 const &</paramtype></parameter><description><para>
+</para></description><returns><para>A new <computeroutput>expr<></computeroutput> object initialized with the specified arguments. </para></returns></method></method-group></struct-specialization></namespace><namespace name="result_of"><struct name="funop0"><template>
+ <template-type-parameter name="Expr"/>
+ </template><typedef name="type"><type>expr< <classname>tag::function</classname>, <classname>args1</classname>< <classname>ref_</classname>< Expr >>></type></typedef><method-group name="public static functions"><method name="call" cv=""><type>static type const</type><parameter name="expr"><paramtype>Expr &</paramtype></parameter></method></method-group></struct><struct-specialization name="funop"><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="This"/>
+ </template><specialization><template-arg>Expr()</template-arg><template-arg>This</template-arg></specialization><inherit access="public">boost::proto::result_of::funop0< This ></inherit></struct-specialization><struct-specialization name="funop"><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="This"/>
+ </template><specialization><template-arg>Expr const ()</template-arg><template-arg>This</template-arg></specialization><inherit access="public">boost::proto::result_of::funop0< This const ></inherit></struct-specialization><struct name="funop1"><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="A0"/>
+ </template><typedef name="type"><type>expr< <classname>tag::function</classname>, <classname>args2</classname>< <classname>ref_</classname>< Expr >, typename <classname>result_of::as_arg</classname>< A0 >::type >></type></typedef><method-group name="public static functions"><method name="call" cv=""><type>static type const</type><parameter name="expr"><paramtype>Expr &</paramtype></parameter><parameter name="a0"><paramtype>A0 &</paramtype></parameter></method></method-group></struct><struct-specialization name="funop"><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="A0"/>
+ <template-type-parameter name="This"/>
+ </template><specialization><template-arg>Expr(A0)</template-arg><template-arg>This</template-arg></specialization><inherit access="public">boost::proto::result_of::funop1< This, remove_reference< A0 >::type ></inherit></struct-specialization><struct-specialization name="funop"><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="A0"/>
+ <template-type-parameter name="This"/>
+ </template><specialization><template-arg>Expr const (A0)</template-arg><template-arg>This</template-arg></specialization><inherit access="public">boost::proto::result_of::funop1< This const , remove_reference< A0 >::type ></inherit></struct-specialization><struct name="funop2"><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="A0"/>
+ <template-type-parameter name="A1"/>
+ </template><typedef name="type"><type>expr< <classname>tag::function</classname>, <classname>args3</classname>< <classname>ref_</classname>< Expr >, typename <classname>result_of::as_arg</classname>< A0 >::type, typename <classname>result_of::as_arg</classname>< A1 >::type >></type></typedef><method-group name="public static functions"><method name="call" cv=""><type>static type const</type><parameter name="expr"><paramtype>Expr &</paramtype></parameter><parameter name="a0"><paramtype>A0 &</paramtype></parameter><parameter name="a1"><paramtype>A1 &</paramtype></parameter></method></method-group></struct><struct-specialization name="funop"><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="A0"/>
+ <template-type-parameter name="A1"/>
+ <template-type-parameter name="This"/>
+ </template><specialization><template-arg>Expr(A0</template-arg><template-arg>A1)</template-arg><template-arg>This</template-arg></specialization><inherit access="public">boost::proto::result_of::funop2< This, remove_reference< A0 >::type, remove_reference< A1 >::type ></inherit></struct-specialization><struct-specialization name="funop"><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="A0"/>
+ <template-type-parameter name="A1"/>
+ <template-type-parameter name="This"/>
+ </template><specialization><template-arg>Expr const (A0</template-arg><template-arg>A1)</template-arg><template-arg>This</template-arg></specialization><inherit access="public">boost::proto::result_of::funop2< This const , remove_reference< A0 >::type, remove_reference< A1 >::type ></inherit></struct-specialization><struct name="funop3"><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="A0"/>
+ <template-type-parameter name="A1"/>
+ <template-type-parameter name="A2"/>
+ </template><typedef name="type"><type>expr< <classname>tag::function</classname>, <classname>args4</classname>< <classname>ref_</classname>< Expr >, typename <classname>result_of::as_arg</classname>< A0 >::type, typename <classname>result_of::as_arg</classname>< A1 >::type, typename <classname>result_of::as_arg</classname>< A2 >::type >></type></typedef><method-group name="public static functions"><method name="call" cv=""><type>static type const</type><parameter name="expr"><paramtype>Expr &</paramtype></parameter><parameter name="a0"><paramtype>A0 &</paramtype></parameter><parameter name="a1"><paramtype>A1 &</paramtype></parameter><parameter name="a2"><paramtype>A2 &</paramtype></parameter></method></method-group></struct><struct-specialization name="funop"><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="A0"/>
+ <template-type-parameter name="A1"/>
+ <template-type-parameter name="A2"/>
+ <template-type-parameter name="This"/>
+ </template><specialization><template-arg>Expr(A0</template-arg><template-arg>A1</template-arg><template-arg>A2)</template-arg><template-arg>This</template-arg></specialization><inherit access="public">boost::proto::result_of::funop3< This, remove_reference< A0 >::type, remove_reference< A1 >::type, remove_reference< A2 >::type ></inherit></struct-specialization><struct-specialization name="funop"><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="A0"/>
+ <template-type-parameter name="A1"/>
+ <template-type-parameter name="A2"/>
+ <template-type-parameter name="This"/>
+ </template><specialization><template-arg>Expr const (A0</template-arg><template-arg>A1</template-arg><template-arg>A2)</template-arg><template-arg>This</template-arg></specialization><inherit access="public">boost::proto::result_of::funop3< This const , remove_reference< A0 >::type, remove_reference< A1 >::type, remove_reference< A2 >::type ></inherit></struct-specialization><struct name="funop4"><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="A0"/>
+ <template-type-parameter name="A1"/>
+ <template-type-parameter name="A2"/>
+ <template-type-parameter name="A3"/>
+ </template><typedef name="type"><type>expr< <classname>tag::function</classname>, <classname>args5</classname>< <classname>ref_</classname>< Expr >, typename <classname>result_of::as_arg</classname>< A0 >::type, typename <classname>result_of::as_arg</classname>< A1 >::type, typename <classname>result_of::as_arg</classname>< A2 >::type, typename <classname>result_of::as_arg</classname>< A3 >::type >></type></typedef><method-group name="public static functions"><method name="call" cv=""><type>static type const</type><parameter name="expr"><paramtype>Expr &</paramtype></parameter><parameter name="a0"><paramtype>A0 &</paramtype></parameter><parameter name="a1"><paramtype>A1 &</paramtype></parameter><parameter name="a2"><paramtype>A2 &</paramtype></parameter><parameter name="a3"><paramtype>A3 &</paramtype></parameter></method></method-group></struct><struct-specialization name="funop"><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="A0"/>
+ <template-type-parameter name="A1"/>
+ <template-type-parameter name="A2"/>
+ <template-type-parameter name="A3"/>
+ <template-type-parameter name="This"/>
+ </template><specialization><template-arg>Expr(A0</template-arg><template-arg>A1</template-arg><template-arg>A2</template-arg><template-arg>A3)</template-arg><template-arg>This</template-arg></specialization><inherit access="public">boost::proto::result_of::funop4< This, remove_reference< A0 >::type, remove_reference< A1 >::type, remove_reference< A2 >::type, remove_reference< A3 >::type ></inherit></struct-specialization><struct-specialization name="funop"><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="A0"/>
+ <template-type-parameter name="A1"/>
+ <template-type-parameter name="A2"/>
+ <template-type-parameter name="A3"/>
+ <template-type-parameter name="This"/>
+ </template><specialization><template-arg>Expr const (A0</template-arg><template-arg>A1</template-arg><template-arg>A2</template-arg><template-arg>A3)</template-arg><template-arg>This</template-arg></specialization><inherit access="public">boost::proto::result_of::funop4< This const , remove_reference< A0 >::type, remove_reference< A1 >::type, remove_reference< A2 >::type, remove_reference< A3 >::type ></inherit></struct-specialization></namespace></namespace></namespace></header><header name="boost/xpressive/proto/extends.hpp"><para>Macros and a base class for defining end-user expression types </para><namespace name="boost"><namespace name="proto"><namespace name="exprns_"><struct name="is_proto_expr"><purpose>Empty type to be used as a dummy template parameter of POD expression wrappers. It allows argument-dependent lookup to find Proto's operator overloads. </purpose><description><para><computeroutput>proto::is_proto_expr</computeroutput> allows argument-dependent lookup
to find Proto's operator overloads. For example:</para><para><programlisting>
+
+
+
+
+
+
+
+
+
+
+
+
+///
+</programlisting></para><para>Without the second <computeroutput>Dummy</computeroutput> template parameter, Proto's operator overloads would not be considered by name lookup. </para></description></struct><struct name="extends"><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="Derived"/>
+ <template-type-parameter name="Domain"/>
+ <template-type-parameter name="Tag"/>
+ </template><purpose>extends<> class template for adding behaviors to a proto expression template </purpose><struct name="apply"><template>
+ <template-type-parameter name="Expr_"/>
+ <template-type-parameter name=""/>
+ <template-type-parameter name=""/>
+ </template><typedef name="type"><type>Expr_</type></typedef></struct><struct name="result"><template>
+ <template-type-parameter name="Sig"/>
+ </template><typedef name="type"><type>boost::mpl::apply_wrap1< Domain, typename boost::proto::result_of::funop< Sig, Derived >::type >::type</type></typedef></struct><typedef name="proto_base_expr"><type>Expr</type></typedef><typedef name="proto_domain"><type>Domain</type></typedef><typedef name="proto_derived_expr"><type>Derived</type></typedef><typedef name="proto_tag"><type>Expr::proto_tag</type></typedef><typedef name="proto_args"><type>Expr::proto_args</type></typedef><typedef name="proto_arity"><type>Expr::proto_arity</type></typedef><typedef name="proto_is_expr_"><type>void</type></typedef><typedef name="fusion_tag"><type>boost::proto::tag::proto_expr</type></typedef><typedef name="proto_arg0"><type>Expr::proto_arg0</type></typedef><typedef name="proto_arg1"><type>Expr::proto_arg1</type></typedef><typedef name="proto_arg2"><type>Expr::proto_arg2</type></typedef><typedef name="proto_arg3"><type>Expr::proto_arg3</type></typedef><typedef name="proto_arg4"><type>Expr::proto_arg4</type></t
ypedef><method-group name="public member functions"><method name="proto_base" cv=""><type>Expr &</type></method><method name="proto_base" cv="const"><type>Expr const &</type></method><method name="operator[]" cv="const"><type>boost::mpl::apply_wrap1< Domain, boost::proto::expr< <classname>boost::proto::tag::subscript</classname>, <classname>boost::proto::args2</classname>< boost::proto::ref_< Derived const >, typename <classname>boost::proto::result_of::as_arg</classname>< A >::type > > >::type const</type><template>
+ <template-type-parameter name="A"/>
+ </template><parameter name="a"><paramtype>A &</paramtype></parameter></method><method name="operator[]" cv="const"><type>boost::mpl::apply_wrap1< Domain, boost::proto::expr< <classname>boost::proto::tag::subscript</classname>, <classname>boost::proto::args2</classname>< boost::proto::ref_< Derived const >, typename <classname>boost::proto::result_of::as_arg</classname>< A const >::type > > >::type const</type><template>
+ <template-type-parameter name="A"/>
+ </template><parameter name="a"><paramtype>A const &</paramtype></parameter></method><method name="operator()" cv="const"><type>boost::mpl::apply_wrap1< Domain, typename <classname>boost::proto::result_of::funop0</classname>< Derived const >::type >::type const</type></method><method name="operator()" cv="const"><type>boost::mpl::apply_wrap1< Domain, typename <classname>boost::proto::result_of::funop1</classname>< Derived const , const A0 >::type >::type const</type><template>
+ <template-type-parameter name="A0"/>
+ </template><parameter name="a0"><paramtype>A0 const &</paramtype></parameter></method><method name="operator()" cv="const"><type>boost::mpl::apply_wrap1< Domain, typename <classname>boost::proto::result_of::funop2</classname>< Derived const , const A0, const A1 >::type >::type const</type><template>
+ <template-type-parameter name="A0"/>
+ <template-type-parameter name="A1"/>
+ </template><parameter name="a0"><paramtype>A0 const &</paramtype></parameter><parameter name="a1"><paramtype>A1 const &</paramtype></parameter></method><method name="operator()" cv="const"><type>boost::mpl::apply_wrap1< Domain, typename <classname>boost::proto::result_of::funop3</classname>< Derived const , const A0, const A1, const A2 >::type >::type const</type><template>
+ <template-type-parameter name="A0"/>
+ <template-type-parameter name="A1"/>
+ <template-type-parameter name="A2"/>
+ </template><parameter name="a0"><paramtype>A0 const &</paramtype></parameter><parameter name="a1"><paramtype>A1 const &</paramtype></parameter><parameter name="a2"><paramtype>A2 const &</paramtype></parameter></method><method name="operator()" cv="const"><type>boost::mpl::apply_wrap1< Domain, typename <classname>boost::proto::result_of::funop4</classname>< Derived const , const A0, const A1, const A2, const A3 >::type >::type const</type><template>
+ <template-type-parameter name="A0"/>
+ <template-type-parameter name="A1"/>
+ <template-type-parameter name="A2"/>
+ <template-type-parameter name="A3"/>
+ </template><parameter name="a0"><paramtype>A0 const &</paramtype></parameter><parameter name="a1"><paramtype>A1 const &</paramtype></parameter><parameter name="a2"><paramtype>A2 const &</paramtype></parameter><parameter name="a3"><paramtype>A3 const &</paramtype></parameter></method></method-group><constructor/><constructor><parameter name="that"><paramtype><classname>extends</classname> const &</paramtype></parameter></constructor><constructor><parameter name="expr_"><paramtype>Expr const &</paramtype></parameter></constructor><copy-assignment><template>
+ <template-type-parameter name="A"/>
+ </template><parameter name="a"><paramtype>A &</paramtype></parameter></copy-assignment><copy-assignment><template>
+ <template-type-parameter name="A"/>
+ </template><parameter name="a"><paramtype>A const &</paramtype></parameter></copy-assignment><data-member name="expr"><type>Expr</type></data-member><method-group name="public static functions"><method name="call" cv=""><type>static Expr_ const &</type><template>
+ <template-type-parameter name="Expr_"/>
+ <template-type-parameter name="State_"/>
+ <template-type-parameter name="Visitor_"/>
+ </template><parameter name="expr_"><paramtype>Expr_ const &</paramtype></parameter><parameter name=""><paramtype>State_ const &</paramtype></parameter><parameter name=""><paramtype>Visitor_ &</paramtype></parameter></method><method name="make" cv=""><type>static Derived const</type><parameter name="expr"><paramtype>Expr const &</paramtype></parameter></method></method-group></struct><struct-specialization name="extends"><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="Derived"/>
+ <template-type-parameter name="Domain"/>
+ </template><specialization><template-arg>Expr</template-arg><template-arg>Derived</template-arg><template-arg>Domain</template-arg><template-arg>tag::terminal</template-arg></specialization><purpose>extends<> class template for adding behaviors to a proto expression template </purpose><struct name="apply"><template>
+ <template-type-parameter name="Expr_"/>
+ <template-type-parameter name=""/>
+ <template-type-parameter name=""/>
+ </template><typedef name="type"><type>Expr_</type></typedef></struct><struct name="result"><template>
+ <template-type-parameter name="Sig"/>
+ </template><typedef name="type"><type>boost::mpl::apply_wrap1< Domain, typename boost::proto::result_of::funop< Sig, Derived >::type >::type</type></typedef></struct><typedef name="proto_base_expr"><type>Expr</type></typedef><typedef name="proto_domain"><type>Domain</type></typedef><typedef name="proto_derived_expr"><type>Derived</type></typedef><typedef name="proto_tag"><type>Expr::proto_tag</type></typedef><typedef name="proto_args"><type>Expr::proto_args</type></typedef><typedef name="proto_arity"><type>Expr::proto_arity</type></typedef><typedef name="proto_is_expr_"><type>void</type></typedef><typedef name="fusion_tag"><type>boost::proto::tag::proto_expr</type></typedef><typedef name="proto_arg0"><type>Expr::proto_arg0</type></typedef><typedef name="proto_arg1"><type>Expr::proto_arg1</type></typedef><typedef name="proto_arg2"><type>Expr::proto_arg2</type></typedef><typedef name="proto_arg3"><type>Expr::proto_arg3</type></typedef><typedef name="proto_arg4"><type>Expr::proto_arg4</type></t
ypedef><method-group name="public member functions"><method name="extends" cv=""><type/></method><method name="extends" cv=""><type/><parameter name="that"><paramtype><classname>extends</classname> const &</paramtype></parameter></method><method name="extends" cv=""><type/><parameter name="expr_"><paramtype>Expr const &</paramtype></parameter></method><method name="proto_base" cv=""><type>Expr &</type></method><method name="proto_base" cv="const"><type>Expr const &</type></method><method name="operator[]" cv="const"><type>boost::mpl::apply_wrap1< Domain, boost::proto::expr< <classname>boost::proto::tag::subscript</classname>, <classname>boost::proto::args2</classname>< boost::proto::ref_< Derived const >, typename <classname>boost::proto::result_of::as_arg</classname>< A >::type > > >::type const</type><template>
+ <template-type-parameter name="A"/>
+ </template><parameter name="a"><paramtype>A &</paramtype></parameter></method><method name="operator[]" cv="const"><type>boost::mpl::apply_wrap1< Domain, boost::proto::expr< <classname>boost::proto::tag::subscript</classname>, <classname>boost::proto::args2</classname>< boost::proto::ref_< Derived const >, typename <classname>boost::proto::result_of::as_arg</classname>< A const >::type > > >::type const</type><template>
+ <template-type-parameter name="A"/>
+ </template><parameter name="a"><paramtype>A const &</paramtype></parameter></method><method name="operator[]" cv=""><type>boost::mpl::apply_wrap1< Domain, boost::proto::expr< <classname>boost::proto::tag::subscript</classname>, <classname>boost::proto::args2</classname>< boost::proto::ref_< Derived >, typename <classname>boost::proto::result_of::as_arg</classname>< A >::type > > >::type const</type><template>
+ <template-type-parameter name="A"/>
+ </template><parameter name="a"><paramtype>A &</paramtype></parameter></method><method name="operator[]" cv=""><type>boost::mpl::apply_wrap1< Domain, boost::proto::expr< <classname>boost::proto::tag::subscript</classname>, <classname>boost::proto::args2</classname>< boost::proto::ref_< Derived >, typename <classname>boost::proto::result_of::as_arg</classname>< A const >::type > > >::type const</type><template>
+ <template-type-parameter name="A"/>
+ </template><parameter name="a"><paramtype>A const &</paramtype></parameter></method><method name="operator()" cv="const"><type>boost::mpl::apply_wrap1< Domain, typename <classname>boost::proto::result_of::funop0</classname>< Derived const >::type >::type const</type></method><method name="operator()" cv=""><type>boost::mpl::apply_wrap1< Domain, typename <classname>boost::proto::result_of::funop0</classname>< Derived >::type >::type const</type></method><method name="operator()" cv="const"><type>boost::mpl::apply_wrap1< Domain, typename <classname>boost::proto::result_of::funop1</classname>< Derived const , const A0 >::type >::type const</type><template>
+ <template-type-parameter name="A0"/>
+ </template><parameter name="a0"><paramtype>A0 const &</paramtype></parameter></method><method name="operator()" cv=""><type>boost::mpl::apply_wrap1< Domain, typename <classname>boost::proto::result_of::funop1</classname>< Derived, const A0 >::type >::type const</type><template>
+ <template-type-parameter name="A0"/>
+ </template><parameter name="a0"><paramtype>A0 const &</paramtype></parameter></method><method name="operator()" cv="const"><type>boost::mpl::apply_wrap1< Domain, typename <classname>boost::proto::result_of::funop2</classname>< Derived const , const A0, const A1 >::type >::type const</type><template>
+ <template-type-parameter name="A0"/>
+ <template-type-parameter name="A1"/>
+ </template><parameter name="a0"><paramtype>A0 const &</paramtype></parameter><parameter name="a1"><paramtype>A1 const &</paramtype></parameter></method><method name="operator()" cv=""><type>boost::mpl::apply_wrap1< Domain, typename <classname>boost::proto::result_of::funop2</classname>< Derived, const A0, const A1 >::type >::type const</type><template>
+ <template-type-parameter name="A0"/>
+ <template-type-parameter name="A1"/>
+ </template><parameter name="a0"><paramtype>A0 const &</paramtype></parameter><parameter name="a1"><paramtype>A1 const &</paramtype></parameter></method><method name="operator()" cv="const"><type>boost::mpl::apply_wrap1< Domain, typename <classname>boost::proto::result_of::funop3</classname>< Derived const , const A0, const A1, const A2 >::type >::type const</type><template>
+ <template-type-parameter name="A0"/>
+ <template-type-parameter name="A1"/>
+ <template-type-parameter name="A2"/>
+ </template><parameter name="a0"><paramtype>A0 const &</paramtype></parameter><parameter name="a1"><paramtype>A1 const &</paramtype></parameter><parameter name="a2"><paramtype>A2 const &</paramtype></parameter></method><method name="operator()" cv=""><type>boost::mpl::apply_wrap1< Domain, typename <classname>boost::proto::result_of::funop3</classname>< Derived, const A0, const A1, const A2 >::type >::type const</type><template>
+ <template-type-parameter name="A0"/>
+ <template-type-parameter name="A1"/>
+ <template-type-parameter name="A2"/>
+ </template><parameter name="a0"><paramtype>A0 const &</paramtype></parameter><parameter name="a1"><paramtype>A1 const &</paramtype></parameter><parameter name="a2"><paramtype>A2 const &</paramtype></parameter></method><method name="operator()" cv="const"><type>boost::mpl::apply_wrap1< Domain, typename <classname>boost::proto::result_of::funop4</classname>< Derived const , const A0, const A1, const A2, const A3 >::type >::type const</type><template>
+ <template-type-parameter name="A0"/>
+ <template-type-parameter name="A1"/>
+ <template-type-parameter name="A2"/>
+ <template-type-parameter name="A3"/>
+ </template><parameter name="a0"><paramtype>A0 const &</paramtype></parameter><parameter name="a1"><paramtype>A1 const &</paramtype></parameter><parameter name="a2"><paramtype>A2 const &</paramtype></parameter><parameter name="a3"><paramtype>A3 const &</paramtype></parameter></method><method name="operator()" cv=""><type>boost::mpl::apply_wrap1< Domain, typename <classname>boost::proto::result_of::funop4</classname>< Derived, const A0, const A1, const A2, const A3 >::type >::type const</type><template>
+ <template-type-parameter name="A0"/>
+ <template-type-parameter name="A1"/>
+ <template-type-parameter name="A2"/>
+ <template-type-parameter name="A3"/>
+ </template><parameter name="a0"><paramtype>A0 const &</paramtype></parameter><parameter name="a1"><paramtype>A1 const &</paramtype></parameter><parameter name="a2"><paramtype>A2 const &</paramtype></parameter><parameter name="a3"><paramtype>A3 const &</paramtype></parameter></method></method-group><copy-assignment><template>
+ <template-type-parameter name="A"/>
+ </template><parameter name="a"><paramtype>A &</paramtype></parameter></copy-assignment><copy-assignment><template>
+ <template-type-parameter name="A"/>
+ </template><parameter name="a"><paramtype>A const &</paramtype></parameter></copy-assignment><copy-assignment><template>
+ <template-type-parameter name="A"/>
+ </template><parameter name="a"><paramtype>A &</paramtype></parameter></copy-assignment><copy-assignment><template>
+ <template-type-parameter name="A"/>
+ </template><parameter name="a"><paramtype>A const &</paramtype></parameter></copy-assignment><data-member name="expr"><type>Expr</type></data-member><method-group name="public static functions"><method name="call" cv=""><type>static Expr_ const &</type><template>
+ <template-type-parameter name="Expr_"/>
+ <template-type-parameter name="State_"/>
+ <template-type-parameter name="Visitor_"/>
+ </template><parameter name="expr_"><paramtype>Expr_ const &</paramtype></parameter><parameter name=""><paramtype>State_ const &</paramtype></parameter><parameter name=""><paramtype>Visitor_ &</paramtype></parameter></method><method name="make" cv=""><type>static Derived const</type><parameter name="expr"><paramtype>Expr const &</paramtype></parameter></method></method-group></struct-specialization></namespace></namespace></namespace></header><header name="boost/xpressive/proto/fusion.hpp"><para>Make any Proto parse tree a valid Fusion sequence </para><namespace name="boost"><namespace name="fusion"><namespace name="extension"><struct name="as_element"><template>
+ <template-type-parameter name="Tag"/>
+ </template><struct name="result"><template>
+ <template-type-parameter name="Sig"/>
+ </template></struct><struct-specialization name="result"><template>
+ <template-type-parameter name="This"/>
+ <template-type-parameter name="Expr"/>
+ </template><specialization><template-arg>This(Expr)</template-arg></specialization></struct-specialization></struct><struct-specialization name="is_view_impl"><template>
+ </template><specialization><template-arg>proto::tag::proto_ref</template-arg></specialization><struct name="apply"><template>
+ <template-type-parameter name="Iterator"/>
+ </template></struct></struct-specialization><struct-specialization name="is_view_impl"><template>
+ </template><specialization><template-arg>proto::tag::proto_expr</template-arg></specialization><struct name="apply"><template>
+ <template-type-parameter name="Iterator"/>
+ </template></struct></struct-specialization><struct-specialization name="value_of_impl"><template>
+ </template><specialization><template-arg>proto::tag::proto_ref_iterator</template-arg></specialization><struct name="apply"><template>
+ <template-type-parameter name="Iterator"/>
+ </template><inherit access="public">boost::proto::result_of::arg< Iterator::expr_type, Iterator::index ></inherit></struct></struct-specialization><struct-specialization name="deref_impl"><template>
+ </template><specialization><template-arg>proto::tag::proto_ref_iterator</template-arg></specialization><struct name="apply"><template>
+ <template-type-parameter name="Iterator"/>
+ </template><typedef name="type"><type><classname>proto::result_of::arg</classname>< typename Iterator::expr_type, typename Iterator::index >::type const &</type></typedef><method-group name="public static functions"><method name="call" cv=""><type>static type</type><parameter name="iter"><paramtype>Iterator const &</paramtype></parameter></method></method-group></struct></struct-specialization><struct-specialization name="advance_impl"><template>
+ </template><specialization><template-arg>proto::tag::proto_ref_iterator</template-arg></specialization><struct name="apply"><template>
+ <template-type-parameter name="Iterator"/>
+ <template-type-parameter name="N"/>
+ </template><typedef name="type"><type><emphasis>unspecified</emphasis></type></typedef><method-group name="public static functions"><method name="call" cv=""><type>static <classname>type</classname></type><parameter name="iter"><paramtype>Iterator const &</paramtype></parameter></method></method-group></struct></struct-specialization><struct-specialization name="distance_impl"><template>
+ </template><specialization><template-arg>proto::tag::proto_ref_iterator</template-arg></specialization><struct name="apply"><template>
+ <template-type-parameter name="IteratorFrom"/>
+ <template-type-parameter name="IteratorTo"/>
+ </template></struct></struct-specialization><struct-specialization name="next_impl"><template>
+ </template><specialization><template-arg>proto::tag::proto_ref_iterator</template-arg></specialization><struct name="apply"><template>
+ <template-type-parameter name="Iterator"/>
+ </template></struct></struct-specialization><struct-specialization name="prior_impl"><template>
+ </template><specialization><template-arg>proto::tag::proto_ref_iterator</template-arg></specialization><struct name="apply"><template>
+ <template-type-parameter name="Iterator"/>
+ </template></struct></struct-specialization><struct-specialization name="category_of_impl"><template>
+ </template><specialization><template-arg>proto::tag::proto_ref</template-arg></specialization><struct name="apply"><template>
+ <template-type-parameter name="Sequence"/>
+ </template><typedef name="type"><type>random_access_traversal_tag</type></typedef></struct></struct-specialization><struct-specialization name="size_impl"><template>
+ </template><specialization><template-arg>proto::tag::proto_ref</template-arg></specialization><struct name="apply"><template>
+ <template-type-parameter name="Sequence"/>
+ </template></struct></struct-specialization><struct-specialization name="begin_impl"><template>
+ </template><specialization><template-arg>proto::tag::proto_ref</template-arg></specialization><struct name="apply"><template>
+ <template-type-parameter name="Sequence"/>
+ </template><typedef name="type"><type><emphasis>unspecified</emphasis></type></typedef><method-group name="public static functions"><method name="call" cv=""><type>static <classname>type</classname></type><parameter name="seq"><paramtype>Sequence &</paramtype></parameter></method></method-group></struct></struct-specialization><struct-specialization name="end_impl"><template>
+ </template><specialization><template-arg>proto::tag::proto_ref</template-arg></specialization><struct name="apply"><template>
+ <template-type-parameter name="Sequence"/>
+ </template><typedef name="type"><type><emphasis>unspecified</emphasis></type></typedef><method-group name="public static functions"><method name="call" cv=""><type>static <classname>type</classname></type><parameter name="seq"><paramtype>Sequence &</paramtype></parameter></method></method-group></struct></struct-specialization><struct-specialization name="value_at_impl"><template>
+ </template><specialization><template-arg>proto::tag::proto_ref</template-arg></specialization><struct name="apply"><template>
+ <template-type-parameter name="Sequence"/>
+ <template-type-parameter name="N"/>
+ </template><typedef name="type"><type><classname>proto::result_of::arg</classname>< Sequence, N >::type</type></typedef></struct></struct-specialization><struct-specialization name="at_impl"><template>
+ </template><specialization><template-arg>proto::tag::proto_ref</template-arg></specialization><struct name="apply"><template>
+ <template-type-parameter name="Sequence"/>
+ <template-type-parameter name="N"/>
+ </template><typedef name="type"><type><classname>proto::result_of::arg</classname>< Sequence, N >::type const &</type></typedef><method-group name="public static functions"><method name="call" cv=""><type>static type</type><parameter name="seq"><paramtype>Sequence &</paramtype></parameter></method></method-group></struct></struct-specialization><struct-specialization name="is_segmented_impl"><template>
+ </template><specialization><template-arg>proto::tag::proto_expr</template-arg></specialization><struct name="apply"><template>
+ <template-type-parameter name="Iterator"/>
+ </template></struct></struct-specialization><struct-specialization name="segments_impl"><template>
+ </template><specialization><template-arg>proto::tag::proto_expr</template-arg></specialization><struct name="apply"><template>
+ <template-type-parameter name="Sequence"/>
+ </template><typedef name="proto_tag"><type>Sequence::proto_tag</type></typedef><typedef name="type"><type>fusion::transform_view< proto::ref_< Sequence >, <classname>as_element</classname>< proto_tag >></type></typedef><method-group name="public static functions"><method name="call" cv=""><type>static type</type><parameter name="sequence"><paramtype>Sequence &</paramtype></parameter></method></method-group></struct></struct-specialization><struct-specialization name="category_of_impl"><template>
+ </template><specialization><template-arg>proto::tag::proto_expr</template-arg></specialization><struct name="apply"><template>
+ <template-type-parameter name="Sequence"/>
+ </template><typedef name="type"><type>forward_traversal_tag</type></typedef></struct></struct-specialization><struct-specialization name="begin_impl"><template>
+ </template><specialization><template-arg>proto::tag::proto_expr</template-arg></specialization><struct name="apply"><template>
+ <template-type-parameter name="Sequence"/>
+ </template></struct></struct-specialization><struct-specialization name="end_impl"><template>
+ </template><specialization><template-arg>proto::tag::proto_expr</template-arg></specialization><struct name="apply"><template>
+ <template-type-parameter name="Sequence"/>
+ </template></struct></struct-specialization><struct-specialization name="size_impl"><template>
+ </template><specialization><template-arg>proto::tag::proto_expr</template-arg></specialization><struct name="apply"><template>
+ <template-type-parameter name="Sequence"/>
+ </template></struct></struct-specialization></namespace></namespace><namespace name="proto"><struct name="children"><template>
+ <template-type-parameter name="Expr"/>
+ </template><method-group name="public member functions"/><constructor><parameter name="expr"><paramtype>Expr &</paramtype></parameter></constructor></struct><struct name="eval_fun"><template>
+ <template-type-parameter name="Context"/>
+ </template><struct name="result"><template>
+ <template-type-parameter name="Sig"/>
+ </template></struct><struct-specialization name="result"><template>
+ <template-type-parameter name="This"/>
+ <template-type-parameter name="Expr"/>
+ </template><specialization><template-arg>This(Expr)</template-arg></specialization><typedef name="type"><type>Context::template eval< typename remove_reference< Expr >::type >::result_type</type></typedef></struct-specialization><method-group name="public member functions"/><constructor><parameter name="ctx"><paramtype>Context &</paramtype></parameter></constructor></struct><function name="children_of"><type><classname>children</classname>< Expr ></type><template>
+ <template-type-parameter name="Expr"/>
+ </template><parameter name="expr"><paramtype>Expr &</paramtype></parameter></function></namespace></namespace></header><header name="boost/xpressive/proto/generate.hpp"><para>Contains definition of generate<> class template, which end users can specialize for generating domain-specific expression wrappers. </para><namespace name="boost"><namespace name="proto"><namespace name="generatorns_"><struct name="default_generator"><struct name="apply"><template>
+ <template-type-parameter name="Expr"/>
+ </template><typedef name="type"><type>Expr</type></typedef></struct><method-group name="public static functions"><method name="make" cv=""><type>static Expr const &</type><template>
+ <template-type-parameter name="Expr"/>
+ </template><parameter name="expr"><paramtype>Expr const &</paramtype></parameter></method></method-group></struct><struct name="generator"><template>
+ <template-nontype-parameter name="Extends"><type>template< typename > class</type></template-nontype-parameter>
+ </template><struct name="apply"><template>
+ <template-type-parameter name="Expr"/>
+ </template><typedef name="type"><type>Extends< Expr ></type></typedef></struct><method-group name="public static functions"><method name="make" cv=""><type>static Extends< Expr ></type><template>
+ <template-type-parameter name="Expr"/>
+ </template><parameter name="expr"><paramtype>Expr const &</paramtype></parameter></method></method-group></struct><struct name="pod_generator"><template>
+ <template-nontype-parameter name="Extends"><type>template< typename > class</type></template-nontype-parameter>
+ </template><struct name="apply"><template>
+ <template-type-parameter name="Expr"/>
+ </template><typedef name="type"><type>Extends< Expr ></type></typedef></struct><method-group name="public static functions"><method name="make" cv=""><type>static Extends< Expr ></type><template>
+ <template-type-parameter name="Expr"/>
+ </template><parameter name="expr"><paramtype>Expr const &</paramtype></parameter></method></method-group></struct></namespace></namespace></namespace></header><header name="boost/xpressive/proto/literal.hpp"><para>The literal<> terminal wrapper, and the proto::lit() function for creating literal<> wrappers. </para><namespace name="boost"><namespace name="proto"><namespace name="utility"><struct name="literal"><template>
+ <template-type-parameter name="T"/>
+ <template-type-parameter name="Domain"/>
+ </template><inherit access="public">boost::proto::exprns_::extends< Expr, Derived, Domain, Tag ></inherit><typedef name="terminal_type"><type><classname>terminal</classname>< T >::type</type></typedef><typedef name="base_type"><type><classname>extends</classname>< terminal_type, <classname>literal</classname>< T, Domain >, Domain ></type></typedef><method-group name="public member functions"/><constructor><template>
+ <template-type-parameter name="U"/>
+ </template><parameter name="u"><paramtype>U &</paramtype></parameter></constructor><constructor><template>
+ <template-type-parameter name="U"/>
+ </template><parameter name="u"><paramtype>U const &</paramtype></parameter></constructor><constructor><template>
+ <template-type-parameter name="U"/>
+ </template><parameter name="u"><paramtype><classname>literal</classname>< U, Domain > const &</paramtype></parameter></constructor></struct></namespace><overloaded-function name="lit"><signature><type><classname>literal</classname>< T & ></type><template>
+ <template-type-parameter name="T"/>
+ </template><parameter name="t"><paramtype>T &</paramtype></parameter></signature><signature><type><classname>literal</classname>< T const & ></type><template>
+ <template-type-parameter name="T"/>
+ </template><parameter name="t"><paramtype>T const &</paramtype></parameter></signature><description><para>lit </para></description></overloaded-function></namespace></namespace></header><header name="boost/xpressive/proto/make_expr.hpp"><para>Given a Fusion sequence of arguments and the type of a proto Expression, unpacks the sequence into the Expression. </para><namespace name="boost"><namespace name="fusion"/><namespace name="proto"><namespace name="functional"><struct name="make_expr"><template>
+ <template-type-parameter name="Tag"/>
+ <template-type-parameter name="Domain"/>
+ </template><struct name="result"><template>
+ <template-type-parameter name="Sig"/>
+ </template></struct><struct-specialization name="result"><template>
+ <template-type-parameter name="This"/>
+ <template-type-parameter name="A0"/>
+ </template><specialization><template-arg>This(A0)</template-arg></specialization><inherit access="public">boost::proto::result_of::make_expr< Tag, Domain, remove_reference< A0 >::type ></inherit></struct-specialization><struct-specialization name="result"><template>
+ <template-type-parameter name="This"/>
+ <template-type-parameter name="A0"/>
+ <template-type-parameter name="A1"/>
+ </template><specialization><template-arg>This(A0</template-arg><template-arg>A1)</template-arg></specialization><inherit access="public">boost::proto::result_of::make_expr< Tag, Domain, remove_reference< A0 >::type, remove_reference< A1 >::type ></inherit></struct-specialization><struct-specialization name="result"><template>
+ <template-type-parameter name="This"/>
+ <template-type-parameter name="A0"/>
+ <template-type-parameter name="A1"/>
+ <template-type-parameter name="A2"/>
+ </template><specialization><template-arg>This(A0</template-arg><template-arg>A1</template-arg><template-arg>A2)</template-arg></specialization><inherit access="public">boost::proto::result_of::make_expr< Tag, Domain, remove_reference< A0 >::type, remove_reference< A1 >::type, remove_reference< A2 >::type ></inherit></struct-specialization><struct-specialization name="result"><template>
+ <template-type-parameter name="This"/>
+ <template-type-parameter name="A0"/>
+ <template-type-parameter name="A1"/>
+ <template-type-parameter name="A2"/>
+ <template-type-parameter name="A3"/>
+ </template><specialization><template-arg>This(A0</template-arg><template-arg>A1</template-arg><template-arg>A2</template-arg><template-arg>A3)</template-arg></specialization><inherit access="public">boost::proto::result_of::make_expr< Tag, Domain, remove_reference< A0 >::type, remove_reference< A1 >::type, remove_reference< A2 >::type, remove_reference< A3 >::type ></inherit></struct-specialization><struct-specialization name="result"><template>
+ <template-type-parameter name="This"/>
+ <template-type-parameter name="A0"/>
+ <template-type-parameter name="A1"/>
+ <template-type-parameter name="A2"/>
+ <template-type-parameter name="A3"/>
+ <template-type-parameter name="A4"/>
+ </template><specialization><template-arg>This(A0</template-arg><template-arg>A1</template-arg><template-arg>A2</template-arg><template-arg>A3</template-arg><template-arg>A4)</template-arg></specialization><inherit access="public">boost::proto::result_of::make_expr< Tag, Domain, remove_reference< A0 >::type, remove_reference< A1 >::type, remove_reference< A2 >::type, remove_reference< A3 >::type, remove_reference< A4 >::type ></inherit></struct-specialization><method-group name="public member functions"><method name="operator()" cv="const"><type><classname>result_of::make_expr</classname>< Tag, Domain, A >::type const</type><template>
+ <template-type-parameter name="A"/>
+ </template><parameter name="a"><paramtype>A &</paramtype></parameter></method><method name="operator()" cv="const"><type><classname>result_of::make_expr</classname>< Tag, Domain, const A0 >::type const</type><template>
+ <template-type-parameter name="A0"/>
+ </template><parameter name="a0"><paramtype>const A0 &</paramtype></parameter></method><method name="operator()" cv="const"><type><classname>result_of::make_expr</classname>< Tag, Domain, const A0, const A1 >::type const</type><template>
+ <template-type-parameter name="A0"/>
+ <template-type-parameter name="A1"/>
+ </template><parameter name="a0"><paramtype>const A0 &</paramtype></parameter><parameter name="a1"><paramtype>const A1 &</paramtype></parameter></method><method name="operator()" cv="const"><type><classname>result_of::make_expr</classname>< Tag, Domain, const A0, const A1, const A2 >::type const</type><template>
+ <template-type-parameter name="A0"/>
+ <template-type-parameter name="A1"/>
+ <template-type-parameter name="A2"/>
+ </template><parameter name="a0"><paramtype>const A0 &</paramtype></parameter><parameter name="a1"><paramtype>const A1 &</paramtype></parameter><parameter name="a2"><paramtype>const A2 &</paramtype></parameter></method><method name="operator()" cv="const"><type><classname>result_of::make_expr</classname>< Tag, Domain, const A0, const A1, const A2, const A3 >::type const</type><template>
+ <template-type-parameter name="A0"/>
+ <template-type-parameter name="A1"/>
+ <template-type-parameter name="A2"/>
+ <template-type-parameter name="A3"/>
+ </template><parameter name="a0"><paramtype>const A0 &</paramtype></parameter><parameter name="a1"><paramtype>const A1 &</paramtype></parameter><parameter name="a2"><paramtype>const A2 &</paramtype></parameter><parameter name="a3"><paramtype>const A3 &</paramtype></parameter></method><method name="operator()" cv="const"><type><classname>result_of::make_expr</classname>< Tag, Domain, const A0, const A1, const A2, const A3, const A4 >::type const</type><template>
+ <template-type-parameter name="A0"/>
+ <template-type-parameter name="A1"/>
+ <template-type-parameter name="A2"/>
+ <template-type-parameter name="A3"/>
+ <template-type-parameter name="A4"/>
+ </template><parameter name="a0"><paramtype>const A0 &</paramtype></parameter><parameter name="a1"><paramtype>const A1 &</paramtype></parameter><parameter name="a2"><paramtype>const A2 &</paramtype></parameter><parameter name="a3"><paramtype>const A3 &</paramtype></parameter><parameter name="a4"><paramtype>const A4 &</paramtype></parameter></method></method-group></struct><struct name="unpack_expr"><template>
+ <template-type-parameter name="Tag"/>
+ <template-type-parameter name="Domain"/>
+ </template><struct name="result"><template>
+ <template-type-parameter name="Sig"/>
+ </template></struct><struct-specialization name="result"><template>
+ <template-type-parameter name="This"/>
+ <template-type-parameter name="Sequence"/>
+ </template><specialization><template-arg>This(Sequence)</template-arg></specialization></struct-specialization><method-group name="public member functions"><method name="operator()" cv="const"><type><classname>result_of::unpack_expr</classname>< Tag, Domain, Sequence >::type</type><template>
+ <template-type-parameter name="Sequence"/>
+ </template><parameter name="sequence"><paramtype>Sequence const &</paramtype></parameter></method></method-group></struct><struct name="unfused_expr_fun"><template>
+ <template-type-parameter name="Tag"/>
+ <template-type-parameter name="Domain"/>
+ </template><struct name="result"><template>
+ <template-type-parameter name="Sequence"/>
+ </template><inherit access="public">boost::proto::result_of::unpack_expr< Tag, Domain, Sequence ></inherit></struct><method-group name="public member functions"><method name="operator()" cv="const"><type><classname>proto::result_of::unpack_expr</classname>< Tag, Domain, Sequence >::type</type><template>
+ <template-type-parameter name="Sequence"/>
+ </template><parameter name="sequence"><paramtype>Sequence const &</paramtype></parameter></method></method-group></struct><struct name="unfused_expr"><template>
+ <template-type-parameter name="Tag"/>
+ <template-type-parameter name="Domain"/>
+ </template></struct><struct-specialization name="make_expr"><template>
+ <template-type-parameter name="Domain"/>
+ </template><specialization><template-arg>tag::terminal</template-arg><template-arg>Domain</template-arg></specialization><struct name="result"><template>
+ <template-type-parameter name="Sig"/>
+ </template></struct><struct-specialization name="result"><template>
+ <template-type-parameter name="This"/>
+ <template-type-parameter name="A"/>
+ </template><specialization><template-arg>This(A)</template-arg></specialization><inherit access="public">boost::proto::result_of::make_expr< tag::terminal, Domain, A ></inherit></struct-specialization><method-group name="public member functions"><method name="operator()" cv="const"><type><classname>result_of::make_expr</classname>< <classname>tag::terminal</classname>, Domain, A >::type</type><template>
+ <template-type-parameter name="A"/>
+ </template><parameter name="a"><paramtype>A &</paramtype></parameter></method><method name="operator()" cv="const"><type><classname>result_of::make_expr</classname>< <classname>tag::terminal</classname>, Domain, A const >::type</type><template>
+ <template-type-parameter name="A"/>
+ </template><parameter name="a"><paramtype>A const &</paramtype></parameter></method></method-group></struct-specialization></namespace><namespace name="result_of"><struct name="unpack_expr"><template>
+ <template-type-parameter name="Tag"/>
+ <template-type-parameter name="Sequence"/>
+ <template-type-parameter name=""/>
+ <template-type-parameter name=""/>
+ </template></struct><struct name="make_expr"><template>
+ <template-type-parameter name="Tag"/>
+ <template-type-parameter name="A0"/>
+ <template-type-parameter name="A1"/>
+ <template-type-parameter name="A2"/>
+ <template-type-parameter name="A3"/>
+ <template-type-parameter name="A4"/>
+ <template-type-parameter name=""/>
+ <template-type-parameter name=""/>
+ </template></struct><struct-specialization name="make_expr"><template>
+ <template-type-parameter name="Tag"/>
+ <template-type-parameter name="A0"/>
+ <template-type-parameter name="A1"/>
+ <template-type-parameter name="A2"/>
+ <template-type-parameter name="A3"/>
+ <template-type-parameter name="A4"/>
+ </template><specialization><template-arg>Tag</template-arg><template-arg>deduce_domain</template-arg><template-arg>A0</template-arg><template-arg>A1</template-arg><template-arg>A2</template-arg><template-arg>A3</template-arg><template-arg>A4</template-arg><template-arg>void</template-arg></specialization></struct-specialization><struct-specialization name="unpack_expr"><template>
+ <template-type-parameter name="Tag"/>
+ <template-type-parameter name="Domain"/>
+ <template-type-parameter name="Sequence"/>
+ </template><specialization><template-arg>Tag</template-arg><template-arg>Domain</template-arg><template-arg>Sequence</template-arg><template-arg>typename Domain::proto_is_domain_</template-arg></specialization></struct-specialization><struct-specialization name="make_expr"><template>
+ <template-type-parameter name="Tag"/>
+ <template-type-parameter name="Domain"/>
+ <template-type-parameter name="A0"/>
+ <template-type-parameter name="A1"/>
+ <template-type-parameter name="A2"/>
+ <template-type-parameter name="A3"/>
+ <template-type-parameter name="A4"/>
+ </template><specialization><template-arg>Tag</template-arg><template-arg>Domain</template-arg><template-arg>A0</template-arg><template-arg>A1</template-arg><template-arg>A2</template-arg><template-arg>A3</template-arg><template-arg>A4</template-arg><template-arg>typename Domain::proto_is_domain_</template-arg></specialization></struct-specialization></namespace><overloaded-function name="unpack_expr"><signature><type>lazy_disable_if< <classname>is_domain</classname>< Sequence >, <classname>result_of::unpack_expr</classname>< Tag, Sequence >>::type const</type><template>
+ <template-type-parameter name="Tag"/>
+ <template-type-parameter name="Sequence"/>
+ </template><parameter name="sequence"><paramtype>Sequence const &</paramtype></parameter></signature><signature><type><classname>result_of::unpack_expr</classname>< Tag, Domain, Sequence2 >::type const</type><template>
+ <template-type-parameter name="Tag"/>
+ <template-type-parameter name="Domain"/>
+ <template-type-parameter name="Sequence2"/>
+ </template><parameter name="sequence2"><paramtype>Sequence2 const &</paramtype></parameter></signature><description><para>unpack_expr </para></description></overloaded-function><overloaded-function name="make_expr"><signature><type>lazy_disable_if< <classname>is_domain</classname>< A0 >, <classname>result_of::make_expr</classname>< Tag, A0 >>::type const</type><template>
+ <template-type-parameter name="Tag"/>
+ <template-type-parameter name="A0"/>
+ </template><parameter name="a0"><paramtype>A0 &</paramtype></parameter></signature><signature><type><classname>result_of::make_expr</classname>< Tag, Domain, B0 >::type const</type><template>
+ <template-type-parameter name="Tag"/>
+ <template-type-parameter name="Domain"/>
+ <template-type-parameter name="B0"/>
+ </template><parameter name="b0"><paramtype>B0 &</paramtype></parameter></signature><signature><type>lazy_disable_if< <classname>is_domain</classname>< A0 >, <classname>result_of::make_expr</classname>< Tag, const A0 >>::type const</type><template>
+ <template-type-parameter name="Tag"/>
+ <template-type-parameter name="A0"/>
+ </template><parameter name="a0"><paramtype>const A0 &</paramtype></parameter></signature><signature><type><classname>result_of::make_expr</classname>< Tag, Domain, const B0 >::type const</type><template>
+ <template-type-parameter name="Tag"/>
+ <template-type-parameter name="Domain"/>
+ <template-type-parameter name="B0"/>
+ </template><parameter name="b0"><paramtype>const B0 &</paramtype></parameter></signature><signature><type>lazy_disable_if< <classname>is_domain</classname>< A0 >, <classname>result_of::make_expr</classname>< Tag, const A0, const A1 >>::type const</type><template>
+ <template-type-parameter name="Tag"/>
+ <template-type-parameter name="A0"/>
+ <template-type-parameter name="A1"/>
+ </template><parameter name="a0"><paramtype>const A0 &</paramtype></parameter><parameter name="a1"><paramtype>const A1 &</paramtype></parameter></signature><signature><type><classname>result_of::make_expr</classname>< Tag, Domain, const B0, const B1 >::type const</type><template>
+ <template-type-parameter name="Tag"/>
+ <template-type-parameter name="Domain"/>
+ <template-type-parameter name="B0"/>
+ <template-type-parameter name="B1"/>
+ </template><parameter name="b0"><paramtype>const B0 &</paramtype></parameter><parameter name="b1"><paramtype>const B1 &</paramtype></parameter></signature><signature><type>lazy_disable_if< <classname>is_domain</classname>< A0 >, <classname>result_of::make_expr</classname>< Tag, const A0, const A1, const A2 >>::type const</type><template>
+ <template-type-parameter name="Tag"/>
+ <template-type-parameter name="A0"/>
+ <template-type-parameter name="A1"/>
+ <template-type-parameter name="A2"/>
+ </template><parameter name="a0"><paramtype>const A0 &</paramtype></parameter><parameter name="a1"><paramtype>const A1 &</paramtype></parameter><parameter name="a2"><paramtype>const A2 &</paramtype></parameter></signature><signature><type><classname>result_of::make_expr</classname>< Tag, Domain, const B0, const B1, const B2 >::type const</type><template>
+ <template-type-parameter name="Tag"/>
+ <template-type-parameter name="Domain"/>
+ <template-type-parameter name="B0"/>
+ <template-type-parameter name="B1"/>
+ <template-type-parameter name="B2"/>
+ </template><parameter name="b0"><paramtype>const B0 &</paramtype></parameter><parameter name="b1"><paramtype>const B1 &</paramtype></parameter><parameter name="b2"><paramtype>const B2 &</paramtype></parameter></signature><signature><type>lazy_disable_if< <classname>is_domain</classname>< A0 >, <classname>result_of::make_expr</classname>< Tag, const A0, const A1, const A2, const A3 >>::type const</type><template>
+ <template-type-parameter name="Tag"/>
+ <template-type-parameter name="A0"/>
+ <template-type-parameter name="A1"/>
+ <template-type-parameter name="A2"/>
+ <template-type-parameter name="A3"/>
+ </template><parameter name="a0"><paramtype>const A0 &</paramtype></parameter><parameter name="a1"><paramtype>const A1 &</paramtype></parameter><parameter name="a2"><paramtype>const A2 &</paramtype></parameter><parameter name="a3"><paramtype>const A3 &</paramtype></parameter></signature><signature><type><classname>result_of::make_expr</classname>< Tag, Domain, const B0, const B1, const B2, const B3 >::type const</type><template>
+ <template-type-parameter name="Tag"/>
+ <template-type-parameter name="Domain"/>
+ <template-type-parameter name="B0"/>
+ <template-type-parameter name="B1"/>
+ <template-type-parameter name="B2"/>
+ <template-type-parameter name="B3"/>
+ </template><parameter name="b0"><paramtype>const B0 &</paramtype></parameter><parameter name="b1"><paramtype>const B1 &</paramtype></parameter><parameter name="b2"><paramtype>const B2 &</paramtype></parameter><parameter name="b3"><paramtype>const B3 &</paramtype></parameter></signature><signature><type>lazy_disable_if< <classname>is_domain</classname>< A0 >, <classname>result_of::make_expr</classname>< Tag, const A0, const A1, const A2, const A3, const A4 >>::type const</type><template>
+ <template-type-parameter name="Tag"/>
+ <template-type-parameter name="A0"/>
+ <template-type-parameter name="A1"/>
+ <template-type-parameter name="A2"/>
+ <template-type-parameter name="A3"/>
+ <template-type-parameter name="A4"/>
+ </template><parameter name="a0"><paramtype>const A0 &</paramtype></parameter><parameter name="a1"><paramtype>const A1 &</paramtype></parameter><parameter name="a2"><paramtype>const A2 &</paramtype></parameter><parameter name="a3"><paramtype>const A3 &</paramtype></parameter><parameter name="a4"><paramtype>const A4 &</paramtype></parameter></signature><signature><type><classname>result_of::make_expr</classname>< Tag, Domain, const B0, const B1, const B2, const B3, const B4 >::type const</type><template>
+ <template-type-parameter name="Tag"/>
+ <template-type-parameter name="Domain"/>
+ <template-type-parameter name="B0"/>
+ <template-type-parameter name="B1"/>
+ <template-type-parameter name="B2"/>
+ <template-type-parameter name="B3"/>
+ <template-type-parameter name="B4"/>
+ </template><parameter name="b0"><paramtype>const B0 &</paramtype></parameter><parameter name="b1"><paramtype>const B1 &</paramtype></parameter><parameter name="b2"><paramtype>const B2 &</paramtype></parameter><parameter name="b3"><paramtype>const B3 &</paramtype></parameter><parameter name="b4"><paramtype>const B4 &</paramtype></parameter></signature><description><para>make_expr </para></description></overloaded-function></namespace></namespace></header><header name="boost/xpressive/proto/matches.hpp"><para>Contains definition of matches<> metafunction for determining if a given expression matches a given pattern. </para><namespace name="boost"><namespace name="proto"><namespace name="control"><struct name="not_"><template>
+ <template-type-parameter name="Grammar"/>
+ </template><inherit access="public">boost::proto::has_transformns_::has_identity_transform</inherit><typedef name="proto_base_expr"><type><classname>not_</classname></type></typedef></struct><struct name="if_"><template>
+ <template-type-parameter name="Condition"/>
+ <template-type-parameter name="Then"/>
+ <template-type-parameter name="Else"/>
+ </template><inherit access="public">boost::proto::control::or_< and_< if_< Condition >, Then >, and_< not_< if_< Condition > >, Else > ></inherit></struct><struct-specialization name="if_"><template>
+ <template-type-parameter name="Condition"/>
+ <template-type-parameter name="Then"/>
+ </template><specialization><template-arg>Condition</template-arg><template-arg>Then</template-arg><template-arg>void</template-arg></specialization><inherit access="public">boost::proto::control::and_< if_< Condition >, Then ></inherit></struct-specialization><struct-specialization name="if_"><template>
+ <template-type-parameter name="Condition"/>
+ </template><specialization><template-arg>Condition</template-arg><template-arg>void</template-arg><template-arg>void</template-arg></specialization><inherit access="public">boost::proto::has_transformns_::has_identity_transform</inherit><typedef name="proto_base_expr"><type><classname>if_</classname></type></typedef></struct-specialization><struct name="or_"><template>
+ <template-type-parameter name="G0"/>
+ <template-type-parameter name="G1"/>
+ <template-type-parameter name="G2"/>
+ <template-type-parameter name="G3"/>
+ <template-type-parameter name="G4"/>
+ <template-type-parameter name="G5"/>
+ <template-type-parameter name="G6"/>
+ <template-type-parameter name="G7"/>
+ </template><struct name="apply"><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="State"/>
+ <template-type-parameter name="Visitor"/>
+ </template><typedef name="which"><type><emphasis>unspecified</emphasis></type></typedef><typedef name="type"><type>which::template <classname>apply</classname>< Expr, State, Visitor >::type</type></typedef></struct><typedef name="proto_base_expr"><type><classname>or_</classname></type></typedef><method-group name="public static functions"><method name="call" cv=""><type>static <classname>apply</classname>< Expr, State, Visitor >::type</type><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="State"/>
+ <template-type-parameter name="Visitor"/>
+ </template><parameter name="expr"><paramtype>Expr const &</paramtype></parameter><parameter name="state"><paramtype>State const &</paramtype></parameter><parameter name="visitor"><paramtype>Visitor &</paramtype></parameter></method></method-group></struct><struct name="and_"><template>
+ <template-type-parameter name="G0"/>
+ <template-type-parameter name="G1"/>
+ <template-type-parameter name="G2"/>
+ <template-type-parameter name="G3"/>
+ <template-type-parameter name="G4"/>
+ <template-type-parameter name="G5"/>
+ <template-type-parameter name="G6"/>
+ <template-type-parameter name="G7"/>
+ </template><struct name="apply"><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="State"/>
+ <template-type-parameter name="Visitor"/>
+ </template><typedef name="which"><type><emphasis>unspecified</emphasis></type></typedef><typedef name="type"><type>which::template <classname>apply</classname>< Expr, State, Visitor >::type</type></typedef></struct><typedef name="proto_base_expr"><type><classname>and_</classname></type></typedef><method-group name="public static functions"><method name="call" cv=""><type>static <classname>apply</classname>< Expr, State, Visitor >::type</type><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="State"/>
+ <template-type-parameter name="Visitor"/>
+ </template><parameter name="expr"><paramtype>Expr const &</paramtype></parameter><parameter name="state"><paramtype>State const &</paramtype></parameter><parameter name="visitor"><paramtype>Visitor &</paramtype></parameter></method></method-group></struct><struct name="switch_"><template>
+ <template-type-parameter name="Cases"/>
+ </template><struct name="apply"><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="State"/>
+ <template-type-parameter name="Visitor"/>
+ </template></struct><typedef name="proto_base_expr"><type><classname>switch_</classname></type></typedef><method-group name="public static functions"><method name="call" cv=""><type>static <classname>apply</classname>< Expr, State, Visitor >::type</type><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="State"/>
+ <template-type-parameter name="Visitor"/>
+ </template><parameter name="expr"><paramtype>Expr const &</paramtype></parameter><parameter name="state"><paramtype>State const &</paramtype></parameter><parameter name="visitor"><paramtype>Visitor &</paramtype></parameter></method></method-group></struct><struct name="exact"><template>
+ <template-type-parameter name="T"/>
+ </template></struct><struct name="convertible_to"><template>
+ <template-type-parameter name="T"/>
+ </template></struct><struct name="vararg"><template>
+ <template-type-parameter name="Grammar"/>
+ </template><typedef name="proto_is_vararg_"><type>void</type></typedef></struct></namespace><namespace name="result_of"><struct name="matches"><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="Grammar"/>
+ </template></struct></namespace><namespace name="wildcardns_"><struct name="_"><inherit access="public">boost::proto::has_transformns_::has_identity_transform</inherit><typedef name="proto_base_expr"><type><classname>_</classname></type></typedef><typedef name="proto_is_wildcard_"><type>void</type></typedef></struct><function name="is_wildcard_expression_fun"><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="T"/>
+ </template><parameter name=""><paramtype>T const *</paramtype></parameter></function></namespace></namespace></namespace></header><header name="boost/xpressive/proto/operators.hpp"><para>Contains all the overloaded operators that make it possible to build expression templates using proto components </para><namespace name="boost"><namespace name="proto"><struct name="is_extension"><template>
+ <template-type-parameter name="T"/>
+ </template></struct><namespace name="exprns_"><function name="operator+"><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Arg"/>
+ </template><parameter name="arg"><paramtype>Arg &</paramtype></parameter></function><function name="operator+"><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Arg"/>
+ </template><parameter name="arg"><paramtype>Arg const &</paramtype></parameter></function><function name="operator-"><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Arg"/>
+ </template><parameter name="arg"><paramtype>Arg &</paramtype></parameter></function><function name="operator-"><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Arg"/>
+ </template><parameter name="arg"><paramtype>Arg const &</paramtype></parameter></function><function name="operator*"><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Arg"/>
+ </template><parameter name="arg"><paramtype>Arg &</paramtype></parameter></function><function name="operator*"><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Arg"/>
+ </template><parameter name="arg"><paramtype>Arg const &</paramtype></parameter></function><function name="operator~"><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Arg"/>
+ </template><parameter name="arg"><paramtype>Arg &</paramtype></parameter></function><function name="operator~"><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Arg"/>
+ </template><parameter name="arg"><paramtype>Arg const &</paramtype></parameter></function><function name="operator&"><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Arg"/>
+ </template><parameter name="arg"><paramtype>Arg &</paramtype></parameter></function><function name="operator&"><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Arg"/>
+ </template><parameter name="arg"><paramtype>Arg const &</paramtype></parameter></function><function name="operator!"><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Arg"/>
+ </template><parameter name="arg"><paramtype>Arg &</paramtype></parameter></function><function name="operator!"><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Arg"/>
+ </template><parameter name="arg"><paramtype>Arg const &</paramtype></parameter></function><function name="operator++"><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Arg"/>
+ </template><parameter name="arg"><paramtype>Arg &</paramtype></parameter></function><function name="operator++"><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Arg"/>
+ </template><parameter name="arg"><paramtype>Arg const &</paramtype></parameter></function><function name="operator--"><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Arg"/>
+ </template><parameter name="arg"><paramtype>Arg &</paramtype></parameter></function><function name="operator--"><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Arg"/>
+ </template><parameter name="arg"><paramtype>Arg const &</paramtype></parameter></function><function name="operator++"><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Arg"/>
+ </template><parameter name="arg"><paramtype>Arg &</paramtype></parameter><parameter name=""><paramtype>int</paramtype></parameter></function><function name="operator++"><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Arg"/>
+ </template><parameter name="arg"><paramtype>Arg const &</paramtype></parameter><parameter name=""><paramtype>int</paramtype></parameter></function><function name="operator--"><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Arg"/>
+ </template><parameter name="arg"><paramtype>Arg &</paramtype></parameter><parameter name=""><paramtype>int</paramtype></parameter></function><function name="operator--"><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Arg"/>
+ </template><parameter name="arg"><paramtype>Arg const &</paramtype></parameter><parameter name=""><paramtype>int</paramtype></parameter></function><function name="operator<<"><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Left"/>
+ <template-type-parameter name="Right"/>
+ </template><parameter name="left"><paramtype>Left &</paramtype></parameter><parameter name="right"><paramtype>Right &</paramtype></parameter></function><function name="operator<<"><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Left"/>
+ <template-type-parameter name="Right"/>
+ </template><parameter name="left"><paramtype>Left &</paramtype></parameter><parameter name="right"><paramtype>Right const &</paramtype></parameter></function><function name="operator<<"><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Left"/>
+ <template-type-parameter name="Right"/>
+ </template><parameter name="left"><paramtype>Left const &</paramtype></parameter><parameter name="right"><paramtype>Right &</paramtype></parameter></function><function name="operator<<"><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Left"/>
+ <template-type-parameter name="Right"/>
+ </template><parameter name="left"><paramtype>Left const &</paramtype></parameter><parameter name="right"><paramtype>Right const &</paramtype></parameter></function><function name="operator>>"><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Left"/>
+ <template-type-parameter name="Right"/>
+ </template><parameter name="left"><paramtype>Left &</paramtype></parameter><parameter name="right"><paramtype>Right &</paramtype></parameter></function><function name="operator>>"><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Left"/>
+ <template-type-parameter name="Right"/>
+ </template><parameter name="left"><paramtype>Left &</paramtype></parameter><parameter name="right"><paramtype>Right const &</paramtype></parameter></function><function name="operator>>"><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Left"/>
+ <template-type-parameter name="Right"/>
+ </template><parameter name="left"><paramtype>Left const &</paramtype></parameter><parameter name="right"><paramtype>Right &</paramtype></parameter></function><function name="operator>>"><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Left"/>
+ <template-type-parameter name="Right"/>
+ </template><parameter name="left"><paramtype>Left const &</paramtype></parameter><parameter name="right"><paramtype>Right const &</paramtype></parameter></function><function name="operator*"><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Left"/>
+ <template-type-parameter name="Right"/>
+ </template><parameter name="left"><paramtype>Left &</paramtype></parameter><parameter name="right"><paramtype>Right &</paramtype></parameter></function><function name="operator*"><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Left"/>
+ <template-type-parameter name="Right"/>
+ </template><parameter name="left"><paramtype>Left &</paramtype></parameter><parameter name="right"><paramtype>Right const &</paramtype></parameter></function><function name="operator*"><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Left"/>
+ <template-type-parameter name="Right"/>
+ </template><parameter name="left"><paramtype>Left const &</paramtype></parameter><parameter name="right"><paramtype>Right &</paramtype></parameter></function><function name="operator*"><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Left"/>
+ <template-type-parameter name="Right"/>
+ </template><parameter name="left"><paramtype>Left const &</paramtype></parameter><parameter name="right"><paramtype>Right const &</paramtype></parameter></function><function name="operator/"><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Left"/>
+ <template-type-parameter name="Right"/>
+ </template><parameter name="left"><paramtype>Left &</paramtype></parameter><parameter name="right"><paramtype>Right &</paramtype></parameter></function><function name="operator/"><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Left"/>
+ <template-type-parameter name="Right"/>
+ </template><parameter name="left"><paramtype>Left &</paramtype></parameter><parameter name="right"><paramtype>Right const &</paramtype></parameter></function><function name="operator/"><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Left"/>
+ <template-type-parameter name="Right"/>
+ </template><parameter name="left"><paramtype>Left const &</paramtype></parameter><parameter name="right"><paramtype>Right &</paramtype></parameter></function><function name="operator/"><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Left"/>
+ <template-type-parameter name="Right"/>
+ </template><parameter name="left"><paramtype>Left const &</paramtype></parameter><parameter name="right"><paramtype>Right const &</paramtype></parameter></function><function name="operator%"><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Left"/>
+ <template-type-parameter name="Right"/>
+ </template><parameter name="left"><paramtype>Left &</paramtype></parameter><parameter name="right"><paramtype>Right &</paramtype></parameter></function><function name="operator%"><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Left"/>
+ <template-type-parameter name="Right"/>
+ </template><parameter name="left"><paramtype>Left &</paramtype></parameter><parameter name="right"><paramtype>Right const &</paramtype></parameter></function><function name="operator%"><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Left"/>
+ <template-type-parameter name="Right"/>
+ </template><parameter name="left"><paramtype>Left const &</paramtype></parameter><parameter name="right"><paramtype>Right &</paramtype></parameter></function><function name="operator%"><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Left"/>
+ <template-type-parameter name="Right"/>
+ </template><parameter name="left"><paramtype>Left const &</paramtype></parameter><parameter name="right"><paramtype>Right const &</paramtype></parameter></function><function name="operator+"><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Left"/>
+ <template-type-parameter name="Right"/>
+ </template><parameter name="left"><paramtype>Left &</paramtype></parameter><parameter name="right"><paramtype>Right &</paramtype></parameter></function><function name="operator+"><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Left"/>
+ <template-type-parameter name="Right"/>
+ </template><parameter name="left"><paramtype>Left &</paramtype></parameter><parameter name="right"><paramtype>Right const &</paramtype></parameter></function><function name="operator+"><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Left"/>
+ <template-type-parameter name="Right"/>
+ </template><parameter name="left"><paramtype>Left const &</paramtype></parameter><parameter name="right"><paramtype>Right &</paramtype></parameter></function><function name="operator+"><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Left"/>
+ <template-type-parameter name="Right"/>
+ </template><parameter name="left"><paramtype>Left const &</paramtype></parameter><parameter name="right"><paramtype>Right const &</paramtype></parameter></function><function name="operator-"><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Left"/>
+ <template-type-parameter name="Right"/>
+ </template><parameter name="left"><paramtype>Left &</paramtype></parameter><parameter name="right"><paramtype>Right &</paramtype></parameter></function><function name="operator-"><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Left"/>
+ <template-type-parameter name="Right"/>
+ </template><parameter name="left"><paramtype>Left &</paramtype></parameter><parameter name="right"><paramtype>Right const &</paramtype></parameter></function><function name="operator-"><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Left"/>
+ <template-type-parameter name="Right"/>
+ </template><parameter name="left"><paramtype>Left const &</paramtype></parameter><parameter name="right"><paramtype>Right &</paramtype></parameter></function><function name="operator-"><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Left"/>
+ <template-type-parameter name="Right"/>
+ </template><parameter name="left"><paramtype>Left const &</paramtype></parameter><parameter name="right"><paramtype>Right const &</paramtype></parameter></function><function name="operator<"><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Left"/>
+ <template-type-parameter name="Right"/>
+ </template><parameter name="left"><paramtype>Left &</paramtype></parameter><parameter name="right"><paramtype>Right &</paramtype></parameter></function><function name="operator<"><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Left"/>
+ <template-type-parameter name="Right"/>
+ </template><parameter name="left"><paramtype>Left &</paramtype></parameter><parameter name="right"><paramtype>Right const &</paramtype></parameter></function><function name="operator<"><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Left"/>
+ <template-type-parameter name="Right"/>
+ </template><parameter name="left"><paramtype>Left const &</paramtype></parameter><parameter name="right"><paramtype>Right &</paramtype></parameter></function><function name="operator<"><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Left"/>
+ <template-type-parameter name="Right"/>
+ </template><parameter name="left"><paramtype>Left const &</paramtype></parameter><parameter name="right"><paramtype>Right const &</paramtype></parameter></function><function name="operator>"><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Left"/>
+ <template-type-parameter name="Right"/>
+ </template><parameter name="left"><paramtype>Left &</paramtype></parameter><parameter name="right"><paramtype>Right &</paramtype></parameter></function><function name="operator>"><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Left"/>
+ <template-type-parameter name="Right"/>
+ </template><parameter name="left"><paramtype>Left &</paramtype></parameter><parameter name="right"><paramtype>Right const &</paramtype></parameter></function><function name="operator>"><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Left"/>
+ <template-type-parameter name="Right"/>
+ </template><parameter name="left"><paramtype>Left const &</paramtype></parameter><parameter name="right"><paramtype>Right &</paramtype></parameter></function><function name="operator>"><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Left"/>
+ <template-type-parameter name="Right"/>
+ </template><parameter name="left"><paramtype>Left const &</paramtype></parameter><parameter name="right"><paramtype>Right const &</paramtype></parameter></function><function name="operator<="><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Left"/>
+ <template-type-parameter name="Right"/>
+ </template><parameter name="left"><paramtype>Left &</paramtype></parameter><parameter name="right"><paramtype>Right &</paramtype></parameter></function><function name="operator<="><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Left"/>
+ <template-type-parameter name="Right"/>
+ </template><parameter name="left"><paramtype>Left &</paramtype></parameter><parameter name="right"><paramtype>Right const &</paramtype></parameter></function><function name="operator<="><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Left"/>
+ <template-type-parameter name="Right"/>
+ </template><parameter name="left"><paramtype>Left const &</paramtype></parameter><parameter name="right"><paramtype>Right &</paramtype></parameter></function><function name="operator<="><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Left"/>
+ <template-type-parameter name="Right"/>
+ </template><parameter name="left"><paramtype>Left const &</paramtype></parameter><parameter name="right"><paramtype>Right const &</paramtype></parameter></function><function name="operator>="><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Left"/>
+ <template-type-parameter name="Right"/>
+ </template><parameter name="left"><paramtype>Left &</paramtype></parameter><parameter name="right"><paramtype>Right &</paramtype></parameter></function><function name="operator>="><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Left"/>
+ <template-type-parameter name="Right"/>
+ </template><parameter name="left"><paramtype>Left &</paramtype></parameter><parameter name="right"><paramtype>Right const &</paramtype></parameter></function><function name="operator>="><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Left"/>
+ <template-type-parameter name="Right"/>
+ </template><parameter name="left"><paramtype>Left const &</paramtype></parameter><parameter name="right"><paramtype>Right &</paramtype></parameter></function><function name="operator>="><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Left"/>
+ <template-type-parameter name="Right"/>
+ </template><parameter name="left"><paramtype>Left const &</paramtype></parameter><parameter name="right"><paramtype>Right const &</paramtype></parameter></function><function name="operator=="><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Left"/>
+ <template-type-parameter name="Right"/>
+ </template><parameter name="left"><paramtype>Left &</paramtype></parameter><parameter name="right"><paramtype>Right &</paramtype></parameter></function><function name="operator=="><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Left"/>
+ <template-type-parameter name="Right"/>
+ </template><parameter name="left"><paramtype>Left &</paramtype></parameter><parameter name="right"><paramtype>Right const &</paramtype></parameter></function><function name="operator=="><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Left"/>
+ <template-type-parameter name="Right"/>
+ </template><parameter name="left"><paramtype>Left const &</paramtype></parameter><parameter name="right"><paramtype>Right &</paramtype></parameter></function><function name="operator=="><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Left"/>
+ <template-type-parameter name="Right"/>
+ </template><parameter name="left"><paramtype>Left const &</paramtype></parameter><parameter name="right"><paramtype>Right const &</paramtype></parameter></function><function name="operator!="><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Left"/>
+ <template-type-parameter name="Right"/>
+ </template><parameter name="left"><paramtype>Left &</paramtype></parameter><parameter name="right"><paramtype>Right &</paramtype></parameter></function><function name="operator!="><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Left"/>
+ <template-type-parameter name="Right"/>
+ </template><parameter name="left"><paramtype>Left &</paramtype></parameter><parameter name="right"><paramtype>Right const &</paramtype></parameter></function><function name="operator!="><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Left"/>
+ <template-type-parameter name="Right"/>
+ </template><parameter name="left"><paramtype>Left const &</paramtype></parameter><parameter name="right"><paramtype>Right &</paramtype></parameter></function><function name="operator!="><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Left"/>
+ <template-type-parameter name="Right"/>
+ </template><parameter name="left"><paramtype>Left const &</paramtype></parameter><parameter name="right"><paramtype>Right const &</paramtype></parameter></function><function name="operator||"><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Left"/>
+ <template-type-parameter name="Right"/>
+ </template><parameter name="left"><paramtype>Left &</paramtype></parameter><parameter name="right"><paramtype>Right &</paramtype></parameter></function><function name="operator||"><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Left"/>
+ <template-type-parameter name="Right"/>
+ </template><parameter name="left"><paramtype>Left &</paramtype></parameter><parameter name="right"><paramtype>Right const &</paramtype></parameter></function><function name="operator||"><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Left"/>
+ <template-type-parameter name="Right"/>
+ </template><parameter name="left"><paramtype>Left const &</paramtype></parameter><parameter name="right"><paramtype>Right &</paramtype></parameter></function><function name="operator||"><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Left"/>
+ <template-type-parameter name="Right"/>
+ </template><parameter name="left"><paramtype>Left const &</paramtype></parameter><parameter name="right"><paramtype>Right const &</paramtype></parameter></function><function name="operator&&"><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Left"/>
+ <template-type-parameter name="Right"/>
+ </template><parameter name="left"><paramtype>Left &</paramtype></parameter><parameter name="right"><paramtype>Right &</paramtype></parameter></function><function name="operator&&"><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Left"/>
+ <template-type-parameter name="Right"/>
+ </template><parameter name="left"><paramtype>Left &</paramtype></parameter><parameter name="right"><paramtype>Right const &</paramtype></parameter></function><function name="operator&&"><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Left"/>
+ <template-type-parameter name="Right"/>
+ </template><parameter name="left"><paramtype>Left const &</paramtype></parameter><parameter name="right"><paramtype>Right &</paramtype></parameter></function><function name="operator&&"><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Left"/>
+ <template-type-parameter name="Right"/>
+ </template><parameter name="left"><paramtype>Left const &</paramtype></parameter><parameter name="right"><paramtype>Right const &</paramtype></parameter></function><function name="operator&"><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Left"/>
+ <template-type-parameter name="Right"/>
+ </template><parameter name="left"><paramtype>Left &</paramtype></parameter><parameter name="right"><paramtype>Right &</paramtype></parameter></function><function name="operator&"><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Left"/>
+ <template-type-parameter name="Right"/>
+ </template><parameter name="left"><paramtype>Left &</paramtype></parameter><parameter name="right"><paramtype>Right const &</paramtype></parameter></function><function name="operator&"><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Left"/>
+ <template-type-parameter name="Right"/>
+ </template><parameter name="left"><paramtype>Left const &</paramtype></parameter><parameter name="right"><paramtype>Right &</paramtype></parameter></function><function name="operator&"><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Left"/>
+ <template-type-parameter name="Right"/>
+ </template><parameter name="left"><paramtype>Left const &</paramtype></parameter><parameter name="right"><paramtype>Right const &</paramtype></parameter></function><function name="operator|"><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Left"/>
+ <template-type-parameter name="Right"/>
+ </template><parameter name="left"><paramtype>Left &</paramtype></parameter><parameter name="right"><paramtype>Right &</paramtype></parameter></function><function name="operator|"><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Left"/>
+ <template-type-parameter name="Right"/>
+ </template><parameter name="left"><paramtype>Left &</paramtype></parameter><parameter name="right"><paramtype>Right const &</paramtype></parameter></function><function name="operator|"><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Left"/>
+ <template-type-parameter name="Right"/>
+ </template><parameter name="left"><paramtype>Left const &</paramtype></parameter><parameter name="right"><paramtype>Right &</paramtype></parameter></function><function name="operator|"><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Left"/>
+ <template-type-parameter name="Right"/>
+ </template><parameter name="left"><paramtype>Left const &</paramtype></parameter><parameter name="right"><paramtype>Right const &</paramtype></parameter></function><function name="operator^"><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Left"/>
+ <template-type-parameter name="Right"/>
+ </template><parameter name="left"><paramtype>Left &</paramtype></parameter><parameter name="right"><paramtype>Right &</paramtype></parameter></function><function name="operator^"><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Left"/>
+ <template-type-parameter name="Right"/>
+ </template><parameter name="left"><paramtype>Left &</paramtype></parameter><parameter name="right"><paramtype>Right const &</paramtype></parameter></function><function name="operator^"><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Left"/>
+ <template-type-parameter name="Right"/>
+ </template><parameter name="left"><paramtype>Left const &</paramtype></parameter><parameter name="right"><paramtype>Right &</paramtype></parameter></function><function name="operator^"><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Left"/>
+ <template-type-parameter name="Right"/>
+ </template><parameter name="left"><paramtype>Left const &</paramtype></parameter><parameter name="right"><paramtype>Right const &</paramtype></parameter></function><function name="operator,"><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Left"/>
+ <template-type-parameter name="Right"/>
+ </template><parameter name="left"><paramtype>Left &</paramtype></parameter><parameter name="right"><paramtype>Right &</paramtype></parameter></function><function name="operator,"><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Left"/>
+ <template-type-parameter name="Right"/>
+ </template><parameter name="left"><paramtype>Left &</paramtype></parameter><parameter name="right"><paramtype>Right const &</paramtype></parameter></function><function name="operator,"><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Left"/>
+ <template-type-parameter name="Right"/>
+ </template><parameter name="left"><paramtype>Left const &</paramtype></parameter><parameter name="right"><paramtype>Right &</paramtype></parameter></function><function name="operator,"><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Left"/>
+ <template-type-parameter name="Right"/>
+ </template><parameter name="left"><paramtype>Left const &</paramtype></parameter><parameter name="right"><paramtype>Right const &</paramtype></parameter></function><function name="operator->*"><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Left"/>
+ <template-type-parameter name="Right"/>
+ </template><parameter name="left"><paramtype>Left &</paramtype></parameter><parameter name="right"><paramtype>Right &</paramtype></parameter></function><function name="operator->*"><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Left"/>
+ <template-type-parameter name="Right"/>
+ </template><parameter name="left"><paramtype>Left &</paramtype></parameter><parameter name="right"><paramtype>Right const &</paramtype></parameter></function><function name="operator->*"><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Left"/>
+ <template-type-parameter name="Right"/>
+ </template><parameter name="left"><paramtype>Left const &</paramtype></parameter><parameter name="right"><paramtype>Right &</paramtype></parameter></function><function name="operator->*"><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Left"/>
+ <template-type-parameter name="Right"/>
+ </template><parameter name="left"><paramtype>Left const &</paramtype></parameter><parameter name="right"><paramtype>Right const &</paramtype></parameter></function><function name="operator<<="><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Left"/>
+ <template-type-parameter name="Right"/>
+ </template><parameter name="left"><paramtype>Left &</paramtype></parameter><parameter name="right"><paramtype>Right &</paramtype></parameter></function><function name="operator<<="><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Left"/>
+ <template-type-parameter name="Right"/>
+ </template><parameter name="left"><paramtype>Left &</paramtype></parameter><parameter name="right"><paramtype>Right const &</paramtype></parameter></function><function name="operator<<="><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Left"/>
+ <template-type-parameter name="Right"/>
+ </template><parameter name="left"><paramtype>Left const &</paramtype></parameter><parameter name="right"><paramtype>Right &</paramtype></parameter></function><function name="operator<<="><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Left"/>
+ <template-type-parameter name="Right"/>
+ </template><parameter name="left"><paramtype>Left const &</paramtype></parameter><parameter name="right"><paramtype>Right const &</paramtype></parameter></function><function name="operator>>="><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Left"/>
+ <template-type-parameter name="Right"/>
+ </template><parameter name="left"><paramtype>Left &</paramtype></parameter><parameter name="right"><paramtype>Right &</paramtype></parameter></function><function name="operator>>="><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Left"/>
+ <template-type-parameter name="Right"/>
+ </template><parameter name="left"><paramtype>Left &</paramtype></parameter><parameter name="right"><paramtype>Right const &</paramtype></parameter></function><function name="operator>>="><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Left"/>
+ <template-type-parameter name="Right"/>
+ </template><parameter name="left"><paramtype>Left const &</paramtype></parameter><parameter name="right"><paramtype>Right &</paramtype></parameter></function><function name="operator>>="><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Left"/>
+ <template-type-parameter name="Right"/>
+ </template><parameter name="left"><paramtype>Left const &</paramtype></parameter><parameter name="right"><paramtype>Right const &</paramtype></parameter></function><function name="operator*="><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Left"/>
+ <template-type-parameter name="Right"/>
+ </template><parameter name="left"><paramtype>Left &</paramtype></parameter><parameter name="right"><paramtype>Right &</paramtype></parameter></function><function name="operator*="><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Left"/>
+ <template-type-parameter name="Right"/>
+ </template><parameter name="left"><paramtype>Left &</paramtype></parameter><parameter name="right"><paramtype>Right const &</paramtype></parameter></function><function name="operator*="><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Left"/>
+ <template-type-parameter name="Right"/>
+ </template><parameter name="left"><paramtype>Left const &</paramtype></parameter><parameter name="right"><paramtype>Right &</paramtype></parameter></function><function name="operator*="><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Left"/>
+ <template-type-parameter name="Right"/>
+ </template><parameter name="left"><paramtype>Left const &</paramtype></parameter><parameter name="right"><paramtype>Right const &</paramtype></parameter></function><function name="operator/="><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Left"/>
+ <template-type-parameter name="Right"/>
+ </template><parameter name="left"><paramtype>Left &</paramtype></parameter><parameter name="right"><paramtype>Right &</paramtype></parameter></function><function name="operator/="><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Left"/>
+ <template-type-parameter name="Right"/>
+ </template><parameter name="left"><paramtype>Left &</paramtype></parameter><parameter name="right"><paramtype>Right const &</paramtype></parameter></function><function name="operator/="><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Left"/>
+ <template-type-parameter name="Right"/>
+ </template><parameter name="left"><paramtype>Left const &</paramtype></parameter><parameter name="right"><paramtype>Right &</paramtype></parameter></function><function name="operator/="><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Left"/>
+ <template-type-parameter name="Right"/>
+ </template><parameter name="left"><paramtype>Left const &</paramtype></parameter><parameter name="right"><paramtype>Right const &</paramtype></parameter></function><function name="operator%="><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Left"/>
+ <template-type-parameter name="Right"/>
+ </template><parameter name="left"><paramtype>Left &</paramtype></parameter><parameter name="right"><paramtype>Right &</paramtype></parameter></function><function name="operator%="><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Left"/>
+ <template-type-parameter name="Right"/>
+ </template><parameter name="left"><paramtype>Left &</paramtype></parameter><parameter name="right"><paramtype>Right const &</paramtype></parameter></function><function name="operator%="><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Left"/>
+ <template-type-parameter name="Right"/>
+ </template><parameter name="left"><paramtype>Left const &</paramtype></parameter><parameter name="right"><paramtype>Right &</paramtype></parameter></function><function name="operator%="><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Left"/>
+ <template-type-parameter name="Right"/>
+ </template><parameter name="left"><paramtype>Left const &</paramtype></parameter><parameter name="right"><paramtype>Right const &</paramtype></parameter></function><function name="operator+="><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Left"/>
+ <template-type-parameter name="Right"/>
+ </template><parameter name="left"><paramtype>Left &</paramtype></parameter><parameter name="right"><paramtype>Right &</paramtype></parameter></function><function name="operator+="><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Left"/>
+ <template-type-parameter name="Right"/>
+ </template><parameter name="left"><paramtype>Left &</paramtype></parameter><parameter name="right"><paramtype>Right const &</paramtype></parameter></function><function name="operator+="><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Left"/>
+ <template-type-parameter name="Right"/>
+ </template><parameter name="left"><paramtype>Left const &</paramtype></parameter><parameter name="right"><paramtype>Right &</paramtype></parameter></function><function name="operator+="><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Left"/>
+ <template-type-parameter name="Right"/>
+ </template><parameter name="left"><paramtype>Left const &</paramtype></parameter><parameter name="right"><paramtype>Right const &</paramtype></parameter></function><function name="operator-="><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Left"/>
+ <template-type-parameter name="Right"/>
+ </template><parameter name="left"><paramtype>Left &</paramtype></parameter><parameter name="right"><paramtype>Right &</paramtype></parameter></function><function name="operator-="><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Left"/>
+ <template-type-parameter name="Right"/>
+ </template><parameter name="left"><paramtype>Left &</paramtype></parameter><parameter name="right"><paramtype>Right const &</paramtype></parameter></function><function name="operator-="><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Left"/>
+ <template-type-parameter name="Right"/>
+ </template><parameter name="left"><paramtype>Left const &</paramtype></parameter><parameter name="right"><paramtype>Right &</paramtype></parameter></function><function name="operator-="><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Left"/>
+ <template-type-parameter name="Right"/>
+ </template><parameter name="left"><paramtype>Left const &</paramtype></parameter><parameter name="right"><paramtype>Right const &</paramtype></parameter></function><function name="operator&="><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Left"/>
+ <template-type-parameter name="Right"/>
+ </template><parameter name="left"><paramtype>Left &</paramtype></parameter><parameter name="right"><paramtype>Right &</paramtype></parameter></function><function name="operator&="><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Left"/>
+ <template-type-parameter name="Right"/>
+ </template><parameter name="left"><paramtype>Left &</paramtype></parameter><parameter name="right"><paramtype>Right const &</paramtype></parameter></function><function name="operator&="><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Left"/>
+ <template-type-parameter name="Right"/>
+ </template><parameter name="left"><paramtype>Left const &</paramtype></parameter><parameter name="right"><paramtype>Right &</paramtype></parameter></function><function name="operator&="><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Left"/>
+ <template-type-parameter name="Right"/>
+ </template><parameter name="left"><paramtype>Left const &</paramtype></parameter><parameter name="right"><paramtype>Right const &</paramtype></parameter></function><function name="operator|="><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Left"/>
+ <template-type-parameter name="Right"/>
+ </template><parameter name="left"><paramtype>Left &</paramtype></parameter><parameter name="right"><paramtype>Right &</paramtype></parameter></function><function name="operator|="><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Left"/>
+ <template-type-parameter name="Right"/>
+ </template><parameter name="left"><paramtype>Left &</paramtype></parameter><parameter name="right"><paramtype>Right const &</paramtype></parameter></function><function name="operator|="><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Left"/>
+ <template-type-parameter name="Right"/>
+ </template><parameter name="left"><paramtype>Left const &</paramtype></parameter><parameter name="right"><paramtype>Right &</paramtype></parameter></function><function name="operator|="><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Left"/>
+ <template-type-parameter name="Right"/>
+ </template><parameter name="left"><paramtype>Left const &</paramtype></parameter><parameter name="right"><paramtype>Right const &</paramtype></parameter></function><function name="operator^="><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Left"/>
+ <template-type-parameter name="Right"/>
+ </template><parameter name="left"><paramtype>Left &</paramtype></parameter><parameter name="right"><paramtype>Right &</paramtype></parameter></function><function name="operator^="><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Left"/>
+ <template-type-parameter name="Right"/>
+ </template><parameter name="left"><paramtype>Left &</paramtype></parameter><parameter name="right"><paramtype>Right const &</paramtype></parameter></function><function name="operator^="><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Left"/>
+ <template-type-parameter name="Right"/>
+ </template><parameter name="left"><paramtype>Left const &</paramtype></parameter><parameter name="right"><paramtype>Right &</paramtype></parameter></function><function name="operator^="><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Left"/>
+ <template-type-parameter name="Right"/>
+ </template><parameter name="left"><paramtype>Left const &</paramtype></parameter><parameter name="right"><paramtype>Right const &</paramtype></parameter></function><function name="if_else"><type><classname>boost::proto::result_of::make_expr</classname>< <classname>tag::if_else_</classname>, <classname>deduce_domain</classname>, const A0, const A1, const A2 >::type const</type><template>
+ <template-type-parameter name="A0"/>
+ <template-type-parameter name="A1"/>
+ <template-type-parameter name="A2"/>
+ </template><parameter name="a0"><paramtype>const A0 &</paramtype></parameter><parameter name="a1"><paramtype>const A1 &</paramtype></parameter><parameter name="a2"><paramtype>const A2 &</paramtype></parameter><description><para>if_else </para></description></function></namespace></namespace></namespace></header><header name="boost/xpressive/proto/proto.hpp"><para>The proto expression template compiler and supporting utilities. </para></header><header name="boost/xpressive/proto/proto_fwd.hpp"><para>Forward declarations of all of proto's public types and functions. </para><namespace name="boost"><namespace name="proto"><namespace name="context"/><namespace name="control"><data-member name="N"><type>int const</type></data-member></namespace><namespace name="domainns_"/><namespace name="exops"/><namespace name="exprns_"/><namespace name="functional"/><namespace name="generatorns_"/><namespace name="has_transformns_"><struct name="has_identity_transform"><struct name="apply"><template>
+ <template-type-parameter name="Expr_"/>
+ <template-type-parameter name=""/>
+ <template-type-parameter name=""/>
+ </template><typedef name="type"><type>Expr_</type></typedef></struct><method-group name="public static functions"><method name="call" cv=""><type>static Expr_ const &</type><template>
+ <template-type-parameter name="Expr_"/>
+ <template-type-parameter name="State_"/>
+ <template-type-parameter name="Visitor_"/>
+ </template><parameter name="expr_"><paramtype>Expr_ const &</paramtype></parameter><parameter name=""><paramtype>State_ const &</paramtype></parameter><parameter name=""><paramtype>Visitor_ &</paramtype></parameter></method></method-group></struct></namespace><namespace name="op"/><namespace name="refns_"/><namespace name="result_of"/><namespace name="tag"/><namespace name="transform"/><namespace name="utility"/><namespace name="wildcardns_"/></namespace></namespace></header><header name="boost/xpressive/proto/ref.hpp"><para>Utility for storing a sub-expr by reference </para><namespace name="boost"><namespace name="proto"><namespace name="functional"><struct name="unref"><struct name="result"><template>
+ <template-type-parameter name="T"/>
+ </template></struct><struct-specialization name="result"><template>
+ <template-type-parameter name="This"/>
+ <template-type-parameter name="T"/>
+ </template><specialization><template-arg>This(T)</template-arg></specialization></struct-specialization><method-group name="public member functions"><method name="operator()" cv="const"><type>T &</type><template>
+ <template-type-parameter name="T"/>
+ </template><parameter name="t"><paramtype>T &</paramtype></parameter></method><method name="operator()" cv="const"><type>T const &</type><template>
+ <template-type-parameter name="T"/>
+ </template><parameter name="t"><paramtype>T const &</paramtype></parameter></method><method name="operator()" cv="const"><type>T &</type><template>
+ <template-type-parameter name="T"/>
+ </template><parameter name="t"><paramtype><classname>ref_</classname>< T > &</paramtype></parameter></method><method name="operator()" cv="const"><type>T &</type><template>
+ <template-type-parameter name="T"/>
+ </template><parameter name="t"><paramtype><classname>ref_</classname>< T > const &</paramtype></parameter></method></method-group></struct></namespace><namespace name="refns_"><struct name="ref_"><template>
+ <template-type-parameter name="Expr"/>
+ </template><typedef name="proto_base_expr"><type>Expr::proto_base_expr</type></typedef><typedef name="proto_tag"><type>Expr::proto_tag</type></typedef><typedef name="proto_args"><type>Expr::proto_args</type></typedef><typedef name="proto_arity"><type>Expr::proto_arity</type></typedef><typedef name="proto_domain"><type>Expr::proto_domain</type></typedef><typedef name="fusion_tag"><type>tag::proto_ref</type></typedef><typedef name="proto_is_ref_"><type>void</type></typedef><typedef name="proto_is_expr_"><type>void</type></typedef><typedef name="proto_derived_expr"><type>Expr</type></typedef><typedef name="proto_arg0"><type>Expr::proto_arg0</type></typedef><typedef name="proto_arg1"><type>Expr::proto_arg1</type></typedef><typedef name="proto_arg2"><type>Expr::proto_arg2</type></typedef><typedef name="proto_arg3"><type>Expr::proto_arg3</type></typedef><typedef name="proto_arg4"><type>Expr::proto_arg4</type></typedef><method-group name="public member functions"><method name="proto_base" cv="const"><type>mpl:
:if_< is_const < Expr >, proto_base_expr const &, proto_base_expr & >::type</type></method></method-group><data-member name="expr"><type>Expr &</type></data-member><method-group name="public static functions"><method name="make" cv=""><type>static <classname>ref_</classname>< Expr ></type><parameter name="expr"><paramtype>Expr &</paramtype></parameter></method></method-group></struct><struct-specialization name="ref_"><template>
+ <template-type-parameter name="Expr"/>
+ </template><specialization><template-arg>ref_< Expr ></template-arg></specialization></struct-specialization></namespace><namespace name="result_of"><struct name="unref"><template>
+ <template-type-parameter name="T"/>
+ </template><typedef name="type"><type>T</type></typedef><typedef name="reference"><type>T &</type></typedef><typedef name="const_reference"><type>T const &</type></typedef></struct><struct-specialization name="unref"><template>
+ <template-type-parameter name="T"/>
+ </template><specialization><template-arg>ref_< T ></template-arg></specialization><typedef name="type"><type>T::proto_derived_expr</type></typedef><typedef name="reference"><type>T &</type></typedef><typedef name="const_reference"><type>T &</type></typedef></struct-specialization><struct-specialization name="unref"><template>
+ <template-type-parameter name="T"/>
+ </template><specialization><template-arg>T &</template-arg></specialization><typedef name="type"><type>T</type></typedef><typedef name="reference"><type>T &</type></typedef><typedef name="const_reference"><type>T &</type></typedef></struct-specialization><struct-specialization name="unref"><template>
+ <template-type-parameter name="T"/>
+ </template><specialization><template-arg>T const &</template-arg></specialization><typedef name="type"><type>T</type></typedef><typedef name="reference"><type>T const &</type></typedef><typedef name="const_reference"><type>T const &</type></typedef></struct-specialization></namespace><data-member name="unref"><type><classname>functional::unref</classname> const</type></data-member></namespace></namespace></header><header name="boost/xpressive/proto/tags.hpp"><para>Contains the tags for all the overloadable operators in C++ </para><namespace name="boost"><namespace name="proto"><namespace name="tag"><struct name="terminal"><purpose>Tag type for terminals; aka, leaves in the expression tree. </purpose></struct><struct name="posit"><purpose>Tag type for the unary + operator. </purpose></struct><struct name="negate"><purpose>Tag type for the unary - operator. </purpose></struct><struct name="dereference"><purpose>Tag type for the unary * operator. </purpose></struct><struct name="complement"><pu
rpose>Tag type for the unary ~ operator. </purpose></struct><struct name="address_of"><purpose>Tag type for the unary & operator. </purpose></struct><struct name="logical_not"><purpose>Tag type for the unary ! operator. </purpose></struct><struct name="pre_inc"><purpose>Tag type for the unary prefix ++ operator. </purpose></struct><struct name="pre_dec"><purpose>Tag type for the unary prefix -- operator. </purpose></struct><struct name="post_inc"><purpose>Tag type for the unary postfix ++ operator. </purpose></struct><struct name="post_dec"><purpose>Tag type for the unary postfix -- operator. </purpose></struct><struct name="shift_left"><purpose>Tag type for the binary << operator. </purpose></struct><struct name="shift_right"><purpose>Tag type for the binary >> operator. </purpose></struct><struct name="multiplies"><purpose>Tag type for the binary * operator. </purpose></struct><struct name="divides"><purpose>Tag type for the binary / operator. </purpose></struct><struct name="modulus"><purp
ose>Tag type for the binary % operator. </purpose></struct><struct name="plus"><purpose>Tag type for the binary + operator. </purpose></struct><struct name="minus"><purpose>Tag type for the binary - operator. </purpose></struct><struct name="less"><purpose>Tag type for the binary < operator. </purpose></struct><struct name="greater"><purpose>Tag type for the binary > operator. </purpose></struct><struct name="less_equal"><purpose>Tag type for the binary <= operator. </purpose></struct><struct name="greater_equal"><purpose>Tag type for the binary >= operator. </purpose></struct><struct name="equal_to"><purpose>Tag type for the binary == operator. </purpose></struct><struct name="not_equal_to"><purpose>Tag type for the binary != operator. </purpose></struct><struct name="logical_or"><purpose>Tag type for the binary || operator. </purpose></struct><struct name="logical_and"><purpose>Tag type for the binary && operator. </purpose></struct><struct name="bitwise_and"><purpose>Tag type for the b
inary & operator. </purpose></struct><struct name="bitwise_or"><purpose>Tag type for the binary | operator. </purpose></struct><struct name="bitwise_xor"><purpose>Tag type for the binary ^ operator. </purpose></struct><struct name="comma"><purpose>Tag type for the binary , operator. </purpose></struct><struct name="mem_ptr"><purpose>Tag type for the binary ->* operator. </purpose></struct><struct name="assign"><purpose>Tag type for the binary = operator. </purpose></struct><struct name="shift_left_assign"><purpose>Tag type for the binary <<= operator. </purpose></struct><struct name="shift_right_assign"><purpose>Tag type for the binary >>= operator. </purpose></struct><struct name="multilpies_assign"><purpose>Tag type for the binary *= operator. </purpose></struct><struct name="divides_assign"><purpose>Tag type for the binary /= operator. </purpose></struct><struct name="modulus_assign"><purpose>Tag type for the binary = operator. </purpose></struct><struct name="plus_assign"><purpose>Tag
type for the binary += operator. </purpose></struct><struct name="minus_assign"><purpose>Tag type for the binary -= operator. </purpose></struct><struct name="bitwise_and_assign"><purpose>Tag type for the binary &= operator. </purpose></struct><struct name="bitwise_or_assign"><purpose>Tag type for the binary |= operator. </purpose></struct><struct name="bitwise_xor_assign"><purpose>Tag type for the binary ^= operator. </purpose></struct><struct name="subscript"><purpose>Tag type for the binary subscript operator. </purpose></struct><struct name="if_else_"><purpose>Tag type for the ternary ?: conditional operator. </purpose></struct><struct name="function"><purpose>Tag type for the nary function call operator. </purpose></struct></namespace></namespace></namespace></header><header name="boost/xpressive/proto/traits.hpp"><para>Contains definitions for arg<>, arg_c<>, left<>, right<>, tag<>, and the helper functions arg(), arg_c(), left() and right(). </para><namespace name="bo
ost"><namespace name="proto"><namespace name="functional"><struct name="as_expr"><template>
+ <template-type-parameter name="Domain"/>
+ </template><struct name="result"><template>
+ <template-type-parameter name="Sig"/>
+ </template></struct><struct-specialization name="result"><template>
+ <template-type-parameter name="This"/>
+ <template-type-parameter name="T"/>
+ </template><specialization><template-arg>This(T)</template-arg></specialization><inherit access="public">boost::proto::result_of::as_expr< remove_reference< T >::type, Domain ></inherit></struct-specialization><method-group name="public member functions"><method name="operator()" cv="const"><type><classname>result_of::as_expr</classname>< T, Domain >::result_type</type><template>
+ <template-type-parameter name="T"/>
+ </template><parameter name="t"><paramtype>T &</paramtype></parameter></method><method name="operator()" cv="const"><type><classname>result_of::as_expr</classname>< T const, Domain >::result_type</type><template>
+ <template-type-parameter name="T"/>
+ </template><parameter name="t"><paramtype>T const &</paramtype></parameter></method></method-group></struct><struct name="as_arg"><template>
+ <template-type-parameter name="Domain"/>
+ </template><struct name="result"><template>
+ <template-type-parameter name="Sig"/>
+ </template></struct><struct-specialization name="result"><template>
+ <template-type-parameter name="This"/>
+ <template-type-parameter name="T"/>
+ </template><specialization><template-arg>This(T)</template-arg></specialization><inherit access="public">boost::proto::result_of::as_arg< remove_reference< T >::type, Domain ></inherit></struct-specialization><method-group name="public member functions"><method name="operator()" cv="const"><type><classname>result_of::as_arg</classname>< T, Domain >::type</type><template>
+ <template-type-parameter name="T"/>
+ </template><parameter name="t"><paramtype>T &</paramtype></parameter></method><method name="operator()" cv="const"><type><classname>result_of::as_arg</classname>< T const, Domain >::type</type><template>
+ <template-type-parameter name="T"/>
+ </template><parameter name="t"><paramtype>T const &</paramtype></parameter></method></method-group></struct><struct name="arg_c"><template>
+ <template-nontype-parameter name="N"><type>long</type></template-nontype-parameter>
+ </template><struct name="result"><template>
+ <template-type-parameter name="Sig"/>
+ </template></struct><struct-specialization name="result"><template>
+ <template-type-parameter name="This"/>
+ <template-type-parameter name="Expr"/>
+ </template><specialization><template-arg>This(Expr)</template-arg></specialization></struct-specialization><method-group name="public member functions"><method name="operator()" cv="const"><type>result_of::arg_c< Expr, N >::reference</type><template>
+ <template-type-parameter name="Expr"/>
+ </template><parameter name="expr"><paramtype>Expr &</paramtype></parameter></method><method name="operator()" cv="const"><type>result_of::arg_c< Expr, N >::const_reference</type><template>
+ <template-type-parameter name="Expr"/>
+ </template><parameter name="expr"><paramtype>Expr const &</paramtype></parameter></method></method-group></struct><struct name="arg"><template>
+ <template-type-parameter name="N"/>
+ </template><struct name="result"><template>
+ <template-type-parameter name="Sig"/>
+ </template></struct><struct-specialization name="result"><template>
+ <template-type-parameter name="This"/>
+ <template-type-parameter name="Expr"/>
+ </template><specialization><template-arg>This(Expr)</template-arg></specialization></struct-specialization><method-group name="public member functions"><method name="operator()" cv="const"><type><classname>result_of::arg</classname>< Expr, N >::reference</type><template>
+ <template-type-parameter name="Expr"/>
+ </template><parameter name="expr"><paramtype>Expr &</paramtype></parameter></method><method name="operator()" cv="const"><type><classname>result_of::arg</classname>< Expr, N >::const_reference</type><template>
+ <template-type-parameter name="Expr"/>
+ </template><parameter name="expr"><paramtype>Expr const &</paramtype></parameter></method></method-group></struct><struct name="left"><struct name="result"><template>
+ <template-type-parameter name="Sig"/>
+ </template></struct><struct-specialization name="result"><template>
+ <template-type-parameter name="This"/>
+ <template-type-parameter name="Expr"/>
+ </template><specialization><template-arg>This(Expr)</template-arg></specialization></struct-specialization><method-group name="public member functions"><method name="operator()" cv="const"><type><classname>result_of::left</classname>< Expr >::reference</type><template>
+ <template-type-parameter name="Expr"/>
+ </template><parameter name="expr"><paramtype>Expr &</paramtype></parameter></method><method name="operator()" cv="const"><type><classname>result_of::left</classname>< Expr >::const_reference</type><template>
+ <template-type-parameter name="Expr"/>
+ </template><parameter name="expr"><paramtype>Expr const &</paramtype></parameter></method></method-group></struct><struct name="right"><struct name="result"><template>
+ <template-type-parameter name="Sig"/>
+ </template></struct><struct-specialization name="result"><template>
+ <template-type-parameter name="This"/>
+ <template-type-parameter name="Expr"/>
+ </template><specialization><template-arg>This(Expr)</template-arg></specialization></struct-specialization><method-group name="public member functions"><method name="operator()" cv="const"><type><classname>result_of::right</classname>< Expr >::reference</type><template>
+ <template-type-parameter name="Expr"/>
+ </template><parameter name="expr"><paramtype>Expr &</paramtype></parameter></method><method name="operator()" cv="const"><type><classname>result_of::right</classname>< Expr >::const_reference</type><template>
+ <template-type-parameter name="Expr"/>
+ </template><parameter name="expr"><paramtype>Expr const &</paramtype></parameter></method></method-group></struct></namespace><namespace name="op"><struct name="terminal"><template>
+ <template-type-parameter name="T"/>
+ </template><inherit access="public">boost::proto::has_transformns_::has_identity_transform</inherit><typedef name="type"><type>expr< <classname>proto::tag::terminal</classname>, <classname>args0</classname>< T > ></type></typedef><typedef name="proto_base_expr"><type>type</type></typedef><typedef name="proto_tag"><type><classname>proto::tag::terminal</classname></type></typedef><typedef name="proto_arg0"><type>T</type></typedef><method-group name="public member functions"/><constructor/></struct><struct name="if_else_"><template>
+ <template-type-parameter name="T"/>
+ <template-type-parameter name="U"/>
+ <template-type-parameter name="V"/>
+ </template><inherit access="public">boost::proto::has_transformns_::has_pass_through_transform< Grammar ></inherit><typedef name="type"><type>expr< <classname>proto::tag::if_else_</classname>, <classname>args3</classname>< T, U, V > ></type></typedef><typedef name="proto_base_expr"><type>type</type></typedef><typedef name="proto_tag"><type><classname>proto::tag::if_else_</classname></type></typedef><typedef name="proto_arg0"><type>T</type></typedef><typedef name="proto_arg1"><type>U</type></typedef><typedef name="proto_arg2"><type>V</type></typedef><method-group name="public member functions"/><constructor/></struct><struct name="unary_expr"><template>
+ <template-type-parameter name="Tag"/>
+ <template-type-parameter name="T"/>
+ </template><inherit access="public">boost::proto::has_transformns_::has_pass_through_transform< Grammar ></inherit><typedef name="type"><type>expr< Tag, <classname>args1</classname>< T > ></type></typedef><typedef name="proto_base_expr"><type>type</type></typedef><typedef name="proto_tag"><type>Tag</type></typedef><typedef name="proto_arg0"><type>T</type></typedef><method-group name="public member functions"/><constructor/></struct><struct name="binary_expr"><template>
+ <template-type-parameter name="Tag"/>
+ <template-type-parameter name="T"/>
+ <template-type-parameter name="U"/>
+ </template><inherit access="public">boost::proto::has_transformns_::has_pass_through_transform< Grammar ></inherit><typedef name="type"><type>expr< Tag, <classname>args2</classname>< T, U > ></type></typedef><typedef name="proto_base_expr"><type>type</type></typedef><typedef name="proto_tag"><type>Tag</type></typedef><typedef name="proto_arg0"><type>T</type></typedef><typedef name="proto_arg1"><type>U</type></typedef><method-group name="public member functions"/><constructor/></struct><struct name="posit"><template>
+ <template-type-parameter name="T"/>
+ </template><inherit access="public">boost::proto::has_transformns_::has_pass_through_transform< Grammar ></inherit><typedef name="type"><type>expr< <classname>proto::tag::posit</classname>, <classname>args1</classname>< T > ></type></typedef><typedef name="proto_base_expr"><type>type</type></typedef><typedef name="proto_tag"><type><classname>proto::tag::posit</classname></type></typedef><typedef name="proto_arg0"><type>T</type></typedef><method-group name="public member functions"/><constructor/></struct><struct name="negate"><template>
+ <template-type-parameter name="T"/>
+ </template><inherit access="public">boost::proto::has_transformns_::has_pass_through_transform< Grammar ></inherit><typedef name="type"><type>expr< <classname>proto::tag::negate</classname>, <classname>args1</classname>< T > ></type></typedef><typedef name="proto_base_expr"><type>type</type></typedef><typedef name="proto_tag"><type><classname>proto::tag::negate</classname></type></typedef><typedef name="proto_arg0"><type>T</type></typedef><method-group name="public member functions"/><constructor/></struct><struct name="dereference"><template>
+ <template-type-parameter name="T"/>
+ </template><inherit access="public">boost::proto::has_transformns_::has_pass_through_transform< Grammar ></inherit><typedef name="type"><type>expr< <classname>proto::tag::dereference</classname>, <classname>args1</classname>< T > ></type></typedef><typedef name="proto_base_expr"><type>type</type></typedef><typedef name="proto_tag"><type><classname>proto::tag::dereference</classname></type></typedef><typedef name="proto_arg0"><type>T</type></typedef><method-group name="public member functions"/><constructor/></struct><struct name="complement"><template>
+ <template-type-parameter name="T"/>
+ </template><inherit access="public">boost::proto::has_transformns_::has_pass_through_transform< Grammar ></inherit><typedef name="type"><type>expr< <classname>proto::tag::complement</classname>, <classname>args1</classname>< T > ></type></typedef><typedef name="proto_base_expr"><type>type</type></typedef><typedef name="proto_tag"><type><classname>proto::tag::complement</classname></type></typedef><typedef name="proto_arg0"><type>T</type></typedef><method-group name="public member functions"/><constructor/></struct><struct name="address_of"><template>
+ <template-type-parameter name="T"/>
+ </template><inherit access="public">boost::proto::has_transformns_::has_pass_through_transform< Grammar ></inherit><typedef name="type"><type>expr< <classname>proto::tag::address_of</classname>, <classname>args1</classname>< T > ></type></typedef><typedef name="proto_base_expr"><type>type</type></typedef><typedef name="proto_tag"><type><classname>proto::tag::address_of</classname></type></typedef><typedef name="proto_arg0"><type>T</type></typedef><method-group name="public member functions"/><constructor/></struct><struct name="logical_not"><template>
+ <template-type-parameter name="T"/>
+ </template><inherit access="public">boost::proto::has_transformns_::has_pass_through_transform< Grammar ></inherit><typedef name="type"><type>expr< <classname>proto::tag::logical_not</classname>, <classname>args1</classname>< T > ></type></typedef><typedef name="proto_base_expr"><type>type</type></typedef><typedef name="proto_tag"><type><classname>proto::tag::logical_not</classname></type></typedef><typedef name="proto_arg0"><type>T</type></typedef><method-group name="public member functions"/><constructor/></struct><struct name="pre_inc"><template>
+ <template-type-parameter name="T"/>
+ </template><inherit access="public">boost::proto::has_transformns_::has_pass_through_transform< Grammar ></inherit><typedef name="type"><type>expr< <classname>proto::tag::pre_inc</classname>, <classname>args1</classname>< T > ></type></typedef><typedef name="proto_base_expr"><type>type</type></typedef><typedef name="proto_tag"><type><classname>proto::tag::pre_inc</classname></type></typedef><typedef name="proto_arg0"><type>T</type></typedef><method-group name="public member functions"/><constructor/></struct><struct name="pre_dec"><template>
+ <template-type-parameter name="T"/>
+ </template><inherit access="public">boost::proto::has_transformns_::has_pass_through_transform< Grammar ></inherit><typedef name="type"><type>expr< <classname>proto::tag::pre_dec</classname>, <classname>args1</classname>< T > ></type></typedef><typedef name="proto_base_expr"><type>type</type></typedef><typedef name="proto_tag"><type><classname>proto::tag::pre_dec</classname></type></typedef><typedef name="proto_arg0"><type>T</type></typedef><method-group name="public member functions"/><constructor/></struct><struct name="post_inc"><template>
+ <template-type-parameter name="T"/>
+ </template><inherit access="public">boost::proto::has_transformns_::has_pass_through_transform< Grammar ></inherit><typedef name="type"><type>expr< <classname>proto::tag::post_inc</classname>, <classname>args1</classname>< T > ></type></typedef><typedef name="proto_base_expr"><type>type</type></typedef><typedef name="proto_tag"><type><classname>proto::tag::post_inc</classname></type></typedef><typedef name="proto_arg0"><type>T</type></typedef><method-group name="public member functions"/><constructor/></struct><struct name="post_dec"><template>
+ <template-type-parameter name="T"/>
+ </template><inherit access="public">boost::proto::has_transformns_::has_pass_through_transform< Grammar ></inherit><typedef name="type"><type>expr< <classname>proto::tag::post_dec</classname>, <classname>args1</classname>< T > ></type></typedef><typedef name="proto_base_expr"><type>type</type></typedef><typedef name="proto_tag"><type><classname>proto::tag::post_dec</classname></type></typedef><typedef name="proto_arg0"><type>T</type></typedef><method-group name="public member functions"/><constructor/></struct><struct name="shift_left"><template>
+ <template-type-parameter name="T"/>
+ <template-type-parameter name="U"/>
+ </template><inherit access="public">boost::proto::has_transformns_::has_pass_through_transform< Grammar ></inherit><typedef name="type"><type>expr< <classname>proto::tag::shift_left</classname>, <classname>args2</classname>< T, U > ></type></typedef><typedef name="proto_base_expr"><type>type</type></typedef><typedef name="proto_tag"><type><classname>proto::tag::shift_left</classname></type></typedef><typedef name="proto_arg0"><type>T</type></typedef><typedef name="proto_arg1"><type>U</type></typedef><method-group name="public member functions"/><constructor/></struct><struct name="shift_right"><template>
+ <template-type-parameter name="T"/>
+ <template-type-parameter name="U"/>
+ </template><inherit access="public">boost::proto::has_transformns_::has_pass_through_transform< Grammar ></inherit><typedef name="type"><type>expr< <classname>proto::tag::shift_right</classname>, <classname>args2</classname>< T, U > ></type></typedef><typedef name="proto_base_expr"><type>type</type></typedef><typedef name="proto_tag"><type><classname>proto::tag::shift_right</classname></type></typedef><typedef name="proto_arg0"><type>T</type></typedef><typedef name="proto_arg1"><type>U</type></typedef><method-group name="public member functions"/><constructor/></struct><struct name="multiplies"><template>
+ <template-type-parameter name="T"/>
+ <template-type-parameter name="U"/>
+ </template><inherit access="public">boost::proto::has_transformns_::has_pass_through_transform< Grammar ></inherit><typedef name="type"><type>expr< <classname>proto::tag::multiplies</classname>, <classname>args2</classname>< T, U > ></type></typedef><typedef name="proto_base_expr"><type>type</type></typedef><typedef name="proto_tag"><type><classname>proto::tag::multiplies</classname></type></typedef><typedef name="proto_arg0"><type>T</type></typedef><typedef name="proto_arg1"><type>U</type></typedef><method-group name="public member functions"/><constructor/></struct><struct name="divides"><template>
+ <template-type-parameter name="T"/>
+ <template-type-parameter name="U"/>
+ </template><inherit access="public">boost::proto::has_transformns_::has_pass_through_transform< Grammar ></inherit><typedef name="type"><type>expr< <classname>proto::tag::divides</classname>, <classname>args2</classname>< T, U > ></type></typedef><typedef name="proto_base_expr"><type>type</type></typedef><typedef name="proto_tag"><type><classname>proto::tag::divides</classname></type></typedef><typedef name="proto_arg0"><type>T</type></typedef><typedef name="proto_arg1"><type>U</type></typedef><method-group name="public member functions"/><constructor/></struct><struct name="modulus"><template>
+ <template-type-parameter name="T"/>
+ <template-type-parameter name="U"/>
+ </template><inherit access="public">boost::proto::has_transformns_::has_pass_through_transform< Grammar ></inherit><typedef name="type"><type>expr< <classname>proto::tag::modulus</classname>, <classname>args2</classname>< T, U > ></type></typedef><typedef name="proto_base_expr"><type>type</type></typedef><typedef name="proto_tag"><type><classname>proto::tag::modulus</classname></type></typedef><typedef name="proto_arg0"><type>T</type></typedef><typedef name="proto_arg1"><type>U</type></typedef><method-group name="public member functions"/><constructor/></struct><struct name="plus"><template>
+ <template-type-parameter name="T"/>
+ <template-type-parameter name="U"/>
+ </template><inherit access="public">boost::proto::has_transformns_::has_pass_through_transform< Grammar ></inherit><typedef name="type"><type>expr< <classname>proto::tag::plus</classname>, <classname>args2</classname>< T, U > ></type></typedef><typedef name="proto_base_expr"><type>type</type></typedef><typedef name="proto_tag"><type><classname>proto::tag::plus</classname></type></typedef><typedef name="proto_arg0"><type>T</type></typedef><typedef name="proto_arg1"><type>U</type></typedef><method-group name="public member functions"/><constructor/></struct><struct name="minus"><template>
+ <template-type-parameter name="T"/>
+ <template-type-parameter name="U"/>
+ </template><inherit access="public">boost::proto::has_transformns_::has_pass_through_transform< Grammar ></inherit><typedef name="type"><type>expr< <classname>proto::tag::minus</classname>, <classname>args2</classname>< T, U > ></type></typedef><typedef name="proto_base_expr"><type>type</type></typedef><typedef name="proto_tag"><type><classname>proto::tag::minus</classname></type></typedef><typedef name="proto_arg0"><type>T</type></typedef><typedef name="proto_arg1"><type>U</type></typedef><method-group name="public member functions"/><constructor/></struct><struct name="less"><template>
+ <template-type-parameter name="T"/>
+ <template-type-parameter name="U"/>
+ </template><inherit access="public">boost::proto::has_transformns_::has_pass_through_transform< Grammar ></inherit><typedef name="type"><type>expr< <classname>proto::tag::less</classname>, <classname>args2</classname>< T, U > ></type></typedef><typedef name="proto_base_expr"><type>type</type></typedef><typedef name="proto_tag"><type><classname>proto::tag::less</classname></type></typedef><typedef name="proto_arg0"><type>T</type></typedef><typedef name="proto_arg1"><type>U</type></typedef><method-group name="public member functions"/><constructor/></struct><struct name="greater"><template>
+ <template-type-parameter name="T"/>
+ <template-type-parameter name="U"/>
+ </template><inherit access="public">boost::proto::has_transformns_::has_pass_through_transform< Grammar ></inherit><typedef name="type"><type>expr< <classname>proto::tag::greater</classname>, <classname>args2</classname>< T, U > ></type></typedef><typedef name="proto_base_expr"><type>type</type></typedef><typedef name="proto_tag"><type><classname>proto::tag::greater</classname></type></typedef><typedef name="proto_arg0"><type>T</type></typedef><typedef name="proto_arg1"><type>U</type></typedef><method-group name="public member functions"/><constructor/></struct><struct name="less_equal"><template>
+ <template-type-parameter name="T"/>
+ <template-type-parameter name="U"/>
+ </template><inherit access="public">boost::proto::has_transformns_::has_pass_through_transform< Grammar ></inherit><typedef name="type"><type>expr< <classname>proto::tag::less_equal</classname>, <classname>args2</classname>< T, U > ></type></typedef><typedef name="proto_base_expr"><type>type</type></typedef><typedef name="proto_tag"><type><classname>proto::tag::less_equal</classname></type></typedef><typedef name="proto_arg0"><type>T</type></typedef><typedef name="proto_arg1"><type>U</type></typedef><method-group name="public member functions"/><constructor/></struct><struct name="greater_equal"><template>
+ <template-type-parameter name="T"/>
+ <template-type-parameter name="U"/>
+ </template><inherit access="public">boost::proto::has_transformns_::has_pass_through_transform< Grammar ></inherit><typedef name="type"><type>expr< <classname>proto::tag::greater_equal</classname>, <classname>args2</classname>< T, U > ></type></typedef><typedef name="proto_base_expr"><type>type</type></typedef><typedef name="proto_tag"><type><classname>proto::tag::greater_equal</classname></type></typedef><typedef name="proto_arg0"><type>T</type></typedef><typedef name="proto_arg1"><type>U</type></typedef><method-group name="public member functions"/><constructor/></struct><struct name="equal_to"><template>
+ <template-type-parameter name="T"/>
+ <template-type-parameter name="U"/>
+ </template><inherit access="public">boost::proto::has_transformns_::has_pass_through_transform< Grammar ></inherit><typedef name="type"><type>expr< <classname>proto::tag::equal_to</classname>, <classname>args2</classname>< T, U > ></type></typedef><typedef name="proto_base_expr"><type>type</type></typedef><typedef name="proto_tag"><type><classname>proto::tag::equal_to</classname></type></typedef><typedef name="proto_arg0"><type>T</type></typedef><typedef name="proto_arg1"><type>U</type></typedef><method-group name="public member functions"/><constructor/></struct><struct name="not_equal_to"><template>
+ <template-type-parameter name="T"/>
+ <template-type-parameter name="U"/>
+ </template><inherit access="public">boost::proto::has_transformns_::has_pass_through_transform< Grammar ></inherit><typedef name="type"><type>expr< <classname>proto::tag::not_equal_to</classname>, <classname>args2</classname>< T, U > ></type></typedef><typedef name="proto_base_expr"><type>type</type></typedef><typedef name="proto_tag"><type><classname>proto::tag::not_equal_to</classname></type></typedef><typedef name="proto_arg0"><type>T</type></typedef><typedef name="proto_arg1"><type>U</type></typedef><method-group name="public member functions"/><constructor/></struct><struct name="logical_or"><template>
+ <template-type-parameter name="T"/>
+ <template-type-parameter name="U"/>
+ </template><inherit access="public">boost::proto::has_transformns_::has_pass_through_transform< Grammar ></inherit><typedef name="type"><type>expr< <classname>proto::tag::logical_or</classname>, <classname>args2</classname>< T, U > ></type></typedef><typedef name="proto_base_expr"><type>type</type></typedef><typedef name="proto_tag"><type><classname>proto::tag::logical_or</classname></type></typedef><typedef name="proto_arg0"><type>T</type></typedef><typedef name="proto_arg1"><type>U</type></typedef><method-group name="public member functions"/><constructor/></struct><struct name="logical_and"><template>
+ <template-type-parameter name="T"/>
+ <template-type-parameter name="U"/>
+ </template><inherit access="public">boost::proto::has_transformns_::has_pass_through_transform< Grammar ></inherit><typedef name="type"><type>expr< <classname>proto::tag::logical_and</classname>, <classname>args2</classname>< T, U > ></type></typedef><typedef name="proto_base_expr"><type>type</type></typedef><typedef name="proto_tag"><type><classname>proto::tag::logical_and</classname></type></typedef><typedef name="proto_arg0"><type>T</type></typedef><typedef name="proto_arg1"><type>U</type></typedef><method-group name="public member functions"/><constructor/></struct><struct name="bitwise_and"><template>
+ <template-type-parameter name="T"/>
+ <template-type-parameter name="U"/>
+ </template><inherit access="public">boost::proto::has_transformns_::has_pass_through_transform< Grammar ></inherit><typedef name="type"><type>expr< <classname>proto::tag::bitwise_and</classname>, <classname>args2</classname>< T, U > ></type></typedef><typedef name="proto_base_expr"><type>type</type></typedef><typedef name="proto_tag"><type><classname>proto::tag::bitwise_and</classname></type></typedef><typedef name="proto_arg0"><type>T</type></typedef><typedef name="proto_arg1"><type>U</type></typedef><method-group name="public member functions"/><constructor/></struct><struct name="bitwise_or"><template>
+ <template-type-parameter name="T"/>
+ <template-type-parameter name="U"/>
+ </template><inherit access="public">boost::proto::has_transformns_::has_pass_through_transform< Grammar ></inherit><typedef name="type"><type>expr< <classname>proto::tag::bitwise_or</classname>, <classname>args2</classname>< T, U > ></type></typedef><typedef name="proto_base_expr"><type>type</type></typedef><typedef name="proto_tag"><type><classname>proto::tag::bitwise_or</classname></type></typedef><typedef name="proto_arg0"><type>T</type></typedef><typedef name="proto_arg1"><type>U</type></typedef><method-group name="public member functions"/><constructor/></struct><struct name="bitwise_xor"><template>
+ <template-type-parameter name="T"/>
+ <template-type-parameter name="U"/>
+ </template><inherit access="public">boost::proto::has_transformns_::has_pass_through_transform< Grammar ></inherit><typedef name="type"><type>expr< <classname>proto::tag::bitwise_xor</classname>, <classname>args2</classname>< T, U > ></type></typedef><typedef name="proto_base_expr"><type>type</type></typedef><typedef name="proto_tag"><type><classname>proto::tag::bitwise_xor</classname></type></typedef><typedef name="proto_arg0"><type>T</type></typedef><typedef name="proto_arg1"><type>U</type></typedef><method-group name="public member functions"/><constructor/></struct><struct name="comma"><template>
+ <template-type-parameter name="T"/>
+ <template-type-parameter name="U"/>
+ </template><inherit access="public">boost::proto::has_transformns_::has_pass_through_transform< Grammar ></inherit><typedef name="type"><type>expr< <classname>proto::tag::comma</classname>, <classname>args2</classname>< T, U > ></type></typedef><typedef name="proto_base_expr"><type>type</type></typedef><typedef name="proto_tag"><type><classname>proto::tag::comma</classname></type></typedef><typedef name="proto_arg0"><type>T</type></typedef><typedef name="proto_arg1"><type>U</type></typedef><method-group name="public member functions"/><constructor/></struct><struct name="mem_ptr"><template>
+ <template-type-parameter name="T"/>
+ <template-type-parameter name="U"/>
+ </template><inherit access="public">boost::proto::has_transformns_::has_pass_through_transform< Grammar ></inherit><typedef name="type"><type>expr< <classname>proto::tag::mem_ptr</classname>, <classname>args2</classname>< T, U > ></type></typedef><typedef name="proto_base_expr"><type>type</type></typedef><typedef name="proto_tag"><type><classname>proto::tag::mem_ptr</classname></type></typedef><typedef name="proto_arg0"><type>T</type></typedef><typedef name="proto_arg1"><type>U</type></typedef><method-group name="public member functions"/><constructor/></struct><struct name="assign"><template>
+ <template-type-parameter name="T"/>
+ <template-type-parameter name="U"/>
+ </template><inherit access="public">boost::proto::has_transformns_::has_pass_through_transform< Grammar ></inherit><typedef name="type"><type>expr< <classname>proto::tag::assign</classname>, <classname>args2</classname>< T, U > ></type></typedef><typedef name="proto_base_expr"><type>type</type></typedef><typedef name="proto_tag"><type><classname>proto::tag::assign</classname></type></typedef><typedef name="proto_arg0"><type>T</type></typedef><typedef name="proto_arg1"><type>U</type></typedef><method-group name="public member functions"/><constructor/></struct><struct name="shift_left_assign"><template>
+ <template-type-parameter name="T"/>
+ <template-type-parameter name="U"/>
+ </template><inherit access="public">boost::proto::has_transformns_::has_pass_through_transform< Grammar ></inherit><typedef name="type"><type>expr< <classname>proto::tag::shift_left_assign</classname>, <classname>args2</classname>< T, U > ></type></typedef><typedef name="proto_base_expr"><type>type</type></typedef><typedef name="proto_tag"><type><classname>proto::tag::shift_left_assign</classname></type></typedef><typedef name="proto_arg0"><type>T</type></typedef><typedef name="proto_arg1"><type>U</type></typedef><method-group name="public member functions"/><constructor/></struct><struct name="shift_right_assign"><template>
+ <template-type-parameter name="T"/>
+ <template-type-parameter name="U"/>
+ </template><inherit access="public">boost::proto::has_transformns_::has_pass_through_transform< Grammar ></inherit><typedef name="type"><type>expr< <classname>proto::tag::shift_right_assign</classname>, <classname>args2</classname>< T, U > ></type></typedef><typedef name="proto_base_expr"><type>type</type></typedef><typedef name="proto_tag"><type><classname>proto::tag::shift_right_assign</classname></type></typedef><typedef name="proto_arg0"><type>T</type></typedef><typedef name="proto_arg1"><type>U</type></typedef><method-group name="public member functions"/><constructor/></struct><struct name="multilpies_assign"><template>
+ <template-type-parameter name="T"/>
+ <template-type-parameter name="U"/>
+ </template><inherit access="public">boost::proto::has_transformns_::has_pass_through_transform< Grammar ></inherit><typedef name="type"><type>expr< <classname>proto::tag::multilpies_assign</classname>, <classname>args2</classname>< T, U > ></type></typedef><typedef name="proto_base_expr"><type>type</type></typedef><typedef name="proto_tag"><type><classname>proto::tag::multilpies_assign</classname></type></typedef><typedef name="proto_arg0"><type>T</type></typedef><typedef name="proto_arg1"><type>U</type></typedef><method-group name="public member functions"/><constructor/></struct><struct name="divides_assign"><template>
+ <template-type-parameter name="T"/>
+ <template-type-parameter name="U"/>
+ </template><inherit access="public">boost::proto::has_transformns_::has_pass_through_transform< Grammar ></inherit><typedef name="type"><type>expr< <classname>proto::tag::divides_assign</classname>, <classname>args2</classname>< T, U > ></type></typedef><typedef name="proto_base_expr"><type>type</type></typedef><typedef name="proto_tag"><type><classname>proto::tag::divides_assign</classname></type></typedef><typedef name="proto_arg0"><type>T</type></typedef><typedef name="proto_arg1"><type>U</type></typedef><method-group name="public member functions"/><constructor/></struct><struct name="modulus_assign"><template>
+ <template-type-parameter name="T"/>
+ <template-type-parameter name="U"/>
+ </template><inherit access="public">boost::proto::has_transformns_::has_pass_through_transform< Grammar ></inherit><typedef name="type"><type>expr< <classname>proto::tag::modulus_assign</classname>, <classname>args2</classname>< T, U > ></type></typedef><typedef name="proto_base_expr"><type>type</type></typedef><typedef name="proto_tag"><type><classname>proto::tag::modulus_assign</classname></type></typedef><typedef name="proto_arg0"><type>T</type></typedef><typedef name="proto_arg1"><type>U</type></typedef><method-group name="public member functions"/><constructor/></struct><struct name="plus_assign"><template>
+ <template-type-parameter name="T"/>
+ <template-type-parameter name="U"/>
+ </template><inherit access="public">boost::proto::has_transformns_::has_pass_through_transform< Grammar ></inherit><typedef name="type"><type>expr< <classname>proto::tag::plus_assign</classname>, <classname>args2</classname>< T, U > ></type></typedef><typedef name="proto_base_expr"><type>type</type></typedef><typedef name="proto_tag"><type><classname>proto::tag::plus_assign</classname></type></typedef><typedef name="proto_arg0"><type>T</type></typedef><typedef name="proto_arg1"><type>U</type></typedef><method-group name="public member functions"/><constructor/></struct><struct name="minus_assign"><template>
+ <template-type-parameter name="T"/>
+ <template-type-parameter name="U"/>
+ </template><inherit access="public">boost::proto::has_transformns_::has_pass_through_transform< Grammar ></inherit><typedef name="type"><type>expr< <classname>proto::tag::minus_assign</classname>, <classname>args2</classname>< T, U > ></type></typedef><typedef name="proto_base_expr"><type>type</type></typedef><typedef name="proto_tag"><type><classname>proto::tag::minus_assign</classname></type></typedef><typedef name="proto_arg0"><type>T</type></typedef><typedef name="proto_arg1"><type>U</type></typedef><method-group name="public member functions"/><constructor/></struct><struct name="bitwise_and_assign"><template>
+ <template-type-parameter name="T"/>
+ <template-type-parameter name="U"/>
+ </template><inherit access="public">boost::proto::has_transformns_::has_pass_through_transform< Grammar ></inherit><typedef name="type"><type>expr< <classname>proto::tag::bitwise_and_assign</classname>, <classname>args2</classname>< T, U > ></type></typedef><typedef name="proto_base_expr"><type>type</type></typedef><typedef name="proto_tag"><type><classname>proto::tag::bitwise_and_assign</classname></type></typedef><typedef name="proto_arg0"><type>T</type></typedef><typedef name="proto_arg1"><type>U</type></typedef><method-group name="public member functions"/><constructor/></struct><struct name="bitwise_or_assign"><template>
+ <template-type-parameter name="T"/>
+ <template-type-parameter name="U"/>
+ </template><inherit access="public">boost::proto::has_transformns_::has_pass_through_transform< Grammar ></inherit><typedef name="type"><type>expr< <classname>proto::tag::bitwise_or_assign</classname>, <classname>args2</classname>< T, U > ></type></typedef><typedef name="proto_base_expr"><type>type</type></typedef><typedef name="proto_tag"><type><classname>proto::tag::bitwise_or_assign</classname></type></typedef><typedef name="proto_arg0"><type>T</type></typedef><typedef name="proto_arg1"><type>U</type></typedef><method-group name="public member functions"/><constructor/></struct><struct name="bitwise_xor_assign"><template>
+ <template-type-parameter name="T"/>
+ <template-type-parameter name="U"/>
+ </template><inherit access="public">boost::proto::has_transformns_::has_pass_through_transform< Grammar ></inherit><typedef name="type"><type>expr< <classname>proto::tag::bitwise_xor_assign</classname>, <classname>args2</classname>< T, U > ></type></typedef><typedef name="proto_base_expr"><type>type</type></typedef><typedef name="proto_tag"><type><classname>proto::tag::bitwise_xor_assign</classname></type></typedef><typedef name="proto_arg0"><type>T</type></typedef><typedef name="proto_arg1"><type>U</type></typedef><method-group name="public member functions"/><constructor/></struct><struct name="subscript"><template>
+ <template-type-parameter name="T"/>
+ <template-type-parameter name="U"/>
+ </template><inherit access="public">boost::proto::has_transformns_::has_pass_through_transform< Grammar ></inherit><typedef name="type"><type>expr< <classname>proto::tag::subscript</classname>, <classname>args2</classname>< T, U > ></type></typedef><typedef name="proto_base_expr"><type>type</type></typedef><typedef name="proto_tag"><type><classname>proto::tag::subscript</classname></type></typedef><typedef name="proto_arg0"><type>T</type></typedef><typedef name="proto_arg1"><type>U</type></typedef><method-group name="public member functions"/><constructor/></struct><struct-specialization name="function"><template>
+ <template-type-parameter name="A0"/>
+ </template><specialization><template-arg>A0</template-arg><template-arg>void</template-arg><template-arg>void</template-arg><template-arg>void</template-arg><template-arg>void</template-arg><template-arg>void</template-arg></specialization><inherit access="public">boost::proto::has_transformns_::has_pass_through_transform< Grammar ></inherit><typedef name="type"><type>expr< <classname>proto::tag::function</classname>, <classname>args1</classname>< A0 > ></type></typedef><typedef name="proto_base_expr"><type>type</type></typedef><typedef name="proto_tag"><type><classname>proto::tag::function</classname></type></typedef><typedef name="proto_arg0"><type>A0</type></typedef><typedef name="proto_arg1"><type><emphasis>unspecified</emphasis></type></typedef><typedef name="proto_arg2"><type><emphasis>unspecified</emphasis></type></typedef><typedef name="proto_arg3"><type><emphasis>unspecified</emphasis></type></typedef><typedef name="proto_arg4"><type><emphasis>unspecified</emphasis></type></ty
pedef></struct-specialization><struct-specialization name="nary_expr"><template>
+ <template-type-parameter name="Tag"/>
+ <template-type-parameter name="A0"/>
+ </template><specialization><template-arg>Tag</template-arg><template-arg>A0</template-arg><template-arg>void</template-arg><template-arg>void</template-arg><template-arg>void</template-arg><template-arg>void</template-arg><template-arg>void</template-arg></specialization><inherit access="public">boost::proto::has_transformns_::has_pass_through_transform< Grammar ></inherit><typedef name="type"><type>expr< Tag, <classname>args1</classname>< A0 > ></type></typedef><typedef name="proto_base_expr"><type>type</type></typedef><typedef name="proto_tag"><type>Tag</type></typedef><typedef name="proto_arg0"><type>A0</type></typedef><typedef name="proto_arg1"><type><emphasis>unspecified</emphasis></type></typedef><typedef name="proto_arg2"><type><emphasis>unspecified</emphasis></type></typedef><typedef name="proto_arg3"><type><emphasis>unspecified</emphasis></type></typedef><typedef name="proto_arg4"><type><emphasis>unspecified</emphasis></type></typedef></struct-specialization><struct-specializa
tion name="function"><template>
+ <template-type-parameter name="A0"/>
+ <template-type-parameter name="A1"/>
+ </template><specialization><template-arg>A0</template-arg><template-arg>A1</template-arg><template-arg>void</template-arg><template-arg>void</template-arg><template-arg>void</template-arg><template-arg>void</template-arg></specialization><inherit access="public">boost::proto::has_transformns_::has_pass_through_transform< Grammar ></inherit><typedef name="type"><type>expr< <classname>proto::tag::function</classname>, <classname>args2</classname>< A0, A1 > ></type></typedef><typedef name="proto_base_expr"><type>type</type></typedef><typedef name="proto_tag"><type><classname>proto::tag::function</classname></type></typedef><typedef name="proto_arg0"><type>A0</type></typedef><typedef name="proto_arg1"><type>A1</type></typedef><typedef name="proto_arg2"><type><emphasis>unspecified</emphasis></type></typedef><typedef name="proto_arg3"><type><emphasis>unspecified</emphasis></type></typedef><typedef name="proto_arg4"><type><emphasis>unspecified</emphasis></type></typedef></struct-specializatio
n><struct-specialization name="nary_expr"><template>
+ <template-type-parameter name="Tag"/>
+ <template-type-parameter name="A0"/>
+ <template-type-parameter name="A1"/>
+ </template><specialization><template-arg>Tag</template-arg><template-arg>A0</template-arg><template-arg>A1</template-arg><template-arg>void</template-arg><template-arg>void</template-arg><template-arg>void</template-arg><template-arg>void</template-arg></specialization><inherit access="public">boost::proto::has_transformns_::has_pass_through_transform< Grammar ></inherit><typedef name="type"><type>expr< Tag, <classname>args2</classname>< A0, A1 > ></type></typedef><typedef name="proto_base_expr"><type>type</type></typedef><typedef name="proto_tag"><type>Tag</type></typedef><typedef name="proto_arg0"><type>A0</type></typedef><typedef name="proto_arg1"><type>A1</type></typedef><typedef name="proto_arg2"><type><emphasis>unspecified</emphasis></type></typedef><typedef name="proto_arg3"><type><emphasis>unspecified</emphasis></type></typedef><typedef name="proto_arg4"><type><emphasis>unspecified</emphasis></type></typedef></struct-specialization><struct-specialization name="function"><templa
te>
+ <template-type-parameter name="A0"/>
+ <template-type-parameter name="A1"/>
+ <template-type-parameter name="A2"/>
+ </template><specialization><template-arg>A0</template-arg><template-arg>A1</template-arg><template-arg>A2</template-arg><template-arg>void</template-arg><template-arg>void</template-arg><template-arg>void</template-arg></specialization><inherit access="public">boost::proto::has_transformns_::has_pass_through_transform< Grammar ></inherit><typedef name="type"><type>expr< <classname>proto::tag::function</classname>, <classname>args3</classname>< A0, A1, A2 > ></type></typedef><typedef name="proto_base_expr"><type>type</type></typedef><typedef name="proto_tag"><type><classname>proto::tag::function</classname></type></typedef><typedef name="proto_arg0"><type>A0</type></typedef><typedef name="proto_arg1"><type>A1</type></typedef><typedef name="proto_arg2"><type>A2</type></typedef><typedef name="proto_arg3"><type><emphasis>unspecified</emphasis></type></typedef><typedef name="proto_arg4"><type><emphasis>unspecified</emphasis></type></typedef></struct-specialization><struct-specialization nam
e="nary_expr"><template>
+ <template-type-parameter name="Tag"/>
+ <template-type-parameter name="A0"/>
+ <template-type-parameter name="A1"/>
+ <template-type-parameter name="A2"/>
+ </template><specialization><template-arg>Tag</template-arg><template-arg>A0</template-arg><template-arg>A1</template-arg><template-arg>A2</template-arg><template-arg>void</template-arg><template-arg>void</template-arg><template-arg>void</template-arg></specialization><inherit access="public">boost::proto::has_transformns_::has_pass_through_transform< Grammar ></inherit><typedef name="type"><type>expr< Tag, <classname>args3</classname>< A0, A1, A2 > ></type></typedef><typedef name="proto_base_expr"><type>type</type></typedef><typedef name="proto_tag"><type>Tag</type></typedef><typedef name="proto_arg0"><type>A0</type></typedef><typedef name="proto_arg1"><type>A1</type></typedef><typedef name="proto_arg2"><type>A2</type></typedef><typedef name="proto_arg3"><type><emphasis>unspecified</emphasis></type></typedef><typedef name="proto_arg4"><type><emphasis>unspecified</emphasis></type></typedef></struct-specialization><struct-specialization name="function"><template>
+ <template-type-parameter name="A0"/>
+ <template-type-parameter name="A1"/>
+ <template-type-parameter name="A2"/>
+ <template-type-parameter name="A3"/>
+ </template><specialization><template-arg>A0</template-arg><template-arg>A1</template-arg><template-arg>A2</template-arg><template-arg>A3</template-arg><template-arg>void</template-arg><template-arg>void</template-arg></specialization><inherit access="public">boost::proto::has_transformns_::has_pass_through_transform< Grammar ></inherit><typedef name="type"><type>expr< <classname>proto::tag::function</classname>, <classname>args4</classname>< A0, A1, A2, A3 > ></type></typedef><typedef name="proto_base_expr"><type>type</type></typedef><typedef name="proto_tag"><type><classname>proto::tag::function</classname></type></typedef><typedef name="proto_arg0"><type>A0</type></typedef><typedef name="proto_arg1"><type>A1</type></typedef><typedef name="proto_arg2"><type>A2</type></typedef><typedef name="proto_arg3"><type>A3</type></typedef><typedef name="proto_arg4"><type><emphasis>unspecified</emphasis></type></typedef></struct-specialization><struct-specialization name="nary_expr"><template>
+ <template-type-parameter name="Tag"/>
+ <template-type-parameter name="A0"/>
+ <template-type-parameter name="A1"/>
+ <template-type-parameter name="A2"/>
+ <template-type-parameter name="A3"/>
+ </template><specialization><template-arg>Tag</template-arg><template-arg>A0</template-arg><template-arg>A1</template-arg><template-arg>A2</template-arg><template-arg>A3</template-arg><template-arg>void</template-arg><template-arg>void</template-arg></specialization><inherit access="public">boost::proto::has_transformns_::has_pass_through_transform< Grammar ></inherit><typedef name="type"><type>expr< Tag, <classname>args4</classname>< A0, A1, A2, A3 > ></type></typedef><typedef name="proto_base_expr"><type>type</type></typedef><typedef name="proto_tag"><type>Tag</type></typedef><typedef name="proto_arg0"><type>A0</type></typedef><typedef name="proto_arg1"><type>A1</type></typedef><typedef name="proto_arg2"><type>A2</type></typedef><typedef name="proto_arg3"><type>A3</type></typedef><typedef name="proto_arg4"><type><emphasis>unspecified</emphasis></type></typedef></struct-specialization><struct-specialization name="function"><template>
+ <template-type-parameter name="A0"/>
+ <template-type-parameter name="A1"/>
+ <template-type-parameter name="A2"/>
+ <template-type-parameter name="A3"/>
+ <template-type-parameter name="A4"/>
+ </template><specialization><template-arg>A0</template-arg><template-arg>A1</template-arg><template-arg>A2</template-arg><template-arg>A3</template-arg><template-arg>A4</template-arg><template-arg>void</template-arg></specialization><inherit access="public">boost::proto::has_transformns_::has_pass_through_transform< Grammar ></inherit><typedef name="type"><type>expr< <classname>proto::tag::function</classname>, <classname>args5</classname>< A0, A1, A2, A3, A4 > ></type></typedef><typedef name="proto_base_expr"><type>type</type></typedef><typedef name="proto_tag"><type><classname>proto::tag::function</classname></type></typedef><typedef name="proto_arg0"><type>A0</type></typedef><typedef name="proto_arg1"><type>A1</type></typedef><typedef name="proto_arg2"><type>A2</type></typedef><typedef name="proto_arg3"><type>A3</type></typedef><typedef name="proto_arg4"><type>A4</type></typedef></struct-specialization><struct-specialization name="nary_expr"><template>
+ <template-type-parameter name="Tag"/>
+ <template-type-parameter name="A0"/>
+ <template-type-parameter name="A1"/>
+ <template-type-parameter name="A2"/>
+ <template-type-parameter name="A3"/>
+ <template-type-parameter name="A4"/>
+ </template><specialization><template-arg>Tag</template-arg><template-arg>A0</template-arg><template-arg>A1</template-arg><template-arg>A2</template-arg><template-arg>A3</template-arg><template-arg>A4</template-arg><template-arg>void</template-arg></specialization><inherit access="public">boost::proto::has_transformns_::has_pass_through_transform< Grammar ></inherit><typedef name="type"><type>expr< Tag, <classname>args5</classname>< A0, A1, A2, A3, A4 > ></type></typedef><typedef name="proto_base_expr"><type>type</type></typedef><typedef name="proto_tag"><type>Tag</type></typedef><typedef name="proto_arg0"><type>A0</type></typedef><typedef name="proto_arg1"><type>A1</type></typedef><typedef name="proto_arg2"><type>A2</type></typedef><typedef name="proto_arg3"><type>A3</type></typedef><typedef name="proto_arg4"><type>A4</type></typedef></struct-specialization></namespace><namespace name="result_of"><struct name="is_ref"><template>
+ <template-type-parameter name="T"/>
+ <template-type-parameter name="EnableIf"/>
+ </template></struct><struct name="is_expr"><template>
+ <template-type-parameter name="T"/>
+ <template-type-parameter name="EnableIf"/>
+ </template></struct><struct name="tag_of"><template>
+ <template-type-parameter name="Expr"/>
+ </template><typedef name="type"><type>Expr::proto_tag</type></typedef></struct><struct name="id"><template>
+ <template-type-parameter name="Expr"/>
+ </template><inherit access="public">boost::proto::result_of::deep_copy< Expr ></inherit></struct><struct name="as_expr"><template>
+ <template-type-parameter name="T"/>
+ <template-type-parameter name="Domain"/>
+ <template-type-parameter name="EnableIf"/>
+ </template><typedef name="proto_arg0"><type>mpl::eval_if< mpl::or_< boost::is_array< T >, is_function< T > >, add_reference< T >, remove_cv< T >>::type</type></typedef><typedef name="expr_type"><type>expr< <classname>proto::tag::terminal</classname>, <classname>args0</classname>< proto_arg0 > ></type></typedef><typedef name="type"><type>Domain::template apply< expr_type >::type</type></typedef><typedef name="result_type"><type>type const</type></typedef><method-group name="public static functions"><method name="call" cv=""><type>static result_type</type><template>
+ <template-type-parameter name="T2"/>
+ </template><parameter name="t"><paramtype>T2 &</paramtype></parameter></method></method-group></struct><struct name="as_arg"><template>
+ <template-type-parameter name="T"/>
+ <template-type-parameter name="Domain"/>
+ <template-type-parameter name="EnableIf"/>
+ </template><typedef name="expr_type"><type>expr< <classname>proto::tag::terminal</classname>, <classname>args0</classname>< T & > ></type></typedef><typedef name="type"><type>Domain::template apply< expr_type >::type</type></typedef><method-group name="public static functions"><method name="call" cv=""><type>static type</type><template>
+ <template-type-parameter name="T2"/>
+ </template><parameter name="t"><paramtype>T2 &</paramtype></parameter></method></method-group></struct><struct name="arg"><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="N"/>
+ </template></struct><struct name="left"><template>
+ <template-type-parameter name="Expr"/>
+ </template><inherit access="public">boost::proto::result_of::unref< Expr::proto_arg0 ></inherit></struct><struct name="right"><template>
+ <template-type-parameter name="Expr"/>
+ </template><inherit access="public">boost::proto::result_of::unref< Expr::proto_arg1 ></inherit></struct><struct-specialization name="arg_c"><template>
+ <template-type-parameter name="Expr"/>
+ </template><specialization><template-arg>Expr</template-arg><template-arg>0</template-arg></specialization><inherit access="public">boost::proto::result_of::unref< Expr::proto_arg0 ></inherit><method-group name="public static functions"><method name="call" cv=""><type>static <classname>arg_c</classname>< Expr, 0 >::reference</type><parameter name="expr"><paramtype>Expr &</paramtype></parameter></method><method name="call" cv=""><type>static <classname>arg_c</classname>< Expr, 0 >::const_reference</type><parameter name="expr"><paramtype>Expr const &</paramtype></parameter></method></method-group></struct-specialization><struct-specialization name="arg_c"><template>
+ <template-type-parameter name="Expr"/>
+ </template><specialization><template-arg>Expr const</template-arg><template-arg>0</template-arg></specialization><inherit access="public">boost::proto::result_of::arg_c< Expr, 0 ></inherit></struct-specialization><struct-specialization name="arg_c"><template>
+ <template-type-parameter name="Expr"/>
+ </template><specialization><template-arg>Expr</template-arg><template-arg>1</template-arg></specialization><inherit access="public">boost::proto::result_of::unref< Expr::proto_arg1 ></inherit><method-group name="public static functions"><method name="call" cv=""><type>static <classname>arg_c</classname>< Expr, 1 >::reference</type><parameter name="expr"><paramtype>Expr &</paramtype></parameter></method><method name="call" cv=""><type>static <classname>arg_c</classname>< Expr, 1 >::const_reference</type><parameter name="expr"><paramtype>Expr const &</paramtype></parameter></method></method-group></struct-specialization><struct-specialization name="arg_c"><template>
+ <template-type-parameter name="Expr"/>
+ </template><specialization><template-arg>Expr const</template-arg><template-arg>1</template-arg></specialization><inherit access="public">boost::proto::result_of::arg_c< Expr, 1 ></inherit></struct-specialization><struct-specialization name="arg_c"><template>
+ <template-type-parameter name="Expr"/>
+ </template><specialization><template-arg>Expr</template-arg><template-arg>2</template-arg></specialization><inherit access="public">boost::proto::result_of::unref< Expr::proto_arg2 ></inherit><method-group name="public static functions"><method name="call" cv=""><type>static <classname>arg_c</classname>< Expr, 2 >::reference</type><parameter name="expr"><paramtype>Expr &</paramtype></parameter></method><method name="call" cv=""><type>static <classname>arg_c</classname>< Expr, 2 >::const_reference</type><parameter name="expr"><paramtype>Expr const &</paramtype></parameter></method></method-group></struct-specialization><struct-specialization name="arg_c"><template>
+ <template-type-parameter name="Expr"/>
+ </template><specialization><template-arg>Expr const</template-arg><template-arg>2</template-arg></specialization><inherit access="public">boost::proto::result_of::arg_c< Expr, 2 ></inherit></struct-specialization><struct-specialization name="arg_c"><template>
+ <template-type-parameter name="Expr"/>
+ </template><specialization><template-arg>Expr</template-arg><template-arg>3</template-arg></specialization><inherit access="public">boost::proto::result_of::unref< Expr::proto_arg3 ></inherit><method-group name="public static functions"><method name="call" cv=""><type>static <classname>arg_c</classname>< Expr, 3 >::reference</type><parameter name="expr"><paramtype>Expr &</paramtype></parameter></method><method name="call" cv=""><type>static <classname>arg_c</classname>< Expr, 3 >::const_reference</type><parameter name="expr"><paramtype>Expr const &</paramtype></parameter></method></method-group></struct-specialization><struct-specialization name="arg_c"><template>
+ <template-type-parameter name="Expr"/>
+ </template><specialization><template-arg>Expr const</template-arg><template-arg>3</template-arg></specialization><inherit access="public">boost::proto::result_of::arg_c< Expr, 3 ></inherit></struct-specialization><struct-specialization name="arg_c"><template>
+ <template-type-parameter name="Expr"/>
+ </template><specialization><template-arg>Expr</template-arg><template-arg>4</template-arg></specialization><inherit access="public">boost::proto::result_of::unref< Expr::proto_arg4 ></inherit><method-group name="public static functions"><method name="call" cv=""><type>static <classname>arg_c</classname>< Expr, 4 >::reference</type><parameter name="expr"><paramtype>Expr &</paramtype></parameter></method><method name="call" cv=""><type>static <classname>arg_c</classname>< Expr, 4 >::const_reference</type><parameter name="expr"><paramtype>Expr const &</paramtype></parameter></method></method-group></struct-specialization><struct-specialization name="arg_c"><template>
+ <template-type-parameter name="Expr"/>
+ </template><specialization><template-arg>Expr const</template-arg><template-arg>4</template-arg></specialization><inherit access="public">boost::proto::result_of::arg_c< Expr, 4 ></inherit></struct-specialization><struct-specialization name="arg_c"><template>
+ <template-type-parameter name="Expr"/>
+ </template><specialization><template-arg>Expr</template-arg><template-arg>5</template-arg></specialization><inherit access="public">boost::proto::result_of::unref< Expr::proto_arg5 ></inherit><method-group name="public static functions"><method name="call" cv=""><type>static <classname>arg_c</classname>< Expr, 5 >::reference</type><parameter name="expr"><paramtype>Expr &</paramtype></parameter></method><method name="call" cv=""><type>static <classname>arg_c</classname>< Expr, 5 >::const_reference</type><parameter name="expr"><paramtype>Expr const &</paramtype></parameter></method></method-group></struct-specialization><struct-specialization name="arg_c"><template>
+ <template-type-parameter name="Expr"/>
+ </template><specialization><template-arg>Expr const</template-arg><template-arg>5</template-arg></specialization><inherit access="public">boost::proto::result_of::arg_c< Expr, 5 ></inherit></struct-specialization><struct-specialization name="is_ref"><template>
+ <template-type-parameter name="T"/>
+ </template><specialization><template-arg>T</template-arg><template-arg>typename T::proto_is_ref_</template-arg></specialization></struct-specialization><struct-specialization name="is_expr"><template>
+ <template-type-parameter name="T"/>
+ </template><specialization><template-arg>T</template-arg><template-arg>typename T::proto_is_expr_</template-arg></specialization></struct-specialization><struct-specialization name="as_expr"><template>
+ <template-type-parameter name="T"/>
+ <template-type-parameter name="Domain"/>
+ </template><specialization><template-arg>T</template-arg><template-arg>Domain</template-arg><template-arg>typename T::proto_is_expr_</template-arg></specialization><typedef name="type"><type>T::proto_derived_expr</type></typedef><typedef name="result_type"><type>T &</type></typedef><method-group name="public static functions"><method name="call" cv=""><type>static result_type</type><template>
+ <template-type-parameter name="T2"/>
+ </template><parameter name="t"><paramtype>T2 &</paramtype></parameter></method></method-group></struct-specialization><struct-specialization name="as_arg"><template>
+ <template-type-parameter name="T"/>
+ <template-type-parameter name="Domain"/>
+ </template><specialization><template-arg>T</template-arg><template-arg>Domain</template-arg><template-arg>typename T::proto_is_expr_</template-arg></specialization><typedef name="type"><type><classname>ref_</classname>< T ></type></typedef><method-group name="public static functions"><method name="call" cv=""><type>static <classname>type</classname></type><template>
+ <template-type-parameter name="T2"/>
+ </template><parameter name="t"><paramtype>T2 &</paramtype></parameter></method></method-group></struct-specialization></namespace><function name="implicit_expr"><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="A0"/>
+ </template><parameter name="a0"><paramtype>A0 &</paramtype></parameter></function><function name="implicit_expr"><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="A0"/>
+ <template-type-parameter name="A1"/>
+ </template><parameter name="a0"><paramtype>A0 &</paramtype></parameter><parameter name="a1"><paramtype>A1 &</paramtype></parameter></function><function name="implicit_expr"><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="A0"/>
+ <template-type-parameter name="A1"/>
+ <template-type-parameter name="A2"/>
+ </template><parameter name="a0"><paramtype>A0 &</paramtype></parameter><parameter name="a1"><paramtype>A1 &</paramtype></parameter><parameter name="a2"><paramtype>A2 &</paramtype></parameter></function><function name="implicit_expr"><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="A0"/>
+ <template-type-parameter name="A1"/>
+ <template-type-parameter name="A2"/>
+ <template-type-parameter name="A3"/>
+ </template><parameter name="a0"><paramtype>A0 &</paramtype></parameter><parameter name="a1"><paramtype>A1 &</paramtype></parameter><parameter name="a2"><paramtype>A2 &</paramtype></parameter><parameter name="a3"><paramtype>A3 &</paramtype></parameter></function><function name="implicit_expr"><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="A0"/>
+ <template-type-parameter name="A1"/>
+ <template-type-parameter name="A2"/>
+ <template-type-parameter name="A3"/>
+ <template-type-parameter name="A4"/>
+ </template><parameter name="a0"><paramtype>A0 &</paramtype></parameter><parameter name="a1"><paramtype>A1 &</paramtype></parameter><parameter name="a2"><paramtype>A2 &</paramtype></parameter><parameter name="a3"><paramtype>A3 &</paramtype></parameter><parameter name="a4"><paramtype>A4 &</paramtype></parameter></function><overloaded-function name="as_expr"><signature><type><classname>result_of::as_expr</classname>< T >::result_type</type><template>
+ <template-type-parameter name="T"/>
+ </template><parameter name="t"><paramtype>T &</paramtype></parameter></signature><signature><type><classname>result_of::as_expr</classname>< T const >::result_type</type><template>
+ <template-type-parameter name="T"/>
+ </template><parameter name="t"><paramtype>T const &</paramtype></parameter></signature><description><para>as_expr </para></description></overloaded-function><overloaded-function name="as_arg"><signature><type><classname>result_of::as_arg</classname>< T >::type</type><template>
+ <template-type-parameter name="T"/>
+ </template><parameter name="t"><paramtype>T &</paramtype></parameter></signature><signature><type><classname>result_of::as_arg</classname>< T const >::type</type><template>
+ <template-type-parameter name="T"/>
+ </template><parameter name="t"><paramtype>T const &</paramtype></parameter></signature><description><para>as_arg </para></description></overloaded-function><overloaded-function name="arg"><signature><type><classname>result_of::unref</classname>< typename Expr::proto_base_expr::proto_arg0 >::reference</type><template>
+ <template-type-parameter name="Expr"/>
+ </template><parameter name="expr"><paramtype>Expr &</paramtype></parameter></signature><signature><type><classname>result_of::unref</classname>< typename Expr::proto_base_expr::proto_arg0 >::const_reference</type><template>
+ <template-type-parameter name="Expr"/>
+ </template><parameter name="expr"><paramtype>Expr const &</paramtype></parameter></signature><description><para>arg </para></description></overloaded-function><overloaded-function name="arg_c"><signature><type>result_of::arg_c< Expr, N >::reference</type><template>
+ <template-nontype-parameter name="N"><type>long</type></template-nontype-parameter>
+ <template-type-parameter name="Expr"/>
+ </template><parameter name="expr"><paramtype>Expr &</paramtype></parameter></signature><signature><type>result_of::arg_c< Expr, N >::const_reference</type><template>
+ <template-nontype-parameter name="N"><type>long</type></template-nontype-parameter>
+ <template-type-parameter name="Expr"/>
+ </template><parameter name="expr"><paramtype>Expr const &</paramtype></parameter></signature><description><para>arg_c </para></description></overloaded-function><data-member name="left"><type><classname>functional::left</classname> const</type></data-member><data-member name="right"><type><classname>functional::right</classname> const</type></data-member></namespace></namespace></header><header name="boost/xpressive/proto/transform.hpp"><para>Includes all the transforms in the transform/ sub-directory. </para></header><header name="boost/xpressive/proto/transform/apply.hpp"><para>Proto transforms for applying MPL placeholder expressions. </para><namespace name="boost"><namespace name="proto"><namespace name="transform"><struct name="always"><template>
+ <template-type-parameter name="Grammar"/>
+ <template-type-parameter name="Always"/>
+ <template-type-parameter name="Factory"/>
+ </template><struct name="apply"><template>
+ <template-type-parameter name=""/>
+ <template-type-parameter name=""/>
+ <template-type-parameter name=""/>
+ </template><typedef name="type"><type>Always</type></typedef></struct><method-group name="public member functions"/><constructor/><method-group name="public static functions"><method name="call" cv=""><type>static Always</type><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="State"/>
+ <template-type-parameter name="Visitor"/>
+ </template><parameter name=""><paramtype>Expr const &</paramtype></parameter><parameter name=""><paramtype>State const &</paramtype></parameter><parameter name=""><paramtype>Visitor &</paramtype></parameter></method></method-group></struct><struct name="apply1"><template>
+ <template-type-parameter name="Grammar"/>
+ <template-type-parameter name="Lambda"/>
+ <template-type-parameter name="Factory"/>
+ </template><struct name="apply"><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="State"/>
+ <template-type-parameter name="Visitor"/>
+ </template></struct><method-group name="public member functions"/><constructor/><method-group name="public static functions"><method name="call" cv=""><type>static <classname>apply</classname>< Expr, State, Visitor >::type</type><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="State"/>
+ <template-type-parameter name="Visitor"/>
+ </template><parameter name="expr"><paramtype>Expr const &</paramtype></parameter><parameter name="state"><paramtype>State const &</paramtype></parameter><parameter name="visitor"><paramtype>Visitor &</paramtype></parameter></method></method-group></struct><struct name="apply2"><template>
+ <template-type-parameter name="Grammar"/>
+ <template-type-parameter name="Lambda"/>
+ <template-type-parameter name="Factory"/>
+ </template><struct name="apply"><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="State"/>
+ <template-type-parameter name="Visitor"/>
+ </template></struct><method-group name="public member functions"/><constructor/><method-group name="public static functions"><method name="call" cv=""><type>static <classname>apply</classname>< Expr, State, Visitor >::type</type><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="State"/>
+ <template-type-parameter name="Visitor"/>
+ </template><parameter name="expr"><paramtype>Expr const &</paramtype></parameter><parameter name="state"><paramtype>State const &</paramtype></parameter><parameter name="visitor"><paramtype>Visitor &</paramtype></parameter></method></method-group></struct><struct name="apply3"><template>
+ <template-type-parameter name="Grammar"/>
+ <template-type-parameter name="Lambda"/>
+ <template-type-parameter name="Factory"/>
+ </template><struct name="apply"><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="State"/>
+ <template-type-parameter name="Visitor"/>
+ </template></struct><method-group name="public member functions"/><constructor/><method-group name="public static functions"><method name="call" cv=""><type>static <classname>apply</classname>< Expr, State, Visitor >::type</type><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="State"/>
+ <template-type-parameter name="Visitor"/>
+ </template><parameter name="expr"><paramtype>Expr const &</paramtype></parameter><parameter name="state"><paramtype>State const &</paramtype></parameter><parameter name="visitor"><paramtype>Visitor &</paramtype></parameter></method></method-group></struct></namespace></namespace></namespace></header><header name="boost/xpressive/proto/transform/arg.hpp"><para>Proto transforms for extracting arguments from expressions. </para><namespace name="boost"><namespace name="proto"><namespace name="transform"><struct name="arg"><template>
+ <template-type-parameter name="Grammar"/>
+ <template-type-parameter name="N"/>
+ </template><struct name="apply"><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="State"/>
+ <template-type-parameter name="Visitor"/>
+ </template><inherit access="public">boost::proto::result_of::arg< Grammar::template apply< Expr, State, Visitor >::type, N ></inherit></struct><method-group name="public member functions"/><constructor/><method-group name="public static functions"><method name="call" cv=""><type>static <classname>apply</classname>< Expr, State, Visitor >::type</type><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="State"/>
+ <template-type-parameter name="Visitor"/>
+ </template><parameter name="expr"><paramtype>Expr const &</paramtype></parameter><parameter name="state"><paramtype>State const &</paramtype></parameter><parameter name="visitor"><paramtype>Visitor &</paramtype></parameter></method></method-group></struct><struct name="arg_c"><template>
+ <template-type-parameter name="Grammar"/>
+ <template-nontype-parameter name="N"><type>long</type></template-nontype-parameter>
+ </template><struct name="apply"><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="State"/>
+ <template-type-parameter name="Visitor"/>
+ </template></struct><method-group name="public member functions"/><constructor/><method-group name="public static functions"><method name="call" cv=""><type>static <classname>apply</classname>< Expr, State, Visitor >::type</type><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="State"/>
+ <template-type-parameter name="Visitor"/>
+ </template><parameter name="expr"><paramtype>Expr const &</paramtype></parameter><parameter name="state"><paramtype>State const &</paramtype></parameter><parameter name="visitor"><paramtype>Visitor &</paramtype></parameter></method></method-group></struct><struct name="left"><template>
+ <template-type-parameter name="Grammar"/>
+ </template><struct name="apply"><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="State"/>
+ <template-type-parameter name="Visitor"/>
+ </template><inherit access="public">boost::proto::result_of::left< Grammar::template apply< Expr, State, Visitor >::type ></inherit></struct><method-group name="public member functions"/><constructor/><method-group name="public static functions"><method name="call" cv=""><type>static <classname>apply</classname>< Expr, State, Visitor >::type</type><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="State"/>
+ <template-type-parameter name="Visitor"/>
+ </template><parameter name="expr"><paramtype>Expr const &</paramtype></parameter><parameter name="state"><paramtype>State const &</paramtype></parameter><parameter name="visitor"><paramtype>Visitor &</paramtype></parameter></method></method-group></struct><struct name="right"><template>
+ <template-type-parameter name="Grammar"/>
+ </template><struct name="apply"><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="State"/>
+ <template-type-parameter name="Visitor"/>
+ </template><inherit access="public">boost::proto::result_of::right< Grammar::template apply< Expr, State, Visitor >::type ></inherit></struct><method-group name="public member functions"/><constructor/><method-group name="public static functions"><method name="call" cv=""><type>static <classname>apply</classname>< Expr, State, Visitor >::type</type><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="State"/>
+ <template-type-parameter name="Visitor"/>
+ </template><parameter name="expr"><paramtype>Expr const &</paramtype></parameter><parameter name="state"><paramtype>State const &</paramtype></parameter><parameter name="visitor"><paramtype>Visitor &</paramtype></parameter></method></method-group></struct><struct name="identity"><template>
+ <template-type-parameter name="Grammar"/>
+ </template><struct name="apply"><template>
+ <template-type-parameter name="Expr_"/>
+ <template-type-parameter name=""/>
+ <template-type-parameter name=""/>
+ </template><typedef name="type"><type>Expr_</type></typedef></struct><method-group name="public member functions"/><constructor/><method-group name="public static functions"><method name="call" cv=""><type>static Expr_ const &</type><template>
+ <template-type-parameter name="Expr_"/>
+ <template-type-parameter name="State_"/>
+ <template-type-parameter name="Visitor_"/>
+ </template><parameter name="expr_"><paramtype>Expr_ const &</paramtype></parameter><parameter name=""><paramtype>State_ const &</paramtype></parameter><parameter name=""><paramtype>Visitor_ &</paramtype></parameter></method></method-group></struct><struct name="state"><template>
+ <template-type-parameter name="Grammar"/>
+ </template><struct name="apply"><template>
+ <template-type-parameter name=""/>
+ <template-type-parameter name="State"/>
+ <template-type-parameter name=""/>
+ </template><typedef name="type"><type>State</type></typedef></struct><method-group name="public member functions"/><constructor/><method-group name="public static functions"><method name="call" cv=""><type>static State const &</type><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="State"/>
+ <template-type-parameter name="Visitor"/>
+ </template><parameter name=""><paramtype>Expr const &</paramtype></parameter><parameter name="state_"><paramtype>State const &</paramtype></parameter><parameter name=""><paramtype>Visitor &</paramtype></parameter></method></method-group></struct><struct name="visitor"><template>
+ <template-type-parameter name="Grammar"/>
+ </template><struct name="apply"><template>
+ <template-type-parameter name=""/>
+ <template-type-parameter name=""/>
+ <template-type-parameter name="Visitor"/>
+ </template><typedef name="type"><type>Visitor</type></typedef></struct><method-group name="public member functions"/><constructor/><method-group name="public static functions"><method name="call" cv=""><type>static Visitor &</type><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="State"/>
+ <template-type-parameter name="Visitor"/>
+ </template><parameter name=""><paramtype>Expr const &</paramtype></parameter><parameter name=""><paramtype>State const &</paramtype></parameter><parameter name="visitor_"><paramtype>Visitor &</paramtype></parameter></method></method-group></struct></namespace></namespace></namespace></header><header name="boost/xpressive/proto/transform/branch.hpp"><para>A special-purpose proto transform for transforming one branch of the expression tree separately from the rest. Given an expression and a new state, it transforms the expression using the new state. </para><namespace name="boost"><namespace name="proto"><namespace name="transform"><struct name="branch"><template>
+ <template-type-parameter name="Grammar"/>
+ <template-type-parameter name="BranchState"/>
+ </template><struct name="apply"><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="State"/>
+ <template-type-parameter name="Visitor"/>
+ </template></struct><method-group name="public member functions"/><constructor/><method-group name="public static functions"><method name="call" cv=""><type>static <classname>apply</classname>< Expr, State, Visitor >::type</type><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="State"/>
+ <template-type-parameter name="Visitor"/>
+ </template><parameter name="expr"><paramtype>Expr const &</paramtype></parameter><parameter name=""><paramtype>State const &</paramtype></parameter><parameter name="visitor"><paramtype>Visitor &</paramtype></parameter></method></method-group></struct></namespace></namespace></namespace></header><header name="boost/xpressive/proto/transform/compose.hpp"><para>A special-purpose proto transform for composing two transfomations. Given two Grammars, expressions that match the first grammar are transformed according to that grammar, and the result is forwarded to the second for further transformation. </para><namespace name="boost"><namespace name="proto"><namespace name="transform"><struct name="compose"><template>
+ <template-type-parameter name="Grammar1"/>
+ <template-type-parameter name="Grammar2"/>
+ </template><struct name="apply"><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="State"/>
+ <template-type-parameter name="Visitor"/>
+ </template><typedef name="type"><type>Grammar2::template <classname>apply</classname>< typename Grammar1::template <classname>apply</classname>< Expr, State, Visitor >::type, State, Visitor >::type</type></typedef></struct><method-group name="public member functions"/><constructor/><method-group name="public static functions"><method name="call" cv=""><type>static <classname>apply</classname>< Expr, State, Visitor >::type</type><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="State"/>
+ <template-type-parameter name="Visitor"/>
+ </template><parameter name="expr"><paramtype>Expr const &</paramtype></parameter><parameter name="state"><paramtype>State const &</paramtype></parameter><parameter name="visitor"><paramtype>Visitor &</paramtype></parameter></method></method-group></struct></namespace></namespace></namespace></header><header name="boost/xpressive/proto/transform/construct.hpp"><para>For constructing an arbitrary type from a bunch of transforms. </para><namespace name="boost"><namespace name="proto"><namespace name="transform"><struct-specialization name="construct"><template>
+ <template-type-parameter name="Grammar"/>
+ <template-type-parameter name="Result"/>
+ </template><specialization><template-arg>Grammar</template-arg><template-arg>Result()</template-arg></specialization><struct name="apply"><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="State"/>
+ <template-type-parameter name="Visitor"/>
+ </template></struct><method-group name="public static functions"><method name="call" cv=""><type>static apply< Expr, State, Visitor >::type</type><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="State"/>
+ <template-type-parameter name="Visitor"/>
+ </template><parameter name="expr"><paramtype>Expr const &</paramtype></parameter><parameter name="state"><paramtype>State const &</paramtype></parameter><parameter name="visitor"><paramtype>Visitor &</paramtype></parameter></method></method-group><method-group name="private static functions"/></struct-specialization><struct-specialization name="construct"><template>
+ <template-type-parameter name="Grammar"/>
+ <template-type-parameter name="Result"/>
+ <template-type-parameter name="Arg0"/>
+ </template><specialization><template-arg>Grammar</template-arg><template-arg>Result(Arg0)</template-arg></specialization><struct name="apply"><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="State"/>
+ <template-type-parameter name="Visitor"/>
+ </template></struct><method-group name="public static functions"><method name="call" cv=""><type>static apply< Expr, State, Visitor >::type</type><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="State"/>
+ <template-type-parameter name="Visitor"/>
+ </template><parameter name="expr"><paramtype>Expr const &</paramtype></parameter><parameter name="state"><paramtype>State const &</paramtype></parameter><parameter name="visitor"><paramtype>Visitor &</paramtype></parameter></method></method-group><method-group name="private static functions"/></struct-specialization><struct-specialization name="construct"><template>
+ <template-type-parameter name="Grammar"/>
+ <template-type-parameter name="Result"/>
+ <template-type-parameter name="Arg0"/>
+ <template-type-parameter name="Arg1"/>
+ </template><specialization><template-arg>Grammar</template-arg><template-arg>Result(Arg0</template-arg><template-arg>Arg1)</template-arg></specialization><struct name="apply"><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="State"/>
+ <template-type-parameter name="Visitor"/>
+ </template></struct><method-group name="public static functions"><method name="call" cv=""><type>static apply< Expr, State, Visitor >::type</type><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="State"/>
+ <template-type-parameter name="Visitor"/>
+ </template><parameter name="expr"><paramtype>Expr const &</paramtype></parameter><parameter name="state"><paramtype>State const &</paramtype></parameter><parameter name="visitor"><paramtype>Visitor &</paramtype></parameter></method></method-group><method-group name="private static functions"/></struct-specialization><struct-specialization name="construct"><template>
+ <template-type-parameter name="Grammar"/>
+ <template-type-parameter name="Result"/>
+ <template-type-parameter name="Arg0"/>
+ <template-type-parameter name="Arg1"/>
+ <template-type-parameter name="Arg2"/>
+ </template><specialization><template-arg>Grammar</template-arg><template-arg>Result(Arg0</template-arg><template-arg>Arg1</template-arg><template-arg>Arg2)</template-arg></specialization><struct name="apply"><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="State"/>
+ <template-type-parameter name="Visitor"/>
+ </template></struct><method-group name="public static functions"><method name="call" cv=""><type>static apply< Expr, State, Visitor >::type</type><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="State"/>
+ <template-type-parameter name="Visitor"/>
+ </template><parameter name="expr"><paramtype>Expr const &</paramtype></parameter><parameter name="state"><paramtype>State const &</paramtype></parameter><parameter name="visitor"><paramtype>Visitor &</paramtype></parameter></method></method-group><method-group name="private static functions"/></struct-specialization><struct-specialization name="construct"><template>
+ <template-type-parameter name="Grammar"/>
+ <template-type-parameter name="Result"/>
+ <template-type-parameter name="Arg0"/>
+ <template-type-parameter name="Arg1"/>
+ <template-type-parameter name="Arg2"/>
+ <template-type-parameter name="Arg3"/>
+ </template><specialization><template-arg>Grammar</template-arg><template-arg>Result(Arg0</template-arg><template-arg>Arg1</template-arg><template-arg>Arg2</template-arg><template-arg>Arg3)</template-arg></specialization><struct name="apply"><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="State"/>
+ <template-type-parameter name="Visitor"/>
+ </template></struct><method-group name="public static functions"><method name="call" cv=""><type>static apply< Expr, State, Visitor >::type</type><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="State"/>
+ <template-type-parameter name="Visitor"/>
+ </template><parameter name="expr"><paramtype>Expr const &</paramtype></parameter><parameter name="state"><paramtype>State const &</paramtype></parameter><parameter name="visitor"><paramtype>Visitor &</paramtype></parameter></method></method-group><method-group name="private static functions"/></struct-specialization><struct-specialization name="construct"><template>
+ <template-type-parameter name="Grammar"/>
+ <template-type-parameter name="Result"/>
+ <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><specialization><template-arg>Grammar</template-arg><template-arg>Result(Arg0</template-arg><template-arg>Arg1</template-arg><template-arg>Arg2</template-arg><template-arg>Arg3</template-arg><template-arg>Arg4)</template-arg></specialization><struct name="apply"><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="State"/>
+ <template-type-parameter name="Visitor"/>
+ </template></struct><method-group name="public static functions"><method name="call" cv=""><type>static apply< Expr, State, Visitor >::type</type><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="State"/>
+ <template-type-parameter name="Visitor"/>
+ </template><parameter name="expr"><paramtype>Expr const &</paramtype></parameter><parameter name="state"><paramtype>State const &</paramtype></parameter><parameter name="visitor"><paramtype>Visitor &</paramtype></parameter></method></method-group><method-group name="private static functions"/></struct-specialization></namespace></namespace></namespace></header><header name="boost/xpressive/proto/transform/fold.hpp"><para>A special-purpose proto transform for merging sequences of binary operations. It transforms the right operand and passes the result as state while transforming the left. Or, it might do the left first, if you choose. </para><namespace name="boost"><namespace name="proto"><namespace name="transform"><struct-specialization name="fold"><template>
+ <template-type-parameter name="Grammar"/>
+ </template><specialization><template-arg>Grammar</template-arg><template-arg>void</template-arg></specialization><struct name="apply"><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="State"/>
+ <template-type-parameter name="Visitor"/>
+ </template></struct><method-group name="public member functions"><method name="fold" cv=""><type/></method></method-group><method-group name="public static functions"><method name="call" cv=""><type>static apply< Expr, State, Visitor >::type</type><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="State"/>
+ <template-type-parameter name="Visitor"/>
+ </template><parameter name="expr"><paramtype>Expr const &</paramtype></parameter><parameter name="state"><paramtype>State const &</paramtype></parameter><parameter name="visitor"><paramtype>Visitor &</paramtype></parameter></method></method-group></struct-specialization><struct-specialization name="reverse_fold"><template>
+ <template-type-parameter name="Grammar"/>
+ </template><specialization><template-arg>Grammar</template-arg><template-arg>void</template-arg></specialization><struct name="apply"><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="State"/>
+ <template-type-parameter name="Visitor"/>
+ </template></struct><method-group name="public member functions"><method name="reverse_fold" cv=""><type/></method></method-group><method-group name="public static functions"><method name="call" cv=""><type>static apply< Expr, State, Visitor >::type</type><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="State"/>
+ <template-type-parameter name="Visitor"/>
+ </template><parameter name="expr"><paramtype>Expr const &</paramtype></parameter><parameter name="state"><paramtype>State const &</paramtype></parameter><parameter name="visitor"><paramtype>Visitor &</paramtype></parameter></method></method-group></struct-specialization></namespace></namespace></namespace></header><header name="boost/xpressive/proto/transform/fold_tree.hpp"><para>A higher-level transform that uses the fold, and branch transforms to recursively fold a tree. </para><namespace name="boost"><namespace name="proto"><namespace name="transform"><struct name="fold_tree"><template>
+ <template-type-parameter name="Tag"/>
+ <template-type-parameter name="Grammar"/>
+ <template-type-parameter name="State"/>
+ </template><description><para>fold_tree </para></description></struct><struct name="reverse_fold_tree"><template>
+ <template-type-parameter name="Tag"/>
+ <template-type-parameter name="Grammar"/>
+ <template-type-parameter name="State"/>
+ </template><description><para>reverse_fold_tree </para></description></struct></namespace></namespace></namespace></header><header name="boost/xpressive/proto/transform/function.hpp"><para>Proto transforms for applying a function object. </para><namespace name="boost"><namespace name="proto"><namespace name="transform"><struct name="function1"><template>
+ <template-type-parameter name="Grammar"/>
+ <template-type-parameter name="Function1"/>
+ </template><struct name="apply"><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="State"/>
+ <template-type-parameter name="Visitor"/>
+ </template></struct><method-group name="public member functions"/><constructor/><method-group name="public static functions"><method name="call" cv=""><type>static <classname>apply</classname>< Expr, State, Visitor >::type</type><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="State"/>
+ <template-type-parameter name="Visitor"/>
+ </template><parameter name="expr"><paramtype>Expr const &</paramtype></parameter><parameter name="state"><paramtype>State const &</paramtype></parameter><parameter name="visitor"><paramtype>Visitor &</paramtype></parameter></method></method-group></struct><struct name="function2"><template>
+ <template-type-parameter name="Grammar"/>
+ <template-type-parameter name="Function2"/>
+ </template><struct name="apply"><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="State"/>
+ <template-type-parameter name="Visitor"/>
+ </template></struct><method-group name="public member functions"/><constructor/><method-group name="public static functions"><method name="call" cv=""><type>static <classname>apply</classname>< Expr, State, Visitor >::type</type><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="State"/>
+ <template-type-parameter name="Visitor"/>
+ </template><parameter name="expr"><paramtype>Expr const &</paramtype></parameter><parameter name="state"><paramtype>State const &</paramtype></parameter><parameter name="visitor"><paramtype>Visitor &</paramtype></parameter></method></method-group></struct><struct name="function3"><template>
+ <template-type-parameter name="Grammar"/>
+ <template-type-parameter name="Function3"/>
+ </template><struct name="apply"><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="State"/>
+ <template-type-parameter name="Visitor"/>
+ </template></struct><method-group name="public member functions"/><constructor/><method-group name="public static functions"><method name="call" cv=""><type>static <classname>apply</classname>< Expr, State, Visitor >::type</type><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="State"/>
+ <template-type-parameter name="Visitor"/>
+ </template><parameter name="expr"><paramtype>Expr const &</paramtype></parameter><parameter name="state"><paramtype>State const &</paramtype></parameter><parameter name="visitor"><paramtype>Visitor &</paramtype></parameter></method></method-group></struct></namespace></namespace></namespace></header><header name="boost/xpressive/proto/transform/list.hpp"><para>A special-purpose proto transform for putting things into a fusion::cons<> list. </para><namespace name="boost"><namespace name="proto"><namespace name="transform"><struct name="list"><template>
+ <template-type-parameter name="Grammar"/>
+ </template><struct name="apply"><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="State"/>
+ <template-type-parameter name="Visitor"/>
+ </template><typedef name="type"><type>fusion::cons< typename Grammar::template <classname>apply</classname>< Expr, State, Visitor >::type, State ></type></typedef></struct><method-group name="public member functions"/><constructor/><method-group name="public static functions"><method name="call" cv=""><type>static <classname>apply</classname>< Expr, State, Visitor >::type</type><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="State"/>
+ <template-type-parameter name="Visitor"/>
+ </template><parameter name="expr"><paramtype>Expr const &</paramtype></parameter><parameter name="state"><paramtype>State const &</paramtype></parameter><parameter name="visitor"><paramtype>Visitor &</paramtype></parameter></method></method-group></struct><struct name="tail"><template>
+ <template-type-parameter name="Grammar"/>
+ </template><struct name="apply"><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="State"/>
+ <template-type-parameter name="Visitor"/>
+ </template><typedef name="type"><type>Grammar::template <classname>apply</classname>< Expr, State, Visitor >::type::cdr_type</type></typedef></struct><method-group name="public member functions"/><constructor/><method-group name="public static functions"><method name="call" cv=""><type>static <classname>apply</classname>< Expr, State, Visitor >::type</type><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="State"/>
+ <template-type-parameter name="Visitor"/>
+ </template><parameter name="expr"><paramtype>Expr const &</paramtype></parameter><parameter name="state"><paramtype>State const &</paramtype></parameter><parameter name="visitor"><paramtype>Visitor &</paramtype></parameter></method></method-group></struct></namespace></namespace></namespace></header><header name="boost/xpressive/proto/transform/pass_through.hpp"><para>TODO </para><namespace name="boost"><namespace name="proto"><namespace name="has_transformns_"><struct name="has_pass_through_transform"><template>
+ <template-type-parameter name="Grammar"/>
+ </template><struct name="apply"><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="State"/>
+ <template-type-parameter name="Visitor"/>
+ </template></struct><method-group name="public member functions"/><constructor/><method-group name="public static functions"><method name="call" cv=""><type>static <classname>apply</classname>< Expr, State, Visitor >::type</type><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="State"/>
+ <template-type-parameter name="Visitor"/>
+ </template><parameter name="expr"><paramtype>Expr const &</paramtype></parameter><parameter name="state"><paramtype>State const &</paramtype></parameter><parameter name="visitor"><paramtype>Visitor &</paramtype></parameter></method></method-group></struct></namespace><namespace name="transform"><struct name="pass_through"><template>
+ <template-type-parameter name="Grammar"/>
+ </template><struct name="apply"><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="State"/>
+ <template-type-parameter name="Visitor"/>
+ </template></struct><method-group name="public member functions"/><constructor/><method-group name="public static functions"><method name="call" cv=""><type>static <classname>apply</classname>< Expr, State, Visitor >::type</type><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="State"/>
+ <template-type-parameter name="Visitor"/>
+ </template><parameter name="expr"><paramtype>Expr const &</paramtype></parameter><parameter name="state"><paramtype>State const &</paramtype></parameter><parameter name="visitor"><paramtype>Visitor &</paramtype></parameter></method></method-group></struct></namespace></namespace></namespace></header></library-reference>
Added: branches/proto/v3/libs/xpressive/proto3/doc/quick_start.qbk
==============================================================================
--- (empty file)
+++ branches/proto/v3/libs/xpressive/proto3/doc/quick_start.qbk 2007-11-07 17:03:47 EST (Wed, 07 Nov 2007)
@@ -0,0 +1,81 @@
+[/
+ / Copyright (c) 2006 Eric Niebler
+ /
+ / Distributed under the Boost Software License, Version 1.0. (See accompanying
+ / file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+ /]
+
+[section Hello World]
+
+Below is a very simple program that uses Proto to build an expression template
+and then execute it.
+
+ #include <iostream>
+ #include <boost/xpressive/proto/proto.hpp>
+ #include <boost/xpressive/proto/context.hpp>
+ #include <boost/typeof/std/ostream.hpp>
+ using namespace boost;
+
+ proto::terminal< std::ostream & >::type cout_ = { std::cout };
+
+ template< typename Expr >
+ void evaluate( Expr const & expr )
+ {
+ proto::default_context ctx;
+ proto::eval(expr, ctx);
+ }
+
+ int main()
+ {
+ evaluate( cout_ << "hello" << ',' << " world" );
+ return 0;
+ }
+
+This program outputs the following:
+
+[pre
+hello, world
+]
+
+This program builds an object representing the output operation and passes
+it to an `evaluate()` function, which then executes it.
+
+The basic idea of expression templates is to overload all the operators so
+that, rather than evaluating the expression immediately, they build a tree-like
+representation of the expression so that it can be evaluated later. For each
+operator in an expression, at least one operand must be Proto-ified in order
+for Proto's operator overloads to be found. In the expression ...
+
+ cout_ << "hello" << ',' << " world"
+
+... the Proto-ified sub-expression is `cout_`, which is the Proto-ification of
+`std::cout`. The presence of `cout_` "infects" the expression, and brings
+Proto's tree-building operator overloads into consideration. Any literals in
+the expression are then Proto-ified by wrapping them in a Proto terminal before
+they are combined into larger Proto expressions.
+
+Once Proto's operator overloads have built the expression tree, the expression
+can be lazily evaluated later by walking the tree. That is what `proto::eval()`
+does. It is a general tree-walking expression evaluator, whose behavior is
+customizable via a /context/ parameter. The use of _default_context_ assigns
+the standard meanings to the operators in the expression. (By using a different
+context, you could give the operators in your expressions different semantics.
+By default, Proto makes no assumptions about what operators actually /mean/.)
+
+[note [*Proto Design Philosophy]
+
+Before we continue, let's use the above example to illustrate an important
+design principle of Proto's. The expression template created in the ['hello
+world] example is totally general and abstract. It is not tied in any way to
+any particular domain or application, nor does it have any particular meaning
+or behavior on its own, until it is evaluated in a /context/. Expression
+templates are really just heterogeneous trees, which might mean something in
+one domain, and something else entirely in a different one.
+
+As we'll see later, there is a way to create Proto expression trees that are
+['not] purely abstract, and that have meaning and behaviors independent of any
+context. There is also a way to control which operators are overloaded for your
+particular domain. But that is not the default behavior. We'll see later why
+the default is often a good thing.]
+
+[endsect]
Added: branches/proto/v3/libs/xpressive/proto3/doc/rationale.qbk
==============================================================================
--- (empty file)
+++ branches/proto/v3/libs/xpressive/proto3/doc/rationale.qbk 2007-11-07 17:03:47 EST (Wed, 07 Nov 2007)
@@ -0,0 +1,27 @@
+[/
+ / Copyright (c) 2006 Eric Niebler
+ /
+ / Distributed under the Boost Software License, Version 1.0. (See accompanying
+ / file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+ /]
+
+[section:rationale Appendix B: Rationale]
+
+[section:static_initialization Static Initialization]
+
+Proto expression types are PODs (Plain Old Data), and do not have constructors.
+They are brace-initialized, as follows:
+
+ terminal<int>::type const _i = {1};
+
+The reason is so that expression objects like `_i` above can be ['statically
+initialized]. Why is static initialization important? The terminals of many
+domain-specific embedded languages are likely to be global const objects, like
+`_1` and `_2` from the Boost.Lambda library. Were these object to require
+run-time initialization, it might be possible to use these objects before they
+are initialized. That would be bad. Statically initialized objects cannot be
+misused that way.
+
+[endsect]
+
+[endsect]
Added: branches/proto/v3/libs/xpressive/proto3/doc/transforms.qbk
==============================================================================
--- (empty file)
+++ branches/proto/v3/libs/xpressive/proto3/doc/transforms.qbk 2007-11-07 17:03:47 EST (Wed, 07 Nov 2007)
@@ -0,0 +1,925 @@
+[/
+ / Copyright (c) 2006 Eric Niebler
+ /
+ / Distributed under the Boost Software License, Version 1.0. (See accompanying
+ / file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+ /]
+
+[import ../test/examples.cpp]
+
+[/==========================================================]
+[section:expression_transformation Expression Transformation]
+[/==========================================================]
+
+Sometimes, rather than immediately executing an expression template, you'd
+like to transform it into some other object. Maybe the transformation is simple,
+like converting all references into values. Maybe it's complicated, like
+transforming an expression template into a finite-state automata for matching a
+regular expression. Proto provides a framework for applying tree
+transformations and several canned transformations that are generally useful.
+
+[/===============]
+[heading Overview]
+[/===============]
+
+Defining tree transformations involves defining the grammar for your DSEL
+and decorating it with transformations. Each rule in your grammar will
+have an associated transform describing how sub-expressions matching that rule
+are to be transformed. Just as the grammar is defined recursively, so too
+is the tree transformation.
+
+A grammar decorated with transforms has a static member function named
+`call()` which takes three parameters:
+
+* `expr` -- the expression to transform
+* `state` -- the state of the transformation so far
+* `visitor` -- any optional auxiliary mutable state information
+
+It also has a nested `apply<>` template which is used to calculate the return
+type of the `call()` member function.
+
+Let's say we have a grammar called `Grammar`, an expression template
+object called `expr` that matches the grammar, and `state` and `visitor`
+objects of your choosing. What happens when you call
+`Grammar::call(expr, state, visitor)`? Well, if `Grammar` were defined as
+`shift_right< Rule1, Rule2 >`, for instance, it might transform the left
+child of `expr` according to `Rule1`'s transform, do the same thing to the
+right child using `Rule2`, and combine the results somehow. Of course, `Rule1`
+and `Rule2` might be defined in terms of other rules with other transforms, so
+the process executes recursively. Some transforms, the `fold<>` in particular,
+use the result of transforming one child as the `state` parameter when
+transforming the other child. In this way, the results of the recursive
+transformations can be accumulated bottom-up.
+
+That's it, in a nutshell. Now let's crack this nut and peek inside.
+
+[/==========================================]
+[section Example: Calculator Arity Transform]
+[/==========================================]
+
+Let's have another look at our trusty calculator example. If you recall, the
+calculator allows the lazy evaluation of arithmetic expressions, with
+placeholders substituted with actual values provided at evaluation time. Valid
+expressions are of the form:
+
+ (_1 + 3)
+ (_2 - _1) / _2 * 100
+
+... and so on. In the first expression, one argument must be provided before
+the expression can be evaluated. In the second, two arguments are needed. We
+could say the /arity/ of the first expression is one and of the second is two.
+The arity is determined by the highest placeholder in the expression. Our job
+will be to write a transform that calculates the arity of any calculator
+expression.
+
+[/=========================]
+[heading Defining a Grammar]
+[/=========================]
+
+First, we must write the grammar for the calculator. It's really very simple.
+Calculator expression can be made up of any combination of 5 constituents:
+
+* Placeholder 1
+* Placeholder 2
+* A literal
+* Unary operations
+* Binary operations
+
+We can immediately write the calculator grammar as follows:
+
+[CalculatorGrammar]
+
+We can read this as follows: a calculator expression is either placeholder 1,
+placeholder 2, some other terminal, or some unary or binary operator whose
+operands are calculator expressions. Recall that `proto::_` is a wildcard which
+matches anything. So `terminal< _ >` will match any terminal, and
+`unary_expr< _, CalculatorGrammar >` will match any unary expression
+for which the operand matches CalculatorGrammar (the `_` matches any operator
+tag).
+
+[/============================]
+[heading Writing the Transform]
+[/============================]
+
+It's straightforward to describe in words how the arity of an expression should
+be calculated. First, we describe the arity of each of the 5 constituents in
+the calculator grammar.
+
+[table Calculator Sub-Expression Arities
+ [[Sub-Expression] [Arity]]
+ [[Placeholder 1] [`1`]]
+ [[Placeholder 2] [`2`]]
+ [[Literal] [`0`]]
+ [[Unary Expression] [ /arity of the operand/ ]]
+ [[Binary Expression] [ /max arity of the two operands/ ]]
+]
+
+The total arity of a calculator expression is found by recursively evaluating
+the arity of all of the sub-expressions and taking the maximum.
+
+Let's look at the sub-expression for placeholder 1. It is matched by this part
+of our grammar: `terminal< placeholder1 >`. We want to associate this
+part of our grammar with an arity of `1`. We do that by attaching a transform.
+Since the arity of an expression can be evaluated at compile time, let's use
+`mpl::int_<1>` to represent the arity of the first placeholder. The following
+attaches a transform that always evaluates to `mpl::int_<1>`:
+
+ transform::always< terminal< placeholder1 >, mpl::int_<1> >
+
+This grammar rule will match any `placeholder1` terminal, and will transform it
+to `mpl::int_<1>`. Likewise, we will use the `transform::always<>` transform to
+transform `placeholder2` terminals into `mpl::int_<2>`, and other terminals
+into `mpl::int_<0>`.
+
+Next, let's write a transform for unary operators that returns the arity of the
+operand. It is simply:
+
+ transform::arg< unary_expr< _, CalculatorGrammar > >
+
+As you might expect, the `transform::arg<>` transform returns the argument of the
+unary expression. This looks simple, but there is quite a lot going on here.
+
+First, you should know that transforms are written so that they can be chained.
+So `transform::arg<>` invokes the transform associated with
+`unary_expr< _, CalculatorGrammar >` before it does anything else.
+
+That begs the question, what does `unary_expr<>`'s transform do? Well,
+`unary_expr< _, CalculatorGrammar >` has a default transform
+associated with it. It is a /pass-through/ transform. When an expression
+of the form `expr< T, arg1< X > >` is passed to the transform, its `apply<>`
+member template will invoke the `CalculatorGrammar` transform (which we haven't
+completely defined yet -- patience) on `X` resulting in `Y`, and then
+reassemble the expression as `expr< T, arg1< Y > >`.
+
+[note You may have noticed that Proto types like `unary_expr<>` serve several
+different but related roles. In particular, `unary_expr<>` is ...
+
+... [*a meta-function]: `unary_expr<T, X>::type` is a typedef for
+`expr<T, args1<X> >`.
+
+... [*a grammar]: `unary_expr<U, Y>` is a simle grammar that matches
+`expr<T, args1<X> >` if an only if `U` is `T` or `proto::_`, and `Y` is a
+grammar that matches `X`.
+
+... [*a transform]: `unary_expr<U, Y>::apply<expr<T, args1<X> >, S, V>::type`
+applies `unary_expr<>`'s pass-through transform to `expr<T, args1<X> >` with
+state `S` and visitor `V`. The result is
+`expr<T, args1< Y::apply<X, S, V>::type > >`.
+]
+
+So, putting a few things together, consider the calculator expression `+_1`,
+which would have the following type:
+
+ expr< tag::posit, arg1<
+ expr< tag::terminal, arg0< placeholder1 > >
+ > >
+
+If we executed the `unary_expr< _, CalculatorGrammar >` transform on this
+expression, we would expect to get:
+
+ expr< tag::posit, arg1<
+ mpl::int_<1>
+ > >
+
+And if we added the `transform::arg<>` transform also, as in
+`transform::arg< unary_expr< _, CalculatorGrammar > >`, we expect the result
+to be:
+
+ mpl::int_<1>
+
+Which is exactly what we want.
+
+[note *Default Transforms*
+
+All the tools Proto provides for defining grammar rules have default transforms
+associated with them. Just as `unary_expr<>` has a pass-through transform,
+so too does `binary_expr<>`, `shift_right<>`, and all the others.
+`proto::or_<>` has a default transform which evaluates the transform of the
+branch that matched. `proto::and_<>`'s default transform evaluates the
+transform of the last branch. Even `proto::expr<>`, `proto::if_<>`,
+`proto::not_<>`, and `proto::_` have no-op default transforms that simply return
+unmodified the expressions passed to them.
+]
+
+The arity of a binary operator is the maximum of the arity of the left and
+right operands. Proto does not provide a transform that can help us directly,
+but we can easily write our own. This is what it looks like, and we'll describe
+it below:
+
+[binary_max]
+
+This transform will be used as follows:
+`binary_max< binary_expr< _, CalculatorGrammar, CalculatorGrammar > >`.
+First, note that the transform is a template that takes a Grammar as a template
+parameter. It inherits from the Grammar, as all transforms must. Next, we
+define a nested `apply<>` template which calculates the return type. The first
+thing it does is invoke `Grammar`'s transform. Recall that `binary_expr<>`
+has a pass-through transform. Given an expression like
+`expr< T, arg2< A, B > >`, it transforms it to `expr< T, arg2< X, Y > >`, where
+`X` and `Y` are the results of transforming `A` and `B` according to
+`CalculatorGrammar`.
+
+Next, we extract from this transformed binary expression the left and right
+argument types. As the arguments were transformed in the previous step, we
+expect them to already be of the form `mpl::int_<N>`. Then we use `mpl::max<>`
+to find the maximum, and we're done.
+
+The static `call()` member function is needed to complete the transform
+interface. It simply returns a default-constructed object, which will be an
+instantiation of `mpl::int_<>`.
+
+Piecing it all together, the complete `CalculatorGrammar` looks like this:
+
+[CalculatorArityGrammar]
+
+We can use our CalculatorGrammar transform to calculate the arity of any
+calculator expression:
+
+ int i = 0; // not used, dummy state and visitor parameter
+
+ std::cout << CalculatorGrammar::call( lit(100) * 200, i, i) << '\n';
+ std::cout << CalculatorGrammar::call( (_1 - _1) / _1 * 100, i, i) << '\n';
+ std::cout << CalculatorGrammar::call( (_2 - _1) / _2 * 100, i, i) << '\n';
+
+This displays the following:
+
+[pre
+0
+1
+2
+]
+
+(Aside: this uses the fact that `mpl::int_<1>` has a conversion to `int(1)`.)
+
+[endsect]
+
+[/========================]
+[section Canned Transforms]
+[/========================]
+
+Some transforms are generally useful, so Proto provides them. They are
+described below. Each is of the form:
+
+ boost::proto::transform::``[~transform-name]``< Grammar ``[~\[, additional args ...\]]`` >
+
+They each inherit from their `Grammar` parameter; therefore, they themselves
+match the same expressions as `Grammar` does. As transforms, they all have
+nested static `call()` member functions that accept `expr`, `state`, and
+`visitor` parameters, as well as `apply<>` member templates for calculating
+the return type of `call()`. The tables below show what `call()` and `apply<>`
+do for each of the transforms that Proto provides.
+
+[section:arg_c_and_friends [^arg<>], [^arc_c<>], [^left<>] and [^right<>]]
+
+ namespace boost { namespace proto { namespace transform
+ {
+ template<typename Grammar, typename N = mpl::long_<0> >
+ struct arg;
+
+ template<typename Grammar, long N>
+ struct arg_c;
+
+ template<typename Grammar>
+ struct left;
+
+ template<typename Grammar>
+ struct right;
+ }}}
+
+These transforms are useful for extracting the ['[^N]]th argument from an
+expression. The `left<Grammar>` transform is equivalent to the
+`arg_c<Grammar, 0>` transform, and the `right<Grammar>` transform is equivalent
+to the `arg_c<Grammar, 1>` transform.
+
+[table
+ [ [Expression]
+ [Returns]
+ ]
+ [ [`transform::arg<Grammar, N>::apply<Expr, State, Visitor>::type`]
+ [`proto::result_of::arg<typename Grammar::apply<Expr, State, Visitor>::type, N>::type`]
+ ]
+ [ [`transform::arg<Grammar, N>::call(expr, state, visitor)`]
+ [`proto::arg<N>(Grammar::call(expr, state, visitor))`]
+ ]
+ [ [`transform::arg_c<Grammar, N>::apply<Expr, State, Visitor>::type`]
+ [`proto::result_of::arg_c<typename Grammar::apply<Expr, State, Visitor>::type, N>::type`]
+ ]
+ [ [`transform::arg_c<Grammar, N>::call(expr, state, visitor)`]
+ [`proto::arg_c<N>(Grammar::call(expr, state, visitor))`]
+ ]
+ [ [`transform::left<Grammar>::apply<Expr, State, Visitor>::type`]
+ [`proto::result_of::left<typename Grammar::apply<Expr, State, Visitor>::type>::type`]
+ ]
+ [ [`transform::left<Grammar>::call(expr, state, visitor)`]
+ [`proto::left(Grammar::call(expr, state, visitor))`]
+ ]
+ [ [`transform::right<Grammar>::apply<Expr, State, Visitor>::type`]
+ [`proto::result_of::right<typename Grammar::apply<Expr, State, Visitor>::type>::type`]
+ ]
+ [ [`transform::right<Grammar>::call(expr, state, visitor)`]
+ [`proto::right(Grammar::call(expr, state, visitor))`]
+ ]
+]
+
+Example:
+
+ // Matches an integer terminal and extracts the int.
+ struct Int
+ : transform::arg< terminal<int> >
+ {};
+
+[endsect]
+
+[section:identity_and_friends [^identity<>], [^state<>] and [^visitor<>]]
+
+ namespace boost { namespace proto { namespace transform
+ {
+ template<typename Grammar>
+ struct identity;
+
+ template<typename Grammar>
+ struct state;
+
+ template<typename Grammar>
+ struct visitor;
+ }}}
+
+The `identity<>`, `state<>` and `visitor<>` transforms merely return the
+`expr`, `state` and `visitor` arguments, respectively.
+
+[table
+ [ [Expression]
+ [Returns]
+ ]
+ [ [`transform::identity<Grammar>::apply<Expr, State, Visitor>::type`]
+ [`Expr`]
+ ]
+ [ [`transform::identity<Grammar>::call(expr, state, visitor)`]
+ [`expr`]
+ ]
+ [ [`transform::state<Grammar>::apply<Expr, State, Visitor>::type`]
+ [`State`]
+ ]
+ [ [`transform::state<Grammar>::call(expr, state, visitor)`]
+ [`state`]
+ ]
+ [ [`transform::visitor<Grammar>::apply<Expr, State, Visitor>::type`]
+ [`Visitor`]
+ ]
+ [ [`transform::visitor<Grammar>::call(expr, state, visitor)`]
+ [`visitor`]
+ ]
+]
+
+Example:
+
+ // Matches a subscript expression where the left- and right-hand operands
+ // match MyGrammar, returns the expression unmodified; that is, without
+ // applying MyGrammar's transforms to the left and right operands, as would
+ // happen by default.
+ struct Subscript
+ : transform::identity< subscript<MyGrammar, MyGrammar> >
+ {};
+
+[endsect]
+
+[section:always [^always<>]]
+
+ namespace boost { namespace proto { namespace transform
+ {
+ template<typename Grammar, typename Always, typename Factory = ``[~default-factory]``>
+ struct always;
+ }}}
+
+The `always<>` transform always returns a certain type. By default, its
+`call()` member returns a default constructed object of that type, but you can
+configure this with the optional `Factory` parameter.
+
+[table
+ [ [Expression]
+ [Returns]
+ ]
+ [ [`transform::always<Grammar, Type, Factory>::apply<Expr, State, Visitor>::type`]
+ [`Type`]
+ ]
+ [ [`transform::always<Grammar, Type, Factory>::call(expr, state, visitor)`]
+ [`Factory()()`]
+ ]
+]
+
+Example:
+
+ // Match a placeholder terminal and return the arity of the
+ // placeholder.
+ struct PlaceholderArity
+ : transform::always< terminal<placeholder1>, mpl::int_<1> >
+ {};
+
+[endsect]
+
+[section:applyn [^apply1<>], [^apply2<>] and [^apply3<>]]
+
+ namespace boost { namespace proto { namespace transform
+ {
+ template<typename Grammar, typename Lambda, typename Factory = ``[~default-factory]``>
+ struct apply1;
+
+ template<typename Grammar, typename Lambda, typename Factory = ``[~default-factory]``>
+ struct apply2;
+
+ template<typename Grammar, typename Lambda, typename Factory = ``[~default-factory]``>
+ struct apply3;
+ }}}
+
+The `apply1<>` transform invokes an MPL lambda expression with the Proto
+expression as the argument, `apply2<>` uses the expression and the state
+as arguments and `apply3<>` uses the expression, state and visitor.
+
+[table
+ [ [Expression]
+ [Returns]
+ ]
+ [ [`transform::apply1<Grammar, Lambda, Factory>::apply<Expr, State, Visitor>::type`]
+ [`mpl::apply1<Lambda, typename Grammar::apply<Expr, State, Visitor>::type>::type`]
+ ]
+ [ [`transform::apply1<Grammar, Lambda, Factory>::call(expr, state, visitor)`]
+ [`Factory()(Grammar::call(expr, state, visitor))`]
+ ]
+ [ [`transform::apply2<Grammar, Lambda, Factory>::apply<Expr, State, Visitor>::type`]
+ [`mpl::apply2<Lambda, typename Grammar::apply<Expr, State, Visitor>::type, State>::type`]
+ ]
+ [ [`transform::apply2<Grammar, Lambda, Factory>::call(expr, state, visitor)`]
+ [`Factory()(Grammar::call(expr, state, visitor), state)`]
+ ]
+ [ [`transform::apply3<Grammar, Lambda, Factory>::apply<Expr, State, Visitor>::type`]
+ [`mpl::apply3<Lambda, typename Grammar::apply<Expr, State, Visitor>::type, State, Visitor>::type`]
+ ]
+ [ [`transform::apply3<Grammar, Lambda, Factory>::call(expr, state, visitor)`]
+ [`Factory()(Grammar::call(expr, state, visitor), state, visitor)`]
+ ]
+]
+
+The `call()` member functions of Proto's `applyN<>` transforms simply return a
+default constructed object of the appropriate type by default. If you want a
+different behavior, you can specify a `Factory` type as the third template
+parameter.
+
+Example:
+
+ // Another way to implement a transform that calculates the arity of a
+ // binary Calculator expression. This code is functionally equivalent to
+ // the binary_max<> transform defined above. The mpl::max<...> type below
+ // is an MPL Placeholder expression (note the use of mpl::_) that
+ // mpl::apply1<> knows how to evaluate. The effect of the
+ // BinaryCalculatorArity grammar is to match binary Calculator expressions,
+ // evaluate the arity of the left and right sub-expressions and return the
+ // maximum of the two.
+ struct BinaryCalculatorArity
+ : transform::apply1<
+ binary_expr<_, CalculatorArity, CalculatorArity>
+ , mpl::max<result_of::left<mpl::_>, result_of::right<mpl::_> >
+ >
+ {};
+
+[endsect]
+
+[section:branch [^branch<>]]
+
+ namespace boost { namespace proto { namespace transform
+ {
+ template<typename Grammar, typename BranchState>
+ struct branch;
+ }}}
+
+The `branch<>` transform applies `Grammar`'s transform with a new `state`
+parameter. This is useful when you want to compile a branch of the expression
+tree independently of the rest; for example, when you want to fold everything
+under a certain child node into a list.
+
+[table
+ [ [Expression]
+ [Returns]
+ ]
+ [ [`transform::branch<Grammar, BranchState>::apply<Expr, State, Visitor>::type`]
+ [`typename Grammar::template apply<Expr, BranchState, Visitor>::type`]
+ ]
+ [ [`transform::branch<Grammar, BranchState>::call(expr, state, visitor)`]
+ [`Grammar::call(expr, BranchState(), visitor)`]
+ ]
+]
+
+Example:
+
+See the [link reverse_fold_example [^reverse_fold<>] example].
+
+[endsect]
+
+[section:compose [^compose<>]]
+
+ namespace boost { namespace proto { namespace transform
+ {
+ template<typename Grammar1, typename Grammar2>
+ struct compose;
+ }}}
+
+The `compose<>` transform applies two transformations in succession. It
+inherits from `Grammar1`, so it matches whatever `Grammar1` matches. The
+result of applying `Grammar1`'s transform is passed to `Grammar2`'s transform,
+along with the `state` and `visitor` parameters. It is assumed that the
+result of applying `Grammar1`'s transform is an expression that matches
+the grammar specified by `Grammar2`.
+
+The `compose<>` transform is useful in situations where you would like to
+preprocess a node in the expression tree before forwarding it on for further
+processing.
+
+[table
+ [ [Expression]
+ [Returns]
+ ]
+ [ [`transform::compose<Grammar1, Grammar2>::apply<Expr, State, Visitor>::type`]
+ [``typename Grammar2::template apply<
+ typename Grammar1::template apply<Expr, State, Visitor>::type
+ , State
+ , Visitor
+>::type``]
+ ]
+ [ [`transform::compose<Grammar1, Grammar2>::call(expr, state, visitor)`]
+ [``Grammar2::call(
+ Grammar1::call(expr, state, visitor), state, visitor)``]
+ ]
+]
+
+Example:
+
+ // A fragment of a Calculator grammar which uses compose<> to process
+ // a node in the expression tree after it has been preprocessed by
+ // an arg<> transform.
+ struct Calculator
+ : or_<
+ // ...
+ transform::compose<
+ // Match anything of the form +X, and
+ // extract X, discarding the +.
+ transform::arg<posit<_> >
+ // Now invoke the Calculator transform on X
+ , Calculator
+ >
+ >
+ {};
+
+[endsect]
+
+[section:list [^list<>]]
+
+ namespace boost { namespace proto { namespace transform
+ {
+ template<typename Grammar>
+ struct list;
+ }}}
+
+`list<>` is a simple transform that builds a fusion cons list, using the
+transformed expression as the list's head, and the state as the list's tail.
+
+[table
+ [ [Expression]
+ [Returns]
+ ]
+ [ [`transform::list<Grammar>::apply<Expr, State, Visitor>::type`]
+ [``fusion::cons<
+ typename Grammar::template apply<Expr, State, Visitor>::type
+ , State
+>``]
+ ]
+ [ [`transform::list<Grammar>::call(expr, state, visitor)`]
+ [``fusion::cons<
+ typename Grammar::template apply<Expr, State, Visitor>::type
+ , State
+>(Grammar::call(expr, state, visitor), state)``]
+ ]
+]
+
+Example:
+
+See the [link reverse_fold_example [^reverse_fold<>] example].
+
+[endsect]
+
+[section:fold [^fold<>] and [^reverse_fold<>]]
+
+ namespace boost { namespace proto { namespace transform
+ {
+ template<typename Grammar, typename State = void>
+ struct fold;
+
+ template<typename Grammar, typename State = void>
+ struct reverse_fold;
+ }}}
+
+The transforms `fold<>` and `reverse_fold<>` are akin to the
+`std::accumulate()` algorithm in the STL. They iterate over some sequence and
+accumulate some state at each element. For Proto's `fold<>` and
+`reverse_fold<>`, the "elements" of the sequence are actually pairs consisting
+of the corresponding child grammars and expressions. The state is accumulated
+by applying the child grammar's transform to the corresponding child
+expression. The result of one transform is used as the state of the next
+transform, such that the transforms nest like Russian dolls. The `fold<>`
+transform iterates over the children in order, starting with the 0th child.
+The `reverse_fold<>` transform does it in reverse order, starting with the Nth
+child. (Note that for building things like cons lists, you'll often want to
+built it back-to-front with `reverse_fold<>`.)
+
+[def __arg_N__ proto_arg[~N]]
+[def __arg_N_sub_1__ proto_arg[~N-1]]
+
+[table
+ [ [Expression]
+ [Returns]
+ ]
+ [ [`transform::fold<Grammar>::apply<Expr, State, Visitor>::type`]
+ [``typename Grammar::__arg_N__::apply<
+ typename Expr::__arg_N__::proto_base_expr
+ , typename Grammar::__arg_N_sub_1__::apply<
+ typename Expr::__arg_N_sub_1__::proto_base_expr
+ , // ...
+ typename Grammar::proto_arg0::apply<
+ typename Expr::proto_arg0::proto_base_expr, State, Visitor>::type
+ // ...
+ , Visitor
+ >::type
+ , Visitor
+>::type``]
+ ]
+ [ [`transform::fold<Grammar>::call(expr, state, visitor)`]
+ [``Grammar::__arg_N__::call(
+ proto::arg_c<N>(expr)
+ , Grammar::__arg_N_sub_1__::call(
+ proto::arg_c<N-1>(expr)
+ , // ...
+ Grammar::proto_arg0::call(
+ proto::arg_c<0>(expr), state, visitor)
+ // ...
+ , visitor
+ )
+ , visitor
+)``]
+ ]
+ [ [`transform::reverse_fold<Grammar>::apply<Expr, State, Visitor>::type`]
+ [``typename Grammar::proto_arg0::apply<
+ typename Expr::proto_arg0::proto_base_expr
+ , typename Grammar::proto_arg1::apply<
+ typename Expr::proto_arg1::proto_base_expr
+ , // ...
+ typename Grammar::__arg_N__::apply<
+ typename Expr::__arg_N__::proto_base_expr, State, Visitor>::type
+ // ...
+ , Visitor
+ >::type
+ , Visitor
+>::type``]
+ ]
+ [ [`transform::reverse_fold<Grammar>::call(expr, state, visitor)`]
+ [``Grammar::proto_arg0::call(
+ proto::arg_c<0>(expr)
+ , Grammar::proto_arg1::call(
+ proto::arg_c<1>(expr)
+ , // ...
+ Grammar::__arg_N__::call(
+ proto::arg_c<N>(expr), state, visitor)
+ // ...
+ , visitor
+ )
+ , visitor
+)``]
+ ]
+]
+
+Both the `fold<>` and `reverse_fold<>` transforms take an optional `State`
+template parameter. For non-`void` `State` parameters, the following
+equivalances hold:
+
+[table fold<> and reverse_fold<> Equivalencies
+ [[Short-Cut Grammar] [Equivalent Grammar]]
+ [[`transform::fold<Grammar, State>`] [``transform::branch<
+ transform::fold<Grammar>
+ , State
+>``]]
+ [[`transform::reverse_fold<Grammar, State>`][``transform::branch<
+ transform::reverse_fold<Grammar>
+ , State
+>``]]
+]
+
+[#reverse_fold_example]Example:
+
+[AsArgList]
+
+[endsect]
+
+[section:fold_tree [^fold_tree<>] and [^reverse_fold_tree<>]]
+
+ namespace boost { namespace proto { namespace transform
+ {
+ template<typename Tag, typename Grammar, typename State = void>
+ struct fold_tree;
+
+ template<typename Tag, typename Grammar, typename State = void>
+ struct reverse_fold_tree;
+ }}}
+
+The `fold_tree<>` and `reverse_fold_tree<>` transforms recursively apply the
+`fold<>` and `reverse_fold<>` transforms to sub-trees that all share a common
+`Tag` type. This is useful for flattening trees into lists; for example, you
+might use `reverse_fold_tree<>` to flatten an expression tree like `a | b | c`
+into a Fusion list like `cons(a, cons(b, cons(c)))`.
+
+The `fold_tree<>` and `reverse_fold_tree<>` transforms are unlike the other
+transforms that Proto provides in that they operate on entire sub-trees rather
+than just single nodes within the tree. As a result, their interface is
+different. The `Tag` parameter is the type of the operator tag that behaves
+like a separator. The `Grammar` parameter represents that grammar that the
+separated sub-expressions must match, and the transform that will be applied
+to each. The optional `State` parameter is the initial state of the transform.
+
+These are higher-level transforms, implemented in terms of the `fold<>`
+transform. They are probably best understood in terms of their definition,
+which is fairly small.
+
+ namespace detail
+ {
+ // fold_tree_ either recurses into the expression, if its Tag
+ // matches, or else ends the recursion by matching Grammar and
+ // applying its transform.
+ template<typename Tag, typename Grammar>
+ struct fold_tree_
+ : or_<
+ transform::fold<
+ nary_expr<Tag, vararg<fold_tree_<Tag, Grammar> > >
+ >
+ , Grammar
+ >
+ {};
+ }
+
+ template<typename Tag, typename Grammar, typename State = void>
+ struct fold_tree
+ : transform::fold<
+ nary_expr<Tag, vararg<detail::fold_tree_<Tag, Grammar> > >
+ , State
+ >
+ {};
+
+The `reverse_fold_tree<>` transform is specified similarly, only with
+`reverse_fold<>` instead of `fold<>`.
+
+Example:
+
+[FoldTreeToList]
+
+[endsect]
+
+[section:construct [^construct<>]]
+
+ namespace boost { namespace proto { namespace transform
+ {
+ template<typename Grammar, typename Constructor>
+ struct construct;
+ }}}
+
+The `construct<>` transform is a flexible tool for transforming expressions
+into other types of objects. With it, you can specify both the type of the
+object to construct as well as what parameters to pass to its constructor. A
+typical usage of the `construct<>` transform is like this:
+
+ transform::construct<
+ terminal<float>
+ , terminal<double>::type(transform::arg<_>)
+ >
+
+The first template parameter is the grammar to match; in this case, terminals
+of type `float`. The second template parameter might look a little strange. It
+is actually a function type, but here we're using it to describe what object to
+construct and how to initialize it. In this case, we will be constructing a
+`double` terminal, using the argument from the `float` terminal. This transform
+effectively promotes a `float` to a `double`.
+
+The `Constructor` template parameter is a function type of the following form:
+
+ ResultType(Transform1, Transform2, ...)
+
+where `Transform1`, `Transform2`, etc, are Proto transforms. They specify what
+arguments should be used to construct the `ResultType` object. The way it works
+is as follows. Consider the transform `transform::construct<G, R(T)>`, and an
+expression object `e` of type `E` that matches `G`. Then the result will be an
+object of type `R` constructed like this:
+
+ E2 e2 = G::call(e, s, v);
+ R(T::call(e2, s, v));
+
+where `s` and `v` are some state and visitor parameters, and `E2` is the return
+type of `G::call(e,s,v)`. Note that `G`'s transform is applied first, followed
+by `T`'s transform.
+
+The result type itself may be specified in terms of Proto transforms. In that
+case, the return type is the result of applying the transforms and substituting
+the transforms with the results. Consider the following code that matches an
+invocation of a lazy `make_pair_` function, and actually returns a
+`std::pair<>` of the correct type.
+
+[LazyMakePair]
+
+Notice that the result type, `std::pair<...>`, is specified in terms of Proto
+transforms. Notice also that Proto transforms are used to specify how to
+construct the `std::pair<>` object. We can now use the `MakePair` transform to
+convert a lazy `make_pair_()` function invocation into an actual `std::pair<>`:
+
+[LazyMakePairTest]
+
+The above code would display the following:
+
+[pre
+1
+3.14
+]
+
+When building the result type, if the result of applying a Proto transform is a
+type that has a nested `::type` member typedef, then that type is used instead.
+For instance, here is a transform that matches an integer and negates it lazily
+by wrapping it in a `negate<>` node.
+
+[NegateInt]
+
+The return type is `negate<_>`, but what is actually constructed is
+`negate<terminal<int>::type>::type`. This behavior should seem familiar if you
+have ever used MPL Placeholder expressions.
+
+The `construct<>` transform gives you a simple and convenient syntax for
+creating temporary sub-objects. In the `Constructor` expression
+`ResultType(Transform1, Transform2)`, if the type of `Transform1` is a function
+type, then it is converted into the transform `construct<_, Transform1>`. The
+following example demonstrates how to match an integer, promote it to a long
+integer, and lazily square it.
+
+[SquareAndPromoteInt]
+
+The "arguments" to the constructor are `terminal<long>::type(transform::arg<_>)`,
+which is short-cut syntax for a nested `construct<>` transform. [footnote The
+short-cut syntax for nested constructors does not work on MSVC due to compiler
+bugs.]
+
+[endsect]
+
+[section:pass_through [^pass_through<>]]
+
+ namespace boost { namespace proto { namespace transform
+ {
+ template<typename Grammar>
+ struct pass_through;
+ }}}
+
+The `pass_through<>` transform iterates over the pairs of
+children in the grammar and the expression, applying the child grammar's
+transform to the corresponding child expression. The resulting transformed
+children expressions are reassembled back into an expression of the same
+type as the parent expression.
+
+As a side-effect, `pass_through<>` transforms all sub-expressions held by
+reference into ones held by value.
+
+Note that all expression generator meta-functions (Eg., `posit<>`,
+`shift_right<>`, `function<>`, `nary_expr<>`, etc.) have a pass-through
+transform by default, so there is rarely any need to use the `pass_through<>`
+transform explicitly.
+
+[table
+ [ [Expression]
+ [Returns]
+ ]
+ [ [`transform::pass_through<Grammar>::apply<Expr, State, Visitor>::type`]
+ [``typename nary_expr<
+ typename Expr::proto_tag
+ , typename Grammar::proto_arg0::apply<typename Expr::proto_arg0::proto_base_expr, State, Visitor>::type
+ , typename Grammar::proto_arg1::apply<typename Expr::proto_arg1::proto_base_expr, State, Visitor>::type
+ // ...
+ , typename Grammar::__arg_N__::apply<typename Expr::__arg_N__::proto_base_expr, State, Visitor>::type
+>::type``]
+ ]
+ [ [`transform::pass_through<Grammar>::call(expr, state, visitor)`]
+ [``transform::pass_through<Grammar>::apply<Expr, State, Visitor>::type::make(
+ Grammar::proto_arg0::call(proto::arg_c<0>(expr), state, visitor)
+ , Grammar::proto_arg1::call(proto::arg_c<1>(expr), state, visitor)
+ // ...
+ , Grammar::__arg_N__::call(proto::arg_c<N>(expr), state, visitor)
+)``]
+ ]
+]
+
+Example:
+
+[Promote]
+
+[endsect]
+
+[endsect]
+
+[endsect]
Added: branches/proto/v3/libs/xpressive/proto3/example/Jamfile.v2
==============================================================================
--- (empty file)
+++ branches/proto/v3/libs/xpressive/proto3/example/Jamfile.v2 2007-11-07 17:03:47 EST (Wed, 07 Nov 2007)
@@ -0,0 +1,55 @@
+# (C) Copyright 2004: Eric Niebler
+# Distributed under the Boost Software License, Version 1.0.
+# (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+exe hello
+ :
+ hello.cpp
+ ;
+
+
+exe calc1
+ :
+ calc1.cpp
+ ;
+
+exe calc2
+ :
+ calc2.cpp
+ ;
+
+exe calc3
+ :
+ calc3.cpp
+ ;
+
+exe lazy_vector
+ :
+ lazy_vector.cpp
+ ;
+
+exe tarray
+ :
+ tarray.cpp
+ ;
+
+exe rgb
+ :
+ rgb.cpp
+ ;
+
+exe vec3
+ :
+ vec3.cpp
+ ;
+
+exe vector
+ :
+ vector.cpp
+ ;
+
+exe mixed
+ :
+ mixed.cpp
+ ;
+
Added: branches/proto/v3/libs/xpressive/proto3/example/calc1.cpp
==============================================================================
--- (empty file)
+++ branches/proto/v3/libs/xpressive/proto3/example/calc1.cpp 2007-11-07 17:03:47 EST (Wed, 07 Nov 2007)
@@ -0,0 +1,68 @@
+//[ Calc1
+// Copyright 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)
+//
+// This is a simple example of how to build an arithmetic expression
+// evaluator with placeholders.
+
+#include <iostream>
+#include <boost/mpl/int.hpp>
+#include <boost/xpressive/proto/proto.hpp>
+#include <boost/xpressive/proto/context.hpp>
+using namespace boost;
+
+template<typename I> struct arg {};
+
+// Define some placeholders
+proto::terminal< arg< mpl::int_<1> > >::type const _1 = {{}};
+proto::terminal< arg< mpl::int_<2> > >::type const _2 = {{}};
+
+// Define a calculator context, for evaluating arithmetic expressions
+struct calculator_context
+ : proto::callable_context< calculator_context const >
+{
+ // The values bound to the placeholders
+ double d[2];
+
+ // The result of evaluating arithmetic expressions
+ typedef double result_type;
+
+ explicit calculator_context(double d1 = 0., double d2 = 0.)
+ {
+ d[0] = d1;
+ d[1] = d2;
+ }
+
+ // Handle the evaluation of the placeholder terminals
+ template<typename I>
+ double operator()(proto::tag::terminal, arg<I>) const
+ {
+ return d[ I() - 1 ];
+ }
+};
+
+template<typename Expr>
+double evaluate( Expr const &expr, double d1 = 0., double d2 = 0. )
+{
+ // Create a calculator context with d1 and d2 substituted for _1 and _2
+ calculator_context const ctx(d1, d2);
+
+ // Evaluate the calculator expression with the calculator_context
+ return proto::eval(expr, ctx);
+}
+
+int main()
+{
+ // Displays "5"
+ std::cout << evaluate( _1 + 2.0, 3.0 ) << std::endl;
+
+ // Displays "6"
+ std::cout << evaluate( _1 * _2, 3.0, 2.0 ) << std::endl;
+
+ // Displays "1.5"
+ std::cout << evaluate( (_1 - _2) / _2, 3.0, 2.0 ) << std::endl;
+
+ return 0;
+}
+//]
Added: branches/proto/v3/libs/xpressive/proto3/example/calc2.cpp
==============================================================================
--- (empty file)
+++ branches/proto/v3/libs/xpressive/proto3/example/calc2.cpp 2007-11-07 17:03:47 EST (Wed, 07 Nov 2007)
@@ -0,0 +1,108 @@
+//[ Calc2
+// Copyright 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)
+//
+// This example enhances the simple arithmetic expression evaluator
+// in calc1.cpp by using proto::extends to make arithemetic
+// expressions immediately evaluatable with operator(), a-la a
+// function object
+
+#include <iostream>
+#include <boost/mpl/int.hpp>
+#include <boost/xpressive/proto/proto.hpp>
+#include <boost/xpressive/proto/context.hpp>
+using namespace boost;
+
+// Will be used to define the placeholders _1 and _2
+template<typename I> struct arg {};
+
+// For expressions in the calculator domain, operator()
+// will be special; it will evaluate the expression.
+struct calculator_domain;
+
+// Define a calculator context, for evaluating arithmetic expressions
+// (This is as before, in calc1.cpp)
+struct calculator_context
+ : proto::callable_context< calculator_context const >
+{
+ // The values bound to the placeholders
+ double d[2];
+
+ // The result of evaluating arithmetic expressions
+ typedef double result_type;
+
+ explicit calculator_context(double d1 = 0., double d2 = 0.)
+ {
+ d[0] = d1;
+ d[1] = d2;
+ }
+
+ // Handle the evaluation of the placeholder terminals
+ template<typename I>
+ double operator()(proto::tag::terminal, arg<I>) const
+ {
+ return d[ I() - 1 ];
+ }
+};
+
+// Wrap all calculator expressions in this type, which defines
+// operator() to evaluate the expression.
+template<typename Expr>
+struct calculator_expression
+ : proto::extends<Expr, calculator_expression<Expr>, calculator_domain>
+{
+ typedef
+ proto::extends<Expr, calculator_expression<Expr>, calculator_domain>
+ base_type;
+
+ explicit calculator_expression(Expr const &expr = Expr())
+ : base_type(expr)
+ {}
+
+ using base_type::operator=;
+
+ // Override operator() to evaluate the expression
+ double operator()() const
+ {
+ calculator_context const ctx;
+ return proto::eval(*this, ctx);
+ }
+
+ double operator()(double d1) const
+ {
+ calculator_context const ctx(d1);
+ return proto::eval(*this, ctx);
+ }
+
+ double operator()(double d1, double d2) const
+ {
+ calculator_context const ctx(d1, d2);
+ return proto::eval(*this, ctx);
+ }
+};
+
+// Tell proto how to generate expressions in the calculator_domain
+struct calculator_domain
+ : proto::domain<proto::generator<calculator_expression> >
+{};
+
+// Define some placeholders (notice they're wrapped in calculator_expression<>)
+calculator_expression<proto::terminal< arg< mpl::int_<1> > >::type> const _1;
+calculator_expression<proto::terminal< arg< mpl::int_<2> > >::type> const _2;
+
+// Now, our arithmetic expressions are immediately executable function objects:
+int main()
+{
+ // Displays "5"
+ std::cout << (_1 + 2.0)( 3.0 ) << std::endl;
+
+ // Displays "6"
+ std::cout << ( _1 * _2 )( 3.0, 2.0 ) << std::endl;
+
+ // Displays "1.5"
+ std::cout << ( (_1 - _2) / _2 )( 3.0, 2.0 ) << std::endl;
+
+ return 0;
+}
+//]
Added: branches/proto/v3/libs/xpressive/proto3/example/calc3.cpp
==============================================================================
--- (empty file)
+++ branches/proto/v3/libs/xpressive/proto3/example/calc3.cpp 2007-11-07 17:03:47 EST (Wed, 07 Nov 2007)
@@ -0,0 +1,226 @@
+//[ Calc3
+// Copyright 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)
+//
+// This example enhances the arithmetic expression evaluator
+// in calc2.cpp by using a proto transform to calculate the
+// number of arguments an expression requires and using a
+// compile-time assert to guarantee that the right number of
+// arguments are actually specified.
+
+#include <iostream>
+#include <boost/mpl/int.hpp>
+#include <boost/mpl/assert.hpp>
+#include <boost/mpl/min_max.hpp>
+#include <boost/xpressive/proto/proto.hpp>
+#include <boost/xpressive/proto/context.hpp>
+#include <boost/xpressive/proto/transform/arg.hpp>
+#include <boost/xpressive/proto/transform/fold.hpp>
+#include <boost/xpressive/proto/transform/apply.hpp>
+using namespace boost;
+
+// Will be used to define the placeholders _1 and _2
+template<typename I> struct arg { typedef I arity; };
+
+// A meta-function for getting a placeholder terminal's arity.
+template<typename Arg>
+struct arg_arity
+{
+ typedef typename Arg::arity type;
+};
+
+// A custom transform that fetches the arity of a placeholder terminal
+template<typename Grammar>
+struct placeholder_arity
+ : Grammar
+{
+ template<typename Expr, typename, typename>
+ struct apply
+ : arg_arity<typename proto::result_of::arg<Expr>::type>
+ {};
+
+ //// If this transform had a runtime counterpart, it would look like this:
+ //template<typename Expr, typename State, typename Visitor>
+ //static typename apply<Expr, State, Visitor>::type
+ //call(Expr const &expr, State const &state, Visitor &visitor)
+ //{
+ // ... do stuff ...
+ //}
+};
+
+// A custom transforms for calculating the max arity of a calculator expression
+template<typename Grammar>
+struct max_arity
+ : Grammar
+{
+ template<typename Expr, typename State, typename Visitor>
+ struct apply
+ {
+ // Calculate the arity of the current expression.
+ typedef typename Grammar::template apply<Expr, State, Visitor>::type arity;
+ // The old maximum is passed along in the State parameter by
+ // proto::transform::fold<> (see below). The new maximum is the
+ // larger of the old maximum and the arity we just calculated.
+ typedef typename mpl::max<arity, State>::type type;
+ };
+
+ // As with placeholder_arity<> above, placeholder_arity<> has no need
+ // for a call() member function.
+};
+
+using proto::_;
+
+// This grammar basically says that a calculator expression is one of:
+// - A placeholder terminal
+// - Some other terminal
+// - Some non-terminal whose children are calculator expressions
+// In addition, it has transforms that say how to calculate the
+// expression arity for each of the three cases.
+struct CalculatorGrammar
+ : proto::or_<
+ // placeholders have a non-zero arity ...
+ placeholder_arity< proto::terminal< arg<_> > >
+
+ //// This accomplishes the same thing without the need to
+ //// define a separate placeholder_arity<> transform, but
+ //// is a little more cryptic.
+ //proto::transform::apply1<
+ // proto::terminal< arg<_> >
+ // , arg_arity< proto::result_of::arg<mpl::_> >
+ //>
+
+ // Any other terminals have arity 0 ...
+ , proto::transform::always< proto::terminal<_>, mpl::int_<0> >
+ // For any non-terminals, find the arity of the children and
+ // take the maximum. This is recursive.
+ , proto::transform::fold<
+ // This matches any non-terminal for which the children
+ // are themselves calculator expressions.
+ proto::nary_expr<_, proto::vararg< max_arity< CalculatorGrammar > > >
+
+ //// This accomplishes the same thing without the need to
+ //// define a separate max_arity<> transform, but is a little
+ //// more cryptic.
+ //proto::nary_expr<
+ // _
+ // , proto::vararg<
+ // // Here, mpl::_1 will be replaced with the result of applying
+ // // the CalculatorGrammar transform (i.e., the arity of the
+ // // child node), and mpl::_2 will be replaced with the State of
+ // // the transformation so far (i.e., the maximum arity found so
+ // // far).
+ // proto::transform::apply2<CalculatorGrammar, mpl::max<mpl::_1, mpl::_2> >
+ // >
+ //>
+ >
+ >
+{};
+
+// Simple wrapper for calculating a calculator expression's arity.
+// It specifies mpl::int_<0> as the initial state. The visitor, which
+// is not used, is mpl::void_.
+template<typename Expr>
+struct calculator_arity
+ : CalculatorGrammar::apply<Expr, mpl::int_<0>, mpl::void_>
+{};
+
+// For expressions in the calculator domain, operator()
+// will be special; it will evaluate the expression.
+struct calculator_domain;
+
+// Define a calculator context, for evaluating arithmetic expressions
+// (This is as before, in calc1.cpp and calc2.cpp)
+struct calculator_context
+ : proto::callable_context< calculator_context const >
+{
+ // The values bound to the placeholders
+ double d[2];
+
+ // The result of evaluating arithmetic expressions
+ typedef double result_type;
+
+ explicit calculator_context(double d1 = 0., double d2 = 0.)
+ {
+ d[0] = d1;
+ d[1] = d2;
+ }
+
+ // Handle the evaluation of the placeholder terminals
+ template<typename I>
+ double operator()(proto::tag::terminal, arg<I>) const
+ {
+ return d[ I() - 1 ];
+ }
+};
+
+// Wrap all calculator expressions in this type, which defines
+// operator() to evaluate the expression.
+template<typename Expr>
+struct calculator_expression
+ : proto::extends<Expr, calculator_expression<Expr>, calculator_domain>
+{
+ typedef
+ proto::extends<Expr, calculator_expression<Expr>, calculator_domain>
+ base_type;
+
+ explicit calculator_expression(Expr const &expr = Expr())
+ : base_type(expr)
+ {}
+
+ using base_type::operator=;
+
+ // Override operator() to evaluate the expression
+ double operator()() const
+ {
+ // Assert that the expression has arity 0
+ BOOST_MPL_ASSERT_RELATION(0, ==, calculator_arity<Expr>::type::value);
+ calculator_context const ctx;
+ return proto::eval(*this, ctx);
+ }
+
+ double operator()(double d1) const
+ {
+ // Assert that the expression has arity 1
+ BOOST_MPL_ASSERT_RELATION(1, ==, calculator_arity<Expr>::type::value);
+ calculator_context const ctx(d1);
+ return proto::eval(*this, ctx);
+ }
+
+ double operator()(double d1, double d2) const
+ {
+ // Assert that the expression has arity 2
+ BOOST_MPL_ASSERT_RELATION(2, ==, calculator_arity<Expr>::type::value);
+ calculator_context const ctx(d1, d2);
+ return proto::eval(*this, ctx);
+ }
+};
+
+// Tell proto how to generate expressions in the calculator_domain
+struct calculator_domain
+ : proto::domain<proto::generator<calculator_expression> >
+{};
+
+// Define some placeholders (notice they're wrapped in calculator_expression<>)
+calculator_expression<proto::terminal< arg< mpl::int_<1> > >::type> const _1;
+calculator_expression<proto::terminal< arg< mpl::int_<2> > >::type> const _2;
+
+// Now, our arithmetic expressions are immediately executable function objects:
+int main()
+{
+ // Displays "5"
+ std::cout << (_1 + 2.0)( 3.0 ) << std::endl;
+
+ // Displays "6"
+ std::cout << ( _1 * _2 )( 3.0, 2.0 ) << std::endl;
+
+ // Displays "1.5"
+ std::cout << ( (_1 - _2) / _2 )( 3.0, 2.0 ) << std::endl;
+
+ // This won't compile because the arity of the
+ // expression doesn't match the number of arguments
+ // ( (_1 - _2) / _2 )( 3.0 );
+
+ return 0;
+}
+//]
Added: branches/proto/v3/libs/xpressive/proto3/example/hello.cpp
==============================================================================
--- (empty file)
+++ branches/proto/v3/libs/xpressive/proto3/example/hello.cpp 2007-11-07 17:03:47 EST (Wed, 07 Nov 2007)
@@ -0,0 +1,27 @@
+//[ HelloWorld
+////////////////////////////////////////////////////////////////////
+// Copyright 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)
+
+#include <iostream>
+#include <boost/xpressive/proto/proto.hpp>
+#include <boost/xpressive/proto/context.hpp>
+#include <boost/typeof/std/ostream.hpp>
+using namespace boost;
+
+proto::terminal< std::ostream & >::type cout_ = { std::cout };
+
+template< typename Expr >
+void evaluate( Expr const & expr )
+{
+ proto::default_context ctx;
+ proto::eval(expr, ctx);
+}
+
+int main()
+{
+ evaluate( cout_ << "hello" << ',' << " world" );
+ return 0;
+}
+//]
Added: branches/proto/v3/libs/xpressive/proto3/example/lazy_vector.cpp
==============================================================================
--- (empty file)
+++ branches/proto/v3/libs/xpressive/proto3/example/lazy_vector.cpp 2007-11-07 17:03:47 EST (Wed, 07 Nov 2007)
@@ -0,0 +1,144 @@
+//[ LazyVector
+///////////////////////////////////////////////////////////////////////////////
+// Copyright 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)
+//
+// This example constructs a mini-library for linear algebra, using
+// expression templates to eliminate the need for temporaries when
+// adding vectors of numbers.
+//
+// This example uses a domain with a grammar to prune the set
+// of overloaded operators. Only those operators that produce
+// valid lazy vector expressions are allowed.
+
+#include <vector>
+#include <iostream>
+#include <boost/mpl/int.hpp>
+#include <boost/xpressive/proto/proto.hpp>
+#include <boost/xpressive/proto/context.hpp>
+using namespace boost;
+
+using proto::_;
+
+// This grammar describes which lazy vector expressions
+// are allowed; namely, vector terminals and addition
+// and subtraction of lazy vector expressions.
+struct LazyVectorGrammar
+ : proto::or_<
+ proto::terminal< std::vector<_> >
+ , proto::plus< LazyVectorGrammar, LazyVectorGrammar>
+ , proto::minus< LazyVectorGrammar, LazyVectorGrammar>
+ >
+{};
+
+// Expressions in the lazy vector domain must conform
+// to the lazy vector grammar
+struct lazy_vector_domain;
+
+// Here is an evaluation context that indexes into a lazy vector
+// expression, and combines the result.
+template<typename Size = std::size_t>
+struct lazy_subscript_context
+{
+ lazy_subscript_context(Size subscript)
+ : subscript_(subscript)
+ {}
+
+ // Use default_eval for all the operations ...
+ template<typename Expr, typename Tag = typename Expr::proto_tag>
+ struct eval
+ : proto::default_eval<Expr, lazy_subscript_context>
+ {};
+
+ // ... except for terminals, which we index with our subscript
+ template<typename Expr>
+ struct eval<Expr, proto::tag::terminal>
+ {
+ typedef typename proto::result_of::arg<Expr>::type::value_type result_type;
+
+ result_type operator()( Expr const & expr, lazy_subscript_context & ctx ) const
+ {
+ return proto::arg( expr )[ ctx.subscript_ ];
+ }
+ };
+
+ Size subscript_;
+};
+
+// Here is the domain-specific expression wrapper, which overrides
+// operator[] to evaluate the expression using the lazy_subscript_context.
+template<typename Expr>
+struct lazy_vector_expr
+ : proto::extends<Expr, lazy_vector_expr<Expr>, lazy_vector_domain>
+{
+ typedef proto::extends<Expr, lazy_vector_expr<Expr>, lazy_vector_domain> base_type;
+
+ lazy_vector_expr( Expr const & expr = Expr() )
+ : base_type( expr )
+ {}
+
+ // Use the lazy_subscript_context<> to implement subscripting
+ // of a lazy vector expression tree.
+ template< typename Size >
+ typename proto::result_of::eval< Expr, lazy_subscript_context<Size> >::type
+ operator []( Size subscript ) const
+ {
+ lazy_subscript_context<Size> ctx(subscript);
+ return proto::eval(*this, ctx);
+ }
+};
+
+// Here is our lazy_vector terminal, implemented in terms of lazy_vector_expr
+template< typename T >
+struct lazy_vector
+ : lazy_vector_expr< typename proto::terminal< std::vector<T> >::type >
+{
+ typedef typename proto::terminal< std::vector<T> >::type expr_type;
+
+ lazy_vector( std::size_t size = 0, T const & value = T() )
+ : lazy_vector_expr<expr_type>( expr_type::make( std::vector<T>( size, value ) ) )
+ {}
+
+ // Here we define a += operator for lazy vector terminals that
+ // takes a lazy vector expression and indexes it. expr[i] here
+ // uses lazy_subscript_context<> under the covers.
+ template< typename Expr >
+ lazy_vector &operator += (Expr const & expr)
+ {
+ std::size_t size = proto::arg(*this).size();
+ for(std::size_t i = 0; i < size; ++i)
+ {
+ proto::arg(*this)[i] += expr[i];
+ }
+ return *this;
+ }
+};
+
+// Tell proto that in the lazy_vector_domain, all
+// expressions should be wrapped in laxy_vector_expr<>
+struct lazy_vector_domain
+ : proto::domain<proto::generator<lazy_vector_expr>, LazyVectorGrammar>
+{};
+
+int main()
+{
+ // lazy_vectors with 4 elements each.
+ lazy_vector< double > v1( 4, 1.0 ), v2( 4, 2.0 ), v3( 4, 3.0 );
+
+ // Add two vectors lazily and get the 2nd element.
+ double d1 = ( v2 + v3 )[ 2 ]; // Look ma, no temporaries!
+ std::cout << d1 << std::endl;
+
+ // Subtract two vectors and add the result to a third vector.
+ v1 += v2 - v3; // Still no temporaries!
+ std::cout << '{' << v1[0] << ',' << v1[1]
+ << ',' << v1[2] << ',' << v1[3] << '}' << std::endl;
+
+ // This expression is disallowed because it does not conform
+ // to the LazyVectorGrammar
+ //(v2 + v3) += v1;
+
+ return 0;
+}
+//]
Added: branches/proto/v3/libs/xpressive/proto3/example/mixed.cpp
==============================================================================
--- (empty file)
+++ branches/proto/v3/libs/xpressive/proto3/example/mixed.cpp 2007-11-07 17:03:47 EST (Wed, 07 Nov 2007)
@@ -0,0 +1,357 @@
+//[ Mixed
+///////////////////////////////////////////////////////////////////////////////
+// Copyright 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)
+//
+// This is an example of using BOOST_PROTO_DEFINE_OPERATORS to proto-ify
+// expressions using std::vector<> and std::list, non-proto types. It is a port
+// of the Mixed example from PETE.
+// (http://www.codesourcery.com/pooma/download.html).
+
+#include <list>
+#include <cmath>
+#include <vector>
+#include <complex>
+#include <iostream>
+#include <stdexcept>
+#include <boost/xpressive/proto/proto.hpp>
+#include <boost/xpressive/proto/debug.hpp>
+#include <boost/xpressive/proto/context.hpp>
+#include <boost/typeof/std/list.hpp>
+#include <boost/typeof/std/vector.hpp>
+#include <boost/typeof/std/complex.hpp>
+
+using namespace boost;
+using proto::_;
+
+template<typename Expr>
+struct MixedExpr;
+
+template<typename Iter>
+struct iterator_wrapper
+{
+ explicit iterator_wrapper(Iter iter)
+ : it(iter)
+ {}
+
+ Iter it;
+};
+
+template<typename Cont>
+iterator_wrapper<typename Cont::const_iterator> cbegin(Cont const &cont)
+{
+ return iterator_wrapper<typename Cont::const_iterator>(cont.begin());
+}
+
+template<typename Grammar>
+struct begin
+ : Grammar
+{
+ template<typename Expr, typename State, typename Visitor>
+ struct apply
+ : proto::terminal<
+ iterator_wrapper<
+ typename proto::result_of::arg<Expr>::type::const_iterator
+ >
+ >
+ {};
+
+ template<typename Expr, typename State, typename Visitor>
+ static typename apply<Expr, State, Visitor>::type
+ call(Expr const &expr, State const &state, Visitor &visitor)
+ {
+ return proto::as_expr(cbegin(proto::arg(expr)));
+ }
+};
+
+// Here is a grammar that replaces vector and list terminals with their
+// begin iterators
+struct Begin
+ : proto::or_<
+ begin< proto::terminal< std::vector<_, _> > >
+ , begin< proto::terminal< std::list<_, _> > >
+ , proto::terminal<_>
+ , proto::nary_expr<_, proto::vararg<Begin> >
+ >
+{};
+
+// Here is an evaluation context that dereferences iterator
+// terminals.
+struct DereferenceCtx
+{
+ // Unless this is a vector terminal, use the
+ // default evaluation context
+ template<typename Expr, typename Arg = typename proto::result_of::arg<Expr>::type>
+ struct eval
+ : proto::default_eval<Expr, DereferenceCtx const>
+ {};
+
+ // Index vector terminals with our subscript.
+ template<typename Expr, typename Iter>
+ struct eval<Expr, iterator_wrapper<Iter> >
+ {
+ typedef typename std::iterator_traits<Iter>::reference result_type;
+
+ result_type operator()(Expr &expr, DereferenceCtx const &) const
+ {
+ return *proto::arg(expr).it;
+ }
+ };
+};
+
+// Here is an evaluation context that increments iterator
+// terminals.
+struct IncrementCtx
+{
+ // Unless this is a vector terminal, use the
+ // default evaluation context
+ template<typename Expr, typename Arg = typename proto::result_of::arg<Expr>::type>
+ struct eval
+ : proto::null_eval<Expr, IncrementCtx const>
+ {};
+
+ // Index vector terminals with our subscript.
+ template<typename Expr, typename Iter>
+ struct eval<Expr, iterator_wrapper<Iter> >
+ {
+ typedef void result_type;
+
+ result_type operator()(Expr &expr, IncrementCtx const &) const
+ {
+ ++proto::arg(expr).it;
+ }
+ };
+};
+
+// A grammar which matches all the assignment operators,
+// so we can easily disable them.
+struct AssignOps
+ : proto::switch_<struct AssignOpsCases>
+{};
+
+// Here are the cases used by the switch_ above.
+struct AssignOpsCases
+{
+ template<typename Tag, int D = 0> struct case_ : proto::not_<_> {};
+
+ template<int D> struct case_< proto::tag::plus_assign, D > : _ {};
+ template<int D> struct case_< proto::tag::minus_assign, D > : _ {};
+ template<int D> struct case_< proto::tag::multiplies_assign, D > : _ {};
+ template<int D> struct case_< proto::tag::divides_assign, D > : _ {};
+ template<int D> struct case_< proto::tag::modulus_assign, D > : _ {};
+ template<int D> struct case_< proto::tag::shift_left_assign, D > : _ {};
+ template<int D> struct case_< proto::tag::shift_right_assign, D > : _ {};
+ template<int D> struct case_< proto::tag::bitwise_and_assign, D > : _ {};
+ template<int D> struct case_< proto::tag::bitwise_or_assign, D > : _ {};
+ template<int D> struct case_< proto::tag::bitwise_xor_assign, D > : _ {};
+};
+
+// A vector grammar is a terminal or some op that is not an
+// assignment op. (Assignment will be handles specially.)
+struct MixedGrammar
+ : proto::or_<
+ proto::terminal<_>
+ , proto::and_<proto::nary_expr<_, proto::vararg<MixedGrammar> >, proto::not_<AssignOps> >
+ >
+{};
+
+// Expressions in the vector domain will be wrapped in VectorExpr<>
+// and must conform to the VectorGrammar
+struct MixedDomain
+ : proto::domain<proto::generator<MixedExpr>, MixedGrammar>
+{};
+
+// Here is MixedExpr, a wrapper for expression types in the MixedDomain.
+template<typename Expr>
+struct MixedExpr
+ : proto::extends<Expr, MixedExpr<Expr>, MixedDomain>
+{
+ explicit MixedExpr(Expr const &expr)
+ : proto::extends<Expr, MixedExpr<Expr>, MixedDomain>(expr)
+ {}
+private:
+ // hide this:
+ using proto::extends<Expr, MixedExpr<Expr>, MixedDomain>::operator[];
+};
+
+// Define a trait type for detecting vector and list terminals, to
+// be used by the BOOST_PROTO_DEFINE_OPERATORS macro below.
+template<typename T>
+struct IsMixed
+ : mpl::false_
+{};
+
+template<typename T, typename A>
+struct IsMixed<std::list<T, A> >
+ : mpl::true_
+{};
+
+template<typename T, typename A>
+struct IsMixed<std::vector<T, A> >
+ : mpl::true_
+{};
+
+namespace VectorOps
+{
+ // This defines all the overloads to make expressions involving
+ // std::vector to build expression templates.
+ BOOST_PROTO_DEFINE_OPERATORS(IsMixed, MixedDomain)
+
+ struct assign_op
+ {
+ template<typename T, typename U>
+ void operator()(T &t, U const &u) const
+ {
+ t = u;
+ }
+ };
+
+ struct plus_assign_op
+ {
+ template<typename T, typename U>
+ void operator()(T &t, U const &u) const
+ {
+ t += u;
+ }
+ };
+
+ struct minus_assign_op
+ {
+ template<typename T, typename U>
+ void operator()(T &t, U const &u) const
+ {
+ t -= u;
+ }
+ };
+
+ struct sin_
+ {
+ template<typename Sig> struct result {};
+ template<typename This, typename Arg>
+ struct result<This(Arg)>
+ : remove_const<typename remove_reference<Arg>::type>
+ {};
+
+ template<typename Arg>
+ Arg operator()(Arg const &arg) const
+ {
+ return std::sin(arg);
+ }
+ };
+
+ BOOST_PROTO_DEFINE_FUNCTION_TEMPLATE(
+ 1
+ , sin
+ , MixedDomain
+ , (boost::proto::tag::function)
+ , ((sin_))
+ )
+
+ template<typename FwdIter, typename Expr, typename Op>
+ void evaluate(FwdIter begin, FwdIter end, Expr const &expr, Op op)
+ {
+ int i = 0;
+ IncrementCtx const inc = {};
+ DereferenceCtx const deref = {};
+ typename Begin::apply<Expr, int, int>::type expr2 = Begin::call(expr, i, i);
+ for(; begin != end; ++begin)
+ {
+ op(*begin, proto::eval(expr2, deref));
+ proto::eval(expr2, inc);
+ }
+ }
+
+ // Add-assign to a vector from some expression.
+ template<typename T, typename A, typename Expr>
+ std::vector<T, A> &assign(std::vector<T, A> &arr, Expr const &expr)
+ {
+ evaluate(arr.begin(), arr.end(), proto::as_expr<MixedDomain>(expr), assign_op());
+ return arr;
+ }
+
+ // Add-assign to a list from some expression.
+ template<typename T, typename A, typename Expr>
+ std::list<T, A> &assign(std::list<T, A> &arr, Expr const &expr)
+ {
+ evaluate(arr.begin(), arr.end(), proto::as_expr<MixedDomain>(expr), assign_op());
+ return arr;
+ }
+
+ // Add-assign to a vector from some expression.
+ template<typename T, typename A, typename Expr>
+ std::vector<T, A> &operator +=(std::vector<T, A> &arr, Expr const &expr)
+ {
+ evaluate(arr.begin(), arr.end(), proto::as_expr<MixedDomain>(expr), plus_assign_op());
+ return arr;
+ }
+
+ // Add-assign to a list from some expression.
+ template<typename T, typename A, typename Expr>
+ std::list<T, A> &operator +=(std::list<T, A> &arr, Expr const &expr)
+ {
+ evaluate(arr.begin(), arr.end(), proto::as_expr<MixedDomain>(expr), plus_assign_op());
+ return arr;
+ }
+
+ // Minus-assign to a vector from some expression.
+ template<typename T, typename A, typename Expr>
+ std::vector<T, A> &operator -=(std::vector<T, A> &arr, Expr const &expr)
+ {
+ evaluate(arr.begin(), arr.end(), proto::as_expr<MixedDomain>(expr), minus_assign_op());
+ return arr;
+ }
+
+ // Minus-assign to a list from some expression.
+ template<typename T, typename A, typename Expr>
+ std::list<T, A> &operator -=(std::list<T, A> &arr, Expr const &expr)
+ {
+ evaluate(arr.begin(), arr.end(), proto::as_expr<MixedDomain>(expr), minus_assign_op());
+ return arr;
+ }
+}
+
+int main()
+{
+ using namespace VectorOps;
+
+ int n = 10;
+ std::vector<int> a,b,c,d;
+ std::list<double> e;
+ std::list<std::complex<double> > f;
+
+ int i;
+ for(i = 0;i < n; ++i)
+ {
+ a.push_back(i);
+ b.push_back(2*i);
+ c.push_back(3*i);
+ d.push_back(i);
+ e.push_back(0.0);
+ f.push_back(std::complex<double>(1.0, 1.0));
+ }
+
+ VectorOps::assign(b, 2);
+ VectorOps::assign(d, a + b * c);
+ a += if_else(d < 30, b, c);
+
+ VectorOps::assign(e, c);
+ e += e - 4 / (c + 1);
+
+ f -= sin(0.1 * e * std::complex<double>(0.2, 1.2));
+
+ std::list<double>::const_iterator ei = e.begin();
+ std::list<std::complex<double> >::const_iterator fi = f.begin();
+ for (i = 0; i < n; ++i)
+ {
+ std::cout
+ << "a(" << i << ") = " << a[i]
+ << " b(" << i << ") = " << b[i]
+ << " c(" << i << ") = " << c[i]
+ << " d(" << i << ") = " << d[i]
+ << " e(" << i << ") = " << *ei++
+ << " f(" << i << ") = " << *fi++
+ << std::endl;
+ }
+}
+//]
Added: branches/proto/v3/libs/xpressive/proto3/example/rgb.cpp
==============================================================================
--- (empty file)
+++ branches/proto/v3/libs/xpressive/proto3/example/rgb.cpp 2007-11-07 17:03:47 EST (Wed, 07 Nov 2007)
@@ -0,0 +1,90 @@
+//[ RGB
+///////////////////////////////////////////////////////////////////////////////
+// Copyright 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)
+//
+// This is a simple example of doing arbitrary type manipulations with proto
+// transforms. It takes some expression involving primiary colors and combines
+// the colors according to arbitrary rules. It is a port of the RGB example
+// from PETE (http://www.codesourcery.com/pooma/download.html).
+
+#include <iostream>
+#include <boost/xpressive/proto/proto.hpp>
+#include <boost/xpressive/proto/transform/arg.hpp>
+#include <boost/xpressive/proto/transform/apply.hpp>
+#include <boost/xpressive/proto/transform/compose.hpp>
+using namespace boost::proto;
+
+struct RedTag
+{
+ friend std::ostream &operator <<(std::ostream &sout, RedTag)
+ {
+ return sout << "This expression is red.";
+ }
+};
+
+struct BlueTag
+{
+ friend std::ostream &operator <<(std::ostream &sout, BlueTag)
+ {
+ return sout << "This expression is blue.";
+ }
+};
+
+struct GreenTag
+{
+ friend std::ostream &operator <<(std::ostream &sout, GreenTag)
+ {
+ return sout << "This expression is green.";
+ }
+};
+
+typedef terminal<RedTag>::type Red;
+typedef terminal<BlueTag>::type Blue;
+typedef terminal<GreenTag>::type Green;
+
+///////////////////////////////////////////////////////////////////////////////
+// A transform that produces new colors according to some arbitrary rules:
+// red & green give blue, red & blue give green, blue and green give red.
+struct RGB
+ : or_<
+ // leave terminals as they are
+ terminal<_>
+ , transform::compose<
+ // Match binary nodes, convert left and right to terminals
+ plus<RGB, RGB>
+ // Forward resulting binary expression to the following transform
+ , or_<
+ // Green + Blue -> Red
+ transform::always<plus<Green, Blue>, Red>
+ , transform::always<plus<Blue, Green>, Red>
+ // Red + Green -> Blue
+ , transform::always<plus<Red, Green>, Blue>
+ , transform::always<plus<Green, Red>, Blue>
+ // Red + Blue -> Green
+ , transform::always<plus<Red, Blue>, Green>
+ , transform::always<plus<Blue, Red>, Green>
+ // else (both same color), select the left operand
+ , transform::left<_>
+ >
+ >
+ >
+{};
+
+template<typename Expr>
+void printColor(Expr const & expr)
+{
+ int i = 0; // dummy state and visitor parameter, not used
+ std::cout << arg(RGB::call(expr, i, i)) << std::endl;
+}
+
+int main()
+{
+ printColor(Red() + Green());
+ printColor(Red() + Green() + Blue());
+ printColor(Red() + (Green() + Blue()));
+
+ return 0;
+}
+//]
Added: branches/proto/v3/libs/xpressive/proto3/example/tarray.cpp
==============================================================================
--- (empty file)
+++ branches/proto/v3/libs/xpressive/proto3/example/tarray.cpp 2007-11-07 17:03:47 EST (Wed, 07 Nov 2007)
@@ -0,0 +1,220 @@
+//[ TArray
+///////////////////////////////////////////////////////////////////////////////
+// Copyright 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)
+//
+// This example constructs a mini-library for linear algebra, using
+// expression templates to eliminate the need for temporaries when
+// adding arrays of numbers. It duplicates the TArray example from
+// PETE (http://www.codesourcery.com/pooma/download.html)
+
+#include <iostream>
+#include <boost/mpl/int.hpp>
+#include <boost/xpressive/proto/proto.hpp>
+#include <boost/xpressive/proto/context.hpp>
+using namespace boost;
+
+// This grammar describes which TArray expressions
+// are allowed; namely, int and array terminals
+// plus, minus, multiplies and divides of TArray expressions.
+struct TArrayGrammar
+ : proto::or_<
+ proto::terminal< int >
+ , proto::terminal< int[3] >
+ , proto::plus< TArrayGrammar, TArrayGrammar >
+ , proto::minus< TArrayGrammar, TArrayGrammar >
+ , proto::multiplies< TArrayGrammar, TArrayGrammar >
+ , proto::divides< TArrayGrammar, TArrayGrammar >
+ >
+{};
+
+template<typename Expr>
+struct TArrayExpr;
+
+// Tell proto that in the TArrayDomain, all
+// expressions should be wrapped in TArrayExpr<> and
+// must conform to the TArrayGrammar
+struct TArrayDomain
+ : proto::domain<proto::generator<TArrayExpr>, TArrayGrammar>
+{};
+
+// Here is an evaluation context that indexes into a TArray
+// expression, and combines the result.
+struct TArraySubscriptCtx
+ : proto::callable_context< TArraySubscriptCtx const >
+{
+ typedef int result_type;
+
+ TArraySubscriptCtx(std::ptrdiff_t i)
+ : i_(i)
+ {}
+
+ // Index array terminals with our subscript. Everything
+ // else will be handled by the default evaluation context.
+ int operator()(proto::tag::terminal, int const (&data)[3]) const
+ {
+ return data[this->i_];
+ }
+
+ std::ptrdiff_t i_;
+};
+
+// Here is an evaluation context that prints a TArray expression.
+struct TArrayPrintCtx
+ : proto::callable_context< TArrayPrintCtx const >
+{
+ typedef std::ostream &result_type;
+
+ TArrayPrintCtx() {}
+
+ std::ostream &operator()(proto::tag::terminal, int i) const
+ {
+ return std::cout << i;
+ }
+
+ std::ostream &operator()(proto::tag::terminal, int const (&arr)[3]) const
+ {
+ return std::cout << '{' << arr[0] << ", " << arr[1] << ", " << arr[2] << '}';
+ }
+
+ template<typename L, typename R>
+ std::ostream &operator()(proto::tag::plus, L const &l, R const &r) const
+ {
+ return std::cout << '(' << l << " + " << r << ')';
+ }
+
+ template<typename L, typename R>
+ std::ostream &operator()(proto::tag::minus, L const &l, R const &r) const
+ {
+ return std::cout << '(' << l << " - " << r << ')';
+ }
+
+ template<typename L, typename R>
+ std::ostream &operator()(proto::tag::multiplies, L const &l, R const &r) const
+ {
+ return std::cout << l << " * " << r;
+ }
+
+ template<typename L, typename R>
+ std::ostream &operator()(proto::tag::divides, L const &l, R const &r) const
+ {
+ return std::cout << l << " / " << r;
+ }
+};
+
+// Here is the domain-specific expression wrapper, which overrides
+// operator[] to evaluate the expression using the TArraySubscriptCtx.
+template<typename Expr>
+struct TArrayExpr
+ : proto::extends<Expr, TArrayExpr<Expr>, TArrayDomain>
+{
+ typedef proto::extends<Expr, TArrayExpr<Expr>, TArrayDomain> base_type;
+
+ TArrayExpr( Expr const & expr = Expr() )
+ : base_type( expr )
+ {}
+
+ // Use the TArraySubscriptCtx to implement subscripting
+ // of a TArray expression tree.
+ int operator []( std::ptrdiff_t i ) const
+ {
+ TArraySubscriptCtx const ctx(i);
+ return proto::eval(*this, ctx);
+ }
+
+ // Use the TArrayPrintCtx to display a TArray expression tree.
+ friend std::ostream &operator <<(std::ostream &sout, TArrayExpr<Expr> const &expr)
+ {
+ TArrayPrintCtx const ctx;
+ return proto::eval(expr, ctx);
+ }
+};
+
+// Here is our TArray terminal, implemented in terms of TArrayExpr
+// It is basically just an array of 3 integers.
+struct TArray
+ : TArrayExpr< proto::terminal< int[3] >::type >
+{
+ explicit TArray( int i = 0, int j = 0, int k = 0 )
+ {
+ (*this)[0] = i;
+ (*this)[1] = j;
+ (*this)[2] = k;
+ }
+
+ // Here we override operator[] to give read/write access to
+ // the elements of the array. (We could use the TArrayExpr
+ // operator[] if we made the subscript context smarter about
+ // returning non-const reference when appropriate.)
+ int &operator [](std::ptrdiff_t i)
+ {
+ return proto::arg(*this)[i];
+ }
+
+ int const &operator [](std::ptrdiff_t i) const
+ {
+ return proto::arg(*this)[i];
+ }
+
+ // Here we define a operator= for TArray terminals that
+ // takes a TArray expression.
+ template< typename Expr >
+ TArray &operator =(Expr const & expr)
+ {
+ // proto::as_expr<TArrayDomain>(expr) is the same as
+ // expr unless expr is an integer, in which case it
+ // is made into a TArrayExpr terminal first.
+ return this->assign(proto::as_expr<TArrayDomain>(expr));
+ }
+
+ template< typename Expr >
+ TArray &printAssign(Expr const & expr)
+ {
+ *this = expr;
+ std::cout << *this << " = " << expr << std::endl;
+ return *this;
+ }
+
+private:
+ template< typename Expr >
+ TArray &assign(Expr const & expr)
+ {
+ // expr[i] here uses TArraySubscriptCtx under the covers.
+ (*this)[0] = expr[0];
+ (*this)[1] = expr[1];
+ (*this)[2] = expr[2];
+ return *this;
+ }
+};
+
+int main()
+{
+ TArray a(3,1,2);
+
+ TArray b;
+
+ std::cout << a << std::endl;
+ std::cout << b << std::endl;
+
+ b[0] = 7; b[1] = 33; b[2] = -99;
+
+ TArray c(a);
+
+ std::cout << c << std::endl;
+
+ a = 0;
+
+ std::cout << a << std::endl;
+ std::cout << b << std::endl;
+ std::cout << c << std::endl;
+
+ a = b + c;
+
+ std::cout << a << std::endl;
+
+ a.printAssign(b+c*(b + 3*c));
+
+ return 0;
+}
+//]
Added: branches/proto/v3/libs/xpressive/proto3/example/vec3.cpp
==============================================================================
--- (empty file)
+++ branches/proto/v3/libs/xpressive/proto3/example/vec3.cpp 2007-11-07 17:03:47 EST (Wed, 07 Nov 2007)
@@ -0,0 +1,177 @@
+//[ Vec3
+///////////////////////////////////////////////////////////////////////////////
+// Copyright 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)
+//
+// This is a simple example using proto::extends to extend a terminal type with
+// additional behaviors, and using custom contexts and proto::eval for
+// evaluating expressions. It is a port of the Vec3 example
+// from PETE (http://www.codesourcery.com/pooma/download.html).
+
+#include <cassert>
+#include <iostream>
+#include <functional>
+#include <boost/mpl/int.hpp>
+#include <boost/xpressive/proto/proto.hpp>
+#include <boost/xpressive/proto/context.hpp>
+#include <boost/xpressive/proto/proto_typeof.hpp>
+#include <boost/xpressive/proto/transform/arg.hpp>
+#include <boost/xpressive/proto/transform/fold.hpp>
+#include <boost/xpressive/proto/transform/apply.hpp>
+#include <boost/xpressive/proto/transform/function.hpp>
+using namespace boost::proto;
+namespace mpl = boost::mpl;
+
+// Here is an evaluation context that indexes into a Vec3
+// expression, and combines the result.
+struct Vec3SubscriptCtx
+ : callable_context< Vec3SubscriptCtx const >
+{
+ typedef int result_type;
+
+ Vec3SubscriptCtx(int i)
+ : i_(i)
+ {}
+
+ // Index array terminals with our subscript. Everything
+ // else will be handled by the default evaluation context.
+ int operator()(tag::terminal, int const (&arr)[3]) const
+ {
+ return arr[this->i_];
+ }
+
+ int i_;
+};
+
+// Here is an evaluation context that counts the number
+// of Vec3 terminals in an expression.
+struct CountLeavesCtx
+ : callable_context< CountLeavesCtx, null_context >
+{
+ CountLeavesCtx()
+ : count(0)
+ {}
+
+ typedef void result_type;
+
+ void operator()(tag::terminal, int const(&)[3])
+ {
+ ++this->count;
+ }
+
+ int count;
+};
+
+// Here is a transform that does the same thing as the above context.
+// It demonstrates the use of the std::plus<> function object
+// with the function2 transform. With minor modifications, this
+// transform could be used to calculate the leaf count at compile
+// time, rather at runtime.
+struct CountLeaves
+ : or_<
+ // match a Vec3 terminal, return 1
+ transform::always<terminal<int[3]>, mpl::int_<1> >
+ // match a terminal, return int() (which is 0)
+ , transform::always<terminal<_>, int>
+ // fold everything else, using std::plus<> to add
+ // the leaf count of each child to the accumulated state.
+ , transform::fold<
+ nary_expr<_, vararg<transform::function2<CountLeaves, std::plus<int> > > >
+ , int // initial state of the fold is int() (which is 0)
+ >
+ >
+{};
+
+// Here is the Vec3 struct, which is a vector of 3 integers.
+struct Vec3
+ : extends<terminal<int[3]>::type, Vec3>
+{
+ explicit Vec3(int i=0, int j=0, int k=0)
+ {
+ (*this)[0] = i;
+ (*this)[1] = j;
+ (*this)[2] = k;
+ }
+
+ int &operator[](int i)
+ {
+ return arg(*this)[i];
+ }
+
+ int const &operator[](int i) const
+ {
+ return arg(*this)[i];
+ }
+
+ // Here we define a operator= for Vec3 terminals that
+ // takes a Vec3 expression.
+ template< typename Expr >
+ Vec3 &operator =(Expr const & expr)
+ {
+ typedef Vec3SubscriptCtx const CVec3SubscriptCtx;
+ (*this)[0] = eval(as_expr(expr), CVec3SubscriptCtx(0));
+ (*this)[1] = eval(as_expr(expr), CVec3SubscriptCtx(1));
+ (*this)[2] = eval(as_expr(expr), CVec3SubscriptCtx(2));
+ return *this;
+ }
+
+ void print() const
+ {
+ std::cout << '{' << (*this)[0]
+ << ", " << (*this)[1]
+ << ", " << (*this)[2]
+ << '}' << std::endl;
+ }
+};
+
+// The count_leaves() function uses the CountLeaves transform and
+// to count the number of leaves in an expression.
+template<typename Expr>
+int count_leaves(Expr const &expr)
+{
+ // Count the number of Vec3 terminals using the
+ // CountLeavesCtx evaluation context.
+ CountLeavesCtx ctx;
+ eval(expr, ctx);
+
+ // This is another way to count the leaves using a transform.
+ int i = 0;
+ assert( CountLeaves::call(expr, i, i) == ctx.count );
+
+ return ctx.count;
+}
+
+int main()
+{
+ Vec3 a, b, c;
+
+ c = 4;
+
+ b[0] = -1;
+ b[1] = -2;
+ b[2] = -3;
+
+ a = b + c;
+
+ a.print();
+
+ Vec3 d;
+ BOOST_PROTO_AUTO(expr1, b + c);
+ d = expr1;
+ d.print();
+
+ int num = count_leaves(expr1);
+ std::cout << num << std::endl;
+
+ BOOST_PROTO_AUTO(expr2, b + 3 * c);
+ num = count_leaves(expr2);
+ std::cout << num << std::endl;
+
+ BOOST_PROTO_AUTO(expr3, b + c * d);
+ num = count_leaves(expr3);
+ std::cout << num << std::endl;
+
+ return 0;
+}
+//]
Added: branches/proto/v3/libs/xpressive/proto3/example/vector.cpp
==============================================================================
--- (empty file)
+++ branches/proto/v3/libs/xpressive/proto3/example/vector.cpp 2007-11-07 17:03:47 EST (Wed, 07 Nov 2007)
@@ -0,0 +1,229 @@
+//[ Vector
+///////////////////////////////////////////////////////////////////////////////
+// Copyright 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)
+//
+// This is an example of using BOOST_PROTO_DEFINE_OPERATORS to proto-ify
+// expressions using std::vector<>, a non-proto type. It is a port of the
+// Vector example from PETE (http://www.codesourcery.com/pooma/download.html).
+
+#include <vector>
+#include <iostream>
+#include <stdexcept>
+#include <boost/xpressive/proto/proto.hpp>
+#include <boost/xpressive/proto/debug.hpp>
+#include <boost/xpressive/proto/context.hpp>
+
+using namespace boost;
+using proto::_;
+
+template<typename Expr>
+struct VectorExpr;
+
+// Here is an evaluation context that indexes into a std::vector
+// expression and combines the result.
+struct VectorSubscriptCtx
+{
+ VectorSubscriptCtx(std::size_t i)
+ : i_(i)
+ {}
+
+ // Unless this is a vector terminal, use the
+ // default evaluation context
+ template<typename Expr, typename Arg = typename proto::result_of::arg<Expr>::type>
+ struct eval
+ : proto::default_eval<Expr, VectorSubscriptCtx const>
+ {};
+
+ // Index vector terminals with our subscript.
+ template<typename Expr, typename T, typename A>
+ struct eval<Expr, std::vector<T, A> >
+ {
+ typedef T result_type;
+
+ T operator()(Expr &expr, VectorSubscriptCtx const &ctx) const
+ {
+ return proto::arg(expr)[ctx.i_];
+ }
+ };
+
+ std::size_t i_;
+};
+
+// Here is an evaluation context that verifies that all the
+// vectors in an expression have the same size.
+struct VectorSizeCtx
+{
+ VectorSizeCtx(std::size_t size)
+ : size_(size)
+ {}
+
+ // Unless this is a vector terminal, use the
+ // null evaluation context
+ template<typename Expr, typename Arg = typename proto::result_of::arg<Expr>::type>
+ struct eval
+ : proto::null_eval<Expr, VectorSizeCtx const>
+ {};
+
+ // Index array terminals with our subscript. Everything
+ // else will be handled by the default evaluation context.
+ template<typename Expr, typename T, typename A>
+ struct eval<Expr, std::vector<T, A> >
+ {
+ typedef void result_type;
+
+ result_type operator()(Expr &expr, VectorSizeCtx const &ctx) const
+ {
+ if(ctx.size_ != proto::arg(expr).size())
+ {
+ throw std::invalid_argument("LHS and RHS are not compatible");
+ }
+ }
+ };
+
+ std::size_t size_;
+};
+
+// A grammar which matches all the assignment operators,
+// so we can easily disable them.
+struct AssignOps
+ : proto::switch_<struct AssignOpsCases>
+{};
+
+// Here are the cases used by the switch_ above.
+struct AssignOpsCases
+{
+ template<typename Tag, int D = 0> struct case_ : proto::not_<_> {};
+
+ template<int D> struct case_< proto::tag::plus_assign, D > : _ {};
+ template<int D> struct case_< proto::tag::minus_assign, D > : _ {};
+ template<int D> struct case_< proto::tag::multiplies_assign, D > : _ {};
+ template<int D> struct case_< proto::tag::divides_assign, D > : _ {};
+ template<int D> struct case_< proto::tag::modulus_assign, D > : _ {};
+ template<int D> struct case_< proto::tag::shift_left_assign, D > : _ {};
+ template<int D> struct case_< proto::tag::shift_right_assign, D > : _ {};
+ template<int D> struct case_< proto::tag::bitwise_and_assign, D > : _ {};
+ template<int D> struct case_< proto::tag::bitwise_or_assign, D > : _ {};
+ template<int D> struct case_< proto::tag::bitwise_xor_assign, D > : _ {};
+};
+
+// A vector grammar is a terminal or some op that is not an
+// assignment op. (Assignment will be handles specially.)
+struct VectorGrammar
+ : proto::or_<
+ proto::terminal<_>
+ , proto::and_<proto::nary_expr<_, proto::vararg<VectorGrammar> >, proto::not_<AssignOps> >
+ >
+{};
+
+// Expressions in the vector domain will be wrapped in VectorExpr<>
+// and must conform to the VectorGrammar
+struct VectorDomain
+ : proto::domain<proto::generator<VectorExpr>, VectorGrammar>
+{};
+
+// Here is VectorExpr, which extends a proto expr type by
+// giving it an operator[] which uses the VectorSubscriptCtx
+// to evaluate an expression with a given index.
+template<typename Expr>
+struct VectorExpr
+ : proto::extends<Expr, VectorExpr<Expr>, VectorDomain>
+{
+ explicit VectorExpr(Expr const &expr)
+ : proto::extends<Expr, VectorExpr<Expr>, VectorDomain>(expr)
+ {}
+
+ // Use the VectorSubscriptCtx to implement subscripting
+ // of a Vector expression tree.
+ typename proto::result_of::eval<Expr const, VectorSubscriptCtx const>::type
+ operator []( std::size_t i ) const
+ {
+ VectorSubscriptCtx const ctx(i);
+ return proto::eval(*this, ctx);
+ }
+};
+
+// Define a trait type for detecting vector terminals, to
+// be used by the BOOST_PROTO_DEFINE_OPERATORS macro below.
+template<typename T>
+struct IsVector
+ : mpl::false_
+{};
+
+template<typename T, typename A>
+struct IsVector<std::vector<T, A> >
+ : mpl::true_
+{};
+
+namespace VectorOps
+{
+ // This defines all the overloads to make expressions involving
+ // std::vector to build expression templates.
+ BOOST_PROTO_DEFINE_OPERATORS(IsVector, VectorDomain)
+
+ typedef VectorSubscriptCtx const CVectorSubscriptCtx;
+
+ // Assign to a vector from some expression.
+ template<typename T, typename A, typename Expr>
+ std::vector<T, A> &assign(std::vector<T, A> &arr, Expr const &expr)
+ {
+ VectorSizeCtx const size(arr.size());
+ proto::eval(proto::as_expr<VectorDomain>(expr), size); // will throw if the sizes don't match
+ for(std::size_t i = 0; i < arr.size(); ++i)
+ {
+ arr[i] = proto::as_expr<VectorDomain>(expr)[i];
+ }
+ return arr;
+ }
+
+ // Add-assign to a vector from some expression.
+ template<typename T, typename A, typename Expr>
+ std::vector<T, A> &operator +=(std::vector<T, A> &arr, Expr const &expr)
+ {
+ VectorSizeCtx const size(arr.size());
+ proto::eval(proto::as_expr<VectorDomain>(expr), size); // will throw if the sizes don't match
+ for(std::size_t i = 0; i < arr.size(); ++i)
+ {
+ arr[i] += proto::as_expr<VectorDomain>(expr)[i];
+ }
+ return arr;
+ }
+}
+
+int main()
+{
+ using namespace VectorOps;
+
+ int i;
+ const int n = 10;
+ std::vector<int> a,b,c,d;
+ std::vector<double> e(n);
+
+ for (i = 0; i < n; ++i)
+ {
+ a.push_back(i);
+ b.push_back(2*i);
+ c.push_back(3*i);
+ d.push_back(i);
+ }
+
+ VectorOps::assign(b, 2);
+ VectorOps::assign(d, a + b * c);
+ a += if_else(d < 30, b, c);
+
+ VectorOps::assign(e, c);
+ e += e - 4 / (c + 1);
+
+ for (i = 0; i < n; ++i)
+ {
+ std::cout
+ << " a(" << i << ") = " << a[i]
+ << " b(" << i << ") = " << b[i]
+ << " c(" << i << ") = " << c[i]
+ << " d(" << i << ") = " << d[i]
+ << " e(" << i << ") = " << e[i]
+ << std::endl;
+ }
+}
+//]
Added: branches/proto/v3/libs/xpressive/proto3/test/Jamfile.v2
==============================================================================
--- (empty file)
+++ branches/proto/v3/libs/xpressive/proto3/test/Jamfile.v2 2007-11-07 17:03:47 EST (Wed, 07 Nov 2007)
@@ -0,0 +1,33 @@
+# (C) Copyright 2004: Eric Niebler
+# Distributed under the Boost Software License, Version 1.0.
+# (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+# bring in rules for testing
+import testing ;
+
+project
+ : requirements
+ <toolset>intel:<debug-symbols>off
+ <toolset>msvc-7.1:<debug-symbols>off
+ <toolset>msvc-8.0:<define>_SCL_SECURE_NO_DEPRECATE
+ <toolset>msvc-8.0:<define>_CRT_SECURE_NO_DEPRECATE
+ <toolset>gcc:<cxxflags>-ftemplate-depth-1024
+ #<library>/boost/test//boost_unit_test_framework
+ #<link>static
+ ;
+
+test-suite "proto"
+ :
+ [ run proto_fusion.cpp : : : <toolset>gcc:<cxxflags>-ftemplate-depth-1024 ]
+ [ run proto_fusion_s.cpp ]
+ [ run toy_spirit.cpp ]
+ [ run toy_spirit2.cpp ]
+ [ run toy_spirit3.cpp ]
+ [ run calculator.cpp ]
+ [ run lambda.cpp ]
+ [ run lambda2.cpp ]
+ [ run matches.cpp ]
+ [ run examples.cpp ]
+ [ run examples2.cpp ]
+ ;
+
Added: branches/proto/v3/libs/xpressive/proto3/test/calculator.cpp
==============================================================================
--- (empty file)
+++ branches/proto/v3/libs/xpressive/proto3/test/calculator.cpp 2007-11-07 17:03:47 EST (Wed, 07 Nov 2007)
@@ -0,0 +1,109 @@
+///////////////////////////////////////////////////////////////////////////////
+// calculator.hpp
+//
+// Copyright 2006 Eric Niebler. Distributed under the Boost
+// Software License, Version 1.0. (See accompanying file
+// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/xpressive/proto3/proto.hpp>
+#include <boost/xpressive/proto3/context.hpp>
+#include <boost/test/unit_test.hpp>
+
+using namespace boost;
+
+struct placeholder {};
+proto::terminal<placeholder>::type const _1 = {{}};
+
+struct calculator : proto::callable_context<calculator const>
+{
+ typedef int result_type;
+
+ calculator(int i)
+ : i_(i)
+ {}
+
+ int operator()(proto::tag::terminal, placeholder) const
+ {
+ return this->i_;
+ }
+
+ int operator()(proto::tag::terminal, int j) const
+ {
+ return j;
+ }
+
+ template<typename Left, typename Right>
+ int operator()(proto::tag::plus, Left const &left, Right const &right) const
+ {
+ return proto::eval(left, *this) + proto::eval(right, *this);
+ }
+
+ template<typename Left, typename Right>
+ int operator()(proto::tag::minus, Left const &left, Right const &right) const
+ {
+ return proto::eval(left, *this) - proto::eval(right, *this);
+ }
+
+ template<typename Left, typename Right>
+ int operator()(proto::tag::multiplies, Left const &left, Right const &right) const
+ {
+ return proto::eval(left, *this) * proto::eval(right, *this);
+ }
+
+ template<typename Left, typename Right>
+ int operator()(proto::tag::divides, Left const &left, Right const &right) const
+ {
+ return proto::eval(left, *this) / proto::eval(right, *this);
+ }
+
+private:
+ int i_;
+};
+
+template<typename Fun, typename Expr>
+struct functor
+{
+ typedef typename proto::result_of::eval<Expr, Fun>::type result_type;
+
+ functor(Expr const &expr)
+ : expr_(expr)
+ {}
+
+ template<typename T>
+ result_type operator()(T const &t) const
+ {
+ Fun fun(t);
+ return proto::eval(this->expr_, fun);
+ }
+
+private:
+ Expr const &expr_;
+};
+
+template<typename Fun, typename Expr>
+functor<Fun, Expr> as(Expr const &expr)
+{
+ return functor<Fun, Expr>(expr);
+}
+
+void test_calculator()
+{
+ BOOST_CHECK_EQUAL(10, proto::eval(((_1 + 42)-3)/4, calculator(1)));
+ BOOST_CHECK_EQUAL(11, proto::eval(((_1 + 42)-3)/4, calculator(5)));
+
+ BOOST_CHECK_EQUAL(10, as<calculator>(((_1 + 42)-3)/4)(1));
+ BOOST_CHECK_EQUAL(11, as<calculator>(((_1 + 42)-3)/4)(5));
+}
+
+using namespace unit_test;
+///////////////////////////////////////////////////////////////////////////////
+// init_unit_test_suite
+//
+test_suite* init_unit_test_suite( int argc, char* argv[] )
+{
+ test_suite *test = BOOST_TEST_SUITE("test immediate evaluation of proto parse trees");
+
+ test->add(BOOST_TEST_CASE(&test_calculator));
+
+ return test;
+}
Added: branches/proto/v3/libs/xpressive/proto3/test/examples.cpp
==============================================================================
--- (empty file)
+++ branches/proto/v3/libs/xpressive/proto3/test/examples.cpp 2007-11-07 17:03:47 EST (Wed, 07 Nov 2007)
@@ -0,0 +1,290 @@
+///////////////////////////////////////////////////////////////////////////////
+// examples.hpp
+//
+// Copyright 2006 Eric Niebler. Distributed under the Boost
+// Software License, Version 1.0. (See accompanying file
+// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#include <iostream>
+#include <boost/config.hpp>
+#include <boost/mpl/min_max.hpp>
+#include <boost/xpressive/proto3/proto.hpp>
+#include <boost/xpressive/proto3/transform/arg.hpp>
+#include <boost/xpressive/proto3/transform/fold.hpp>
+#include <boost/xpressive/proto3/transform/branch.hpp>
+#include <boost/xpressive/proto3/transform/list.hpp>
+#include <boost/xpressive/proto3/transform/apply.hpp>
+#include <boost/xpressive/proto3/transform/construct.hpp>
+#include <boost/xpressive/proto3/transform/fold_tree.hpp>
+#include <boost/utility/result_of.hpp>
+#include <boost/test/unit_test.hpp>
+
+using namespace boost::proto;
+namespace mpl = boost::mpl;
+namespace fusion = boost::fusion;
+
+struct placeholder1 {};
+struct placeholder2 {};
+
+namespace test1
+{
+//[ CalculatorGrammar
+ using namespace boost::proto;
+
+ /*<< A Calculator expression is ... >>*/
+ struct CalculatorGrammar
+ : or_<
+ /*<< placeholder1, or ... >>*/
+ terminal< placeholder1 >
+ /*<< placeholder2, or ... >>*/
+ , terminal< placeholder2 >
+ /*<< some other terminal, or ... >>*/
+ , terminal< _ >
+ /*<< a unary expression where the operand is a calculator expression, or ... >>*/
+ , unary_expr< _, CalculatorGrammar >
+ /*<< a binary expression where the operands are calculator expressions, or ... >>*/
+ , binary_expr< _, CalculatorGrammar, CalculatorGrammar >
+ >
+ {};
+//]
+}
+
+//[ binary_max
+// A custom transform that returns the arity of a binary
+// calculator expression by finding the maximum of the
+// arities of the two children expressions.
+/*<< All transforms take a Grammar as a template parameter. >>*/
+template<typename Grammar>
+struct binary_max
+ /*<< All transforms must inherit from the `Grammar`, so that the transform
+ IS-A `Grammar`, and matches the same expressions that `Grammar` does. >>*/
+ : Grammar
+{
+ template<typename Expr, typename State, typename Visitor>
+ /*<< Transforms have a nested `apply<>` for calculating their return type. >>*/
+ struct apply
+ {
+ /*<< Apply `Grammar`'s transform. This is what makes it possible to chain transforms. >>*/
+ typedef typename mpl::apply_wrap3<Grammar, Expr, State, Visitor>::type expr_type;
+ /*<< After applying `Grammar`'s transform, the children expressions have been
+ replaced with their arities. >>*/
+ typedef typename result_of::left<expr_type>::type left_arity;
+ typedef typename result_of::right<expr_type>::type right_arity;
+ /*<< The return type is the maximum of the children's arities. >>*/
+ typedef typename mpl::max<left_arity, right_arity>::type type;
+ };
+
+ template<typename Expr, typename State, typename Visitor>
+ static typename apply<Expr, State, Visitor>::type
+ /*<< Transforms have a nested `call()` member function. >>*/
+ call(Expr const &, State const &, Visitor &)
+ {
+ /*<< Usually, the `call()` member function invokes the `Grammar`'s `call()` function,
+ as `Grammar::call(expr,state,visitor)`, but this transform doesn't have an interesting
+ runtime counterpart, so just return a default-constructed object of the correct type. >>*/
+ return typename apply<Expr, State, Visitor>::type();
+ }
+};
+//]
+
+terminal< placeholder1 >::type const _1 = {{}};
+terminal< placeholder2 >::type const _2 = {{}};
+
+//[ CalculatorArityGrammar
+struct CalculatorGrammar
+ : or_<
+ transform::always< terminal< placeholder1 >, mpl::int_<1> >
+ , transform::always< terminal< placeholder2 >, mpl::int_<2> >
+ , transform::always< terminal< _ >, mpl::int_<0> >
+ , transform::arg< unary_expr< _, CalculatorGrammar > >
+ , binary_max< binary_expr< _, CalculatorGrammar, CalculatorGrammar > >
+ >
+{};
+//]
+
+//[ AsArgList
+// This transform matches function invocations such as foo(1,'a',"b")
+// and transforms them into Fusion cons lists of their arguments. In this
+// case, the result would be cons(1, cons('a', cons("b", nil()))).
+struct ArgsAsList
+ /*<< Use a `branch<>` transform to use `fusion::nil` as the initial
+ state of this transformation. >>*/
+ : transform::branch<
+ /*<< Use a `reverse_fold<>` transform to iterate over the children
+ of this node in reverse order, building a fusion list from back to
+ front. >>*/
+ transform::reverse_fold<
+ /*<< The `Grammar` we're matching is a function invocation. >>*/
+ function<
+ /*<< The first child expression of a `function<>` node is the
+ function being invoked. We don't want that in our list, so use
+ the `state<>` transform to effectively skip it. (Recall that
+ we're building a list in the state parameter, and that the
+ `state<>` transform just returns the state unmodified. So this
+ says to match a `terminal<>` but to not add it to the list.) >>*/
+ transform::state<terminal<_> >
+ /*<< We use `vararg<>` here because the function expression we're
+ matching can have an arbitrary number of arguments. >>*/
+ , vararg<
+ /*<< The `list<>` transform puts the rest of the function
+ arguments in a fusion cons list. >>*/
+ transform::list<
+ /*<< The arguments to the function are terminals.
+ Extract the argument from each terminal before putting
+ them into the list. >>*/
+ transform::arg<terminal<_> >
+ >
+ >
+ >
+ >
+ /*<< Here is the initial state used by this transform. >>*/
+ , fusion::nil
+ >
+{};
+//]
+
+//[ FoldTreeToList
+// This grammar describes what counts as the terminals in expressions
+// of the form (_1=1,'a',"b"), which will be flattened using
+// reverse_fold_tree<> below.
+struct Terminals
+ : or_<
+ transform::arg<transform::right<assign<_, terminal<_> > > >
+ , transform::arg<terminal<_> >
+ >
+{};
+
+// This transform matches expressions of the form (_1=1,'a',"b")
+// (note the use of the comma operator) and transforms it into a
+// Fusion cons list of their arguments. In this case, the result
+// would be cons(1, cons('a', cons("b", nil()))).
+struct FoldTreeToList
+ /*<< Fold all terminals that are separated by commas into a Fusion cons list. >>*/
+ : transform::reverse_fold_tree<tag::comma, transform::list<Terminals>, fusion::nil>
+{};
+//]
+
+//[ Promote
+// This transform finds all float terminals in an expression and promotes
+// them to doubles.
+struct Promote
+ : or_<
+ /*<< Match a `terminal<float>`, then construct a `terminal<double>::type` with the `float`. >>*/
+ transform::construct<terminal<float>, terminal<double>::type(transform::arg<_>) >
+ , terminal<_>
+ /*<< `nary_expr<>` has a pass-through transform which will transform each child
+ sub-expression using the `Promote` transform. >>*/
+ , nary_expr<_, vararg<Promote> >
+ >
+{};
+//]
+
+//[ LazyMakePair
+struct make_pair_tag {};
+terminal<make_pair_tag>::type const make_pair_ = {{}};
+
+// This transform matches lazy function invocations like
+// `make_pair_(1, 3.14)` and actually builds a `std::pair<>`
+// from the arguments.
+struct MakePair
+ : transform::construct<
+ /*<< Match expressions like `make_pair_(1, 3.14)` >>*/
+ function<terminal<make_pair_tag>, terminal<_>, terminal<_> >
+ /*<< Return `std::pair<F,S>(f,s)` where `f` and `s` are the
+ first and second arguments to the lazy `make_pair_()` function >>*/
+ , std::pair<
+ transform::arg<transform::arg_c<_, 1> >
+ , transform::arg<transform::arg_c<_, 2> >
+ >(
+ transform::arg<transform::arg_c<_, 1> >
+ , transform::arg<transform::arg_c<_, 2> >
+ )
+ >
+{};
+//]
+
+//[ NegateInt
+struct NegateInt
+ : transform::construct<
+ terminal<int>
+ , negate<_>(_)
+ >
+{};
+//]
+
+#ifndef BOOST_MSVC
+//[ SquareAndPromoteInt
+struct SquareAndPromoteInt
+ : transform::construct<
+ terminal<int>
+ , multiplies<terminal<long>::type, terminal<long>::type>::type(
+ terminal<long>::type(transform::arg<_>)
+ , terminal<long>::type(transform::arg<_>)
+ )
+ >
+{};
+//]
+#endif
+
+void test_examples()
+{
+ //[ CalculatorArityTest
+ int i = 0; // not used, dummy state and visitor parameter
+
+ std::cout << CalculatorGrammar::call( lit(100) * 200, i, i) << '\n';
+ std::cout << CalculatorGrammar::call( (_1 - _1) / _1 * 100, i, i) << '\n';
+ std::cout << CalculatorGrammar::call( (_2 - _1) / _2 * 100, i, i) << '\n';
+ //]
+
+ BOOST_CHECK_EQUAL(0, CalculatorGrammar::call( lit(100) * 200, i, i));
+ BOOST_CHECK_EQUAL(1, CalculatorGrammar::call( (_1 - _1) / _1 * 100, i, i));
+ BOOST_CHECK_EQUAL(2, CalculatorGrammar::call( (_2 - _1) / _2 * 100, i, i));
+
+ using boost::fusion::cons;
+ using boost::fusion::nil;
+ cons<int, cons<char, cons<char const (&)[2]> > > args(ArgsAsList::call( _1(1, 'a', "b"), i, i ));
+ BOOST_CHECK_EQUAL(args.car, 1);
+ BOOST_CHECK_EQUAL(args.cdr.car, 'a');
+ BOOST_CHECK_EQUAL(args.cdr.cdr.car, std::string("b"));
+
+ cons<int, cons<char, cons<char const (&)[2]> > > lst(FoldTreeToList::call( (_1 = 1, 'a', "b"), i, i ));
+ BOOST_CHECK_EQUAL(lst.car, 1);
+ BOOST_CHECK_EQUAL(lst.cdr.car, 'a');
+ BOOST_CHECK_EQUAL(lst.cdr.cdr.car, std::string("b"));
+
+ plus<
+ terminal<double>::type
+ , terminal<double>::type
+ >::type p = Promote::call( lit(1.f) + 2.f, i, i );
+
+ //[ LazyMakePairTest
+ int j = 0; // not used, dummy state and visitor parameter
+
+ std::pair<int, double> p2 = MakePair::call( make_pair_(1, 3.14), j, j );
+
+ std::cout << p2.first << std::endl;
+ std::cout << p2.second << std::endl;
+ //]
+
+ BOOST_CHECK_EQUAL(p2.first, 1);
+ BOOST_CHECK_EQUAL(p2.second, 3.14);
+
+ NegateInt::call(lit(1), i, i);
+#ifndef BOOST_MSVC
+ SquareAndPromoteInt::call(lit(1), i, i);
+#endif
+}
+
+
+using namespace boost::unit_test;
+///////////////////////////////////////////////////////////////////////////////
+// init_unit_test_suite
+//
+test_suite* init_unit_test_suite( int argc, char* argv[] )
+{
+ test_suite *test = BOOST_TEST_SUITE("test examples from the documentation");
+
+ test->add(BOOST_TEST_CASE(&test_examples));
+
+ return test;
+}
Added: branches/proto/v3/libs/xpressive/proto3/test/examples2.cpp
==============================================================================
--- (empty file)
+++ branches/proto/v3/libs/xpressive/proto3/test/examples2.cpp 2007-11-07 17:03:47 EST (Wed, 07 Nov 2007)
@@ -0,0 +1,317 @@
+///////////////////////////////////////////////////////////////////////////////
+// examples2.hpp
+//
+// Copyright 2006 Eric Niebler. Distributed under the Boost
+// Software License, Version 1.0. (See accompanying file
+// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#include <iostream>
+#include <boost/config.hpp>
+#include <boost/mpl/min_max.hpp>
+#include <boost/xpressive/proto3/proto.hpp>
+#include <boost/xpressive/proto3/transform2.hpp>
+#include <boost/utility/result_of.hpp>
+#include <boost/test/unit_test.hpp>
+
+using namespace boost::proto;
+namespace mpl = boost::mpl;
+namespace fusion = boost::fusion;
+
+struct placeholder1 {};
+struct placeholder2 {};
+
+namespace test1
+{
+//[ CalculatorGrammar
+ using namespace boost::proto;
+
+ /*<< A Calculator expression is ... >>*/
+ struct CalculatorGrammar
+ : or_<
+ /*<< placeholder1, or ... >>*/
+ terminal< placeholder1 >
+ /*<< placeholder2, or ... >>*/
+ , terminal< placeholder2 >
+ /*<< some other terminal, or ... >>*/
+ , terminal< _ >
+ /*<< a unary expression where the operand is a calculator expression, or ... >>*/
+ , unary_expr< _, CalculatorGrammar >
+ /*<< a binary expression where the operands are calculator expressions, or ... >>*/
+ , binary_expr< _, CalculatorGrammar, CalculatorGrammar >
+ >
+ {};
+//]
+}
+
+//[ binary_arity
+/*<< The `CalculatorArity` is a transform for calculating
+the arity of a calculator expression. It will be define in
+terms of `binary_arity`, which is defined in terms of
+`CalculatorArity`; hence, the definition is recursive.>>*/
+struct CalculatorArity;
+
+// A custom transform that returns the arity of a unary
+// calculator expression by finding the arity of the
+// child expression.
+struct unary_arity
+ /*<< All custom transforms should inherit from
+ transform_base. In some cases, (e.g., when the transform
+ is a template), it is also necessary to specialize
+ the proto::is_transform<> trait. >>*/
+ : transform_base
+{
+ template<typename Expr, typename State, typename Visitor>
+ /*<< Transforms have a nested `apply<>` for calculating their return type. >>*/
+ struct apply
+ {
+ /*<< Get the child. >>*/
+ typedef typename result_of::arg<Expr>::type child_expr;
+
+ /*<< Apply `CalculatorArity` to find the arity of the child. >>*/
+ typedef typename mpl::apply_wrap3<CalculatorArity, child_expr, State, Visitor>::type type;
+ };
+
+ template<typename Expr, typename State, typename Visitor>
+ static typename apply<Expr, State, Visitor>::type
+ /*<< Transforms have a nested `call()` member function. >>*/
+ call(Expr const &, State const &, Visitor &)
+ {
+ /*<< The `unary_arity` transform doesn't have an interesting
+ runtime counterpart, so just return a default-constructed object
+ of the correct type. >>*/
+ return typename apply<Expr, State, Visitor>::type();
+ }
+};
+
+// A custom transform that returns the arity of a binary
+// calculator expression by finding the maximum of the
+// arities of the two children expressions.
+struct binary_arity
+ /*<< All custom transforms should inherit from
+ transform_base. In some cases, (e.g., when the transform
+ is a template), it is also necessary to specialize
+ the proto::is_transform<> trait. >>*/
+ : transform_base
+{
+ template<typename Expr, typename State, typename Visitor>
+ /*<< Transforms have a nested `apply<>` for calculating their return type. >>*/
+ struct apply
+ {
+ /*<< Get the left and right children. >>*/
+ typedef typename result_of::left<Expr>::type left_expr;
+ typedef typename result_of::right<Expr>::type right_expr;
+
+ /*<< Apply `CalculatorArity` to find the arity of the left and right children. >>*/
+ typedef typename mpl::apply_wrap3<CalculatorArity, left_expr, State, Visitor>::type left_arity;
+ typedef typename mpl::apply_wrap3<CalculatorArity, right_expr, State, Visitor>::type right_arity;
+
+ /*<< The return type is the maximum of the children's arities. >>*/
+ typedef typename mpl::max<left_arity, right_arity>::type type;
+ };
+
+ template<typename Expr, typename State, typename Visitor>
+ static typename apply<Expr, State, Visitor>::type
+ /*<< Transforms have a nested `call()` member function. >>*/
+ call(Expr const &, State const &, Visitor &)
+ {
+ /*<< The `binary_arity` transform doesn't have an interesting
+ runtime counterpart, so just return a default-constructed object
+ of the correct type. >>*/
+ return typename apply<Expr, State, Visitor>::type();
+ }
+};
+//]
+
+terminal< placeholder1 >::type const _1 = {{}};
+terminal< placeholder2 >::type const _2 = {{}};
+
+//[ CalculatorArityGrammar
+struct CalculatorArity
+ : or_<
+ case_< terminal< placeholder1 >, mpl::int_<1>() >
+ , case_< terminal< placeholder2 >, mpl::int_<2>() >
+ , case_< terminal<_>, mpl::int_<0>() >
+ , case_< unary_expr<_, _>, unary_arity >
+ , case_< binary_expr<_, _, _>, binary_arity >
+ >
+{};
+//]
+
+//[ CalculatorArityGrammar2
+struct CalcArity2
+ : or_<
+ case_< terminal< placeholder1 >, mpl::int_<1>() >
+ , case_< terminal< placeholder2 >, mpl::int_<2>() >
+ , case_< terminal<_>, mpl::int_<0>() >
+ , case_< unary_expr<_, CalcArity2> ***, _arg >
+ , case_< binary_expr<_, CalcArity2, CalcArity2> ***, mpl::max<_left, _right>() >
+ >
+{};
+//]
+
+//[ AsArgList
+// This transform matches function invocations such as foo(1,'a',"b")
+// and transforms them into Fusion cons lists of their arguments. In this
+// case, the result would be cons(1, cons('a', cons("b", nil()))).
+struct ArgsAsList
+ : case_<
+ function<vararg<terminal<_> > >
+ /*<< Use a `reverse_fold<>` transform to iterate over the children
+ of this node in reverse order, building a fusion list from back to
+ front. >>*/
+ , reverse_fold<
+ /*<< The first child expression of a `function<>` node is the
+ function being invoked. We don't want that in our list, so use
+ the `pop_front<>` transform to remove it. >>*/
+ pop_front<_children>
+ /*<< `nil` is the initial state used by the `reverse_fold<>`
+ transform. >>*/
+ , fusion::nil()
+ /*<< Put the rest of the function arguments in a fusion cons
+ list. >>*/
+ , fusion::cons<_arg,_state>(_arg,_state)
+ >
+ >
+{};
+//]
+
+//[ FoldTreeToList
+// This grammar describes what counts as the terminals in expressions
+// of the form (_1=1,'a',"b"), which will be flattened using
+// reverse_fold_tree<> below.
+struct Terminals
+ : or_<
+ case_<assign<_, terminal<_> >, _arg_c<0, _right> >
+ , case_<terminal<_>, _arg >
+ >
+{};
+
+// This transform matches expressions of the form (_1=1,'a',"b")
+// (note the use of the comma operator) and transforms it into a
+// Fusion cons list of their arguments. In this case, the result
+// would be cons(1, cons('a', cons("b", nil()))).
+struct FoldTreeToList
+ /*<< Fold all terminals that are separated by commas into a Fusion cons list. >>*/
+ : reverse_fold_tree<comma<_,_>, fusion::nil(), fusion::cons<Terminals,_state>(Terminals,_state)>
+{};
+//]
+
+//[ Promote
+// This transform finds all float terminals in an expression and promotes
+// them to doubles.
+struct Promote
+ : or_<
+ /*<< Match a `terminal<float>`, then construct a
+ `terminal<double>::type` with the `float`. >>*/
+ case_<terminal<float>, terminal<double>::type(_arg) >
+ , case_<terminal<_> >
+ /*<< `nary_expr<>` has a pass-through transform which
+ will transform each child sub-expression using the
+ `Promote` transform. >>*/
+ , case_<nary_expr<_, vararg<Promote> > ***>
+ >
+{};
+//]
+
+//[ LazyMakePair
+struct make_pair_tag {};
+terminal<make_pair_tag>::type const make_pair_ = {{}};
+
+// This transform matches lazy function invocations like
+// `make_pair_(1, 3.14)` and actually builds a `std::pair<>`
+// from the arguments.
+struct MakePair
+ : case_<
+ /*<< Match expressions like `make_pair_(1, 3.14)` >>*/
+ function<terminal<make_pair_tag>, terminal<_>, terminal<_> >
+ /*<< Return `std::pair<F,S>(f,s)` where `f` and `s` are the
+ first and second arguments to the lazy `make_pair_()` function >>*/
+ , std::pair<_arg_c<0, _arg1>, _arg_c<0, _arg2> >
+ (_arg_c<0, _arg1>, _arg_c<0, _arg2>)
+ >
+{};
+//]
+
+//[ NegateInt
+struct NegateInt
+ : case_<terminal<int>, negate<_>(_)>
+{};
+//]
+
+#ifndef BOOST_MSVC
+//[ SquareAndPromoteInt
+struct SquareAndPromoteInt
+ : case_<
+ terminal<int>
+ , multiplies<terminal<long>::type, terminal<long>::type>::type
+ (terminal<long>::type(_arg), terminal<long>::type(_arg))
+ >
+{};
+//]
+#endif
+
+void test_examples()
+{
+ //[ CalculatorArityTest
+ int i = 0; // not used, dummy state and visitor parameter
+
+ std::cout << CalculatorArity::call( lit(100) * 200, i, i) << '\n';
+ std::cout << CalculatorArity::call( (_1 - _1) / _1 * 100, i, i) << '\n';
+ std::cout << CalculatorArity::call( (_2 - _1) / _2 * 100, i, i) << '\n';
+ //]
+
+ BOOST_CHECK_EQUAL(0, CalculatorArity::call( lit(100) * 200, i, i));
+ BOOST_CHECK_EQUAL(1, CalculatorArity::call( (_1 - _1) / _1 * 100, i, i));
+ BOOST_CHECK_EQUAL(2, CalculatorArity::call( (_2 - _1) / _2 * 100, i, i));
+
+ BOOST_CHECK_EQUAL(0, CalcArity2::call( lit(100) * 200, i, i));
+ BOOST_CHECK_EQUAL(1, CalcArity2::call( (_1 - _1) / _1 * 100, i, i));
+ BOOST_CHECK_EQUAL(2, CalcArity2::call( (_2 - _1) / _2 * 100, i, i));
+
+ using boost::fusion::cons;
+ using boost::fusion::nil;
+ cons<int, cons<char, cons<char const (&)[2]> > > args(ArgsAsList::call( _1(1, 'a', "b"), i, i ));
+ BOOST_CHECK_EQUAL(args.car, 1);
+ BOOST_CHECK_EQUAL(args.cdr.car, 'a');
+ BOOST_CHECK_EQUAL(args.cdr.cdr.car, std::string("b"));
+
+ cons<int, cons<char, cons<char const (&)[2]> > > lst(FoldTreeToList::call( (_1 = 1, 'a', "b"), i, i ));
+ BOOST_CHECK_EQUAL(lst.car, 1);
+ BOOST_CHECK_EQUAL(lst.cdr.car, 'a');
+ BOOST_CHECK_EQUAL(lst.cdr.cdr.car, std::string("b"));
+
+ plus<
+ terminal<double>::type
+ , terminal<double>::type
+ >::type p = Promote::call( lit(1.f) + 2.f, i, i );
+
+ //[ LazyMakePairTest
+ int j = 0; // not used, dummy state and visitor parameter
+
+ std::pair<int, double> p2 = MakePair::call( make_pair_(1, 3.14), j, j );
+
+ std::cout << p2.first << std::endl;
+ std::cout << p2.second << std::endl;
+ //]
+
+ BOOST_CHECK_EQUAL(p2.first, 1);
+ BOOST_CHECK_EQUAL(p2.second, 3.14);
+
+ NegateInt::call(lit(1), i, i);
+#ifndef BOOST_MSVC
+ SquareAndPromoteInt::call(lit(1), i, i);
+#endif
+}
+
+using namespace boost::unit_test;
+///////////////////////////////////////////////////////////////////////////////
+// init_unit_test_suite
+//
+test_suite* init_unit_test_suite( int argc, char* argv[] )
+{
+ test_suite *test = BOOST_TEST_SUITE("test examples from the documentation");
+
+ test->add(BOOST_TEST_CASE(&test_examples));
+
+ return test;
+}
Added: branches/proto/v3/libs/xpressive/proto3/test/lambda.cpp
==============================================================================
--- (empty file)
+++ branches/proto/v3/libs/xpressive/proto3/test/lambda.cpp 2007-11-07 17:03:47 EST (Wed, 07 Nov 2007)
@@ -0,0 +1,220 @@
+///////////////////////////////////////////////////////////////////////////////
+// lambda.hpp
+//
+// Copyright 2006 Eric Niebler. Distributed under the Boost
+// Software License, Version 1.0. (See accompanying file
+// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#include <sstream>
+#include <boost/version.hpp>
+#include <boost/mpl/int.hpp>
+#include <boost/mpl/min_max.hpp>
+#include <boost/mpl/eval_if.hpp>
+#include <boost/mpl/next_prior.hpp>
+#if BOOST_VERSION < 103500
+# include <boost/spirit/fusion/sequence/at.hpp>
+# include <boost/spirit/fusion/sequence/tuple.hpp>
+namespace boost { namespace fusion { namespace result_of { using namespace meta; }}}
+#else
+# include <boost/fusion/include/tuple.hpp>
+#endif
+#include <boost/typeof/typeof.hpp>
+#include <boost/typeof/std/sstream.hpp>
+#include <boost/typeof/std/ostream.hpp>
+#include <boost/typeof/std/iostream.hpp>
+#include <boost/type_traits/add_const.hpp>
+#include <boost/type_traits/add_reference.hpp>
+#include <boost/xpressive/proto3/proto.hpp>
+#include <boost/xpressive/proto3/context.hpp>
+#include <boost/xpressive/proto3/transform/arg.hpp>
+#include <boost/xpressive/proto3/transform/fold.hpp>
+#include <boost/xpressive/proto3/transform/apply.hpp>
+#include <boost/test/unit_test.hpp>
+#include <boost/test/floating_point_comparison.hpp>
+
+using namespace boost;
+
+// Forward declaration of the lambda expression wrapper
+template<typename T>
+struct lambda;
+
+struct lambda_domain
+ : proto::domain<proto::pod_generator<lambda> >
+{};
+
+template<typename I>
+struct placeholder
+{
+ typedef I arity;
+};
+
+// Some custom transforms for calculating the max arity of a lambda expression
+template<typename Grammar>
+struct max_arity
+ : Grammar
+{
+ template<typename Expr, typename State, typename Visitor>
+ struct apply
+ {
+ typedef typename Grammar::template apply<Expr, State, Visitor>::type arity;
+ typedef typename mpl::max<arity, State>::type type;
+ };
+};
+
+template<typename Grammar>
+struct placeholder_arity
+ : Grammar
+{
+ template<typename Expr, typename, typename>
+ struct apply
+ : mpl::next<typename proto::result_of::arg<Expr>::type::arity>
+ {};
+};
+
+using proto::_;
+
+// The lambda grammar, with the transforms for calculating the max arity
+struct LambdaGrammar
+ : proto::or_<
+ placeholder_arity< proto::terminal< placeholder<_> > >
+ , proto::transform::always< proto::terminal<_>, mpl::int_<0> >
+ , proto::transform::fold<
+ proto::nary_expr<_, proto::vararg< max_arity< LambdaGrammar > > >
+ >
+ >
+{};
+
+// simple wrapper for calculating a lambda expression's arity.
+template<typename Expr>
+struct lambda_arity
+ : LambdaGrammar::apply<Expr, mpl::int_<0>, mpl::void_>
+{};
+
+// The lambda context is the same as the default context
+// with the addition of special handling for lambda placeholders
+template<typename Tuple>
+struct lambda_context
+{
+ lambda_context(Tuple const &args)
+ : args_(args)
+ {}
+
+ template<typename Expr, typename EnableIf = void>
+ struct eval
+ : proto::default_eval<Expr, lambda_context<Tuple> >
+ {};
+
+ template<typename Expr>
+ struct eval<Expr, typename enable_if<proto::matches<Expr, proto::terminal<placeholder<_> > > >::type>
+ {
+ typedef typename proto::result_of::arg<Expr>::type::arity index;
+ typedef typename fusion::result_of::at<Tuple, index>::type result_type;
+ result_type operator()(Expr const &expr, lambda_context<Tuple> &ctx)
+ {
+#if BOOST_VERSION < 103500
+ return fusion::at<index::value>(ctx.args_);
+#else
+ return fusion::at<index>(ctx.args_);
+#endif
+ }
+ };
+
+ Tuple args_;
+};
+
+// The lambda<> expression wrapper makes expressions polymorphic
+// function objects
+template<typename T>
+struct lambda
+{
+ BOOST_PROTO_EXTENDS(T, lambda<T>, lambda_domain)
+ BOOST_PROTO_EXTENDS_ASSIGN(T, lambda<T>, lambda_domain)
+ BOOST_PROTO_EXTENDS_SUBSCRIPT(T, lambda<T>, lambda_domain)
+
+ // Careful not to evaluate the return type of the nullary function
+ // unless we have a nullary lambda!
+ typedef typename mpl::eval_if<
+ typename lambda_arity<T>::type
+ , mpl::identity<void>
+ , proto::result_of::eval<T const, lambda_context<fusion::tuple<> > >
+ >::type nullary_type;
+
+ // Define our operator() that evaluates the lambda expression.
+ nullary_type operator()() const
+ {
+ fusion::tuple<> args;
+ lambda_context<fusion::tuple<> > ctx(args);
+ return proto::eval(*this, ctx);
+ }
+
+ template<typename A0>
+ typename proto::result_of::eval<T const, lambda_context<fusion::tuple<A0 const &> > >::type
+ operator()(A0 const &a0) const
+ {
+ fusion::tuple<A0 const &> args(a0);
+ lambda_context<fusion::tuple<A0 const &> > ctx(args);
+ return proto::eval(*this, ctx);
+ }
+
+ template<typename A0, typename A1>
+ typename proto::result_of::eval<T const, lambda_context<fusion::tuple<A0 const &, A1 const &> > >::type
+ operator()(A0 const &a0, A1 const &a1) const
+ {
+ fusion::tuple<A0 const &, A1 const &> args(a0, a1);
+ lambda_context<fusion::tuple<A0 const &, A1 const &> > ctx(args);
+ return proto::eval(*this, ctx);
+ }
+};
+
+// Define some lambda placeholders
+lambda<proto::terminal<placeholder<mpl::int_<0> > >::type> const _1 = {{}};
+lambda<proto::terminal<placeholder<mpl::int_<1> > >::type> const _2 = {{}};
+
+template<typename T>
+lambda<typename proto::terminal<T>::type> const val(T const &t)
+{
+ lambda<typename proto::terminal<T>::type> that = {{t}};
+ return that;
+}
+
+template<typename T>
+lambda<typename proto::terminal<T &>::type> const var(T &t)
+{
+ lambda<typename proto::terminal<T &>::type> that = {{t}};
+ return that;
+}
+
+void test_lambda()
+{
+ BOOST_CHECK_EQUAL(11, ( (_1 + 2) / 4 )(42));
+ BOOST_CHECK_EQUAL(-11, ( (-(_1 + 2)) / 4 )(42));
+ BOOST_CHECK_CLOSE(2.58, ( (4 - _2) * 3 )(42, 3.14), 0.1);
+
+ // check non-const ref terminals
+ std::stringstream sout;
+ (sout << _1 << " -- " << _2)(42, "Life, the Universe and Everything!");
+ BOOST_CHECK_EQUAL("42 -- Life, the Universe and Everything!", sout.str());
+
+ // check nullary lambdas
+ BOOST_CHECK_EQUAL(3, (val(1) + val(2))());
+
+ // check array indexing for kicks
+ int integers[5] = {0};
+ (var(integers)[2] = 2)();
+ (var(integers)[_1] = _1)(3);
+ BOOST_CHECK_EQUAL(2, integers[2]);
+ BOOST_CHECK_EQUAL(3, integers[3]);
+}
+
+using namespace unit_test;
+///////////////////////////////////////////////////////////////////////////////
+// init_unit_test_suite
+//
+test_suite* init_unit_test_suite( int argc, char* argv[] )
+{
+ test_suite *test = BOOST_TEST_SUITE("test expression template domains");
+
+ test->add(BOOST_TEST_CASE(&test_lambda));
+
+ return test;
+}
Added: branches/proto/v3/libs/xpressive/proto3/test/lambda2.cpp
==============================================================================
--- (empty file)
+++ branches/proto/v3/libs/xpressive/proto3/test/lambda2.cpp 2007-11-07 17:03:47 EST (Wed, 07 Nov 2007)
@@ -0,0 +1,203 @@
+///////////////////////////////////////////////////////////////////////////////
+// lambda.hpp
+//
+// Copyright 2006 Eric Niebler. Distributed under the Boost
+// Software License, Version 1.0. (See accompanying file
+// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#include <sstream>
+#include <boost/version.hpp>
+#include <boost/mpl/int.hpp>
+#include <boost/mpl/min_max.hpp>
+#include <boost/mpl/eval_if.hpp>
+#include <boost/mpl/identity.hpp>
+#include <boost/mpl/next_prior.hpp>
+#if BOOST_VERSION < 103500
+# include <boost/spirit/fusion/sequence/at.hpp>
+# include <boost/spirit/fusion/sequence/tuple.hpp>
+namespace boost { namespace fusion { namespace result_of { using namespace meta; }}}
+#else
+# include <boost/fusion/tuple.hpp>
+#endif
+#include <boost/typeof/typeof.hpp>
+#include <boost/typeof/std/sstream.hpp>
+#include <boost/typeof/std/ostream.hpp>
+#include <boost/typeof/std/iostream.hpp>
+#include <boost/type_traits/add_const.hpp>
+#include <boost/type_traits/add_reference.hpp>
+#include <boost/xpressive/proto3/proto.hpp>
+#include <boost/xpressive/proto3/context.hpp>
+#include <boost/xpressive/proto3/transform2.hpp>
+#include <boost/test/unit_test.hpp>
+#include <boost/test/floating_point_comparison.hpp>
+
+using namespace boost;
+
+// Forward declaration of the lambda expression wrapper
+template<typename T>
+struct lambda;
+
+struct lambda_domain
+ : proto::domain<proto::pod_generator<lambda> >
+{};
+
+template<typename I>
+struct placeholder
+{
+ typedef I arity;
+};
+
+template<typename T>
+struct placeholder_arity
+{
+ typedef typename T::arity type;
+};
+
+namespace grammar
+{
+ using namespace proto;
+
+ // The lambda grammar, with the transforms for calculating the max arity
+ struct Lambda
+ : or_<
+ case_< terminal< placeholder<_> >, mpl::next<placeholder_arity<_arg> >() >
+ , case_< terminal<_>, mpl::int_<0>() >
+ , case_< nary_expr<_, vararg<_> >, fold<_children, mpl::int_<0>(), mpl::max<Lambda,_state>()> >
+ >
+ {};
+}
+
+// simple wrapper for calculating a lambda expression's arity.
+template<typename Expr>
+struct lambda_arity
+ : grammar::Lambda::apply<Expr, mpl::void_, mpl::void_>
+{};
+
+// The lambda context is the same as the default context
+// with the addition of special handling for lambda placeholders
+template<typename Tuple>
+struct lambda_context
+ : proto::callable_context<lambda_context<Tuple> const>
+{
+ lambda_context(Tuple const &args)
+ : args_(args)
+ {}
+
+ template<typename Sig>
+ struct result;
+
+ template<typename This, typename I>
+ struct result<This(proto::tag::terminal, placeholder<I> const &)>
+ : fusion::result_of::at<Tuple, I>
+ {};
+
+ template<typename I>
+ typename fusion::result_of::at<Tuple, I>::type
+ operator ()(proto::tag::terminal, placeholder<I> const &) const
+ {
+ #if BOOST_VERSION < 103500
+ return fusion::at<I::value>(this->args_);
+ #else
+ return fusion::at<I>(this->args_);
+ #endif
+ }
+
+ Tuple args_;
+};
+
+// The lambda<> expression wrapper makes expressions polymorphic
+// function objects
+template<typename T>
+struct lambda
+{
+ BOOST_PROTO_EXTENDS(T, lambda<T>, lambda_domain)
+ BOOST_PROTO_EXTENDS_ASSIGN(T, lambda<T>, lambda_domain)
+ BOOST_PROTO_EXTENDS_SUBSCRIPT(T, lambda<T>, lambda_domain)
+
+ // Careful not to evaluate the return type of the nullary function
+ // unless we have a nullary lambda!
+ typedef typename mpl::eval_if<
+ typename lambda_arity<T>::type
+ , mpl::identity<void>
+ , proto::result_of::eval<T const, lambda_context<fusion::tuple<> > >
+ >::type nullary_type;
+
+ // Define our operator() that evaluates the lambda expression.
+ nullary_type operator()() const
+ {
+ fusion::tuple<> args;
+ lambda_context<fusion::tuple<> > ctx(args);
+ return proto::eval(*this, ctx);
+ }
+
+ template<typename A0>
+ typename proto::result_of::eval<T const, lambda_context<fusion::tuple<A0 const &> > >::type
+ operator()(A0 const &a0) const
+ {
+ fusion::tuple<A0 const &> args(a0);
+ lambda_context<fusion::tuple<A0 const &> > ctx(args);
+ return proto::eval(*this, ctx);
+ }
+
+ template<typename A0, typename A1>
+ typename proto::result_of::eval<T const, lambda_context<fusion::tuple<A0 const &, A1 const &> > >::type
+ operator()(A0 const &a0, A1 const &a1) const
+ {
+ fusion::tuple<A0 const &, A1 const &> args(a0, a1);
+ lambda_context<fusion::tuple<A0 const &, A1 const &> > ctx(args);
+ return proto::eval(*this, ctx);
+ }
+};
+
+// Define some lambda placeholders
+lambda<proto::terminal<placeholder<mpl::int_<0> > >::type> const _1 = {{}};
+lambda<proto::terminal<placeholder<mpl::int_<1> > >::type> const _2 = {{}};
+
+template<typename T>
+lambda<typename proto::terminal<T>::type> const val(T const &t)
+{
+ lambda<typename proto::terminal<T>::type> that = {{t}};
+ return that;
+}
+
+template<typename T>
+lambda<typename proto::terminal<T &>::type> const var(T &t)
+{
+ lambda<typename proto::terminal<T &>::type> that = {{t}};
+ return that;
+}
+
+void test_lambda()
+{
+ BOOST_CHECK_EQUAL(11, ( (_1 + 2) / 4 )(42));
+ BOOST_CHECK_EQUAL(-11, ( (-(_1 + 2)) / 4 )(42));
+ BOOST_CHECK_CLOSE(2.58, ( (4 - _2) * 3 )(42, 3.14), 0.1);
+
+ // check non-const ref terminals
+ std::stringstream sout;
+ (sout << _1 << " -- " << _2)(42, "Life, the Universe and Everything!");
+ BOOST_CHECK_EQUAL("42 -- Life, the Universe and Everything!", sout.str());
+
+ // check nullary lambdas
+ BOOST_CHECK_EQUAL(3, (val(1) + val(2))());
+
+ // check array indexing for kicks
+ int integers[5] = {0};
+ (var(integers)[2] = 2)();
+ (var(integers)[_1] = _1)(3);
+ BOOST_CHECK_EQUAL(2, integers[2]);
+ BOOST_CHECK_EQUAL(3, integers[3]);
+}
+
+using namespace unit_test;
+///////////////////////////////////////////////////////////////////////////////
+// init_unit_test_suite
+//
+test_suite* init_unit_test_suite( int argc, char* argv[] )
+{
+ test_suite *test = BOOST_TEST_SUITE("test expression template domains");
+
+ test->add(BOOST_TEST_CASE(&test_lambda));
+
+ return test;
+}
Added: branches/proto/v3/libs/xpressive/proto3/test/main.cpp
==============================================================================
--- (empty file)
+++ branches/proto/v3/libs/xpressive/proto3/test/main.cpp 2007-11-07 17:03:47 EST (Wed, 07 Nov 2007)
@@ -0,0 +1,327 @@
+//#define BOOST_STRICT_CONFIG
+
+int isblank; // BUGBUG
+#include <cstdio>
+#include <iostream>
+#include <typeinfo>
+#include <boost/mpl/assert.hpp>
+#include <boost/mpl/min_max.hpp>
+#include <boost/fusion/include/cons.hpp>
+#include <boost/fusion/include/pop_front.hpp>
+#include <boost/fusion/include/reverse.hpp>
+#include <boost/xpressive/proto3/proto.hpp>
+#include <boost/xpressive/proto3/transform/arg.hpp>
+#include <boost/xpressive/proto3/transform/bind.hpp>
+#include <boost/xpressive/proto3/transform/fold.hpp>
+#include <boost/xpressive/proto3/transform/fold_tree.hpp>
+
+#include <boost/xpressive/proto3/eval.hpp>
+#include <boost/xpressive/proto3/context/default.hpp>
+#include <boost/xpressive/proto3/context/callable.hpp>
+
+namespace boost { namespace fusion
+{
+ inline std::ostream &operator<<(std::ostream &sout, nil)
+ {
+ return sout << "<nil>";
+ }
+}}
+
+using namespace boost::proto;
+using namespace transform;
+namespace mpl = boost::mpl;
+namespace fusion = boost::fusion;
+
+struct any_tag {};
+struct Any : terminal<any_tag> {};
+struct Char : terminal<char> {};
+
+terminal<any_tag>::type char_;
+
+template<typename Grammar, typename Expr>
+void check(Expr const &)
+{
+ BOOST_MPL_ASSERT((matches<Expr, Grammar>));
+}
+
+template<typename Grammar, typename Expr>
+void check_not(Expr const &)
+{
+ BOOST_MPL_ASSERT_NOT((matches<Expr, Grammar>));
+}
+
+template<typename T, typename U>
+struct pair
+{};
+
+struct make_negate : function_transform
+{
+ template<typename Sig> struct result;
+
+ template<typename This, typename T>
+ struct result<This(T)>
+ : negate<T>
+ {};
+
+ template<typename T>
+ typename negate<T>::type
+ operator()(T const &t) const
+ {
+ typename negate<T>::type that = {t};
+ return that;
+ }
+};
+
+struct pop_front : function_transform
+{
+ template<typename Sig> struct result;
+
+ template<typename This, typename T>
+ struct result<This(T)>
+ : fusion::result_of::pop_front<T const>
+ {};
+
+ template<typename T>
+ typename fusion::result_of::pop_front<T const>::type
+ operator()(T const &t) const
+ {
+ return fusion::pop_front(t);
+ }
+};
+
+//struct reverse : function_transform
+//{
+// template<typename Sig> struct result;
+//
+// template<typename This, typename T>
+// struct result<This(T)>
+// : fusion::result_of::reverse<T const>
+// {};
+//
+// template<typename T>
+// typename fusion::result_of::reverse<T const>::type
+// operator()(T const &t) const
+// {
+// return fusion::reverse(t);
+// }
+//};
+
+//struct make_cons : function_transform
+//{
+// template<typename Sig> struct result;
+//
+// template<typename This, typename T, typename U>
+// struct result<This(T, U)>
+// {
+// typedef fusion::cons<T, U> type;
+// };
+//
+// template<typename T, typename U>
+// fusion::cons<T, U>
+// operator()(T const &t, U const &u) const
+// {
+// return fusion::cons<T, U>(t, u);
+// }
+//};
+
+// perhaps change the default transform from pass-through to make-node, to
+// be compatible with the ops role as a meta-function.
+struct Promote
+ : or_<
+ case_< terminal<float>, terminal<double>::type(_arg) >
+ , case_< posit<Promote>, make_negate(Promote(_arg)) >
+ , case_< terminal<char const *>, std::string(_arg) >
+ , case_< terminal<_> >
+ , case_< nary_expr<_, vararg<Promote> > >
+ >
+{};
+
+template<typename Int>
+struct placeholder : Int
+{};
+
+struct zero : mpl::int_<0> {};
+struct one : mpl::int_<1> {};
+struct two : mpl::int_<2> {};
+terminal<placeholder<one> >::type const _1 = {};
+terminal<placeholder<two> >::type const _2 = {};
+
+struct Arity
+ : or_<
+ case_< terminal<placeholder<_> >
+ , _arg
+ >
+ , case_< terminal<_>
+ , zero()
+ >
+ , case_< nary_expr<_, vararg<Arity> >
+ , fold<_, zero(), mpl::max<Arity, _state>() >
+ >
+ >
+{};
+
+struct ArgsAsList
+ : case_<
+ function<terminal<_>, vararg<terminal<_> > >
+ , reverse_fold<
+ pop_front(_) // make (_) optional
+ , fusion::nil()
+ , fusion::cons<_arg, _state>(_arg, _state)
+ >
+ >
+{};
+
+struct FoldTreeToList
+ : or_<
+ case_<assign<_, terminal<_> >
+ , _arg(_right)
+ >
+ , case_<terminal<_>
+ , _arg
+ >
+ , case_<
+ comma<FoldTreeToList, FoldTreeToList>
+ , reverse_fold_tree<
+ _
+ , fusion::nil()
+ , fusion::cons<FoldTreeToList, _state>(FoldTreeToList, _state)
+ >
+ >
+ >
+{};
+
+struct noncopy
+{
+ noncopy() {}
+ ~noncopy() {}
+private:
+ noncopy(const noncopy &);
+ noncopy &operator=(const noncopy &);
+};
+
+struct disp
+{
+ template<typename T>
+ void operator()(T const &t) const
+ {
+ std::printf("%s\n", typeid(T).name());
+ }
+};
+
+int main()
+{
+ int dummy=0;
+ noncopy non_;
+
+ terminal<int>::type u = {42};
+ terminal<int>::type const t = {42};
+
+ int j=0;
+
+ expr<tag::function,
+ args<
+ expr<tag::terminal, term<int> > const &
+ , expr<tag::terminal, term<int const &> >
+ , expr<tag::terminal, term<int &> >
+ , expr<tag::terminal, term<int> > const &
+ >
+ > that = t(1,j,t);
+
+ function<
+ expr<tag::terminal, term<int> > const &
+ , expr<tag::terminal, term<int const &> >
+ , expr<tag::terminal, term<int &> >
+ , expr<tag::terminal, term<int> > const &
+ >::type other = t(1,j,t);
+
+ expr<tag::assign,
+ args<
+ expr<tag::terminal, term<int> > const &
+ , expr<tag::terminal, term<int const &> >
+ >
+ > that2 = (t = 1);
+
+ expr<tag::posit,
+ args<expr<tag::terminal, term<int> > const &>
+ > that3 = +t;
+
+ expr<tag::posit,
+ args<expr<tag::terminal, term<int> > &>
+ > that4 = +u;
+
+ expr<tag::plus,
+ args<
+ expr<tag::terminal, term<int> > &
+ , expr<tag::terminal, term<int &> >
+ >
+ > that5 = u + j;
+
+ std::printf("%d %d\n", arg_c<0>(arg_c<0>(that5)), arg_c<0>(arg_c<1>(that5)));
+
+ check<_>(u+j);
+ check<terminal<int> >(u);
+ check<plus<terminal<int>, terminal<int&> > >(u + j);
+ check<plus<terminal<int>, terminal<int> > >(u + j);
+
+ terminal<pair<int,double> >::type w = {};
+ check<terminal<pair<int,double> > >(w);
+ check<terminal<pair<_,double> > >(w);
+
+ check<
+ or_<
+ minus<terminal<int>, terminal<int> >
+ , plus<terminal<int>, terminal<int> >
+ >
+ >(u + j);
+
+ check<function<Any> >(char_());
+ check<function<Any, Char, Char> >(char_('a', 'b'));
+
+ check_not<function<Any, Char> >(char_());
+ check<function<Any, Char> >(char_('a'));
+ check_not<function<Any, Char> >(char_('a', 'b'));
+
+ check<function<Any, vararg<Char> > >(char_());
+ check<function<Any, vararg<Char> > >(char_('a'));
+ check<function<Any, vararg<Char> > >(char_('a', 'b'));
+
+ terminal<float>::type ff = {1.F};
+ check<Promote>(ff+ff);
+ plus<terminal<double>::type, terminal<double>::type>::type dd =
+ Promote::call(ff+ff, dummy, non_);
+
+ plus<terminal<double>::type, terminal<int>::type>::type du =
+ Promote::call(ff+u, dummy, non_);
+ std::printf("%g %d\n", arg_c<0>(arg_c<0>(du)), arg_c<0>(arg_c<1>(du)));
+
+ plus<negate<terminal<double>::type>::type, terminal<int>::type>::type ndu =
+ Promote::call(+ff+u, dummy, non_);
+ std::printf("%g %d\n", arg_c<0>(arg_c<0>(arg_c<0>(ndu))), arg_c<0>(arg_c<1>(ndu)));
+
+ terminal<char const *>::type sz = {"hello"};
+ std::string str = Promote::call(sz, dummy, non_);
+
+ std::printf(
+ "%d %d %d\n"
+ , (int)Arity::call(sz, dummy, non_)
+ , (int)Arity::call(_1 + 0, dummy, non_)
+ , (int)Arity::call(_2 + _1, dummy, non_)
+ );
+
+ using fusion::cons;
+ cons<char, cons<int, cons<float> > > mylist1 =
+ ArgsAsList::call(_1('a', 42, 3.14f), dummy, non_);
+ std::cout << mylist1.car << ' ' << mylist1.cdr.car << ' ' << mylist1.cdr.cdr.car << std::endl;
+
+ cons<int, cons<char, cons<std::string> > > mylist2
+ (FoldTreeToList::call( (_1 = 1, 'a', str), dummy, non_ ));
+ std::cout << mylist2.car << ' ' << mylist2.cdr.car << ' ' << mylist2.cdr.cdr.car << std::endl;
+
+
+ //default_context ctx;
+ //int r1 = eval(as_expr(1) + as_expr(2), ctx);
+ //std::cout << r1 << std::endl;
+
+
+ return 0;
+}
Added: branches/proto/v3/libs/xpressive/proto3/test/matches.cpp
==============================================================================
--- (empty file)
+++ branches/proto/v3/libs/xpressive/proto3/test/matches.cpp 2007-11-07 17:03:47 EST (Wed, 07 Nov 2007)
@@ -0,0 +1,258 @@
+///////////////////////////////////////////////////////////////////////////////
+// matches.hpp
+//
+// Copyright 2006 Eric Niebler. Distributed under the Boost
+// Software License, Version 1.0. (See accompanying file
+// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+int isblank;
+
+//// BUGBUG
+//#include <cstdlib>
+//#include <cstddef>
+//#include <cstdio>
+//#include <cstdarg>
+//#include <cstring>
+
+#include <string>
+#include <iostream>
+#include <boost/mpl/assert.hpp>
+#include <boost/mpl/placeholders.hpp>
+#include <boost/type_traits/is_same.hpp>
+#include <boost/xpressive/proto3/proto.hpp>
+//#include <boost/test/included/unit_test.hpp>
+
+using namespace boost;
+using namespace proto;
+
+template<typename Grammar, typename Expr>
+void assert_matches(Expr const &expr)
+{
+ BOOST_MPL_ASSERT((matches<Expr, Grammar>));
+}
+
+template<typename Grammar, typename Expr>
+void assert_not_matches(Expr const &expr)
+{
+ BOOST_MPL_ASSERT_NOT((matches<Expr, Grammar>));
+}
+
+struct int_convertible
+{
+ int_convertible() {}
+ operator int() const { return 0; }
+};
+
+struct Input
+ : or_<
+ shift_right< terminal< std::istream & >, _ >
+ , shift_right< Input, _ >
+ >
+{};
+
+struct Output
+ : or_<
+ shift_left< terminal< std::ostream & >, _ >
+ , shift_left< Output, _ >
+ >
+{};
+
+terminal< std::istream & >::type const cin_ = {{ std::cin }};
+terminal< std::ostream & >::type const cout_ = {{ std::cout }};
+
+struct Anything
+ : or_<
+ terminal<_>
+ , nary_expr<_, vararg<Anything> >
+ >
+{};
+
+void a_function() {}
+
+struct MyCases
+{
+ template<typename Tag>
+ struct case_
+ : proto::not_<proto::_>
+ {};
+};
+
+template<>
+struct MyCases::case_<proto::tag::shift_right>
+ : proto::_
+{};
+
+template<>
+struct MyCases::case_<proto::tag::plus>
+ : proto::_
+{};
+
+enum binary_representation_enum
+{
+ magnitude
+ , two_complement
+};
+
+typedef
+ mpl::integral_c<binary_representation_enum, magnitude>
+magnitude_c;
+
+typedef
+ mpl::integral_c<binary_representation_enum, two_complement>
+two_complement_c;
+
+template<typename Type, typename Representation>
+struct number
+{};
+
+struct NumberGrammar
+ : proto::or_ <
+ proto::terminal<number<proto::_, two_complement_c> >
+ , proto::terminal<number<proto::_, magnitude_c> >
+ >
+{};
+
+
+void test_matches()
+{
+ assert_matches< _ >( lit(1) );
+ assert_matches< _ >( as_arg(1) );
+ assert_matches< _ >( as_expr(1) );
+
+ assert_matches< terminal<int> >( lit(1) );
+ assert_matches< terminal<int> >( as_arg(1) );
+ assert_matches< terminal<int> >( as_expr(1) );
+
+ assert_not_matches< terminal<int> >( lit('a') );
+ assert_not_matches< terminal<int> >( as_arg('a') );
+ assert_not_matches< terminal<int> >( as_expr('a') );
+
+ assert_matches< terminal<convertible_to<int> > >( lit('a') );
+ assert_matches< terminal<convertible_to<int> > >( as_arg('a') );
+ assert_matches< terminal<convertible_to<int> > >( as_expr('a') );
+
+ assert_not_matches< terminal<int> >( lit((int_convertible())) );
+ assert_not_matches< terminal<int> >( as_arg((int_convertible())) );
+ assert_not_matches< terminal<int> >( as_expr((int_convertible())) );
+
+ assert_matches< terminal<convertible_to<int> > >( lit((int_convertible())) );
+ assert_matches< terminal<convertible_to<int> > >( as_arg((int_convertible())) );
+ assert_matches< terminal<convertible_to<int> > >( as_expr((int_convertible())) );
+
+ assert_matches< if_<is_same<proto::result_of::arg<mpl::_>, int> > >( lit(1) );
+ assert_not_matches< if_<is_same<proto::result_of::arg<mpl::_>, int> > >( lit('a') );
+
+ assert_matches<
+ and_<
+ terminal<_>
+ , if_<is_same<proto::result_of::arg<mpl::_>, int> >
+ >
+ >( lit(1) );
+
+ assert_not_matches<
+ and_<
+ terminal<_>
+ , if_<is_same<proto::result_of::arg<mpl::_>, int> >
+ >
+ >( lit('a') );
+
+ assert_matches< terminal<char const *> >( lit("hello") );
+ assert_matches< terminal<char const *> >( as_arg("hello") );
+ assert_matches< terminal<char const *> >( as_expr("hello") );
+
+ assert_matches< terminal<char const (&)[6]> >( lit("hello") );
+ assert_matches< terminal<char const (&)[6]> >( as_arg("hello") );
+ assert_matches< terminal<char const (&)[6]> >( as_expr("hello") );
+
+ assert_matches< terminal<char const (&)[N]> >( lit("hello") );
+ assert_matches< terminal<char const (&)[N]> >( as_arg("hello") );
+ assert_matches< terminal<char const (&)[N]> >( as_expr("hello") );
+
+ assert_matches< terminal<std::string> >( lit(std::string("hello")) );
+ assert_matches< terminal<std::string> >( as_arg(std::string("hello")) );
+ assert_matches< terminal<std::string> >( as_expr(std::string("hello")) );
+
+ assert_matches< terminal<std::basic_string<_> > >( lit(std::string("hello")) );
+ assert_matches< terminal<std::basic_string<_> > >( as_arg(std::string("hello")) );
+ assert_matches< terminal<std::basic_string<_> > >( as_expr(std::string("hello")) );
+
+ assert_not_matches< terminal<std::basic_string<_> > >( lit(1) );
+ assert_not_matches< terminal<std::basic_string<_> > >( as_arg(1) );
+ assert_not_matches< terminal<std::basic_string<_> > >( as_expr(1) );
+
+ assert_not_matches< terminal<std::basic_string<_,_,_> > >( lit(1) );
+ assert_not_matches< terminal<std::basic_string<_,_,_> > >( as_arg(1) );
+ assert_not_matches< terminal<std::basic_string<_,_,_> > >( as_expr(1) );
+
+ assert_matches< terminal<std::basic_string<_> const & > >( lit(std::string("hello")) );
+ assert_matches< terminal<std::basic_string<_> const & > >( as_arg(std::string("hello")) );
+ assert_not_matches< terminal<std::basic_string<_> const & > >( as_expr(std::string("hello")) );
+
+ assert_matches< terminal< void(&)() > >( lit(a_function) );
+ assert_matches< terminal< void(&)() > >( as_arg(a_function) );
+ assert_matches< terminal< void(&)() > >( as_expr(a_function) );
+
+ assert_not_matches< terminal< void(*)() > >( lit(a_function) );
+ assert_not_matches< terminal< void(*)() > >( as_arg(a_function) );
+ assert_not_matches< terminal< void(*)() > >( as_expr(a_function) );
+
+ assert_matches< terminal< convertible_to<void(*)()> > >( lit(a_function) );
+ assert_matches< terminal< convertible_to<void(*)()> > >( as_arg(a_function) );
+ assert_matches< terminal< convertible_to<void(*)()> > >( as_expr(a_function) );
+
+ assert_matches< terminal< void(*)() > >( lit(&a_function) );
+ assert_matches< terminal< void(*)() > >( as_arg(&a_function) );
+ assert_matches< terminal< void(*)() > >( as_expr(&a_function) );
+
+ assert_matches< terminal< void(* const &)() > >( lit(&a_function) );
+ assert_matches< terminal< void(* const &)() > >( as_arg(&a_function) );
+ assert_not_matches< terminal< void(* const &)() > >( as_expr(&a_function) );
+
+ assert_matches<
+ or_<
+ if_<is_same<proto::result_of::arg<mpl::_>, char> >
+ , if_<is_same<proto::result_of::arg<mpl::_>, int> >
+ >
+ >( lit(1) );
+
+ assert_not_matches<
+ or_<
+ if_<is_same<proto::result_of::arg<mpl::_>, char> >
+ , if_<is_same<proto::result_of::arg<mpl::_>, int> >
+ >
+ >( lit(1u) );
+
+ assert_matches< Input >( cin_ >> 1 >> 2 >> 3 );
+ assert_not_matches< Output >( cin_ >> 1 >> 2 >> 3 );
+
+ assert_matches< Output >( cout_ << 1 << 2 << 3 );
+ assert_not_matches< Input >( cout_ << 1 << 2 << 3 );
+
+ assert_matches< function< terminal<int>, vararg< terminal<char> > > >( lit(1)('a','b','c','d') );
+ assert_not_matches< function< terminal<int>, vararg< terminal<char> > > >( lit(1)('a','b','c',"d") );
+
+ assert_matches< Anything >( cout_ << 1 << +lit('a') << lit(1)('a','b','c',"d") );
+
+ assert_matches< proto::switch_<MyCases> >( lit(1) >> 'a' );
+ assert_matches< proto::switch_<MyCases> >( lit(1) + 'a' );
+ assert_not_matches< proto::switch_<MyCases> >( lit(1) << 'a' );
+
+ number<int, two_complement_c> num;
+ assert_matches<NumberGrammar>(proto::as_expr(num));
+}
+
+//using namespace unit_test;
+/////////////////////////////////////////////////////////////////////////////////
+//// init_unit_test_suite
+////
+//test_suite* init_unit_test_suite( int argc, char* argv[] )
+//{
+// test_suite *test = BOOST_TEST_SUITE("test proto::matches<>");
+//
+// test->add(BOOST_TEST_CASE(&test_matches));
+//
+// return test;
+//}
+
+int main()
+{}
Added: branches/proto/v3/libs/xpressive/proto3/test/proto_fusion.cpp
==============================================================================
--- (empty file)
+++ branches/proto/v3/libs/xpressive/proto3/test/proto_fusion.cpp 2007-11-07 17:03:47 EST (Wed, 07 Nov 2007)
@@ -0,0 +1,127 @@
+///////////////////////////////////////////////////////////////////////////////
+// proto_fusion.cpp
+//
+// Copyright 2006 Eric Niebler. Distributed under the Boost
+// Software License, Version 1.0. (See accompanying file
+// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/version.hpp>
+#if BOOST_VERSION < 103500
+# error This test only works on Boost v1.35
+#endif
+
+#include <boost/xpressive/proto3/proto.hpp>
+#include <boost/xpressive/proto3/fusion.hpp>
+#include <boost/fusion/include/for_each.hpp>
+#include <boost/test/unit_test.hpp>
+#include <boost/utility/addressof.hpp>
+#include <sstream>
+
+boost::proto::terminal<char>::type a_ = {'a'};
+boost::proto::terminal<char>::type b_ = {'b'};
+boost::proto::terminal<char>::type c_ = {'c'};
+boost::proto::terminal<char>::type d_ = {'d'};
+boost::proto::terminal<char>::type e_ = {'e'};
+boost::proto::terminal<char>::type f_ = {'f'};
+boost::proto::terminal<char>::type g_ = {'g'};
+boost::proto::terminal<char>::type h_ = {'h'};
+boost::proto::terminal<char>::type i_ = {'i'};
+
+std::ostream &operator <<(std::ostream &sout, boost::proto::tag::shift_right)
+{
+ return sout << ">>";
+}
+
+std::ostream &operator <<(std::ostream &sout, boost::proto::tag::bitwise_or)
+{
+ return sout << "|";
+}
+
+template<typename Args>
+std::ostream &operator <<(std::ostream &sout, boost::proto::expr<boost::proto::tag::terminal, Args, 0> const *op)
+{
+ return sout << boost::proto::arg(*op);
+}
+
+template<typename Tag, typename Args>
+std::ostream &operator <<(std::ostream &sout, boost::proto::expr<Tag, Args, 1> const *op)
+{
+ return sout << Tag() << boost::addressof(boost::proto::arg(*op));
+}
+
+template<typename Tag, typename Args>
+std::ostream &operator <<(std::ostream &sout, boost::proto::expr<Tag, Args, 2> const *op)
+{
+ return sout << boost::addressof(boost::proto::left(*op)) << Tag() << boost::addressof(boost::proto::right(*op));
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// to_string
+//
+struct to_string
+{
+ to_string(std::ostream &sout)
+ : sout_(sout)
+ {}
+
+ template<typename Op>
+ void operator()(Op const &op) const
+ {
+ this->sout_ << '(' << boost::addressof(op) << ')';
+ }
+private:
+ std::ostream &sout_;
+};
+
+void test1()
+{
+ std::stringstream sout;
+
+ // Test for 1-way branching "tree"
+ sout.str("");
+ boost::fusion::for_each(!!!!(a_ >> b_), to_string(sout));
+ BOOST_CHECK_EQUAL("(a>>b)", sout.str());
+
+ // Tests for 2-way branching trees
+ sout.str("");
+ boost::fusion::for_each(a_ >> b_ >> c_, to_string(sout));
+ BOOST_CHECK_EQUAL("(a)(b)(c)", sout.str());
+
+ sout.str("");
+ boost::fusion::for_each(a_ | b_ | c_, to_string(sout));
+ BOOST_CHECK_EQUAL("(a)(b)(c)", sout.str());
+
+ sout.str("");
+ boost::fusion::for_each(a_ >> b_ | c_ >> d_, to_string(sout));
+ BOOST_CHECK_EQUAL("(a>>b)(c>>d)", sout.str());
+
+ sout.str("");
+ boost::fusion::for_each(a_ | b_ >> c_ | d_, to_string(sout));
+ BOOST_CHECK_EQUAL("(a)(b>>c)(d)", sout.str());
+
+ sout.str("");
+ boost::fusion::for_each(a_ >> b_ | c_ >> d_ | e_ >> f_ >> g_, to_string(sout));
+ BOOST_CHECK_EQUAL("(a>>b)(c>>d)(e>>f>>g)", sout.str());
+
+ sout.str("");
+ boost::fusion::for_each(a_ >> b_ | c_ >> d_ | e_ >> (f_ | g_) >> h_, to_string(sout));
+ BOOST_CHECK_EQUAL("(a>>b)(c>>d)(e>>f|g>>h)", sout.str());
+
+ // Test for n-way branching tree
+ sout.str("");
+ boost::fusion::for_each(a_(b_(c_ >> d_, e_ | f_), g_ >> h_)(i_), to_string(sout));
+ BOOST_CHECK_EQUAL("(a)(b)(c>>d)(e|f)(g>>h)(i)", sout.str());
+}
+
+using namespace boost::unit_test;
+///////////////////////////////////////////////////////////////////////////////
+// init_unit_test_suite
+//
+test_suite* init_unit_test_suite( int argc, char* argv[] )
+{
+ test_suite *test = BOOST_TEST_SUITE("test proto and fusion integration");
+
+ test->add(BOOST_TEST_CASE(&test1));
+
+ return test;
+}
Added: branches/proto/v3/libs/xpressive/proto3/test/proto_fusion_s.cpp
==============================================================================
--- (empty file)
+++ branches/proto/v3/libs/xpressive/proto3/test/proto_fusion_s.cpp 2007-11-07 17:03:47 EST (Wed, 07 Nov 2007)
@@ -0,0 +1,197 @@
+///////////////////////////////////////////////////////////////////////////////
+// proto_fusion_s.cpp
+//
+// Copyright 2006 Eric Niebler. Distributed under the Boost
+// Software License, Version 1.0. (See accompanying file
+// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/version.hpp>
+#if BOOST_VERSION < 103500
+# error This test only works on Boost v1.35
+#endif
+
+#include <boost/xpressive/proto3/proto.hpp>
+#include <boost/xpressive/proto3/fusion.hpp>
+#include <boost/fusion/algorithm/iteration/ext_/for_each_s.hpp>
+#include <boost/test/unit_test.hpp>
+#include <boost/utility/addressof.hpp>
+#include <sstream>
+
+std::ostream &operator <<(std::ostream &sout, boost::proto::tag::shift_right)
+{
+ return sout << ">>";
+}
+
+std::ostream &operator <<(std::ostream &sout, boost::proto::tag::bitwise_or)
+{
+ return sout << "|";
+}
+
+template<typename Args>
+std::ostream &operator <<(std::ostream &sout, boost::proto::expr<boost::proto::tag::terminal, Args, 0> const *op)
+{
+ return sout << boost::proto::arg(*op);
+}
+
+template<typename Tag, typename Args>
+std::ostream &operator <<(std::ostream &sout, boost::proto::expr<Tag, Args, 1> const *op)
+{
+ return sout << Tag() << boost::addressof(boost::proto::arg(*op).proto_base());
+}
+
+template<typename Tag, typename Args>
+std::ostream &operator <<(std::ostream &sout, boost::proto::expr<Tag, Args, 2> const *op)
+{
+ return sout << boost::addressof(boost::proto::left(*op).proto_base()) << Tag() << boost::addressof(boost::proto::right(*op).proto_base());
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// to_string
+//
+struct to_string
+{
+ to_string(std::ostream &sout)
+ : sout_(sout)
+ {}
+
+ template<typename Op>
+ void operator()(Op const &op) const
+ {
+ this->sout_ << '(' << boost::addressof(op.proto_base()) << ')';
+ }
+private:
+ std::ostream &sout_;
+};
+
+void test1()
+{
+ boost::proto::terminal<char>::type a_ = {'a'};
+ boost::proto::terminal<char>::type b_ = {'b'};
+ boost::proto::terminal<char>::type c_ = {'c'};
+ boost::proto::terminal<char>::type d_ = {'d'};
+ boost::proto::terminal<char>::type e_ = {'e'};
+ boost::proto::terminal<char>::type f_ = {'f'};
+ boost::proto::terminal<char>::type g_ = {'g'};
+ boost::proto::terminal<char>::type h_ = {'h'};
+ boost::proto::terminal<char>::type i_ = {'i'};
+
+ std::stringstream sout;
+
+ // Test for 1-way branching "tree"
+ sout.str("");
+ boost::fusion::for_each_s(!!!!(a_ >> b_), to_string(sout));
+ BOOST_CHECK_EQUAL("(a>>b)", sout.str());
+
+ // Tests for 2-way branching trees
+ sout.str("");
+ boost::fusion::for_each_s(a_ >> b_ >> c_, to_string(sout));
+ BOOST_CHECK_EQUAL("(a)(b)(c)", sout.str());
+
+ sout.str("");
+ boost::fusion::for_each_s(a_ | b_ | c_, to_string(sout));
+ BOOST_CHECK_EQUAL("(a)(b)(c)", sout.str());
+
+ sout.str("");
+ boost::fusion::for_each_s(a_ >> b_ | c_ >> d_, to_string(sout));
+ BOOST_CHECK_EQUAL("(a>>b)(c>>d)", sout.str());
+
+ sout.str("");
+ boost::fusion::for_each_s(a_ | b_ >> c_ | d_, to_string(sout));
+ BOOST_CHECK_EQUAL("(a)(b>>c)(d)", sout.str());
+
+ sout.str("");
+ boost::fusion::for_each_s(a_ >> b_ | c_ >> d_ | e_ >> f_ >> g_, to_string(sout));
+ BOOST_CHECK_EQUAL("(a>>b)(c>>d)(e>>f>>g)", sout.str());
+
+ sout.str("");
+ boost::fusion::for_each_s(a_ >> b_ | c_ >> d_ | e_ >> (f_ | g_) >> h_, to_string(sout));
+ BOOST_CHECK_EQUAL("(a>>b)(c>>d)(e>>f|g>>h)", sout.str());
+
+ // Test for n-way branching tree
+ sout.str("");
+ boost::fusion::for_each_s(a_(b_(c_ >> d_, e_ | f_), g_ >> h_)(i_), to_string(sout));
+ BOOST_CHECK_EQUAL("(a)(b)(c>>d)(e|f)(g>>h)(i)", sout.str());
+}
+
+////////////////////////////////////////////////////////////////////////
+// Test that EXTENDS expression wrappers are also valid fusion sequences
+
+template<typename Expr>
+struct My;
+
+struct MyDomain
+ : boost::proto::domain<boost::proto::pod_generator<My> >
+{};
+
+template<typename Expr>
+struct My
+{
+ BOOST_PROTO_EXTENDS(Expr, My<Expr>, MyDomain)
+ BOOST_PROTO_EXTENDS_ASSIGN(Expr, My<Expr>, MyDomain)
+ BOOST_PROTO_EXTENDS_SUBSCRIPT(Expr, My<Expr>, MyDomain)
+ BOOST_PROTO_EXTENDS_FUNCTION(Expr, My<Expr>, MyDomain)
+};
+
+void test2()
+{
+ My<boost::proto::terminal<char>::type> a_ = {{'a'}};
+ My<boost::proto::terminal<char>::type> b_ = {{'b'}};
+ My<boost::proto::terminal<char>::type> c_ = {{'c'}};
+ My<boost::proto::terminal<char>::type> d_ = {{'d'}};
+ My<boost::proto::terminal<char>::type> e_ = {{'e'}};
+ My<boost::proto::terminal<char>::type> f_ = {{'f'}};
+ My<boost::proto::terminal<char>::type> g_ = {{'g'}};
+ My<boost::proto::terminal<char>::type> h_ = {{'h'}};
+ My<boost::proto::terminal<char>::type> i_ = {{'i'}};
+
+ std::stringstream sout;
+
+ // Test for 1-way branching "tree"
+ sout.str("");
+ boost::fusion::for_each_s(!!!!(a_ >> b_), to_string(sout));
+ BOOST_CHECK_EQUAL("(a>>b)", sout.str());
+
+ // Tests for 2-way branching trees
+ sout.str("");
+ boost::fusion::for_each_s(a_ >> b_ >> c_, to_string(sout));
+ BOOST_CHECK_EQUAL("(a)(b)(c)", sout.str());
+
+ sout.str("");
+ boost::fusion::for_each_s(a_ | b_ | c_, to_string(sout));
+ BOOST_CHECK_EQUAL("(a)(b)(c)", sout.str());
+
+ sout.str("");
+ boost::fusion::for_each_s(a_ >> b_ | c_ >> d_, to_string(sout));
+ BOOST_CHECK_EQUAL("(a>>b)(c>>d)", sout.str());
+
+ sout.str("");
+ boost::fusion::for_each_s(a_ | b_ >> c_ | d_, to_string(sout));
+ BOOST_CHECK_EQUAL("(a)(b>>c)(d)", sout.str());
+
+ sout.str("");
+ boost::fusion::for_each_s(a_ >> b_ | c_ >> d_ | e_ >> f_ >> g_, to_string(sout));
+ BOOST_CHECK_EQUAL("(a>>b)(c>>d)(e>>f>>g)", sout.str());
+
+ sout.str("");
+ boost::fusion::for_each_s(a_ >> b_ | c_ >> d_ | e_ >> (f_ | g_) >> h_, to_string(sout));
+ BOOST_CHECK_EQUAL("(a>>b)(c>>d)(e>>f|g>>h)", sout.str());
+
+ // Test for n-way branching tree
+ sout.str("");
+ boost::fusion::for_each_s(a_(b_(c_ >> d_, e_ | f_), g_ >> h_)(i_), to_string(sout));
+ BOOST_CHECK_EQUAL("(a)(b)(c>>d)(e|f)(g>>h)(i)", sout.str());
+}
+
+using namespace boost::unit_test;
+///////////////////////////////////////////////////////////////////////////////
+// init_unit_test_suite
+//
+test_suite* init_unit_test_suite( int argc, char* argv[] )
+{
+ test_suite *test = BOOST_TEST_SUITE("test proto and segmented fusion integration");
+
+ test->add(BOOST_TEST_CASE(&test1));
+ test->add(BOOST_TEST_CASE(&test2));
+
+ return test;
+}
Added: branches/proto/v3/libs/xpressive/proto3/test/toy_spirit.cpp
==============================================================================
--- (empty file)
+++ branches/proto/v3/libs/xpressive/proto3/test/toy_spirit.cpp 2007-11-07 17:03:47 EST (Wed, 07 Nov 2007)
@@ -0,0 +1,692 @@
+///////////////////////////////////////////////////////////////////////////////
+// toy_spirit.hpp
+//
+// Copyright 2006 Eric Niebler. Distributed under the Boost
+// Software License, Version 1.0. (See accompanying file
+// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#include <cctype>
+#include <string>
+#include <iostream>
+#include <boost/assert.hpp>
+#include <boost/mpl/assert.hpp>
+#include <boost/xpressive/proto3/proto.hpp>
+#include <boost/xpressive/proto3/context.hpp>
+#include <boost/test/unit_test.hpp>
+
+namespace boost
+{
+ // global tags
+ struct char_tag {};
+ struct ichar_tag {};
+ struct istring_tag {};
+ struct ichar_range_tag {};
+ struct never_tag {};
+ struct always_tag {};
+ struct space_tag {};
+
+ // global primitives
+ proto::terminal<char_tag>::type const char_ = {{}};
+ proto::terminal<space_tag>::type const space = {{}};
+
+ using proto::lit;
+ using proto::literal;
+}
+
+namespace boost { namespace spirit2
+{
+
+ // handy typedefs
+ typedef proto::terminal<char_tag>::type anychar_p;
+ typedef proto::terminal<ichar_tag>::type ianychar_p;
+ typedef proto::terminal<istring_tag>::type ianystr_p;
+ typedef proto::terminal<ichar_range_tag>::type ianychar_range_p;
+ typedef proto::terminal<never_tag>::type never_p;
+ typedef proto::terminal<space_tag>::type space_p;
+
+ struct SpiritGrammar;
+ struct SkipperGrammar;
+ struct SpiritPrimitives;
+ template<typename Grammar>
+ struct SpiritComposites;
+
+ struct CharLiteral
+ : proto::terminal<char>
+ {};
+
+ struct NTBSLiteral
+ : proto::terminal<char const *>
+ {};
+
+ struct StdStringLiteral
+ : proto::terminal<std::string>
+ {};
+
+ struct CharParser
+ : proto::function<anychar_p, CharLiteral>
+ {};
+
+ struct ICharParser
+ : proto::function<ianychar_p, CharLiteral, CharLiteral>
+ {};
+
+ struct CharRangeParser
+ : proto::function<anychar_p, CharLiteral, CharLiteral>
+ {};
+
+ struct IStrParser
+ : proto::function<ianystr_p, StdStringLiteral>
+ {};
+
+ struct ICharRangeParser
+ : proto::function<ianychar_range_p, CharLiteral, CharLiteral>
+ {};
+
+ ianychar_p const ichar_ = {{}};
+ ianystr_p const istr_ = {{}};
+ ianychar_range_p const ichar_range_ = {{}};
+
+ namespace utility
+ {
+ inline bool char_icmp(char ch, char lo, char hi)
+ {
+ return ch == lo || ch == hi;
+ }
+
+ template<typename FwdIter>
+ inline bool string_cmp(char const *sz, FwdIter &begin, FwdIter end)
+ {
+ FwdIter tmp = begin;
+ for(; *sz; ++tmp, ++sz)
+ if(tmp == end || *tmp != *sz)
+ return false;
+ begin = tmp;
+ return true;
+ }
+
+ template<typename FwdIter>
+ inline bool string_icmp(std::string const &str, FwdIter &begin, FwdIter end)
+ {
+ BOOST_ASSERT(0 == str.size() % 2);
+ FwdIter tmp = begin;
+ std::string::const_iterator istr = str.begin(), estr = str.end();
+ for(; istr != estr; ++tmp, istr += 2)
+ if(tmp == end || *tmp != *istr && *tmp != *(istr+1))
+ return false;
+ begin = tmp;
+ return true;
+ }
+
+ inline bool in_range(char ch, char lo, char hi)
+ {
+ return ch >= lo && ch <= hi;
+ }
+
+ inline bool in_irange(char ch, char lo, char hi)
+ {
+ return in_range(ch, lo, hi)
+ || in_range(std::tolower(ch), lo, hi)
+ || in_range(std::toupper(ch), lo, hi);
+ }
+
+ inline std::string to_istr(char const *sz)
+ {
+ std::string res;
+ res.reserve(std::strlen(sz) * 2);
+ for(; *sz; ++sz)
+ {
+ res.push_back(std::tolower(*sz));
+ res.push_back(std::toupper(*sz));
+ }
+ return res;
+ }
+ } // namespace utility
+
+ template<typename FwdIter, typename Skipper = never_p>
+ struct spirit_context
+ : std::pair<FwdIter, FwdIter>
+ , proto::callable_context<spirit_context<FwdIter, Skipper> >
+ {
+ typedef bool result_type;
+ typedef FwdIter iterator;
+
+ spirit_context(FwdIter first, FwdIter second, Skipper const &skip = Skipper())
+ : std::pair<FwdIter, FwdIter>(first, second)
+ , skip_(skip)
+ , in_skip_(false)
+ {}
+
+ // parse function for anychar_p
+ bool operator()(proto::tag::terminal, char_tag)
+ {
+ this->skip();
+ if(this->first == this->second)
+ return false;
+ ++this->first;
+ return true;
+ }
+
+ // parse function for char_('a')
+ template<typename Expr>
+ bool operator()(proto::tag::function, anychar_p, Expr const &expr)
+ {
+ this->skip();
+ return proto::eval(expr, *this);
+ }
+
+ // parse function for space_p
+ bool operator()(proto::tag::terminal, space_tag)
+ {
+ this->skip();
+ if(this->first == this->second || !std::isspace(*this->first))
+ return false;
+ ++this->first;
+ return true;
+ }
+
+ // parse function for bare character literals
+ bool operator()(proto::tag::terminal, char ch)
+ {
+ this->skip();
+ if(this->first == this->second || *this->first != ch)
+ return false;
+ ++this->first;
+ return true;
+ }
+
+ // case-insensitive character parser
+ template<typename Arg1, typename Arg2>
+ bool operator()(proto::tag::function, ianychar_p, Arg1 const &arg1, Arg2 const &arg2)
+ {
+ this->skip();
+ if(this->first == this->second
+ || !utility::char_icmp(*this->first, proto::arg(arg1), proto::arg(arg2)))
+ return false;
+ ++this->first;
+ return true;
+ }
+
+ // parse function for NTBS literals
+ bool operator()(proto::tag::terminal, char const *sz)
+ {
+ this->skip();
+ return utility::string_cmp(sz, this->first, this->second);
+ }
+
+ // parse function for istr_("hello")
+ template<typename Expr>
+ bool operator()(proto::tag::function, ianystr_p, Expr const &expr)
+ {
+ this->skip();
+ return utility::string_icmp(proto::arg(expr), this->first, this->second);
+ }
+
+ // parse function for char_('a','z')
+ template<typename Arg1, typename Arg2>
+ bool operator()(proto::tag::function, anychar_p, Arg1 const &arg1, Arg2 const &arg2)
+ {
+ BOOST_ASSERT(proto::arg(arg1) <= proto::arg(arg2));
+ this->skip();
+ if(this->first == this->second
+ || !utility::in_range(*this->first, proto::arg(arg1), proto::arg(arg2)))
+ return false;
+ ++this->first;
+ return true;
+ }
+
+ // parse function for ichar_range_('a','z')
+ template<typename Arg1, typename Arg2>
+ bool operator()(proto::tag::function, ianychar_range_p, Arg1 const &arg1, Arg2 const &arg2)
+ {
+ BOOST_ASSERT(proto::arg(arg1) <= proto::arg(arg2));
+ this->skip();
+ if(this->first == this->second
+ || !utility::in_irange(*this->first, proto::arg(arg1), proto::arg(arg2)))
+ return false;
+ ++this->first;
+ return true;
+ }
+
+ // parse function for complemented thingies (where thingies are assumed
+ // to be 1 character wide).
+ template<typename Expr>
+ bool operator()(proto::tag::complement, Expr const &expr)
+ {
+ this->skip();
+ iterator where = this->first;
+ if(proto::eval(expr, *this))
+ return this->first = where, false;
+ this->first = ++where;
+ return true;
+ }
+
+ // never_p parse function always returns false.
+ bool operator()(proto::tag::terminal, never_tag)
+ {
+ return false;
+ }
+
+ // for A >> B, succeeds if A and B matches.
+ template<typename Left, typename Right>
+ bool operator()(proto::tag::shift_right, Left const &left, Right const &right)
+ {
+ return proto::eval(left, *this) && proto::eval(right, *this);
+ }
+
+ // for A | B, succeeds if either A or B matches at this point.
+ template<typename Left, typename Right>
+ bool operator()(proto::tag::bitwise_or, Left const &left, Right const &right)
+ {
+ iterator where = this->first;
+ return proto::eval(left, *this) || proto::eval(right, this->reset(where));
+ }
+
+ // for *A, greedily match A as many times as possible.
+ template<typename Expr>
+ bool operator()(proto::tag::dereference, Expr const &expr)
+ {
+ iterator where = this->first;
+ while(proto::eval(expr, *this))
+ where = this->first;
+ // make sure that when we return true, the iterator is at the correct position!
+ this->first = where;
+ return true;
+ }
+
+ // for +A, greedily match A one or more times.
+ template<typename Expr>
+ bool operator()(proto::tag::posit, Expr const &expr)
+ {
+ return proto::eval(expr, *this) && proto::eval(*expr, *this);
+ }
+
+ // for !A, optionally match A.
+ template<typename Expr>
+ bool operator()(proto::tag::logical_not, Expr const &expr)
+ {
+ iterator where = this->first;
+ if(!proto::eval(expr, *this))
+ this->first = where;
+ return true;
+ }
+
+ // for (A - B), matches when A but not B matches.
+ template<typename Left, typename Right>
+ bool operator()(proto::tag::minus, Left const &left, Right const &right)
+ {
+ iterator where = this->first;
+ return !proto::eval(right, *this) && proto::eval(left, this->reset(where));
+ }
+ private:
+ spirit_context &reset(iterator where)
+ {
+ this->first = where;
+ return *this;
+ }
+
+ void skip()
+ {
+ if(!this->in_skip_)
+ {
+ this->in_skip_ = true;
+ while(proto::eval(this->skip_, *this))
+ {}
+ this->in_skip_ = false;
+ }
+ }
+
+ Skipper skip_;
+ bool in_skip_;
+ };
+
+ // remove_case
+ template<typename Grammar>
+ struct remove_case;
+
+ template<>
+ struct remove_case<CharParser>
+ {
+ typedef proto::function<
+ ianychar_p
+ , proto::terminal<char>::type
+ , proto::terminal<char>::type
+ >::type type;
+
+ template<typename Expr>
+ static type call(Expr const &expr)
+ {
+ char lo = std::tolower(proto::arg(proto::arg_c<1>(expr)));
+ char hi = std::toupper(proto::arg(proto::arg_c<1>(expr)));
+ type that = {ichar_, {lo}, {hi}};
+ return that;
+ }
+ };
+
+ template<>
+ struct remove_case<CharRangeParser>
+ {
+ typedef proto::function<
+ ianychar_range_p
+ , proto::terminal<char>::type
+ , proto::terminal<char>::type
+ >::type type;
+
+ template<typename Expr>
+ static type call(Expr const &expr)
+ {
+ char lo = proto::arg(proto::arg_c<1>(expr));
+ char hi = proto::arg(proto::arg_c<2>(expr));
+ type that = {ichar_range_, {lo}, {hi}};
+ return that;
+ }
+ };
+
+ template<>
+ struct remove_case<CharLiteral>
+ {
+ typedef proto::function<
+ ianychar_p
+ , proto::terminal<char>::type
+ , proto::terminal<char>::type
+ >::type type;
+
+ template<typename Expr>
+ static type call(Expr const &expr)
+ {
+ char lo = std::tolower(proto::arg(expr));
+ char hi = std::toupper(proto::arg(expr));
+ type that = {ichar_, {lo}, {hi}};
+ return that;
+ }
+ };
+
+ template<>
+ struct remove_case<NTBSLiteral>
+ {
+ typedef proto::function<
+ ianystr_p
+ , proto::terminal<std::string>::type
+ >::type type;
+
+ template<typename Expr>
+ static type call(Expr const &expr)
+ {
+ type that = {istr_, {utility::to_istr(proto::arg(expr))}};
+ return that;
+ }
+ };
+
+ template<>
+ struct remove_case<StdStringLiteral>
+ {
+ typedef proto::function<
+ ianystr_p
+ , proto::terminal<std::string>::type
+ >::type type;
+
+ template<typename Expr>
+ static type call(Expr const &expr)
+ {
+ type that = {istr_, {utility::to_istr(proto::arg(expr).c_str())}};
+ return that;
+ }
+ };
+
+ ///////////////////////////////////////////////////////////////////////////
+ // Transforms
+ ///////////////////////////////////////////////////////////////////////////
+
+ template<typename Grammar>
+ struct case_sensitive
+ : Grammar
+ {
+ template<typename Expr, typename State, typename Visitor>
+ struct apply
+ : remove_case<Grammar>
+ {};
+
+ template<typename Expr, typename State, typename Visitor>
+ static typename apply<Expr, State, Visitor>::type
+ call(Expr const &expr, State const &, Visitor &)
+ {
+ return apply<Expr, State, Visitor>::call(expr);
+ }
+ };
+
+ template<typename Grammar>
+ struct skip_primitives
+ : Grammar
+ {
+ skip_primitives();
+
+ template<typename Expr, typename State, typename Visitor>
+ struct apply
+ {
+ typedef typename proto::shift_right<
+ typename proto::dereference<State>::type
+ , Expr
+ >::type type;
+ };
+
+ template<typename Expr, typename State, typename Visitor>
+ static typename apply<Expr, State, Visitor>::type
+ call(Expr const &expr, State const &state, Visitor &visitor)
+ {
+ typedef typename apply<Expr, State, Visitor>::type type;
+ type that = {{state}, expr};
+ return that;
+ }
+ };
+
+ ///////////////////////////////////////////////////////////////////////////
+ // Grammar
+ ///////////////////////////////////////////////////////////////////////////
+
+ struct SpiritGrammar;
+
+ struct SpiritCaseSensitivePrimitives
+ : proto::or_<
+ case_sensitive<CharParser>
+ , case_sensitive<CharLiteral>
+ , case_sensitive<NTBSLiteral>
+ , case_sensitive<CharRangeParser>
+ , case_sensitive<StdStringLiteral>
+ >
+ {};
+
+ struct SpiritCaseInsensitivePrimitives
+ : proto::or_<
+ anychar_p
+ , IStrParser
+ , ICharParser
+ , ICharRangeParser
+ , proto::complement<SpiritPrimitives>
+ >
+ {};
+
+ struct SpiritPrimitives
+ : proto::or_<
+ SpiritCaseSensitivePrimitives
+ , SpiritCaseInsensitivePrimitives
+ >
+ {};
+
+ template<typename Grammar>
+ struct SpiritComposites
+ : proto::or_<
+ proto::bitwise_or< Grammar, Grammar >
+ , proto::shift_right< Grammar, Grammar >
+ , proto::minus< Grammar, Grammar >
+ , proto::dereference< Grammar >
+ , proto::posit< Grammar >
+ , proto::logical_not< Grammar >
+ >
+ {};
+
+ // Regular Spirit grammar, has no-case transforms
+ struct SpiritGrammar
+ : proto::or_<
+ SpiritComposites<SpiritGrammar>
+ , SpiritPrimitives
+ >
+ {};
+
+ // Spirit grammar with the skipper transform
+ struct SkipperGrammar
+ : proto::or_<
+ SpiritComposites<SkipperGrammar>
+ , skip_primitives<SpiritPrimitives>
+ >
+ {};
+
+ ///////////////////////////////////////////////////////////////////////////
+ // Directives
+ ///////////////////////////////////////////////////////////////////////////
+
+ struct no_case_directive
+ {
+ template<typename Expr>
+ typename SpiritGrammar::apply<Expr, mpl::void_, mpl::void_>::type const
+ operator [](Expr const &expr) const
+ {
+ mpl::void_ null;
+ return SpiritGrammar::call(expr, null, null);
+ }
+ };
+
+ // no_case
+ no_case_directive const no_case = {};
+
+ template<typename Skipper>
+ struct skip_directive
+ {
+ skip_directive(Skipper const &skip)
+ : skip_(skip)
+ {}
+
+ template<typename Expr>
+ typename SkipperGrammar::apply<Expr, Skipper, mpl::void_>::type const
+ operator [](Expr const &expr) const
+ {
+ mpl::void_ null;
+ return SkipperGrammar::call(expr, this->skip_, null);
+ }
+ private:
+ Skipper skip_;
+ };
+
+ // skip
+ template<typename Skipper>
+ skip_directive<Skipper> skip(Skipper const &skip)
+ {
+ return skip_directive<Skipper>(skip);
+ }
+
+ ///////////////////////////////////////////////////////////////////////////
+ // parse
+ ///////////////////////////////////////////////////////////////////////////
+
+ template<typename FwdIter, typename Rule>
+ bool parse(FwdIter begin, FwdIter end, Rule const &rule)
+ {
+ // make sure the rule corresponds to the Spirit grammar:
+ BOOST_MPL_ASSERT((proto::matches<Rule, SpiritGrammar>));
+
+ spirit_context<FwdIter> ctx(begin, end);
+ return proto::eval(rule, ctx);
+ }
+
+ // parse with a skip parser can be implemented in one of two ways:
+ // Method 1)
+ // The skip parser is passed to all the parsers which invoke it
+ // before they invoke themselves. This is how Spirit-1 does it,
+ // and it is the cause of the Scanner Business. However, it has
+ // the advantage of not needing a parser transformation phase.
+ // Method 2)
+ // Transform the expression template to insert the skip parser
+ // in between all sequenced parsers. That is, transform (A >> B)
+ // to (*skip >> A >> *skip >> B). This has the advantage of making
+ // it unnecessary to pass the scanner to all the parsers, which
+ // means its type doesn't show up in function signatures, avoiding
+ // the Scanner Business.
+ // Recommendation:
+ // Both methods should be supported. Method 1 should be preferred
+ // when calling parse with parsers defined inline. Method 2 should
+ // be preferred when a parser expression is assigned to a rule<>,
+ // thereby making the type of the rule<> independent of the skip
+ // parser used. I imagine a syntax like:
+ // rule<> r = skip(space)[A >> B >> C]
+ template<typename FwdIter, typename Rule, typename Skipper>
+ bool parse(FwdIter begin, FwdIter end, Rule const &rule, Skipper const &skipper)
+ {
+ // make sure the rule corresponds to the Spirit grammar:
+ BOOST_MPL_ASSERT((proto::matches<Rule, SpiritGrammar>));
+
+ //// Method 1: pass skip parser in the context structure.
+ //spirit_context<FwdIter, Skipper> ctx(begin, end, skipper);
+ //return proto::eval(rule, ctx);
+
+ // Method 2: Embed skip parser via tree transformation.
+ spirit_context<FwdIter> ctx(begin, end);
+ return proto::eval(spirit2::skip(skipper)[rule], ctx);
+ }
+
+}}
+
+using namespace boost;
+using namespace spirit2;
+
+void test_toy_spirit()
+{
+ std::string str("abcd");
+
+ // This will fail:
+ BOOST_CHECK(!spirit2::parse(str.begin(), str.end()
+ , char_ >> char_('a')));
+
+ // This will succeed:
+ BOOST_CHECK(spirit2::parse(str.begin(), str.end()
+ , char_ >> char_('b') >> char_ >> 'd'));
+
+ // This will succeed:
+ BOOST_CHECK(spirit2::parse(str.begin(), str.end()
+ , 'a' >> ('c' >> char_ | 'b' >> char_('d') | 'b' >> char_('c')) >> 'd'));
+
+ // This will succeed:
+ BOOST_CHECK(spirit2::parse(str.begin(), str.end()
+ , *(char_ - 'd')));
+
+ // This will succeed:
+ BOOST_CHECK(spirit2::parse(str.begin(), str.end()
+ , no_case[char_('A') >> 'B' >> "CD"]));
+
+ // This will succeed:
+ BOOST_CHECK(spirit2::parse(str.begin(), str.end()
+ , no_case[*char_('A','Z')]));
+
+ literal<char> a = lit('a');
+ literal<char const *> bcd = lit("bcd");
+
+ // This will succeed:
+ BOOST_CHECK(spirit2::parse(str.begin(), str.end()
+ , +~~a >> no_case[bcd]));
+
+ // Scanner Business: R.I.P. :-)
+ str = "a b cd";
+ BOOST_CHECK(spirit2::parse(str.begin(), str.end()
+ , char_('a') >> 'b' >> 'c' >> 'd', space >> space));
+
+}
+
+using namespace boost::unit_test;
+///////////////////////////////////////////////////////////////////////////////
+// init_unit_test_suite
+//
+test_suite* init_unit_test_suite( int argc, char* argv[] )
+{
+ test_suite *test = BOOST_TEST_SUITE("test proto and and toy spirit-2");
+
+ test->add(BOOST_TEST_CASE(&test_toy_spirit));
+
+ return test;
+}
Added: branches/proto/v3/libs/xpressive/proto3/test/toy_spirit2.cpp
==============================================================================
--- (empty file)
+++ branches/proto/v3/libs/xpressive/proto3/test/toy_spirit2.cpp 2007-11-07 17:03:47 EST (Wed, 07 Nov 2007)
@@ -0,0 +1,574 @@
+///////////////////////////////////////////////////////////////////////////////
+// toy_spirit2.cpp
+//
+// Copyright 2006 Eric Niebler. Distributed under the Boost
+// Software License, Version 1.0. (See accompanying file
+// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#include <cctype>
+#include <string>
+#include <iomanip>
+#include <iostream>
+#include <boost/assert.hpp>
+#include <boost/mpl/assert.hpp>
+#include <boost/utility/result_of.hpp>
+#include <boost/type_traits/is_same.hpp>
+#include <boost/xpressive/proto3/proto.hpp>
+#include <boost/xpressive/proto3/transform/arg.hpp>
+#include <boost/xpressive/proto3/transform/construct.hpp>
+#include <boost/xpressive/proto3/transform/fold_tree.hpp>
+#include <boost/xpressive/proto3/transform/list.hpp>
+#if BOOST_VERSION < 103500
+# include <boost/spirit/fusion/algorithm/for_each.hpp>
+# include <boost/spirit/fusion/algorithm/fold.hpp>
+# include <boost/spirit/fusion/algorithm/any.hpp>
+#else
+#include <boost/fusion/include/for_each.hpp>
+#include <boost/fusion/include/fold.hpp>
+#include <boost/fusion/include/any.hpp>
+#endif
+#include <boost/test/unit_test.hpp>
+
+namespace boost
+{
+ // global tags
+ struct char_tag {};
+ struct space_tag {};
+
+ // global primitives
+ proto::terminal<char_tag>::type const char_ = {{}};
+ proto::terminal<space_tag>::type const space = {{}};
+
+ using proto::lit;
+ using proto::literal;
+}
+
+namespace boost { namespace spirit2
+{
+ namespace utility
+ {
+ inline bool char_icmp(char ch, char lo, char hi)
+ {
+ return ch == lo || ch == hi;
+ }
+
+ template<typename FwdIter>
+ inline bool string_cmp(char const *sz, FwdIter &begin, FwdIter end)
+ {
+ FwdIter tmp = begin;
+ for(; *sz; ++tmp, ++sz)
+ if(tmp == end || *tmp != *sz)
+ return false;
+ begin = tmp;
+ return true;
+ }
+
+ template<typename FwdIter>
+ inline bool string_icmp(std::string const &str, FwdIter &begin, FwdIter end)
+ {
+ BOOST_ASSERT(0 == str.size() % 2);
+ FwdIter tmp = begin;
+ std::string::const_iterator istr = str.begin(), estr = str.end();
+ for(; istr != estr; ++tmp, istr += 2)
+ if(tmp == end || *tmp != *istr && *tmp != *(istr+1))
+ return false;
+ begin = tmp;
+ return true;
+ }
+
+ inline bool in_range(char ch, char lo, char hi)
+ {
+ return ch >= lo && ch <= hi;
+ }
+
+ inline bool in_irange(char ch, char lo, char hi)
+ {
+ return in_range(ch, lo, hi)
+ || in_range(std::tolower(ch), lo, hi)
+ || in_range(std::toupper(ch), lo, hi);
+ }
+
+ inline std::string to_istr(char const *sz)
+ {
+ std::string res;
+ res.reserve(std::strlen(sz) * 2);
+ for(; *sz; ++sz)
+ {
+ res.push_back(std::tolower(*sz));
+ res.push_back(std::toupper(*sz));
+ }
+ return res;
+ }
+ } // namespace utility
+
+ // Composite parser that contains a Fusion cons-list of other parsers
+ // OR
+ // A compiler that compiles an expression and wraps the result in
+ // a composite<> wrapper
+ template<typename Tag, typename List>
+ struct composite
+ {
+ composite(List const &list)
+ : elems(list)
+ {}
+
+ List elems;
+ };
+
+ template<typename Tag, typename Grammar>
+ struct as_composite
+ : Grammar
+ {
+ as_composite();
+
+ // The apply<> struct and the call() member are to satisfy the
+ // proto compiler/transform protocol
+ template<typename Expr, typename State, typename Visitor>
+ struct apply
+ {
+ typedef composite<
+ Tag
+ , typename Grammar::template apply<Expr, State, Visitor>::type
+ > type;
+ };
+
+ template<typename Expr, typename State, typename Visitor>
+ static typename apply<Expr, State, Visitor>::type
+ call(Expr const &expr, State const &state, Visitor &visitor)
+ {
+ return typename apply<Expr, State, Visitor>::type
+ (Grammar::call(expr, state, visitor));
+ }
+ };
+
+ struct char_range
+ : std::pair<char, char>
+ {
+ char_range(char from, char to)
+ : std::pair<char, char>(from, to)
+ {}
+ };
+
+ struct ichar
+ {
+ ichar(char ch)
+ : lo_(std::tolower(ch))
+ , hi_(std::toupper(ch))
+ {}
+
+ char lo_, hi_;
+ };
+
+ struct istr
+ {
+ istr(char const *sz)
+ : str_(utility::to_istr(sz))
+ {}
+
+ std::string str_;
+ };
+
+ struct ichar_range
+ : std::pair<char, char>
+ {
+ ichar_range(char_range const &rng)
+ : std::pair<char, char>(rng)
+ {}
+ };
+
+ // The no-case directive
+ struct no_case_tag {};
+
+ // The no-case transform, applies the tree-transform with
+ // mpl::true_ as the visitor.
+ template<typename Grammar>
+ struct no_case_transform
+ : Grammar
+ {
+ no_case_transform();
+
+ template<typename Expr, typename State, typename>
+ struct apply
+ : Grammar::template apply<Expr, State, mpl::true_>
+ {};
+
+ template<typename Expr, typename State, typename Visitor>
+ static typename apply<Expr, State, Visitor>::type
+ call(Expr const &expr, State const &state, Visitor &)
+ {
+ mpl::true_ case_sensitive;
+ return Grammar::call(expr, state, case_sensitive);
+ }
+ };
+
+ // remove_case specializations for stripping case-sensitivity from parsers
+ template<typename T, bool CaseSensitive>
+ struct remove_case
+ {
+ typedef T type;
+ template<typename U> static U const &call(U const &t)
+ {
+ return t;
+ }
+ };
+
+ template<>
+ struct remove_case<char, true>
+ {
+ typedef ichar type;
+ static ichar call(char ch)
+ {
+ return ichar(ch);
+ }
+ };
+
+ template<>
+ struct remove_case<char const *, true>
+ {
+ typedef istr type;
+ static istr call(char const *sz)
+ {
+ return istr(sz);
+ }
+ };
+
+ template<typename T, std::size_t N>
+ struct remove_case<T(&)[N], true>
+ : remove_case<char const *, true>
+ {};
+
+ template<>
+ struct remove_case<char_range, true>
+ {
+ typedef ichar_range type;
+ static ichar_range call(char_range const &rng)
+ {
+ return ichar_range(rng);
+ }
+ };
+
+ // A case-sensitive transform that removes case conditionally, depending on
+ // a compile-time flag carried by the visitor.
+ template<typename Grammar>
+ struct case_sensitive
+ : Grammar
+ {
+ case_sensitive();
+
+ template<typename Expr, typename State, typename Visitor>
+ struct apply
+ : remove_case<
+ typename Grammar::template apply<Expr, State, Visitor>::type
+ , Visitor::value
+ >
+ {};
+
+ template<typename Expr, typename State, typename Visitor>
+ static typename apply<Expr, State, Visitor>::type
+ call(Expr const &expr, State const &state, Visitor &visitor)
+ {
+ return apply<Expr, State, Visitor>::call(Grammar::call(expr, state, visitor));
+ }
+ };
+
+ ///////////////////////////////////////////////////////////////////////////////
+ /// Begin ToySpiritGrammar here
+ ///////////////////////////////////////////////////////////////////////////////
+
+ struct ToySpiritGrammar;
+
+ struct AnyChar
+ : proto::terminal<char_tag>
+ {};
+
+ struct CharLiteral
+ : proto::terminal<char>
+ {};
+
+ struct NTBSLiteral
+ : proto::terminal<char const *>
+ {};
+
+ struct CharParser
+ : proto::function<AnyChar, CharLiteral>
+ {};
+
+ struct CharRangeParser
+ : proto::function<AnyChar, CharLiteral, CharLiteral>
+ {};
+
+ struct NoCase
+ : proto::terminal<no_case_tag>
+ {};
+
+ // Extract the arg from terminals
+ struct ToySpiritTerminal
+ : proto::or_<
+ proto::transform::arg< AnyChar >
+ , case_sensitive< proto::transform::arg< CharLiteral > >
+ , case_sensitive< proto::transform::arg< NTBSLiteral > >
+ , case_sensitive<
+ proto::transform::arg< proto::transform::arg_c< CharParser, 1 > > // char_('a')
+ >
+ , case_sensitive<
+ proto::transform::construct< // char_('a','z')
+ CharRangeParser
+ , char_range(
+ proto::transform::arg< proto::transform::arg_c< proto::_, 1 > >
+ , proto::transform::arg< proto::transform::arg_c< proto::_, 2 > >
+ )
+ >
+ >
+ >
+ {};
+
+ // sequence rule folds all >>'s together into a list
+ // and wraps the result in a composite<> wrapper
+ struct ToySpiritSequence
+ : as_composite<
+ proto::tag::shift_right
+ , proto::transform::reverse_fold_tree<
+ proto::tag::shift_right
+ , proto::transform::list<ToySpiritGrammar>
+ , fusion::nil
+ >
+ >
+ {};
+
+ // alternate rule folds all |'s together into a list
+ // and wraps the result in a composite<> wrapper
+ struct ToySpiritAlternate
+ : as_composite<
+ proto::tag::bitwise_or
+ , proto::transform::reverse_fold_tree<
+ proto::tag::bitwise_or
+ , proto::transform::list<ToySpiritGrammar>
+ , fusion::nil
+ >
+ >
+ {};
+
+ // Directives such as no_case are handled here
+ struct ToySpiritDirective
+ : no_case_transform<
+ proto::transform::arg_c<
+ proto::subscript< NoCase, ToySpiritGrammar >
+ , 1
+ >
+ >
+ {};
+
+ // A ToySpiritGrammar is an alternate, a sequence, a directive or a terminal
+ struct ToySpiritGrammar
+ : proto::or_<
+ ToySpiritSequence
+ , ToySpiritAlternate
+ , ToySpiritDirective
+ , ToySpiritTerminal
+ >
+ {};
+
+ ///////////////////////////////////////////////////////////////////////////////
+ /// End ToySpiritGrammar
+ ///////////////////////////////////////////////////////////////////////////////
+
+ // Globals
+ NoCase::type const no_case = {{}};
+
+ // Parser
+ template<typename Iterator, typename Derived>
+ struct with_reset
+ {
+ with_reset(Iterator begin, Iterator end)
+ : first(begin), second(end)
+ {}
+
+ template<typename T>
+ bool operator()(T const &t) const
+ {
+ Iterator tmp = this->first;
+ if((*static_cast<Derived const *>(this))(t))
+ return true;
+ this->first = tmp;
+ return false;
+ }
+
+ bool done() const
+ {
+ return this->first == this->second;
+ }
+
+ mutable Iterator first;
+ Iterator second;
+ };
+
+ template<typename Iterator>
+ struct parser
+ : with_reset<Iterator, parser<Iterator> >
+ {
+ typedef with_reset<Iterator, parser<Iterator> > with_reset;
+
+ parser(Iterator begin, Iterator end)
+ : with_reset(begin, end)
+ {}
+
+#if BOOST_VERSION < 103500
+ template<typename, typename> // used by fusion::fold
+ struct apply
+ {
+ typedef bool type;
+ };
+#else
+ typedef bool result_type; // used by fusion::fold
+#endif
+
+ template<typename T>
+ bool operator()(T const &t, bool success) const // used by fusion::fold
+ {
+ return success && (*this)(t);
+ }
+
+ template<typename List>
+ bool operator()(composite<proto::tag::bitwise_or, List> const &alternates) const
+ {
+ return fusion::any(alternates.elems, *static_cast<with_reset const *>(this));
+ }
+
+ template<typename List>
+ bool operator()(composite<proto::tag::shift_right, List> const &sequence) const
+ {
+ return fusion::fold(sequence.elems, true, *this);
+ }
+
+ bool operator()(char_tag ch) const
+ {
+ if(this->done())
+ return false;
+ ++this->first;
+ return true;
+ }
+
+ bool operator()(char ch) const
+ {
+ if(this->done() || ch != *this->first)
+ return false;
+ ++this->first;
+ return true;
+ }
+
+ bool operator()(ichar ich) const
+ {
+ if(this->done() || !utility::char_icmp(*this->first, ich.lo_, ich.hi_))
+ return false;
+ ++this->first;
+ return true;
+ }
+
+ bool operator()(char const *sz) const
+ {
+ return utility::string_cmp(sz, this->first, this->second);
+ }
+
+ bool operator()(istr const &s) const
+ {
+ return utility::string_icmp(s.str_, this->first, this->second);
+ }
+
+ bool operator()(char_range rng) const
+ {
+ if(this->done() || !utility::in_range(*this->first, rng.first, rng.second))
+ return false;
+ ++this->first;
+ return true;
+ }
+
+ bool operator()(ichar_range rng) const
+ {
+ if(this->done() || !utility::in_irange(*this->first, rng.first, rng.second))
+ return false;
+ ++this->first;
+ return true;
+ }
+ };
+
+ template<typename Rule, typename Iterator>
+ typename enable_if<proto::matches< Rule, ToySpiritGrammar >, bool >::type
+ parse_impl(Rule const &rule, Iterator begin, Iterator end)
+ {
+ mpl::false_ is_case_sensitive;
+ parser<Iterator> parse_fun(begin, end);
+ return parse_fun(ToySpiritGrammar::call(rule, 0, is_case_sensitive));
+ }
+
+ // 2nd overload provides a short error message for invalid rules
+ template<typename Rule, typename Iterator>
+ typename disable_if<proto::matches< Rule, ToySpiritGrammar >, bool >::type
+ parse_impl(Rule const &rule, Iterator begin, Iterator end)
+ {
+ BOOST_MPL_ASSERT((proto::matches<Rule, ToySpiritGrammar>));
+ return false;
+ }
+
+ // parse() converts rule literals to proto expressions if necessary
+ // and dispatches to parse_impl
+ template<typename Rule, typename Iterator>
+ bool parse(Rule const &rule, Iterator begin, Iterator end)
+ {
+ return parse_impl(proto::as_expr(rule), begin, end);
+ }
+
+}}
+
+using namespace boost;
+
+void test_toy_spirit2()
+{
+ using spirit2::no_case;
+ std::string hello("abcd");
+
+ BOOST_CHECK(
+ spirit2::parse(
+ "abcd"
+ , hello.begin()
+ , hello.end()
+ )
+ );
+
+ BOOST_CHECK(
+ spirit2::parse(
+ char_ >> char_('b') >> 'c' >> char_
+ , hello.begin()
+ , hello.end()
+ )
+ );
+
+ BOOST_CHECK(
+ !spirit2::parse(
+ char_ >> char_('b') >> 'c' >> 'D'
+ , hello.begin()
+ , hello.end()
+ )
+ );
+
+ BOOST_CHECK(
+ spirit2::parse(
+ char_ >> char_('b') >> 'c' >> 'e'
+ | char_ >> no_case[char_('B') >> "C" >> char_('D','Z')]
+ , hello.begin()
+ , hello.end()
+ )
+ );
+}
+
+using namespace boost::unit_test;
+///////////////////////////////////////////////////////////////////////////////
+// init_unit_test_suite
+//
+test_suite* init_unit_test_suite( int argc, char* argv[] )
+{
+ test_suite *test = BOOST_TEST_SUITE("test proto, grammars and tree transforms");
+
+ test->add(BOOST_TEST_CASE(&test_toy_spirit2));
+
+ return test;
+}
Added: branches/proto/v3/libs/xpressive/proto3/test/toy_spirit3.cpp
==============================================================================
--- (empty file)
+++ branches/proto/v3/libs/xpressive/proto3/test/toy_spirit3.cpp 2007-11-07 17:03:47 EST (Wed, 07 Nov 2007)
@@ -0,0 +1,472 @@
+///////////////////////////////////////////////////////////////////////////////
+// toy_spirit3.cpp
+//
+// Copyright 2006 Eric Niebler. Distributed under the Boost
+// Software License, Version 1.0. (See accompanying file
+// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#include <cctype>
+#include <string>
+#include <iomanip>
+#include <iostream>
+#include <boost/assert.hpp>
+#include <boost/mpl/assert.hpp>
+#include <boost/utility/result_of.hpp>
+#include <boost/type_traits/is_same.hpp>
+#include <boost/xpressive/proto3/proto.hpp>
+#include <boost/xpressive/proto3/transform2.hpp>
+#if BOOST_VERSION < 103500
+# include <boost/spirit/fusion/algorithm/for_each.hpp>
+# include <boost/spirit/fusion/algorithm/fold.hpp>
+# include <boost/spirit/fusion/algorithm/any.hpp>
+#else
+#include <boost/fusion/include/for_each.hpp>
+#include <boost/fusion/include/fold.hpp>
+#include <boost/fusion/include/any.hpp>
+#endif
+#include <boost/test/unit_test.hpp>
+
+namespace boost
+{
+ // global tags
+ struct char_tag {};
+ struct space_tag {};
+
+ // global primitives
+ proto::terminal<char_tag>::type const char_ = {{}};
+ proto::terminal<space_tag>::type const space = {{}};
+
+ using proto::lit;
+ using proto::literal;
+}
+
+namespace boost { namespace spirit2
+{
+ namespace utility
+ {
+ inline bool char_icmp(char ch, char lo, char hi)
+ {
+ return ch == lo || ch == hi;
+ }
+
+ template<typename FwdIter>
+ inline bool string_cmp(char const *sz, FwdIter &begin, FwdIter end)
+ {
+ FwdIter tmp = begin;
+ for(; *sz; ++tmp, ++sz)
+ if(tmp == end || *tmp != *sz)
+ return false;
+ begin = tmp;
+ return true;
+ }
+
+ template<typename FwdIter>
+ inline bool string_icmp(std::string const &str, FwdIter &begin, FwdIter end)
+ {
+ BOOST_ASSERT(0 == str.size() % 2);
+ FwdIter tmp = begin;
+ std::string::const_iterator istr = str.begin(), estr = str.end();
+ for(; istr != estr; ++tmp, istr += 2)
+ if(tmp == end || *tmp != *istr && *tmp != *(istr+1))
+ return false;
+ begin = tmp;
+ return true;
+ }
+
+ inline bool in_range(char ch, char lo, char hi)
+ {
+ return ch >= lo && ch <= hi;
+ }
+
+ inline bool in_irange(char ch, char lo, char hi)
+ {
+ return in_range(ch, lo, hi)
+ || in_range(std::tolower(ch), lo, hi)
+ || in_range(std::toupper(ch), lo, hi);
+ }
+
+ inline std::string to_istr(char const *sz)
+ {
+ std::string res;
+ res.reserve(std::strlen(sz) * 2);
+ for(; *sz; ++sz)
+ {
+ res.push_back(std::tolower(*sz));
+ res.push_back(std::toupper(*sz));
+ }
+ return res;
+ }
+ } // namespace utility
+
+ template<typename List>
+ struct alternate
+ {
+ explicit alternate(List const &list)
+ : elems(list)
+ {}
+ List elems;
+ };
+
+ template<typename List>
+ struct sequence
+ {
+ explicit sequence(List const &list)
+ : elems(list)
+ {}
+ List elems;
+ };
+
+ struct char_range
+ : std::pair<char, char>
+ {
+ char_range(char from, char to)
+ : std::pair<char, char>(from, to)
+ {}
+ };
+
+ struct ichar
+ {
+ ichar(char ch)
+ : lo_(std::tolower(ch))
+ , hi_(std::toupper(ch))
+ {}
+
+ char lo_, hi_;
+ };
+
+ struct istr
+ {
+ istr(char const *sz)
+ : str_(utility::to_istr(sz))
+ {}
+
+ std::string str_;
+ };
+
+ struct ichar_range
+ : std::pair<char, char>
+ {
+ ichar_range(char from, char to)
+ : std::pair<char, char>(from, to)
+ {}
+ };
+
+ // The no-case directive
+ struct no_case_tag {};
+
+ // remove_case specializations for stripping case-sensitivity from parsers
+ template<typename T, typename CaseSensitive>
+ struct remove_case;
+
+ template<typename T>
+ struct remove_case<T, mpl::false_>
+ {
+ typedef T type;
+ };
+
+ template<>
+ struct remove_case<char, mpl::true_>
+ {
+ typedef ichar type;
+ };
+
+ template<>
+ struct remove_case<char const *, mpl::true_>
+ {
+ typedef istr type;
+ };
+
+ template<>
+ struct remove_case<char_range, mpl::true_>
+ {
+ typedef ichar_range type;
+ };
+
+ ///////////////////////////////////////////////////////////////////////////////
+ /// Begin Spirit grammar here
+ ///////////////////////////////////////////////////////////////////////////////
+ namespace grammar
+ {
+ using namespace proto;
+ using namespace fusion;
+
+ struct SpiritExpr;
+
+ struct AnyChar
+ : terminal<char_tag>
+ {};
+
+ struct CharLiteral
+ : terminal<char>
+ {};
+
+ struct NTBSLiteral
+ : terminal<char const *>
+ {};
+
+ struct CharParser
+ : function<AnyChar, CharLiteral>
+ {};
+
+ struct CharRangeParser
+ : function<AnyChar, CharLiteral, CharLiteral>
+ {};
+
+ struct NoCase
+ : terminal<no_case_tag>
+ {};
+
+ // Extract the arg from terminals
+ struct SpiritTerminal
+ : or_<
+ case_< AnyChar, _arg >
+ , case_< CharLiteral, remove_case<char, _visitor>(_arg) >
+ , case_< CharParser, remove_case<char, _visitor>(_arg_c<0, _arg1>)> // char_('a')
+ , case_< NTBSLiteral, remove_case<char const *, _visitor>(_arg) >
+ , case_< CharRangeParser, remove_case<char_range, _visitor>(_arg_c<0, _arg1>, _arg_c<0, _arg2>)> // char_('a','z')
+ >
+ {};
+
+ template<typename Grammar>
+ struct FoldToList
+ : reverse_fold_tree<Grammar, nil(), cons<SpiritExpr, _state>(SpiritExpr, _state)>
+ {};
+
+ struct AltList : FoldToList< bitwise_or<_, _> > {};
+ struct SeqList : FoldToList< shift_right<_, _> > {};
+
+ // sequence rule folds all >>'s together into a list
+ // and wraps the result in a sequence<> wrapper
+ struct SpiritSequence
+ : case_< shift_right<SpiritExpr, SpiritExpr>, sequence<SeqList>(SeqList) >
+ {};
+
+ // alternate rule folds all |'s together into a list
+ // and wraps the result in a alternate<> wrapper
+ struct SpiritAlternate
+ : case_< bitwise_or<SpiritExpr, SpiritExpr>, alternate<AltList>(AltList) >
+ {};
+
+ // Directives such as no_case are handled here
+ struct SpiritDirective
+ : case_< subscript<NoCase, SpiritExpr>, apply_<SpiritExpr, _right, _state, mpl::true_()> >
+ {};
+
+ // A SpiritExpr is an alternate, a sequence, a directive or a terminal
+ struct SpiritExpr
+ : or_<
+ SpiritSequence
+ , SpiritAlternate
+ , SpiritDirective
+ , SpiritTerminal
+ >
+ {};
+
+ } // namespace grammar
+
+ using grammar::SpiritExpr;
+ using grammar::NoCase;
+
+ ///////////////////////////////////////////////////////////////////////////////
+ /// End SpiritExpr
+ ///////////////////////////////////////////////////////////////////////////////
+
+ // Globals
+ NoCase::type const no_case = {{}};
+
+ // Parser
+ template<typename Iterator, typename Derived>
+ struct with_reset
+ {
+ with_reset(Iterator begin, Iterator end)
+ : first(begin), second(end)
+ {}
+
+ template<typename T>
+ bool operator()(T const &t) const
+ {
+ Iterator tmp = this->first;
+ if((*static_cast<Derived const *>(this))(t))
+ return true;
+ this->first = tmp;
+ return false;
+ }
+
+ bool done() const
+ {
+ return this->first == this->second;
+ }
+
+ mutable Iterator first;
+ Iterator second;
+ };
+
+ template<typename Iterator>
+ struct parser
+ : with_reset<Iterator, parser<Iterator> >
+ {
+ typedef with_reset<Iterator, parser<Iterator> > with_reset;
+
+ parser(Iterator begin, Iterator end)
+ : with_reset(begin, end)
+ {}
+
+ #if BOOST_VERSION < 103500
+ template<typename, typename> // used by fusion::fold
+ struct apply
+ {
+ typedef bool type;
+ };
+ #else
+ typedef bool result_type; // used by fusion::fold
+ #endif
+
+ template<typename T>
+ bool operator()(T const &t, bool success) const // used by fusion::fold
+ {
+ return success && (*this)(t);
+ }
+
+ template<typename List>
+ bool operator()(alternate<List> const &alternates) const
+ {
+ return fusion::any(alternates.elems, *static_cast<with_reset const *>(this));
+ }
+
+ template<typename List>
+ bool operator()(sequence<List> const &sequence) const
+ {
+ return fusion::fold(sequence.elems, true, *this);
+ }
+
+ bool operator()(char_tag ch) const
+ {
+ if(this->done())
+ return false;
+ ++this->first;
+ return true;
+ }
+
+ bool operator()(char ch) const
+ {
+ if(this->done() || ch != *this->first)
+ return false;
+ ++this->first;
+ return true;
+ }
+
+ bool operator()(ichar ich) const
+ {
+ if(this->done() || !utility::char_icmp(*this->first, ich.lo_, ich.hi_))
+ return false;
+ ++this->first;
+ return true;
+ }
+
+ bool operator()(char const *sz) const
+ {
+ return utility::string_cmp(sz, this->first, this->second);
+ }
+
+ bool operator()(istr const &s) const
+ {
+ return utility::string_icmp(s.str_, this->first, this->second);
+ }
+
+ bool operator()(char_range rng) const
+ {
+ if(this->done() || !utility::in_range(*this->first, rng.first, rng.second))
+ return false;
+ ++this->first;
+ return true;
+ }
+
+ bool operator()(ichar_range rng) const
+ {
+ if(this->done() || !utility::in_irange(*this->first, rng.first, rng.second))
+ return false;
+ ++this->first;
+ return true;
+ }
+ };
+
+ template<typename Rule, typename Iterator>
+ typename enable_if<proto::matches< Rule, SpiritExpr >, bool >::type
+ parse_impl(Rule const &rule, Iterator begin, Iterator end)
+ {
+ mpl::false_ is_case_sensitive;
+ parser<Iterator> parse_fun(begin, end);
+ return parse_fun(SpiritExpr::call(rule, 0, is_case_sensitive));
+ }
+
+ // 2nd overload provides a short error message for invalid rules
+ template<typename Rule, typename Iterator>
+ typename disable_if<proto::matches< Rule, SpiritExpr >, bool >::type
+ parse_impl(Rule const &rule, Iterator begin, Iterator end)
+ {
+ BOOST_MPL_ASSERT((proto::matches<Rule, SpiritExpr>));
+ return false;
+ }
+
+ // parse() converts rule literals to proto expressions if necessary
+ // and dispatches to parse_impl
+ template<typename Rule, typename Iterator>
+ bool parse(Rule const &rule, Iterator begin, Iterator end)
+ {
+ return parse_impl(proto::as_expr(rule), begin, end);
+ }
+
+}}
+
+void test_toy_spirit3()
+{
+ using boost::spirit2::no_case;
+ using boost::char_;
+ std::string hello("abcd");
+
+ BOOST_CHECK(
+ boost::spirit2::parse(
+ "abcd"
+ , hello.begin()
+ , hello.end()
+ )
+ );
+
+ BOOST_CHECK(
+ boost::spirit2::parse(
+ char_ >> char_('b') >> 'c' >> char_
+ , hello.begin()
+ , hello.end()
+ )
+ );
+
+ BOOST_CHECK(
+ !boost::spirit2::parse(
+ char_ >> char_('b') >> 'c' >> 'D'
+ , hello.begin()
+ , hello.end()
+ )
+ );
+
+ BOOST_CHECK(
+ boost::spirit2::parse(
+ char_ >> char_('b') >> 'c' >> 'e'
+ | char_ >> no_case[char_('B') >> "C" >> char_('D','Z')]
+ , hello.begin()
+ , hello.end()
+ )
+ );
+}
+
+using namespace boost::unit_test;
+///////////////////////////////////////////////////////////////////////////////
+// init_unit_test_suite
+//
+test_suite* init_unit_test_suite( int argc, char* argv[] )
+{
+ test_suite *test = BOOST_TEST_SUITE("test proto, grammars and tree transforms");
+
+ test->add(BOOST_TEST_CASE(&test_toy_spirit3));
+
+ return test;
+}
Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk