Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r71765 - in trunk: boost/proto boost/proto/context boost/proto/detail boost/proto/detail/preprocessed libs/proto/preprocess
From: eric_at_[hidden]
Date: 2011-05-06 11:55:21


Author: eric_niebler
Date: 2011-05-06 11:55:17 EDT (Fri, 06 May 2011)
New Revision: 71765
URL: http://svn.boost.org/trac/boost/changeset/71765

Log:
more pre-preprocessing
Added:
   trunk/boost/proto/detail/and_n.hpp (contents, props changed)
   trunk/boost/proto/detail/lambda_matches.hpp (contents, props changed)
   trunk/boost/proto/detail/matches_.hpp (contents, props changed)
   trunk/boost/proto/detail/or_n.hpp (contents, props changed)
   trunk/boost/proto/detail/preprocessed/and_n.hpp (contents, props changed)
   trunk/boost/proto/detail/preprocessed/lambda_matches.hpp (contents, props changed)
   trunk/boost/proto/detail/preprocessed/matches_.hpp (contents, props changed)
   trunk/boost/proto/detail/preprocessed/or_n.hpp (contents, props changed)
   trunk/boost/proto/detail/preprocessed/traits.hpp (contents, props changed)
   trunk/boost/proto/detail/preprocessed/vararg_matches_impl.hpp (contents, props changed)
   trunk/boost/proto/detail/traits.hpp (contents, props changed)
   trunk/boost/proto/detail/vararg_matches_impl.hpp (contents, props changed)
Text files modified:
   trunk/boost/proto/context/callable.hpp | 10
   trunk/boost/proto/detail/args.hpp | 4
   trunk/boost/proto/detail/basic_expr.hpp | 2
   trunk/boost/proto/detail/decltype.hpp | 6
   trunk/boost/proto/detail/expr.hpp | 2
   trunk/boost/proto/extends.hpp | 4
   trunk/boost/proto/fusion.hpp | 2
   trunk/boost/proto/generate.hpp | 745 +++++------
   trunk/boost/proto/matches.hpp | 1872 ++++++++++++++-----------------
   trunk/boost/proto/traits.hpp | 2362 ++++++++++++++++++---------------------
   trunk/libs/proto/preprocess/preprocess_proto.cpp | 1
   11 files changed, 2284 insertions(+), 2726 deletions(-)

Modified: trunk/boost/proto/context/callable.hpp
==============================================================================
--- trunk/boost/proto/context/callable.hpp (original)
+++ trunk/boost/proto/context/callable.hpp 2011-05-06 11:55:17 EDT (Fri, 06 May 2011)
@@ -62,14 +62,13 @@
                 static Expr &sexpr_;
                 static typename Expr::proto_tag &stag_;
 
- BOOST_STATIC_CONSTANT(bool, value =
- (
+ static const bool value =
                     sizeof(yes_type) ==
                     sizeof(
                         detail::check_is_expr_handled(
                             (sctx_(stag_, proto::value(sexpr_)), 0)
                         )
- )));
+ );
 
                 typedef mpl::bool_<value> type;
             };
@@ -258,8 +257,7 @@
                 static Expr &sexpr_;
                 static typename Expr::proto_tag &stag_;
 
- BOOST_STATIC_CONSTANT(bool, value =
- (
+ static const bool value =
                     sizeof(yes_type) ==
                     sizeof(
                         detail::check_is_expr_handled(
@@ -268,7 +266,7 @@
                                 BOOST_PP_ENUM_TRAILING(N, BOOST_PROTO_CHILD_N, sexpr_)
                             ), 0)
                         )
- )));
+ );
 
                 typedef mpl::bool_<value> type;
             };

Added: trunk/boost/proto/detail/and_n.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/proto/detail/and_n.hpp 2011-05-06 11:55:17 EDT (Fri, 06 May 2011)
@@ -0,0 +1,94 @@
+#if !defined(BOOST_PROTO_DONT_USE_PREPROCESSED_FILES)
+
+ #include <boost/proto/detail/preprocessed/and_n.hpp>
+
+#elif !defined(BOOST_PP_IS_ITERATING)
+
+ #if defined(__WAVE__) && defined(BOOST_PROTO_CREATE_PREPROCESSED_FILES)
+ #pragma wave option(preserve: 2, line: 0, output: "preprocessed/and_n.hpp")
+ #endif
+
+ ///////////////////////////////////////////////////////////////////////////////
+ /// \file and_n.hpp
+ /// Definitions of and_N, and_impl
+ //
+ // Copyright 2008 Eric Niebler. Distributed under the Boost
+ // Software License, Version 1.0. (See accompanying file
+ // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+ #if defined(__WAVE__) && defined(BOOST_PROTO_CREATE_PREPROCESSED_FILES)
+ #pragma wave option(preserve: 1)
+ #endif
+
+ #define BOOST_PP_ITERATION_PARAMS_1 \
+ (3, (2, BOOST_PP_MAX(BOOST_PROTO_MAX_ARITY, BOOST_PROTO_MAX_LOGICAL_ARITY), <boost/proto/detail/and_n.hpp>))
+ #include BOOST_PP_ITERATE()
+
+ #if defined(__WAVE__) && defined(BOOST_PROTO_CREATE_PREPROCESSED_FILES)
+ #pragma wave option(output: null)
+ #endif
+
+#else // BOOST_PP_IS_ITERATING
+
+ #define N BOOST_PP_ITERATION()
+
+ // Assymetry here between the handling of and_N and or_N because
+ // and_N is used by lambda_matches up to BOOST_PROTO_MAX_ARITY,
+ // regardless of how low BOOST_PROTO_MAX_LOGICAL_ARITY is.
+ template<bool B, BOOST_PP_ENUM_PARAMS(BOOST_PP_DEC(N), typename P)>
+ struct BOOST_PP_CAT(and_, N)
+ #if 2 == N
+ : mpl::bool_<P0::value>
+ {};
+ #else
+ : BOOST_PP_CAT(and_, BOOST_PP_DEC(N))<
+ P0::value BOOST_PP_COMMA_IF(BOOST_PP_SUB(N,2))
+ BOOST_PP_ENUM_SHIFTED_PARAMS(BOOST_PP_DEC(N), P)
+ >
+ {};
+ #endif
+
+ template<BOOST_PP_ENUM_PARAMS(BOOST_PP_DEC(N), typename P)>
+ struct BOOST_PP_CAT(and_, N)<false, BOOST_PP_ENUM_PARAMS(BOOST_PP_DEC(N), P)>
+ : mpl::false_
+ {};
+
+ #if N <= BOOST_PROTO_MAX_LOGICAL_ARITY
+
+ template<BOOST_PP_ENUM_PARAMS(N, typename G), typename Expr, typename State, typename Data>
+ struct _and_impl<proto::and_<BOOST_PP_ENUM_PARAMS(N, G)>, Expr, State, Data>
+ : proto::transform_impl<Expr, State, Data>
+ {
+ #define M0(Z, N, DATA) \
+ typedef \
+ typename proto::when<proto::_, BOOST_PP_CAT(G, N)> \
+ ::template impl<Expr, State, Data> \
+ BOOST_PP_CAT(Gimpl, N); \
+ /**/
+ BOOST_PP_REPEAT(N, M0, ~)
+ #undef M0
+
+ typedef typename BOOST_PP_CAT(Gimpl, BOOST_PP_DEC(N))::result_type result_type;
+
+ result_type operator()(
+ typename _and_impl::expr_param e
+ , typename _and_impl::state_param s
+ , typename _and_impl::data_param d
+ ) const
+ {
+ // Fix: jfalcou - 12/29/2010
+ // Avoid the use of comma operator here so as not to find Proto's
+ // by accident.
+ // expands to G0()(e,s,d); G1()(e,s,d); ... G{N-1}()(e,s,d);
+ #define M0(Z,N,DATA) BOOST_PP_CAT(Gimpl,N)()(e,s,d);
+ BOOST_PP_REPEAT(BOOST_PP_DEC(N),M0,~)
+ return BOOST_PP_CAT(Gimpl,BOOST_PP_DEC(N))()(e,s,d);
+ #undef M0
+ }
+ };
+
+ #endif
+
+ #undef N
+
+#endif

Modified: trunk/boost/proto/detail/args.hpp
==============================================================================
--- trunk/boost/proto/detail/args.hpp (original)
+++ trunk/boost/proto/detail/args.hpp 2011-05-06 11:55:17 EDT (Fri, 06 May 2011)
@@ -40,7 +40,7 @@
     template< typename Arg0 >
     struct term
     {
- BOOST_STATIC_CONSTANT(long, arity = 0);
+ static const long arity = 0;
         typedef Arg0 child0;
         BOOST_PP_REPEAT_FROM_TO(1, BOOST_PROTO_MAX_ARITY, BOOST_PROTO_DEFINE_VOID_N, ~)
 
@@ -71,7 +71,7 @@
     template< BOOST_PP_ENUM_PARAMS(N, typename Arg) >
     struct BOOST_PP_CAT(list, N)
     {
- BOOST_STATIC_CONSTANT(long, arity = N);
+ static const long arity = N;
         BOOST_PP_REPEAT(N, BOOST_PROTO_DEFINE_CHILD_N, ~)
         BOOST_PP_REPEAT_FROM_TO(N, BOOST_PROTO_MAX_ARITY, BOOST_PROTO_DEFINE_VOID_N, ~)
 

Modified: trunk/boost/proto/detail/basic_expr.hpp
==============================================================================
--- trunk/boost/proto/detail/basic_expr.hpp (original)
+++ trunk/boost/proto/detail/basic_expr.hpp 2011-05-06 11:55:17 EDT (Fri, 06 May 2011)
@@ -89,7 +89,7 @@
     #endif
     {
         typedef Tag proto_tag;
- BOOST_STATIC_CONSTANT(long, proto_arity_c = BOOST_PP_ITERATION());
+ static const long proto_arity_c = BOOST_PP_ITERATION();
         typedef mpl::long_<BOOST_PP_ITERATION() > proto_arity;
         typedef basic_expr proto_base_expr;
         #ifdef BOOST_PROTO_DEFINE_TERMINAL

Modified: trunk/boost/proto/detail/decltype.hpp
==============================================================================
--- trunk/boost/proto/detail/decltype.hpp (original)
+++ trunk/boost/proto/detail/decltype.hpp 2011-05-06 11:55:17 EDT (Fri, 06 May 2011)
@@ -228,7 +228,7 @@
             template<typename T>
             struct has_get_pointer
             {
- BOOST_STATIC_CONSTANT(bool, value = sizeof(void *) == sizeof(get_pointer(make<T &>())));
+ static const bool value = sizeof(void *) == sizeof(get_pointer(make<T &>()));
                 typedef mpl::bool_<value> type;
             };
         }
@@ -342,8 +342,8 @@
             template<typename T, typename U, typename V>
             struct result_of_<T U::*(V), typename enable_if_c<is_member_object_pointer<T U::*>::value>::type>
             {
- BOOST_STATIC_CONSTANT(bool, is_V_a_smart_ptr = 2 == sizeof(test_V_is_a_U<U>(&lvalue(make<V>()))));
- BOOST_STATIC_CONSTANT(bool, is_ptr_to_const = 2 == sizeof(test_ptr_to_const(BOOST_PROTO_GET_POINTER(U, make<V>()))));
+ static const bool is_V_a_smart_ptr = 2 == sizeof(test_V_is_a_U<U>(&lvalue(make<V>())));
+ static const bool is_ptr_to_const = 2 == sizeof(test_ptr_to_const(BOOST_PROTO_GET_POINTER(U, make<V>())));
 
                 // If V is not a U, then it is a (smart) pointer and we can always return an lvalue.
                 // Otherwise, we can only return an lvalue if we are given one.

Modified: trunk/boost/proto/detail/expr.hpp
==============================================================================
--- trunk/boost/proto/detail/expr.hpp (original)
+++ trunk/boost/proto/detail/expr.hpp 2011-05-06 11:55:17 EDT (Fri, 06 May 2011)
@@ -120,7 +120,7 @@
     #endif
     {
         typedef Tag proto_tag;
- BOOST_STATIC_CONSTANT(long, proto_arity_c = BOOST_PP_ITERATION());
+ static const long proto_arity_c = BOOST_PP_ITERATION();
         typedef mpl::long_<BOOST_PP_ITERATION() > proto_arity;
         typedef expr proto_base_expr;
         #ifdef BOOST_PROTO_DEFINE_TERMINAL

Added: trunk/boost/proto/detail/lambda_matches.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/proto/detail/lambda_matches.hpp 2011-05-06 11:55:17 EDT (Fri, 06 May 2011)
@@ -0,0 +1,67 @@
+#if !defined(BOOST_PROTO_DONT_USE_PREPROCESSED_FILES)
+
+ #define BOOST_PROTO_LAMBDA_ARITY_PARAM BOOST_MPL_AUX_LAMBDA_ARITY_PARAM
+ #include <boost/proto/detail/preprocessed/lambda_matches.hpp>
+ #undef BOOST_PROTO_LAMBDA_ARITY_PARAM
+
+#elif !defined(BOOST_PP_IS_ITERATING)
+
+ #define BOOST_PROTO_DEFINE_LAMBDA_MATCHES(Z, N, DATA) \
+ lambda_matches< \
+ BOOST_PP_CAT(Expr, N) \
+ , BOOST_PP_CAT(Grammar, N) \
+ >
+
+ #if defined(__WAVE__) && defined(BOOST_PROTO_CREATE_PREPROCESSED_FILES)
+ #pragma wave option(preserve: 2, line: 0, output: "preprocessed/lambda_matches.hpp")
+ #else
+ #define BOOST_PROTO_LAMBDA_ARITY_PARAM BOOST_MPL_AUX_LAMBDA_ARITY_PARAM
+ #endif
+
+ ///////////////////////////////////////////////////////////////////////////////
+ /// \file lambda_matches.hpp
+ /// Specializations of the lambda_matches template
+ //
+ // Copyright 2008 Eric Niebler. Distributed under the Boost
+ // Software License, Version 1.0. (See accompanying file
+ // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+ #if defined(__WAVE__) && defined(BOOST_PROTO_CREATE_PREPROCESSED_FILES)
+ #pragma wave option(preserve: 1)
+ #endif
+
+ #define BOOST_PP_ITERATION_PARAMS_1 \
+ (3, (2, BOOST_PROTO_MAX_ARITY, <boost/proto/detail/lambda_matches.hpp>))
+ #include BOOST_PP_ITERATE()
+
+ #if defined(__WAVE__) && defined(BOOST_PROTO_CREATE_PREPROCESSED_FILES)
+ #pragma wave option(output: null)
+ #else
+ #undef BOOST_PROTO_LAMBDA_ARITY_PARAM
+ #endif
+
+ #undef BOOST_PROTO_DEFINE_LAMBDA_MATCHES
+
+#else // BOOST_PP_IS_ITERATING
+
+ #define N BOOST_PP_ITERATION()
+
+ template<
+ template<BOOST_PP_ENUM_PARAMS(N, typename BOOST_PP_INTERCEPT)> class T
+ BOOST_PP_ENUM_TRAILING_PARAMS(N, typename Expr)
+ BOOST_PP_ENUM_TRAILING_PARAMS(N, typename Grammar)
+ >
+ struct lambda_matches<
+ T<BOOST_PP_ENUM_PARAMS(N, Expr)>
+ , T<BOOST_PP_ENUM_PARAMS(N, Grammar)>
+ BOOST_PROTO_LAMBDA_ARITY_PARAM(N)
+ >
+ : BOOST_PP_CAT(and_, N)<
+ BOOST_PROTO_DEFINE_LAMBDA_MATCHES(~, 0, ~)::value,
+ BOOST_PP_ENUM_SHIFTED(N, BOOST_PROTO_DEFINE_LAMBDA_MATCHES, ~)
+ >
+ {};
+
+ #undef N
+
+#endif

Added: trunk/boost/proto/detail/matches_.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/proto/detail/matches_.hpp 2011-05-06 11:55:17 EDT (Fri, 06 May 2011)
@@ -0,0 +1,96 @@
+#if !defined(BOOST_PROTO_DONT_USE_PREPROCESSED_FILES)
+
+ #include <boost/proto/detail/preprocessed/matches_.hpp>
+
+#elif !defined(BOOST_PP_IS_ITERATING)
+
+ #define BOOST_PROTO_MATCHES_N_FUN(Z, N, DATA) \
+ matches_< \
+ typename detail::expr_traits<typename Args1::BOOST_PP_CAT(child, N)>::value_type::proto_derived_expr \
+ , typename detail::expr_traits<typename Args1::BOOST_PP_CAT(child, N)>::value_type::proto_grammar \
+ , typename Args2::BOOST_PP_CAT(child, N)::proto_grammar \
+ >
+
+ #define BOOST_PROTO_DEFINE_MATCHES(Z, N, DATA) \
+ matches_< \
+ Expr \
+ , BasicExpr \
+ , typename BOOST_PP_CAT(G, N)::proto_grammar \
+ >
+
+ #if defined(__WAVE__) && defined(BOOST_PROTO_CREATE_PREPROCESSED_FILES)
+ #pragma wave option(preserve: 2, line: 0, output: "preprocessed/matches_.hpp")
+ #endif
+
+ ///////////////////////////////////////////////////////////////////////////////
+ /// \file matches_.hpp
+ /// Definitions of matches_ specializations
+ //
+ // Copyright 2008 Eric Niebler. Distributed under the Boost
+ // Software License, Version 1.0. (See accompanying file
+ // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+ #if defined(__WAVE__) && defined(BOOST_PROTO_CREATE_PREPROCESSED_FILES)
+ #pragma wave option(preserve: 1)
+ #endif
+
+ #define BOOST_PP_ITERATION_PARAMS_1 \
+ (3, (2, BOOST_PP_MAX(BOOST_PROTO_MAX_ARITY, BOOST_PROTO_MAX_LOGICAL_ARITY), <boost/proto/detail/matches_.hpp>))
+ #include BOOST_PP_ITERATE()
+
+ #if defined(__WAVE__) && defined(BOOST_PROTO_CREATE_PREPROCESSED_FILES)
+ #pragma wave option(output: null)
+ #endif
+
+ #undef BOOST_PROTO_DEFINE_MATCHES
+ #undef BOOST_PROTO_MATCHES_N_FUN
+
+#else // BOOST_PP_IS_ITERATING
+
+ #define N BOOST_PP_ITERATION()
+
+ #if N <= BOOST_PROTO_MAX_LOGICAL_ARITY
+
+ // handle proto::or_
+ template<typename Expr, typename BasicExpr BOOST_PP_ENUM_TRAILING_PARAMS(N, typename G)>
+ struct matches_<Expr, BasicExpr, proto::or_<BOOST_PP_ENUM_PARAMS(N, G)> >
+ : BOOST_PP_CAT(or_, N)<
+ matches_<Expr, BasicExpr, typename G0::proto_grammar>::value,
+ Expr, BasicExpr BOOST_PP_ENUM_TRAILING_PARAMS(N, G)
+ >
+ {};
+
+ // handle proto::and_
+ template<typename Expr, typename BasicExpr, BOOST_PP_ENUM_PARAMS(N, typename G)>
+ struct matches_<Expr, BasicExpr, proto::and_<BOOST_PP_ENUM_PARAMS(N, G)> >
+ : detail::BOOST_PP_CAT(and_, N)<
+ BOOST_PROTO_DEFINE_MATCHES(~, 0, ~)::value,
+ BOOST_PP_ENUM_SHIFTED(N, BOOST_PROTO_DEFINE_MATCHES, ~)
+ >
+ {};
+
+ #endif
+
+ #if N <= BOOST_PROTO_MAX_ARITY
+
+ template<typename Expr, typename Tag, typename Args1, typename Args2>
+ struct matches_< Expr, proto::basic_expr<Tag, Args1, N>, proto::basic_expr<Tag, Args2, N> >
+ : BOOST_PP_CAT(and_, N)<
+ BOOST_PROTO_MATCHES_N_FUN(~, 0, ~)::value,
+ BOOST_PP_ENUM_SHIFTED(N, BOOST_PROTO_MATCHES_N_FUN, ~)
+ >
+ {};
+
+ template<typename Expr, typename Tag, typename Args1, typename Args2>
+ struct matches_< Expr, proto::basic_expr<Tag, Args1, N>, proto::basic_expr<proto::_, Args2, N> >
+ : BOOST_PP_CAT(and_, N)<
+ BOOST_PROTO_MATCHES_N_FUN(~, 0, ~)::value,
+ BOOST_PP_ENUM_SHIFTED(N, BOOST_PROTO_MATCHES_N_FUN, ~)
+ >
+ {};
+
+ #endif
+
+ #undef N
+
+#endif

Added: trunk/boost/proto/detail/or_n.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/proto/detail/or_n.hpp 2011-05-06 11:55:17 EDT (Fri, 06 May 2011)
@@ -0,0 +1,59 @@
+#if !defined(BOOST_PROTO_DONT_USE_PREPROCESSED_FILES)
+
+ #include <boost/proto/detail/preprocessed/or_n.hpp>
+
+#elif !defined(BOOST_PP_IS_ITERATING)
+
+ #if defined(__WAVE__) && defined(BOOST_PROTO_CREATE_PREPROCESSED_FILES)
+ #pragma wave option(preserve: 2, line: 0, output: "preprocessed/or_n.hpp")
+ #endif
+
+ ///////////////////////////////////////////////////////////////////////////////
+ /// \file or_n.hpp
+ /// Definitions of or_N
+ //
+ // Copyright 2008 Eric Niebler. Distributed under the Boost
+ // Software License, Version 1.0. (See accompanying file
+ // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+ #if defined(__WAVE__) && defined(BOOST_PROTO_CREATE_PREPROCESSED_FILES)
+ #pragma wave option(preserve: 1)
+ #endif
+
+ #define BOOST_PP_ITERATION_PARAMS_1 \
+ (3, (2, BOOST_PROTO_MAX_LOGICAL_ARITY, <boost/proto/detail/or_n.hpp>))
+ #include BOOST_PP_ITERATE()
+
+ #if defined(__WAVE__) && defined(BOOST_PROTO_CREATE_PREPROCESSED_FILES)
+ #pragma wave option(output: null)
+ #endif
+
+#else // BOOST_PP_IS_ITERATING
+
+ #define N BOOST_PP_ITERATION()
+
+ template<bool B, typename Expr, typename BasicExpr, BOOST_PP_ENUM_PARAMS(N, typename G)>
+ struct BOOST_PP_CAT(or_, N)
+ #if 2 == N
+ : mpl::bool_<matches_<Expr, BasicExpr, typename G1::proto_grammar>::value>
+ {
+ typedef G1 which;
+ };
+ #else
+ : BOOST_PP_CAT(or_, BOOST_PP_DEC(N))<
+ matches_<Expr, BasicExpr, typename G1::proto_grammar>::value
+ , Expr, BasicExpr, BOOST_PP_ENUM_SHIFTED_PARAMS(N, G)
+ >
+ {};
+ #endif
+
+ template<typename Expr, typename BasicExpr BOOST_PP_ENUM_TRAILING_PARAMS(N, typename G)>
+ struct BOOST_PP_CAT(or_, N)<true, Expr, BasicExpr, BOOST_PP_ENUM_PARAMS(N, G)>
+ : mpl::true_
+ {
+ typedef G0 which;
+ };
+
+ #undef N
+
+#endif

Added: trunk/boost/proto/detail/preprocessed/and_n.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/proto/detail/preprocessed/and_n.hpp 2011-05-06 11:55:17 EDT (Fri, 06 May 2011)
@@ -0,0 +1,242 @@
+ ///////////////////////////////////////////////////////////////////////////////
+ /// \file and_n.hpp
+ /// Definitions of and_N, and_impl
+ //
+ // Copyright 2008 Eric Niebler. Distributed under the Boost
+ // Software License, Version 1.0. (See accompanying file
+ // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+
+
+ template<bool B, typename P0>
+ struct and_2
+ : mpl::bool_<P0::value>
+ {};
+ template<typename P0>
+ struct and_2<false, P0>
+ : mpl::false_
+ {};
+ template<typename G0 , typename G1, typename Expr, typename State, typename Data>
+ struct _and_impl<proto::and_<G0 , G1>, Expr, State, Data>
+ : proto::transform_impl<Expr, State, Data>
+ {
+ typedef typename proto::when<proto::_, G0> ::template impl<Expr, State, Data> Gimpl0; typedef typename proto::when<proto::_, G1> ::template impl<Expr, State, Data> Gimpl1;
+ typedef typename Gimpl1::result_type result_type;
+ result_type operator()(
+ typename _and_impl::expr_param e
+ , typename _and_impl::state_param s
+ , typename _and_impl::data_param d
+ ) const
+ {
+
+
+
+
+ Gimpl0()(e,s,d);
+ return Gimpl1()(e,s,d);
+ }
+ };
+
+
+
+ template<bool B, typename P0 , typename P1>
+ struct and_3
+ : and_2<
+ P0::value ,
+ P1
+ >
+ {};
+ template<typename P0 , typename P1>
+ struct and_3<false, P0 , P1>
+ : mpl::false_
+ {};
+ template<typename G0 , typename G1 , typename G2, typename Expr, typename State, typename Data>
+ struct _and_impl<proto::and_<G0 , G1 , G2>, Expr, State, Data>
+ : proto::transform_impl<Expr, State, Data>
+ {
+ typedef typename proto::when<proto::_, G0> ::template impl<Expr, State, Data> Gimpl0; typedef typename proto::when<proto::_, G1> ::template impl<Expr, State, Data> Gimpl1; typedef typename proto::when<proto::_, G2> ::template impl<Expr, State, Data> Gimpl2;
+ typedef typename Gimpl2::result_type result_type;
+ result_type operator()(
+ typename _and_impl::expr_param e
+ , typename _and_impl::state_param s
+ , typename _and_impl::data_param d
+ ) const
+ {
+
+
+
+
+ Gimpl0()(e,s,d); Gimpl1()(e,s,d);
+ return Gimpl2()(e,s,d);
+ }
+ };
+
+
+
+ template<bool B, typename P0 , typename P1 , typename P2>
+ struct and_4
+ : and_3<
+ P0::value ,
+ P1 , P2
+ >
+ {};
+ template<typename P0 , typename P1 , typename P2>
+ struct and_4<false, P0 , P1 , P2>
+ : mpl::false_
+ {};
+ template<typename G0 , typename G1 , typename G2 , typename G3, typename Expr, typename State, typename Data>
+ struct _and_impl<proto::and_<G0 , G1 , G2 , G3>, Expr, State, Data>
+ : proto::transform_impl<Expr, State, Data>
+ {
+ typedef typename proto::when<proto::_, G0> ::template impl<Expr, State, Data> Gimpl0; typedef typename proto::when<proto::_, G1> ::template impl<Expr, State, Data> Gimpl1; typedef typename proto::when<proto::_, G2> ::template impl<Expr, State, Data> Gimpl2; typedef typename proto::when<proto::_, G3> ::template impl<Expr, State, Data> Gimpl3;
+ typedef typename Gimpl3::result_type result_type;
+ result_type operator()(
+ typename _and_impl::expr_param e
+ , typename _and_impl::state_param s
+ , typename _and_impl::data_param d
+ ) const
+ {
+
+
+
+
+ Gimpl0()(e,s,d); Gimpl1()(e,s,d); Gimpl2()(e,s,d);
+ return Gimpl3()(e,s,d);
+ }
+ };
+
+
+
+ template<bool B, typename P0 , typename P1 , typename P2 , typename P3>
+ struct and_5
+ : and_4<
+ P0::value ,
+ P1 , P2 , P3
+ >
+ {};
+ template<typename P0 , typename P1 , typename P2 , typename P3>
+ struct and_5<false, P0 , P1 , P2 , P3>
+ : mpl::false_
+ {};
+ template<typename G0 , typename G1 , typename G2 , typename G3 , typename G4, typename Expr, typename State, typename Data>
+ struct _and_impl<proto::and_<G0 , G1 , G2 , G3 , G4>, Expr, State, Data>
+ : proto::transform_impl<Expr, State, Data>
+ {
+ typedef typename proto::when<proto::_, G0> ::template impl<Expr, State, Data> Gimpl0; typedef typename proto::when<proto::_, G1> ::template impl<Expr, State, Data> Gimpl1; typedef typename proto::when<proto::_, G2> ::template impl<Expr, State, Data> Gimpl2; typedef typename proto::when<proto::_, G3> ::template impl<Expr, State, Data> Gimpl3; typedef typename proto::when<proto::_, G4> ::template impl<Expr, State, Data> Gimpl4;
+ typedef typename Gimpl4::result_type result_type;
+ result_type operator()(
+ typename _and_impl::expr_param e
+ , typename _and_impl::state_param s
+ , typename _and_impl::data_param d
+ ) const
+ {
+
+
+
+
+ Gimpl0()(e,s,d); Gimpl1()(e,s,d); Gimpl2()(e,s,d); Gimpl3()(e,s,d);
+ return Gimpl4()(e,s,d);
+ }
+ };
+
+
+
+ template<bool B, typename P0 , typename P1 , typename P2 , typename P3 , typename P4>
+ struct and_6
+ : and_5<
+ P0::value ,
+ P1 , P2 , P3 , P4
+ >
+ {};
+ template<typename P0 , typename P1 , typename P2 , typename P3 , typename P4>
+ struct and_6<false, P0 , P1 , P2 , P3 , P4>
+ : mpl::false_
+ {};
+ template<typename G0 , typename G1 , typename G2 , typename G3 , typename G4 , typename G5, typename Expr, typename State, typename Data>
+ struct _and_impl<proto::and_<G0 , G1 , G2 , G3 , G4 , G5>, Expr, State, Data>
+ : proto::transform_impl<Expr, State, Data>
+ {
+ typedef typename proto::when<proto::_, G0> ::template impl<Expr, State, Data> Gimpl0; typedef typename proto::when<proto::_, G1> ::template impl<Expr, State, Data> Gimpl1; typedef typename proto::when<proto::_, G2> ::template impl<Expr, State, Data> Gimpl2; typedef typename proto::when<proto::_, G3> ::template impl<Expr, State, Data> Gimpl3; typedef typename proto::when<proto::_, G4> ::template impl<Expr, State, Data> Gimpl4; typedef typename proto::when<proto::_, G5> ::template impl<Expr, State, Data> Gimpl5;
+ typedef typename Gimpl5::result_type result_type;
+ result_type operator()(
+ typename _and_impl::expr_param e
+ , typename _and_impl::state_param s
+ , typename _and_impl::data_param d
+ ) const
+ {
+
+
+
+
+ Gimpl0()(e,s,d); Gimpl1()(e,s,d); Gimpl2()(e,s,d); Gimpl3()(e,s,d); Gimpl4()(e,s,d);
+ return Gimpl5()(e,s,d);
+ }
+ };
+
+
+
+ template<bool B, typename P0 , typename P1 , typename P2 , typename P3 , typename P4 , typename P5>
+ struct and_7
+ : and_6<
+ P0::value ,
+ P1 , P2 , P3 , P4 , P5
+ >
+ {};
+ template<typename P0 , typename P1 , typename P2 , typename P3 , typename P4 , typename P5>
+ struct and_7<false, P0 , P1 , P2 , P3 , P4 , P5>
+ : mpl::false_
+ {};
+ template<typename G0 , typename G1 , typename G2 , typename G3 , typename G4 , typename G5 , typename G6, typename Expr, typename State, typename Data>
+ struct _and_impl<proto::and_<G0 , G1 , G2 , G3 , G4 , G5 , G6>, Expr, State, Data>
+ : proto::transform_impl<Expr, State, Data>
+ {
+ typedef typename proto::when<proto::_, G0> ::template impl<Expr, State, Data> Gimpl0; typedef typename proto::when<proto::_, G1> ::template impl<Expr, State, Data> Gimpl1; typedef typename proto::when<proto::_, G2> ::template impl<Expr, State, Data> Gimpl2; typedef typename proto::when<proto::_, G3> ::template impl<Expr, State, Data> Gimpl3; typedef typename proto::when<proto::_, G4> ::template impl<Expr, State, Data> Gimpl4; typedef typename proto::when<proto::_, G5> ::template impl<Expr, State, Data> Gimpl5; typedef typename proto::when<proto::_, G6> ::template impl<Expr, State, Data> Gimpl6;
+ typedef typename Gimpl6::result_type result_type;
+ result_type operator()(
+ typename _and_impl::expr_param e
+ , typename _and_impl::state_param s
+ , typename _and_impl::data_param d
+ ) const
+ {
+
+
+
+
+ Gimpl0()(e,s,d); Gimpl1()(e,s,d); Gimpl2()(e,s,d); Gimpl3()(e,s,d); Gimpl4()(e,s,d); Gimpl5()(e,s,d);
+ return Gimpl6()(e,s,d);
+ }
+ };
+
+
+
+ template<bool B, typename P0 , typename P1 , typename P2 , typename P3 , typename P4 , typename P5 , typename P6>
+ struct and_8
+ : and_7<
+ P0::value ,
+ P1 , P2 , P3 , P4 , P5 , P6
+ >
+ {};
+ template<typename P0 , typename P1 , typename P2 , typename P3 , typename P4 , typename P5 , typename P6>
+ struct and_8<false, P0 , P1 , P2 , P3 , P4 , P5 , P6>
+ : mpl::false_
+ {};
+ template<typename G0 , typename G1 , typename G2 , typename G3 , typename G4 , typename G5 , typename G6 , typename G7, typename Expr, typename State, typename Data>
+ struct _and_impl<proto::and_<G0 , G1 , G2 , G3 , G4 , G5 , G6 , G7>, Expr, State, Data>
+ : proto::transform_impl<Expr, State, Data>
+ {
+ typedef typename proto::when<proto::_, G0> ::template impl<Expr, State, Data> Gimpl0; typedef typename proto::when<proto::_, G1> ::template impl<Expr, State, Data> Gimpl1; typedef typename proto::when<proto::_, G2> ::template impl<Expr, State, Data> Gimpl2; typedef typename proto::when<proto::_, G3> ::template impl<Expr, State, Data> Gimpl3; typedef typename proto::when<proto::_, G4> ::template impl<Expr, State, Data> Gimpl4; typedef typename proto::when<proto::_, G5> ::template impl<Expr, State, Data> Gimpl5; typedef typename proto::when<proto::_, G6> ::template impl<Expr, State, Data> Gimpl6; typedef typename proto::when<proto::_, G7> ::template impl<Expr, State, Data> Gimpl7;
+ typedef typename Gimpl7::result_type result_type;
+ result_type operator()(
+ typename _and_impl::expr_param e
+ , typename _and_impl::state_param s
+ , typename _and_impl::data_param d
+ ) const
+ {
+
+
+
+
+ Gimpl0()(e,s,d); Gimpl1()(e,s,d); Gimpl2()(e,s,d); Gimpl3()(e,s,d); Gimpl4()(e,s,d); Gimpl5()(e,s,d); Gimpl6()(e,s,d);
+ return Gimpl7()(e,s,d);
+ }
+ };

Added: trunk/boost/proto/detail/preprocessed/lambda_matches.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/proto/detail/preprocessed/lambda_matches.hpp 2011-05-06 11:55:17 EDT (Fri, 06 May 2011)
@@ -0,0 +1,67 @@
+ ///////////////////////////////////////////////////////////////////////////////
+ /// \file lambda_matches.hpp
+ /// Specializations of the lambda_matches template
+ //
+ // Copyright 2008 Eric Niebler. Distributed under the Boost
+ // Software License, Version 1.0. (See accompanying file
+ // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+ template<
+ template<typename , typename> class T
+ , typename Expr0 , typename Expr1
+ , typename Grammar0 , typename Grammar1
+ >
+ struct lambda_matches<
+ T<Expr0 , Expr1>
+ , T<Grammar0 , Grammar1>
+ BOOST_PROTO_LAMBDA_ARITY_PARAM(2)
+ >
+ : and_2<
+ lambda_matches< Expr0 , Grammar0 >::value,
+ lambda_matches< Expr1 , Grammar1 >
+ >
+ {};
+ template<
+ template<typename , typename , typename> class T
+ , typename Expr0 , typename Expr1 , typename Expr2
+ , typename Grammar0 , typename Grammar1 , typename Grammar2
+ >
+ struct lambda_matches<
+ T<Expr0 , Expr1 , Expr2>
+ , T<Grammar0 , Grammar1 , Grammar2>
+ BOOST_PROTO_LAMBDA_ARITY_PARAM(3)
+ >
+ : and_3<
+ lambda_matches< Expr0 , Grammar0 >::value,
+ lambda_matches< Expr1 , Grammar1 > , lambda_matches< Expr2 , Grammar2 >
+ >
+ {};
+ template<
+ template<typename , typename , typename , typename> class T
+ , typename Expr0 , typename Expr1 , typename Expr2 , typename Expr3
+ , typename Grammar0 , typename Grammar1 , typename Grammar2 , typename Grammar3
+ >
+ struct lambda_matches<
+ T<Expr0 , Expr1 , Expr2 , Expr3>
+ , T<Grammar0 , Grammar1 , Grammar2 , Grammar3>
+ BOOST_PROTO_LAMBDA_ARITY_PARAM(4)
+ >
+ : and_4<
+ lambda_matches< Expr0 , Grammar0 >::value,
+ lambda_matches< Expr1 , Grammar1 > , lambda_matches< Expr2 , Grammar2 > , lambda_matches< Expr3 , Grammar3 >
+ >
+ {};
+ template<
+ template<typename , typename , typename , typename , typename> class T
+ , typename Expr0 , typename Expr1 , typename Expr2 , typename Expr3 , typename Expr4
+ , typename Grammar0 , typename Grammar1 , typename Grammar2 , typename Grammar3 , typename Grammar4
+ >
+ struct lambda_matches<
+ T<Expr0 , Expr1 , Expr2 , Expr3 , Expr4>
+ , T<Grammar0 , Grammar1 , Grammar2 , Grammar3 , Grammar4>
+ BOOST_PROTO_LAMBDA_ARITY_PARAM(5)
+ >
+ : and_5<
+ lambda_matches< Expr0 , Grammar0 >::value,
+ lambda_matches< Expr1 , Grammar1 > , lambda_matches< Expr2 , Grammar2 > , lambda_matches< Expr3 , Grammar3 > , lambda_matches< Expr4 , Grammar4 >
+ >
+ {};

Added: trunk/boost/proto/detail/preprocessed/matches_.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/proto/detail/preprocessed/matches_.hpp 2011-05-06 11:55:17 EDT (Fri, 06 May 2011)
@@ -0,0 +1,175 @@
+ ///////////////////////////////////////////////////////////////////////////////
+ /// \file matches_.hpp
+ /// Definitions of matches_ specializations
+ //
+ // Copyright 2008 Eric Niebler. Distributed under the Boost
+ // Software License, Version 1.0. (See accompanying file
+ // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+ template<typename Expr, typename BasicExpr , typename G0 , typename G1>
+ struct matches_<Expr, BasicExpr, proto::or_<G0 , G1> >
+ : or_2<
+ matches_<Expr, BasicExpr, typename G0::proto_grammar>::value,
+ Expr, BasicExpr , G0 , G1
+ >
+ {};
+
+ template<typename Expr, typename BasicExpr, typename G0 , typename G1>
+ struct matches_<Expr, BasicExpr, proto::and_<G0 , G1> >
+ : detail::and_2<
+ matches_< Expr , BasicExpr , typename G0::proto_grammar >::value,
+ matches_< Expr , BasicExpr , typename G1::proto_grammar >
+ >
+ {};
+ template<typename Expr, typename Tag, typename Args1, typename Args2>
+ struct matches_< Expr, proto::basic_expr<Tag, Args1, 2>, proto::basic_expr<Tag, Args2, 2> >
+ : and_2<
+ matches_< typename detail::expr_traits<typename Args1::child0>::value_type::proto_derived_expr , typename detail::expr_traits<typename Args1::child0>::value_type::proto_grammar , typename Args2::child0::proto_grammar >::value,
+ matches_< typename detail::expr_traits<typename Args1::child1>::value_type::proto_derived_expr , typename detail::expr_traits<typename Args1::child1>::value_type::proto_grammar , typename Args2::child1::proto_grammar >
+ >
+ {};
+ template<typename Expr, typename Tag, typename Args1, typename Args2>
+ struct matches_< Expr, proto::basic_expr<Tag, Args1, 2>, proto::basic_expr<proto::_, Args2, 2> >
+ : and_2<
+ matches_< typename detail::expr_traits<typename Args1::child0>::value_type::proto_derived_expr , typename detail::expr_traits<typename Args1::child0>::value_type::proto_grammar , typename Args2::child0::proto_grammar >::value,
+ matches_< typename detail::expr_traits<typename Args1::child1>::value_type::proto_derived_expr , typename detail::expr_traits<typename Args1::child1>::value_type::proto_grammar , typename Args2::child1::proto_grammar >
+ >
+ {};
+
+ template<typename Expr, typename BasicExpr , typename G0 , typename G1 , typename G2>
+ struct matches_<Expr, BasicExpr, proto::or_<G0 , G1 , G2> >
+ : or_3<
+ matches_<Expr, BasicExpr, typename G0::proto_grammar>::value,
+ Expr, BasicExpr , G0 , G1 , G2
+ >
+ {};
+
+ template<typename Expr, typename BasicExpr, typename G0 , typename G1 , typename G2>
+ struct matches_<Expr, BasicExpr, proto::and_<G0 , G1 , G2> >
+ : detail::and_3<
+ matches_< Expr , BasicExpr , typename G0::proto_grammar >::value,
+ matches_< Expr , BasicExpr , typename G1::proto_grammar > , matches_< Expr , BasicExpr , typename G2::proto_grammar >
+ >
+ {};
+ template<typename Expr, typename Tag, typename Args1, typename Args2>
+ struct matches_< Expr, proto::basic_expr<Tag, Args1, 3>, proto::basic_expr<Tag, Args2, 3> >
+ : and_3<
+ matches_< typename detail::expr_traits<typename Args1::child0>::value_type::proto_derived_expr , typename detail::expr_traits<typename Args1::child0>::value_type::proto_grammar , typename Args2::child0::proto_grammar >::value,
+ matches_< typename detail::expr_traits<typename Args1::child1>::value_type::proto_derived_expr , typename detail::expr_traits<typename Args1::child1>::value_type::proto_grammar , typename Args2::child1::proto_grammar > , matches_< typename detail::expr_traits<typename Args1::child2>::value_type::proto_derived_expr , typename detail::expr_traits<typename Args1::child2>::value_type::proto_grammar , typename Args2::child2::proto_grammar >
+ >
+ {};
+ template<typename Expr, typename Tag, typename Args1, typename Args2>
+ struct matches_< Expr, proto::basic_expr<Tag, Args1, 3>, proto::basic_expr<proto::_, Args2, 3> >
+ : and_3<
+ matches_< typename detail::expr_traits<typename Args1::child0>::value_type::proto_derived_expr , typename detail::expr_traits<typename Args1::child0>::value_type::proto_grammar , typename Args2::child0::proto_grammar >::value,
+ matches_< typename detail::expr_traits<typename Args1::child1>::value_type::proto_derived_expr , typename detail::expr_traits<typename Args1::child1>::value_type::proto_grammar , typename Args2::child1::proto_grammar > , matches_< typename detail::expr_traits<typename Args1::child2>::value_type::proto_derived_expr , typename detail::expr_traits<typename Args1::child2>::value_type::proto_grammar , typename Args2::child2::proto_grammar >
+ >
+ {};
+
+ template<typename Expr, typename BasicExpr , typename G0 , typename G1 , typename G2 , typename G3>
+ struct matches_<Expr, BasicExpr, proto::or_<G0 , G1 , G2 , G3> >
+ : or_4<
+ matches_<Expr, BasicExpr, typename G0::proto_grammar>::value,
+ Expr, BasicExpr , G0 , G1 , G2 , G3
+ >
+ {};
+
+ template<typename Expr, typename BasicExpr, typename G0 , typename G1 , typename G2 , typename G3>
+ struct matches_<Expr, BasicExpr, proto::and_<G0 , G1 , G2 , G3> >
+ : detail::and_4<
+ matches_< Expr , BasicExpr , typename G0::proto_grammar >::value,
+ matches_< Expr , BasicExpr , typename G1::proto_grammar > , matches_< Expr , BasicExpr , typename G2::proto_grammar > , matches_< Expr , BasicExpr , typename G3::proto_grammar >
+ >
+ {};
+ template<typename Expr, typename Tag, typename Args1, typename Args2>
+ struct matches_< Expr, proto::basic_expr<Tag, Args1, 4>, proto::basic_expr<Tag, Args2, 4> >
+ : and_4<
+ matches_< typename detail::expr_traits<typename Args1::child0>::value_type::proto_derived_expr , typename detail::expr_traits<typename Args1::child0>::value_type::proto_grammar , typename Args2::child0::proto_grammar >::value,
+ matches_< typename detail::expr_traits<typename Args1::child1>::value_type::proto_derived_expr , typename detail::expr_traits<typename Args1::child1>::value_type::proto_grammar , typename Args2::child1::proto_grammar > , matches_< typename detail::expr_traits<typename Args1::child2>::value_type::proto_derived_expr , typename detail::expr_traits<typename Args1::child2>::value_type::proto_grammar , typename Args2::child2::proto_grammar > , matches_< typename detail::expr_traits<typename Args1::child3>::value_type::proto_derived_expr , typename detail::expr_traits<typename Args1::child3>::value_type::proto_grammar , typename Args2::child3::proto_grammar >
+ >
+ {};
+ template<typename Expr, typename Tag, typename Args1, typename Args2>
+ struct matches_< Expr, proto::basic_expr<Tag, Args1, 4>, proto::basic_expr<proto::_, Args2, 4> >
+ : and_4<
+ matches_< typename detail::expr_traits<typename Args1::child0>::value_type::proto_derived_expr , typename detail::expr_traits<typename Args1::child0>::value_type::proto_grammar , typename Args2::child0::proto_grammar >::value,
+ matches_< typename detail::expr_traits<typename Args1::child1>::value_type::proto_derived_expr , typename detail::expr_traits<typename Args1::child1>::value_type::proto_grammar , typename Args2::child1::proto_grammar > , matches_< typename detail::expr_traits<typename Args1::child2>::value_type::proto_derived_expr , typename detail::expr_traits<typename Args1::child2>::value_type::proto_grammar , typename Args2::child2::proto_grammar > , matches_< typename detail::expr_traits<typename Args1::child3>::value_type::proto_derived_expr , typename detail::expr_traits<typename Args1::child3>::value_type::proto_grammar , typename Args2::child3::proto_grammar >
+ >
+ {};
+
+ template<typename Expr, typename BasicExpr , typename G0 , typename G1 , typename G2 , typename G3 , typename G4>
+ struct matches_<Expr, BasicExpr, proto::or_<G0 , G1 , G2 , G3 , G4> >
+ : or_5<
+ matches_<Expr, BasicExpr, typename G0::proto_grammar>::value,
+ Expr, BasicExpr , G0 , G1 , G2 , G3 , G4
+ >
+ {};
+
+ template<typename Expr, typename BasicExpr, typename G0 , typename G1 , typename G2 , typename G3 , typename G4>
+ struct matches_<Expr, BasicExpr, proto::and_<G0 , G1 , G2 , G3 , G4> >
+ : detail::and_5<
+ matches_< Expr , BasicExpr , typename G0::proto_grammar >::value,
+ matches_< Expr , BasicExpr , typename G1::proto_grammar > , matches_< Expr , BasicExpr , typename G2::proto_grammar > , matches_< Expr , BasicExpr , typename G3::proto_grammar > , matches_< Expr , BasicExpr , typename G4::proto_grammar >
+ >
+ {};
+ template<typename Expr, typename Tag, typename Args1, typename Args2>
+ struct matches_< Expr, proto::basic_expr<Tag, Args1, 5>, proto::basic_expr<Tag, Args2, 5> >
+ : and_5<
+ matches_< typename detail::expr_traits<typename Args1::child0>::value_type::proto_derived_expr , typename detail::expr_traits<typename Args1::child0>::value_type::proto_grammar , typename Args2::child0::proto_grammar >::value,
+ matches_< typename detail::expr_traits<typename Args1::child1>::value_type::proto_derived_expr , typename detail::expr_traits<typename Args1::child1>::value_type::proto_grammar , typename Args2::child1::proto_grammar > , matches_< typename detail::expr_traits<typename Args1::child2>::value_type::proto_derived_expr , typename detail::expr_traits<typename Args1::child2>::value_type::proto_grammar , typename Args2::child2::proto_grammar > , matches_< typename detail::expr_traits<typename Args1::child3>::value_type::proto_derived_expr , typename detail::expr_traits<typename Args1::child3>::value_type::proto_grammar , typename Args2::child3::proto_grammar > , matches_< typename detail::expr_traits<typename Args1::child4>::value_type::proto_derived_expr , typename detail::expr_traits<typename Args1::child4>::value_type::proto_grammar , typename Args2::child4::proto_grammar >
+ >
+ {};
+ template<typename Expr, typename Tag, typename Args1, typename Args2>
+ struct matches_< Expr, proto::basic_expr<Tag, Args1, 5>, proto::basic_expr<proto::_, Args2, 5> >
+ : and_5<
+ matches_< typename detail::expr_traits<typename Args1::child0>::value_type::proto_derived_expr , typename detail::expr_traits<typename Args1::child0>::value_type::proto_grammar , typename Args2::child0::proto_grammar >::value,
+ matches_< typename detail::expr_traits<typename Args1::child1>::value_type::proto_derived_expr , typename detail::expr_traits<typename Args1::child1>::value_type::proto_grammar , typename Args2::child1::proto_grammar > , matches_< typename detail::expr_traits<typename Args1::child2>::value_type::proto_derived_expr , typename detail::expr_traits<typename Args1::child2>::value_type::proto_grammar , typename Args2::child2::proto_grammar > , matches_< typename detail::expr_traits<typename Args1::child3>::value_type::proto_derived_expr , typename detail::expr_traits<typename Args1::child3>::value_type::proto_grammar , typename Args2::child3::proto_grammar > , matches_< typename detail::expr_traits<typename Args1::child4>::value_type::proto_derived_expr , typename detail::expr_traits<typename Args1::child4>::value_type::proto_grammar , typename Args2::child4::proto_grammar >
+ >
+ {};
+
+ template<typename Expr, typename BasicExpr , typename G0 , typename G1 , typename G2 , typename G3 , typename G4 , typename G5>
+ struct matches_<Expr, BasicExpr, proto::or_<G0 , G1 , G2 , G3 , G4 , G5> >
+ : or_6<
+ matches_<Expr, BasicExpr, typename G0::proto_grammar>::value,
+ Expr, BasicExpr , G0 , G1 , G2 , G3 , G4 , G5
+ >
+ {};
+
+ template<typename Expr, typename BasicExpr, typename G0 , typename G1 , typename G2 , typename G3 , typename G4 , typename G5>
+ struct matches_<Expr, BasicExpr, proto::and_<G0 , G1 , G2 , G3 , G4 , G5> >
+ : detail::and_6<
+ matches_< Expr , BasicExpr , typename G0::proto_grammar >::value,
+ matches_< Expr , BasicExpr , typename G1::proto_grammar > , matches_< Expr , BasicExpr , typename G2::proto_grammar > , matches_< Expr , BasicExpr , typename G3::proto_grammar > , matches_< Expr , BasicExpr , typename G4::proto_grammar > , matches_< Expr , BasicExpr , typename G5::proto_grammar >
+ >
+ {};
+
+ template<typename Expr, typename BasicExpr , typename G0 , typename G1 , typename G2 , typename G3 , typename G4 , typename G5 , typename G6>
+ struct matches_<Expr, BasicExpr, proto::or_<G0 , G1 , G2 , G3 , G4 , G5 , G6> >
+ : or_7<
+ matches_<Expr, BasicExpr, typename G0::proto_grammar>::value,
+ Expr, BasicExpr , G0 , G1 , G2 , G3 , G4 , G5 , G6
+ >
+ {};
+
+ template<typename Expr, typename BasicExpr, typename G0 , typename G1 , typename G2 , typename G3 , typename G4 , typename G5 , typename G6>
+ struct matches_<Expr, BasicExpr, proto::and_<G0 , G1 , G2 , G3 , G4 , G5 , G6> >
+ : detail::and_7<
+ matches_< Expr , BasicExpr , typename G0::proto_grammar >::value,
+ matches_< Expr , BasicExpr , typename G1::proto_grammar > , matches_< Expr , BasicExpr , typename G2::proto_grammar > , matches_< Expr , BasicExpr , typename G3::proto_grammar > , matches_< Expr , BasicExpr , typename G4::proto_grammar > , matches_< Expr , BasicExpr , typename G5::proto_grammar > , matches_< Expr , BasicExpr , typename G6::proto_grammar >
+ >
+ {};
+
+ template<typename Expr, typename BasicExpr , typename G0 , typename G1 , typename G2 , typename G3 , typename G4 , typename G5 , typename G6 , typename G7>
+ struct matches_<Expr, BasicExpr, proto::or_<G0 , G1 , G2 , G3 , G4 , G5 , G6 , G7> >
+ : or_8<
+ matches_<Expr, BasicExpr, typename G0::proto_grammar>::value,
+ Expr, BasicExpr , G0 , G1 , G2 , G3 , G4 , G5 , G6 , G7
+ >
+ {};
+
+ template<typename Expr, typename BasicExpr, typename G0 , typename G1 , typename G2 , typename G3 , typename G4 , typename G5 , typename G6 , typename G7>
+ struct matches_<Expr, BasicExpr, proto::and_<G0 , G1 , G2 , G3 , G4 , G5 , G6 , G7> >
+ : detail::and_8<
+ matches_< Expr , BasicExpr , typename G0::proto_grammar >::value,
+ matches_< Expr , BasicExpr , typename G1::proto_grammar > , matches_< Expr , BasicExpr , typename G2::proto_grammar > , matches_< Expr , BasicExpr , typename G3::proto_grammar > , matches_< Expr , BasicExpr , typename G4::proto_grammar > , matches_< Expr , BasicExpr , typename G5::proto_grammar > , matches_< Expr , BasicExpr , typename G6::proto_grammar > , matches_< Expr , BasicExpr , typename G7::proto_grammar >
+ >
+ {};

Added: trunk/boost/proto/detail/preprocessed/or_n.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/proto/detail/preprocessed/or_n.hpp 2011-05-06 11:55:17 EDT (Fri, 06 May 2011)
@@ -0,0 +1,97 @@
+ ///////////////////////////////////////////////////////////////////////////////
+ /// \file or_n.hpp
+ /// Definitions of or_N
+ //
+ // Copyright 2008 Eric Niebler. Distributed under the Boost
+ // Software License, Version 1.0. (See accompanying file
+ // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+ template<bool B, typename Expr, typename BasicExpr, typename G0 , typename G1>
+ struct or_2
+ : mpl::bool_<matches_<Expr, BasicExpr, typename G1::proto_grammar>::value>
+ {
+ typedef G1 which;
+ };
+ template<typename Expr, typename BasicExpr , typename G0 , typename G1>
+ struct or_2<true, Expr, BasicExpr, G0 , G1>
+ : mpl::true_
+ {
+ typedef G0 which;
+ };
+ template<bool B, typename Expr, typename BasicExpr, typename G0 , typename G1 , typename G2>
+ struct or_3
+ : or_2<
+ matches_<Expr, BasicExpr, typename G1::proto_grammar>::value
+ , Expr, BasicExpr, G1 , G2
+ >
+ {};
+ template<typename Expr, typename BasicExpr , typename G0 , typename G1 , typename G2>
+ struct or_3<true, Expr, BasicExpr, G0 , G1 , G2>
+ : mpl::true_
+ {
+ typedef G0 which;
+ };
+ template<bool B, typename Expr, typename BasicExpr, typename G0 , typename G1 , typename G2 , typename G3>
+ struct or_4
+ : or_3<
+ matches_<Expr, BasicExpr, typename G1::proto_grammar>::value
+ , Expr, BasicExpr, G1 , G2 , G3
+ >
+ {};
+ template<typename Expr, typename BasicExpr , typename G0 , typename G1 , typename G2 , typename G3>
+ struct or_4<true, Expr, BasicExpr, G0 , G1 , G2 , G3>
+ : mpl::true_
+ {
+ typedef G0 which;
+ };
+ template<bool B, typename Expr, typename BasicExpr, typename G0 , typename G1 , typename G2 , typename G3 , typename G4>
+ struct or_5
+ : or_4<
+ matches_<Expr, BasicExpr, typename G1::proto_grammar>::value
+ , Expr, BasicExpr, G1 , G2 , G3 , G4
+ >
+ {};
+ template<typename Expr, typename BasicExpr , typename G0 , typename G1 , typename G2 , typename G3 , typename G4>
+ struct or_5<true, Expr, BasicExpr, G0 , G1 , G2 , G3 , G4>
+ : mpl::true_
+ {
+ typedef G0 which;
+ };
+ template<bool B, typename Expr, typename BasicExpr, typename G0 , typename G1 , typename G2 , typename G3 , typename G4 , typename G5>
+ struct or_6
+ : or_5<
+ matches_<Expr, BasicExpr, typename G1::proto_grammar>::value
+ , Expr, BasicExpr, G1 , G2 , G3 , G4 , G5
+ >
+ {};
+ template<typename Expr, typename BasicExpr , typename G0 , typename G1 , typename G2 , typename G3 , typename G4 , typename G5>
+ struct or_6<true, Expr, BasicExpr, G0 , G1 , G2 , G3 , G4 , G5>
+ : mpl::true_
+ {
+ typedef G0 which;
+ };
+ template<bool B, typename Expr, typename BasicExpr, typename G0 , typename G1 , typename G2 , typename G3 , typename G4 , typename G5 , typename G6>
+ struct or_7
+ : or_6<
+ matches_<Expr, BasicExpr, typename G1::proto_grammar>::value
+ , Expr, BasicExpr, G1 , G2 , G3 , G4 , G5 , G6
+ >
+ {};
+ template<typename Expr, typename BasicExpr , typename G0 , typename G1 , typename G2 , typename G3 , typename G4 , typename G5 , typename G6>
+ struct or_7<true, Expr, BasicExpr, G0 , G1 , G2 , G3 , G4 , G5 , G6>
+ : mpl::true_
+ {
+ typedef G0 which;
+ };
+ template<bool B, typename Expr, typename BasicExpr, typename G0 , typename G1 , typename G2 , typename G3 , typename G4 , typename G5 , typename G6 , typename G7>
+ struct or_8
+ : or_7<
+ matches_<Expr, BasicExpr, typename G1::proto_grammar>::value
+ , Expr, BasicExpr, G1 , G2 , G3 , G4 , G5 , G6 , G7
+ >
+ {};
+ template<typename Expr, typename BasicExpr , typename G0 , typename G1 , typename G2 , typename G3 , typename G4 , typename G5 , typename G6 , typename G7>
+ struct or_8<true, Expr, BasicExpr, G0 , G1 , G2 , G3 , G4 , G5 , G6 , G7>
+ : mpl::true_
+ {
+ typedef G0 which;
+ };

Added: trunk/boost/proto/detail/preprocessed/traits.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/proto/detail/preprocessed/traits.hpp 2011-05-06 11:55:17 EDT (Fri, 06 May 2011)
@@ -0,0 +1,764 @@
+ ///////////////////////////////////////////////////////////////////////////////
+ /// \file traits.hpp
+ /// Definitions of proto::function, proto::nary_expr and proto::result_of::child_c
+ //
+ // Copyright 2008 Eric Niebler. Distributed under the Boost
+ // Software License, Version 1.0. (See accompanying file
+ // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+ namespace result_of
+ {
+
+
+
+
+
+
+ template<typename Expr>
+ struct child_c<Expr, 0>
+ {
+
+ BOOST_PROTO_STATIC_ASSERT(0 != Expr::proto_arity_c);
+
+
+ typedef typename Expr::proto_child0 value_type;
+
+
+
+
+
+ typedef typename detail::expr_traits<typename Expr::proto_child0>::value_type type;
+ };
+ template<typename Expr>
+ struct child_c<Expr &, 0>
+ {
+
+ BOOST_PROTO_STATIC_ASSERT(0 != Expr::proto_arity_c);
+
+
+ typedef typename Expr::proto_child0 value_type;
+
+
+
+
+
+ typedef typename detail::expr_traits<typename Expr::proto_child0>::reference type;
+
+
+ static type call(Expr &e)
+ {
+ return e.proto_base().child0;
+ }
+ };
+ template<typename Expr>
+ struct child_c<Expr const &, 0>
+ {
+
+ BOOST_PROTO_STATIC_ASSERT(0 != Expr::proto_arity_c);
+
+
+ typedef typename Expr::proto_child0 value_type;
+
+
+
+
+
+ typedef typename detail::expr_traits<typename Expr::proto_child0>::const_reference type;
+
+
+ static type call(Expr const &e)
+ {
+ return e.proto_base().child0;
+ }
+ };
+ }
+
+
+
+
+ template<typename A0>
+ struct function
+ <
+ A0
+ , void , void , void , void
+ >
+ : proto::transform<
+ function<
+ A0
+ , void , void , void , void
+ >
+ , int
+ >
+ {
+ typedef proto::expr<proto::tag::function, list1<A0>, 1> type;
+ typedef proto::basic_expr<proto::tag::function, list1<A0>, 1> proto_grammar;
+ template<typename Expr, typename State, typename Data>
+ struct impl
+ : detail::pass_through_impl<function, Expr, State, Data>
+ {};
+
+ typedef proto::tag::function proto_tag;
+ typedef A0 proto_child0;
+ typedef detail::if_vararg<A0> proto_child1; typedef detail::if_vararg<A0> proto_child2; typedef detail::if_vararg<A0> proto_child3; typedef detail::if_vararg<A0> proto_child4;
+ };
+
+
+
+
+
+
+
+
+ template<typename Tag , typename A0>
+ struct nary_expr
+ <
+ Tag
+ , A0
+ , void , void , void , void
+ >
+ : proto::transform<
+ nary_expr<
+ Tag
+ , A0
+ , void , void , void , void
+ >
+ , int
+ >
+ {
+ typedef proto::expr<Tag, list1<A0>, 1> type;
+ typedef proto::basic_expr<Tag, list1<A0>, 1> proto_grammar;
+ template<typename Expr, typename State, typename Data>
+ struct impl
+ : detail::pass_through_impl<nary_expr, Expr, State, Data>
+ {};
+
+ typedef Tag proto_tag;
+ typedef A0 proto_child0;
+ typedef detail::if_vararg<A0> proto_child1; typedef detail::if_vararg<A0> proto_child2; typedef detail::if_vararg<A0> proto_child3; typedef detail::if_vararg<A0> proto_child4;
+ };
+ namespace detail
+ {
+ template<
+ template<typename> class T
+ , typename A0
+ >
+ struct is_callable_<T<A0> BOOST_PROTO_LAMBDA_ARITY_PARAM(1)>
+ : is_same<A0, callable>
+ {};
+ }
+ namespace result_of
+ {
+
+
+
+
+
+
+ template<typename Expr>
+ struct child_c<Expr, 1>
+ {
+
+ BOOST_PROTO_STATIC_ASSERT(0 != Expr::proto_arity_c);
+
+
+ typedef typename Expr::proto_child1 value_type;
+
+
+
+
+
+ typedef typename detail::expr_traits<typename Expr::proto_child1>::value_type type;
+ };
+ template<typename Expr>
+ struct child_c<Expr &, 1>
+ {
+
+ BOOST_PROTO_STATIC_ASSERT(0 != Expr::proto_arity_c);
+
+
+ typedef typename Expr::proto_child1 value_type;
+
+
+
+
+
+ typedef typename detail::expr_traits<typename Expr::proto_child1>::reference type;
+
+
+ static type call(Expr &e)
+ {
+ return e.proto_base().child1;
+ }
+ };
+ template<typename Expr>
+ struct child_c<Expr const &, 1>
+ {
+
+ BOOST_PROTO_STATIC_ASSERT(0 != Expr::proto_arity_c);
+
+
+ typedef typename Expr::proto_child1 value_type;
+
+
+
+
+
+ typedef typename detail::expr_traits<typename Expr::proto_child1>::const_reference type;
+
+
+ static type call(Expr const &e)
+ {
+ return e.proto_base().child1;
+ }
+ };
+ }
+
+
+
+
+ template<typename A0 , typename A1>
+ struct function
+ <
+ A0 , A1
+ , void , void , void
+ >
+ : proto::transform<
+ function<
+ A0 , A1
+ , void , void , void
+ >
+ , int
+ >
+ {
+ typedef proto::expr<proto::tag::function, list2<A0 , A1>, 2> type;
+ typedef proto::basic_expr<proto::tag::function, list2<A0 , A1>, 2> proto_grammar;
+ template<typename Expr, typename State, typename Data>
+ struct impl
+ : detail::pass_through_impl<function, Expr, State, Data>
+ {};
+
+ typedef proto::tag::function proto_tag;
+ typedef A0 proto_child0; typedef A1 proto_child1;
+ typedef detail::if_vararg<A1> proto_child2; typedef detail::if_vararg<A1> proto_child3; typedef detail::if_vararg<A1> proto_child4;
+ };
+
+
+
+
+
+
+
+
+ template<typename Tag , typename A0 , typename A1>
+ struct nary_expr
+ <
+ Tag
+ , A0 , A1
+ , void , void , void
+ >
+ : proto::transform<
+ nary_expr<
+ Tag
+ , A0 , A1
+ , void , void , void
+ >
+ , int
+ >
+ {
+ typedef proto::expr<Tag, list2<A0 , A1>, 2> type;
+ typedef proto::basic_expr<Tag, list2<A0 , A1>, 2> proto_grammar;
+ template<typename Expr, typename State, typename Data>
+ struct impl
+ : detail::pass_through_impl<nary_expr, Expr, State, Data>
+ {};
+
+ typedef Tag proto_tag;
+ typedef A0 proto_child0; typedef A1 proto_child1;
+ typedef detail::if_vararg<A1> proto_child2; typedef detail::if_vararg<A1> proto_child3; typedef detail::if_vararg<A1> proto_child4;
+ };
+ namespace detail
+ {
+ template<
+ template<typename , typename> class T
+ , typename A0 , typename A1
+ >
+ struct is_callable_<T<A0 , A1> BOOST_PROTO_LAMBDA_ARITY_PARAM(2)>
+ : is_same<A1, callable>
+ {};
+ }
+ namespace result_of
+ {
+
+
+
+
+
+
+ template<typename Expr>
+ struct child_c<Expr, 2>
+ {
+
+ BOOST_PROTO_STATIC_ASSERT(0 != Expr::proto_arity_c);
+
+
+ typedef typename Expr::proto_child2 value_type;
+
+
+
+
+
+ typedef typename detail::expr_traits<typename Expr::proto_child2>::value_type type;
+ };
+ template<typename Expr>
+ struct child_c<Expr &, 2>
+ {
+
+ BOOST_PROTO_STATIC_ASSERT(0 != Expr::proto_arity_c);
+
+
+ typedef typename Expr::proto_child2 value_type;
+
+
+
+
+
+ typedef typename detail::expr_traits<typename Expr::proto_child2>::reference type;
+
+
+ static type call(Expr &e)
+ {
+ return e.proto_base().child2;
+ }
+ };
+ template<typename Expr>
+ struct child_c<Expr const &, 2>
+ {
+
+ BOOST_PROTO_STATIC_ASSERT(0 != Expr::proto_arity_c);
+
+
+ typedef typename Expr::proto_child2 value_type;
+
+
+
+
+
+ typedef typename detail::expr_traits<typename Expr::proto_child2>::const_reference type;
+
+
+ static type call(Expr const &e)
+ {
+ return e.proto_base().child2;
+ }
+ };
+ }
+
+
+
+
+ template<typename A0 , typename A1 , typename A2>
+ struct function
+ <
+ A0 , A1 , A2
+ , void , void
+ >
+ : proto::transform<
+ function<
+ A0 , A1 , A2
+ , void , void
+ >
+ , int
+ >
+ {
+ typedef proto::expr<proto::tag::function, list3<A0 , A1 , A2>, 3> type;
+ typedef proto::basic_expr<proto::tag::function, list3<A0 , A1 , A2>, 3> proto_grammar;
+ template<typename Expr, typename State, typename Data>
+ struct impl
+ : detail::pass_through_impl<function, Expr, State, Data>
+ {};
+
+ typedef proto::tag::function proto_tag;
+ typedef A0 proto_child0; typedef A1 proto_child1; typedef A2 proto_child2;
+ typedef detail::if_vararg<A2> proto_child3; typedef detail::if_vararg<A2> proto_child4;
+ };
+
+
+
+
+
+
+
+
+ template<typename Tag , typename A0 , typename A1 , typename A2>
+ struct nary_expr
+ <
+ Tag
+ , A0 , A1 , A2
+ , void , void
+ >
+ : proto::transform<
+ nary_expr<
+ Tag
+ , A0 , A1 , A2
+ , void , void
+ >
+ , int
+ >
+ {
+ typedef proto::expr<Tag, list3<A0 , A1 , A2>, 3> type;
+ typedef proto::basic_expr<Tag, list3<A0 , A1 , A2>, 3> proto_grammar;
+ template<typename Expr, typename State, typename Data>
+ struct impl
+ : detail::pass_through_impl<nary_expr, Expr, State, Data>
+ {};
+
+ typedef Tag proto_tag;
+ typedef A0 proto_child0; typedef A1 proto_child1; typedef A2 proto_child2;
+ typedef detail::if_vararg<A2> proto_child3; typedef detail::if_vararg<A2> proto_child4;
+ };
+ namespace detail
+ {
+ template<
+ template<typename , typename , typename> class T
+ , typename A0 , typename A1 , typename A2
+ >
+ struct is_callable_<T<A0 , A1 , A2> BOOST_PROTO_LAMBDA_ARITY_PARAM(3)>
+ : is_same<A2, callable>
+ {};
+ }
+ namespace result_of
+ {
+
+
+
+
+
+
+ template<typename Expr>
+ struct child_c<Expr, 3>
+ {
+
+ BOOST_PROTO_STATIC_ASSERT(0 != Expr::proto_arity_c);
+
+
+ typedef typename Expr::proto_child3 value_type;
+
+
+
+
+
+ typedef typename detail::expr_traits<typename Expr::proto_child3>::value_type type;
+ };
+ template<typename Expr>
+ struct child_c<Expr &, 3>
+ {
+
+ BOOST_PROTO_STATIC_ASSERT(0 != Expr::proto_arity_c);
+
+
+ typedef typename Expr::proto_child3 value_type;
+
+
+
+
+
+ typedef typename detail::expr_traits<typename Expr::proto_child3>::reference type;
+
+
+ static type call(Expr &e)
+ {
+ return e.proto_base().child3;
+ }
+ };
+ template<typename Expr>
+ struct child_c<Expr const &, 3>
+ {
+
+ BOOST_PROTO_STATIC_ASSERT(0 != Expr::proto_arity_c);
+
+
+ typedef typename Expr::proto_child3 value_type;
+
+
+
+
+
+ typedef typename detail::expr_traits<typename Expr::proto_child3>::const_reference type;
+
+
+ static type call(Expr const &e)
+ {
+ return e.proto_base().child3;
+ }
+ };
+ }
+
+
+
+
+ template<typename A0 , typename A1 , typename A2 , typename A3>
+ struct function
+ <
+ A0 , A1 , A2 , A3
+ , void
+ >
+ : proto::transform<
+ function<
+ A0 , A1 , A2 , A3
+ , void
+ >
+ , int
+ >
+ {
+ typedef proto::expr<proto::tag::function, list4<A0 , A1 , A2 , A3>, 4> type;
+ typedef proto::basic_expr<proto::tag::function, list4<A0 , A1 , A2 , A3>, 4> proto_grammar;
+ template<typename Expr, typename State, typename Data>
+ struct impl
+ : detail::pass_through_impl<function, Expr, State, Data>
+ {};
+
+ typedef proto::tag::function proto_tag;
+ typedef A0 proto_child0; typedef A1 proto_child1; typedef A2 proto_child2; typedef A3 proto_child3;
+ typedef detail::if_vararg<A3> proto_child4;
+ };
+
+
+
+
+
+
+
+
+ template<typename Tag , typename A0 , typename A1 , typename A2 , typename A3>
+ struct nary_expr
+ <
+ Tag
+ , A0 , A1 , A2 , A3
+ , void
+ >
+ : proto::transform<
+ nary_expr<
+ Tag
+ , A0 , A1 , A2 , A3
+ , void
+ >
+ , int
+ >
+ {
+ typedef proto::expr<Tag, list4<A0 , A1 , A2 , A3>, 4> type;
+ typedef proto::basic_expr<Tag, list4<A0 , A1 , A2 , A3>, 4> proto_grammar;
+ template<typename Expr, typename State, typename Data>
+ struct impl
+ : detail::pass_through_impl<nary_expr, Expr, State, Data>
+ {};
+
+ typedef Tag proto_tag;
+ typedef A0 proto_child0; typedef A1 proto_child1; typedef A2 proto_child2; typedef A3 proto_child3;
+ typedef detail::if_vararg<A3> proto_child4;
+ };
+ namespace detail
+ {
+ template<
+ template<typename , typename , typename , typename> class T
+ , typename A0 , typename A1 , typename A2 , typename A3
+ >
+ struct is_callable_<T<A0 , A1 , A2 , A3> BOOST_PROTO_LAMBDA_ARITY_PARAM(4)>
+ : is_same<A3, callable>
+ {};
+ }
+ namespace result_of
+ {
+
+
+
+
+
+
+ template<typename Expr>
+ struct child_c<Expr, 4>
+ {
+
+ BOOST_PROTO_STATIC_ASSERT(0 != Expr::proto_arity_c);
+
+
+ typedef typename Expr::proto_child4 value_type;
+
+
+
+
+
+ typedef typename detail::expr_traits<typename Expr::proto_child4>::value_type type;
+ };
+ template<typename Expr>
+ struct child_c<Expr &, 4>
+ {
+
+ BOOST_PROTO_STATIC_ASSERT(0 != Expr::proto_arity_c);
+
+
+ typedef typename Expr::proto_child4 value_type;
+
+
+
+
+
+ typedef typename detail::expr_traits<typename Expr::proto_child4>::reference type;
+
+
+ static type call(Expr &e)
+ {
+ return e.proto_base().child4;
+ }
+ };
+ template<typename Expr>
+ struct child_c<Expr const &, 4>
+ {
+
+ BOOST_PROTO_STATIC_ASSERT(0 != Expr::proto_arity_c);
+
+
+ typedef typename Expr::proto_child4 value_type;
+
+
+
+
+
+ typedef typename detail::expr_traits<typename Expr::proto_child4>::const_reference type;
+
+
+ static type call(Expr const &e)
+ {
+ return e.proto_base().child4;
+ }
+ };
+ }
+
+
+
+
+ template<typename A0 , typename A1 , typename A2 , typename A3 , typename A4>
+ struct function
+ : proto::transform<
+ function<
+ A0 , A1 , A2 , A3 , A4
+
+ >
+ , int
+ >
+ {
+ typedef proto::expr<proto::tag::function, list5<A0 , A1 , A2 , A3 , A4>, 5> type;
+ typedef proto::basic_expr<proto::tag::function, list5<A0 , A1 , A2 , A3 , A4>, 5> proto_grammar;
+ template<typename Expr, typename State, typename Data>
+ struct impl
+ : detail::pass_through_impl<function, Expr, State, Data>
+ {};
+
+ typedef proto::tag::function proto_tag;
+ typedef A0 proto_child0; typedef A1 proto_child1; typedef A2 proto_child2; typedef A3 proto_child3; typedef A4 proto_child4;
+
+ };
+
+
+
+
+
+
+
+
+ template<typename Tag , typename A0 , typename A1 , typename A2 , typename A3 , typename A4>
+ struct nary_expr
+ : proto::transform<
+ nary_expr<
+ Tag
+ , A0 , A1 , A2 , A3 , A4
+
+ >
+ , int
+ >
+ {
+ typedef proto::expr<Tag, list5<A0 , A1 , A2 , A3 , A4>, 5> type;
+ typedef proto::basic_expr<Tag, list5<A0 , A1 , A2 , A3 , A4>, 5> proto_grammar;
+ template<typename Expr, typename State, typename Data>
+ struct impl
+ : detail::pass_through_impl<nary_expr, Expr, State, Data>
+ {};
+
+ typedef Tag proto_tag;
+ typedef A0 proto_child0; typedef A1 proto_child1; typedef A2 proto_child2; typedef A3 proto_child3; typedef A4 proto_child4;
+
+ };
+ namespace detail
+ {
+ template<
+ template<typename , typename , typename , typename , typename> class T
+ , typename A0 , typename A1 , typename A2 , typename A3 , typename A4
+ >
+ struct is_callable_<T<A0 , A1 , A2 , A3 , A4> BOOST_PROTO_LAMBDA_ARITY_PARAM(5)>
+ : is_same<A4, callable>
+ {};
+ }
+ namespace result_of
+ {
+
+
+
+
+
+
+ template<typename Expr>
+ struct child_c<Expr, 5>
+ {
+
+ BOOST_PROTO_STATIC_ASSERT(0 != Expr::proto_arity_c);
+
+
+ typedef typename Expr::proto_child5 value_type;
+
+
+
+
+
+ typedef typename detail::expr_traits<typename Expr::proto_child5>::value_type type;
+ };
+ template<typename Expr>
+ struct child_c<Expr &, 5>
+ {
+
+ BOOST_PROTO_STATIC_ASSERT(0 != Expr::proto_arity_c);
+
+
+ typedef typename Expr::proto_child5 value_type;
+
+
+
+
+
+ typedef typename detail::expr_traits<typename Expr::proto_child5>::reference type;
+
+
+ static type call(Expr &e)
+ {
+ return e.proto_base().child5;
+ }
+ };
+ template<typename Expr>
+ struct child_c<Expr const &, 5>
+ {
+
+ BOOST_PROTO_STATIC_ASSERT(0 != Expr::proto_arity_c);
+
+
+ typedef typename Expr::proto_child5 value_type;
+
+
+
+
+
+ typedef typename detail::expr_traits<typename Expr::proto_child5>::const_reference type;
+
+
+ static type call(Expr const &e)
+ {
+ return e.proto_base().child5;
+ }
+ };
+ }

Added: trunk/boost/proto/detail/preprocessed/vararg_matches_impl.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/proto/detail/preprocessed/vararg_matches_impl.hpp 2011-05-06 11:55:17 EDT (Fri, 06 May 2011)
@@ -0,0 +1,83 @@
+ ///////////////////////////////////////////////////////////////////////////////
+ /// \file vararg_matches_impl.hpp
+ /// Specializations of the vararg_matches_impl template
+ //
+ // Copyright 2008 Eric Niebler. Distributed under the Boost
+ // Software License, Version 1.0. (See accompanying file
+ // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+ template<typename Args, typename Back, long To>
+ struct vararg_matches_impl<Args, Back, 2, To>
+ : and_2<
+ matches_<
+ typename detail::expr_traits<typename Args::child1>::value_type::proto_derived_expr
+ , typename detail::expr_traits<typename Args::child1>::value_type::proto_grammar
+ , Back
+ >::value
+ , vararg_matches_impl<Args, Back, 2 + 1, To>
+ >
+ {};
+ template<typename Args, typename Back>
+ struct vararg_matches_impl<Args, Back, 2, 2>
+ : matches_<
+ typename detail::expr_traits<typename Args::child1>::value_type::proto_derived_expr
+ , typename detail::expr_traits<typename Args::child1>::value_type::proto_grammar
+ , Back
+ >
+ {};
+ template<typename Args, typename Back, long To>
+ struct vararg_matches_impl<Args, Back, 3, To>
+ : and_2<
+ matches_<
+ typename detail::expr_traits<typename Args::child2>::value_type::proto_derived_expr
+ , typename detail::expr_traits<typename Args::child2>::value_type::proto_grammar
+ , Back
+ >::value
+ , vararg_matches_impl<Args, Back, 3 + 1, To>
+ >
+ {};
+ template<typename Args, typename Back>
+ struct vararg_matches_impl<Args, Back, 3, 3>
+ : matches_<
+ typename detail::expr_traits<typename Args::child2>::value_type::proto_derived_expr
+ , typename detail::expr_traits<typename Args::child2>::value_type::proto_grammar
+ , Back
+ >
+ {};
+ template<typename Args, typename Back, long To>
+ struct vararg_matches_impl<Args, Back, 4, To>
+ : and_2<
+ matches_<
+ typename detail::expr_traits<typename Args::child3>::value_type::proto_derived_expr
+ , typename detail::expr_traits<typename Args::child3>::value_type::proto_grammar
+ , Back
+ >::value
+ , vararg_matches_impl<Args, Back, 4 + 1, To>
+ >
+ {};
+ template<typename Args, typename Back>
+ struct vararg_matches_impl<Args, Back, 4, 4>
+ : matches_<
+ typename detail::expr_traits<typename Args::child3>::value_type::proto_derived_expr
+ , typename detail::expr_traits<typename Args::child3>::value_type::proto_grammar
+ , Back
+ >
+ {};
+ template<typename Args, typename Back, long To>
+ struct vararg_matches_impl<Args, Back, 5, To>
+ : and_2<
+ matches_<
+ typename detail::expr_traits<typename Args::child4>::value_type::proto_derived_expr
+ , typename detail::expr_traits<typename Args::child4>::value_type::proto_grammar
+ , Back
+ >::value
+ , vararg_matches_impl<Args, Back, 5 + 1, To>
+ >
+ {};
+ template<typename Args, typename Back>
+ struct vararg_matches_impl<Args, Back, 5, 5>
+ : matches_<
+ typename detail::expr_traits<typename Args::child4>::value_type::proto_derived_expr
+ , typename detail::expr_traits<typename Args::child4>::value_type::proto_grammar
+ , Back
+ >
+ {};

Added: trunk/boost/proto/detail/traits.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/proto/detail/traits.hpp 2011-05-06 11:55:17 EDT (Fri, 06 May 2011)
@@ -0,0 +1,229 @@
+#if !defined(BOOST_PROTO_DONT_USE_PREPROCESSED_FILES)
+
+ #define BOOST_PROTO_LAMBDA_ARITY_PARAM BOOST_MPL_AUX_LAMBDA_ARITY_PARAM
+ #define BOOST_PROTO_STATIC_ASSERT BOOST_STATIC_ASSERT
+ #include <boost/proto/detail/preprocessed/traits.hpp>
+ #undef BOOST_PROTO_STATIC_ASSERT
+ #undef BOOST_PROTO_LAMBDA_ARITY_PARAM
+
+#elif !defined(BOOST_PP_IS_ITERATING)
+
+ #define BOOST_PROTO_CHILD(Z, N, DATA) \
+ /** INTERNAL ONLY */ \
+ typedef BOOST_PP_CAT(DATA, N) BOOST_PP_CAT(proto_child, N); \
+ /**/
+
+ #if defined(__WAVE__) && defined(BOOST_PROTO_CREATE_PREPROCESSED_FILES)
+ #pragma wave option(preserve: 2, line: 0, output: "preprocessed/traits.hpp")
+ #else
+ #define BOOST_PROTO_LAMBDA_ARITY_PARAM BOOST_MPL_AUX_LAMBDA_ARITY_PARAM
+ #define BOOST_PROTO_STATIC_ASSERT BOOST_STATIC_ASSERT
+ #endif
+
+ ///////////////////////////////////////////////////////////////////////////////
+ /// \file traits.hpp
+ /// Definitions of proto::function, proto::nary_expr and proto::result_of::child_c
+ //
+ // Copyright 2008 Eric Niebler. Distributed under the Boost
+ // Software License, Version 1.0. (See accompanying file
+ // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+ #if defined(__WAVE__) && defined(BOOST_PROTO_CREATE_PREPROCESSED_FILES)
+ #pragma wave option(preserve: 1)
+ #endif
+
+ #define BOOST_PP_ITERATION_PARAMS_1 \
+ (3, (0, BOOST_PROTO_MAX_ARITY, <boost/proto/detail/traits.hpp>))
+ #include BOOST_PP_ITERATE()
+
+ #if defined(__WAVE__) && defined(BOOST_PROTO_CREATE_PREPROCESSED_FILES)
+ #pragma wave option(output: null)
+ #else
+ #undef BOOST_PROTO_STATIC_ASSERT
+ #undef BOOST_PROTO_LAMBDA_ARITY_PARAM
+ #endif
+
+ #undef BOOST_PROTO_CHILD
+
+#else // BOOST_PP_IS_ITERATING
+
+ #define N BOOST_PP_ITERATION()
+
+ #if N > 0
+ /// \brief A metafunction for generating function-call expression types,
+ /// a grammar element for matching function-call expressions, and a
+ /// PrimitiveTransform that dispatches to the <tt>pass_through\<\></tt>
+ /// transform.
+ template<BOOST_PP_ENUM_PARAMS(N, typename A)>
+ struct function
+ #if N != BOOST_PROTO_MAX_ARITY
+ <
+ BOOST_PP_ENUM_PARAMS(N, A)
+ BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PP_SUB(BOOST_PROTO_MAX_ARITY, N), void BOOST_PP_INTERCEPT)
+ >
+ #endif
+ : proto::transform<
+ function<
+ BOOST_PP_ENUM_PARAMS(N, A)
+ BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PP_SUB(BOOST_PROTO_MAX_ARITY, N), void BOOST_PP_INTERCEPT)
+ >
+ , int
+ >
+ {
+ typedef proto::expr<proto::tag::function, BOOST_PP_CAT(list, N)<BOOST_PP_ENUM_PARAMS(N, A)>, N> type;
+ typedef proto::basic_expr<proto::tag::function, BOOST_PP_CAT(list, N)<BOOST_PP_ENUM_PARAMS(N, A)>, N> proto_grammar;
+
+ template<typename Expr, typename State, typename Data>
+ struct impl
+ : detail::pass_through_impl<function, Expr, State, Data>
+ {};
+
+ /// INTERNAL ONLY
+ typedef proto::tag::function proto_tag;
+ BOOST_PP_REPEAT(N, BOOST_PROTO_CHILD, A)
+ BOOST_PP_REPEAT_FROM_TO(
+ N
+ , BOOST_PROTO_MAX_ARITY
+ , BOOST_PROTO_CHILD
+ , detail::if_vararg<BOOST_PP_CAT(A, BOOST_PP_DEC(N))> BOOST_PP_INTERCEPT
+ )
+ };
+
+ /// \brief A metafunction for generating n-ary expression types with a
+ /// specified tag type,
+ /// a grammar element for matching n-ary expressions, and a
+ /// PrimitiveTransform that dispatches to the <tt>pass_through\<\></tt>
+ /// transform.
+ ///
+ /// Use <tt>nary_expr\<_, vararg\<_\> \></tt> as a grammar element to match any
+ /// n-ary expression; that is, any non-terminal.
+ template<typename Tag BOOST_PP_ENUM_TRAILING_PARAMS(N, typename A)>
+ struct nary_expr
+ #if N != BOOST_PROTO_MAX_ARITY
+ <
+ Tag
+ BOOST_PP_ENUM_TRAILING_PARAMS(N, A)
+ BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PP_SUB(BOOST_PROTO_MAX_ARITY, N), void BOOST_PP_INTERCEPT)
+ >
+ #endif
+ : proto::transform<
+ nary_expr<
+ Tag
+ BOOST_PP_ENUM_TRAILING_PARAMS(N, A)
+ BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PP_SUB(BOOST_PROTO_MAX_ARITY, N), void BOOST_PP_INTERCEPT)
+ >
+ , int
+ >
+ {
+ typedef proto::expr<Tag, BOOST_PP_CAT(list, N)<BOOST_PP_ENUM_PARAMS(N, A)>, N> type;
+ typedef proto::basic_expr<Tag, BOOST_PP_CAT(list, N)<BOOST_PP_ENUM_PARAMS(N, A)>, N> proto_grammar;
+
+ template<typename Expr, typename State, typename Data>
+ struct impl
+ : detail::pass_through_impl<nary_expr, Expr, State, Data>
+ {};
+
+ /// INTERNAL ONLY
+ typedef Tag proto_tag;
+ BOOST_PP_REPEAT(N, BOOST_PROTO_CHILD, A)
+ BOOST_PP_REPEAT_FROM_TO(
+ N
+ , BOOST_PROTO_MAX_ARITY
+ , BOOST_PROTO_CHILD
+ , detail::if_vararg<BOOST_PP_CAT(A, BOOST_PP_DEC(N))> BOOST_PP_INTERCEPT
+ )
+ };
+
+ namespace detail
+ {
+ template<
+ template<BOOST_PP_ENUM_PARAMS(N, typename BOOST_PP_INTERCEPT)> class T
+ , BOOST_PP_ENUM_PARAMS(N, typename A)
+ >
+ struct is_callable_<T<BOOST_PP_ENUM_PARAMS(N, A)> BOOST_PROTO_LAMBDA_ARITY_PARAM(N)>
+ : is_same<BOOST_PP_CAT(A, BOOST_PP_DEC(N)), callable>
+ {};
+ }
+
+ #endif
+
+ namespace result_of
+ {
+ /// \brief A metafunction that returns the type of the Nth child
+ /// of a Proto expression.
+ ///
+ /// A metafunction that returns the type of the Nth child
+ /// of a Proto expression. \c N must be less than
+ /// \c Expr::proto_arity::value.
+ template<typename Expr>
+ struct child_c<Expr, N>
+ {
+ /// Verify that we are not operating on a terminal
+ BOOST_PROTO_STATIC_ASSERT(0 != Expr::proto_arity_c);
+
+ /// The raw type of the Nth child as it is stored within
+ /// \c Expr. This may be a value or a reference
+ typedef typename Expr::BOOST_PP_CAT(proto_child, N) value_type;
+
+ /// The "value" type of the child, suitable for return by value,
+ /// computed as follows:
+ /// \li <tt>T const &</tt> becomes <tt>T</tt>
+ /// \li <tt>T &</tt> becomes <tt>T</tt>
+ /// \li <tt>T</tt> becomes <tt>T</tt>
+ typedef typename detail::expr_traits<typename Expr::BOOST_PP_CAT(proto_child, N)>::value_type type;
+ };
+
+ template<typename Expr>
+ struct child_c<Expr &, N>
+ {
+ /// Verify that we are not operating on a terminal
+ BOOST_PROTO_STATIC_ASSERT(0 != Expr::proto_arity_c);
+
+ /// The raw type of the Nth child as it is stored within
+ /// \c Expr. This may be a value or a reference
+ typedef typename Expr::BOOST_PP_CAT(proto_child, N) value_type;
+
+ /// The "reference" type of the child, suitable for return by
+ /// reference, computed as follows:
+ /// \li <tt>T const &</tt> becomes <tt>T const &</tt>
+ /// \li <tt>T &</tt> becomes <tt>T &</tt>
+ /// \li <tt>T</tt> becomes <tt>T &</tt>
+ typedef typename detail::expr_traits<typename Expr::BOOST_PP_CAT(proto_child, N)>::reference type;
+
+ /// INTERNAL ONLY
+ ///
+ static type call(Expr &e)
+ {
+ return e.proto_base().BOOST_PP_CAT(child, N);
+ }
+ };
+
+ template<typename Expr>
+ struct child_c<Expr const &, N>
+ {
+ /// Verify that we are not operating on a terminal
+ BOOST_PROTO_STATIC_ASSERT(0 != Expr::proto_arity_c);
+
+ /// The raw type of the Nth child as it is stored within
+ /// \c Expr. This may be a value or a reference
+ typedef typename Expr::BOOST_PP_CAT(proto_child, N) value_type;
+
+ /// The "const reference" type of the child, suitable for return by
+ /// const reference, computed as follows:
+ /// \li <tt>T const &</tt> becomes <tt>T const &</tt>
+ /// \li <tt>T &</tt> becomes <tt>T &</tt>
+ /// \li <tt>T</tt> becomes <tt>T const &</tt>
+ typedef typename detail::expr_traits<typename Expr::BOOST_PP_CAT(proto_child, N)>::const_reference type;
+
+ /// INTERNAL ONLY
+ ///
+ static type call(Expr const &e)
+ {
+ return e.proto_base().BOOST_PP_CAT(child, N);
+ }
+ };
+ }
+
+ #undef N
+
+#endif

Added: trunk/boost/proto/detail/vararg_matches_impl.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/proto/detail/vararg_matches_impl.hpp 2011-05-06 11:55:17 EDT (Fri, 06 May 2011)
@@ -0,0 +1,58 @@
+#if !defined(BOOST_PROTO_DONT_USE_PREPROCESSED_FILES)
+
+ #include <boost/proto/detail/preprocessed/vararg_matches_impl.hpp>
+
+#elif !defined(BOOST_PP_IS_ITERATING)
+
+ #if defined(__WAVE__) && defined(BOOST_PROTO_CREATE_PREPROCESSED_FILES)
+ #pragma wave option(preserve: 2, line: 0, output: "preprocessed/vararg_matches_impl.hpp")
+ #endif
+
+ ///////////////////////////////////////////////////////////////////////////////
+ /// \file vararg_matches_impl.hpp
+ /// Specializations of the vararg_matches_impl template
+ //
+ // Copyright 2008 Eric Niebler. Distributed under the Boost
+ // Software License, Version 1.0. (See accompanying file
+ // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+ #if defined(__WAVE__) && defined(BOOST_PROTO_CREATE_PREPROCESSED_FILES)
+ #pragma wave option(preserve: 1)
+ #endif
+
+ #define BOOST_PP_ITERATION_PARAMS_1 \
+ (3, (2, BOOST_PROTO_MAX_ARITY, <boost/proto/detail/vararg_matches_impl.hpp>))
+ #include BOOST_PP_ITERATE()
+
+ #if defined(__WAVE__) && defined(BOOST_PROTO_CREATE_PREPROCESSED_FILES)
+ #pragma wave option(output: null)
+ #endif
+
+#else // BOOST_PP_IS_ITERATING
+
+ #define N BOOST_PP_ITERATION()
+
+ template<typename Args, typename Back, long To>
+ struct vararg_matches_impl<Args, Back, N, To>
+ : and_2<
+ matches_<
+ typename detail::expr_traits<typename Args::BOOST_PP_CAT(child, BOOST_PP_DEC(N))>::value_type::proto_derived_expr
+ , typename detail::expr_traits<typename Args::BOOST_PP_CAT(child, BOOST_PP_DEC(N))>::value_type::proto_grammar
+ , Back
+ >::value
+ , vararg_matches_impl<Args, Back, N + 1, To>
+ >
+ {};
+
+ template<typename Args, typename Back>
+ struct vararg_matches_impl<Args, Back, N, N>
+ : matches_<
+ typename detail::expr_traits<typename Args::BOOST_PP_CAT(child, BOOST_PP_DEC(N))>::value_type::proto_derived_expr
+ , typename detail::expr_traits<typename Args::BOOST_PP_CAT(child, BOOST_PP_DEC(N))>::value_type::proto_grammar
+ , Back
+ >
+ {};
+
+ #undef N
+
+#endif

Modified: trunk/boost/proto/extends.hpp
==============================================================================
--- trunk/boost/proto/extends.hpp (original)
+++ trunk/boost/proto/extends.hpp 2011-05-06 11:55:17 EDT (Fri, 06 May 2011)
@@ -168,7 +168,7 @@
         typedef typename proto_base_expr::proto_grammar proto_grammar; \
         typedef typename proto_base_expr::address_of_hack_type_ proto_address_of_hack_type_; \
         typedef void proto_is_expr_; /**< INTERNAL ONLY */ \
- BOOST_STATIC_CONSTANT(long, proto_arity_c = proto_base_expr::proto_arity_c); \
+ static const long proto_arity_c = proto_base_expr::proto_arity_c; \
         typedef boost::proto::tag::proto_expr fusion_tag; \
         BOOST_PP_REPEAT(BOOST_PROTO_MAX_ARITY, BOOST_PROTO_EXTENDS_CHILD, ~) \
                                                                                                     \
@@ -557,7 +557,7 @@
             typedef mpl::long_<2> proto_arity;
             typedef detail::not_a_valid_type proto_address_of_hack_type_;
             typedef void proto_is_expr_; /**< INTERNAL ONLY */
- BOOST_STATIC_CONSTANT(long, proto_arity_c = 2);
+ static const long proto_arity_c = 2;
             typedef boost::proto::tag::proto_expr fusion_tag;
             typedef This &proto_child0;
             typedef expr<tag::terminal, term<Fun> > const &proto_child1;

Modified: trunk/boost/proto/fusion.hpp
==============================================================================
--- trunk/boost/proto/fusion.hpp (original)
+++ trunk/boost/proto/fusion.hpp 2011-05-06 11:55:17 EDT (Fri, 06 May 2011)
@@ -48,7 +48,7 @@
         {
             typedef Expr expr_type;
             typedef typename Expr::proto_tag proto_tag;
- BOOST_STATIC_CONSTANT(long, index = Pos);
+ static const long index = Pos;
             typedef fusion::random_access_traversal_tag category;
             typedef tag::proto_expr_iterator fusion_tag;
 

Modified: trunk/boost/proto/generate.hpp
==============================================================================
--- trunk/boost/proto/generate.hpp (original)
+++ trunk/boost/proto/generate.hpp 2011-05-06 11:55:17 EDT (Fri, 06 May 2011)
@@ -1,462 +1,399 @@
-#ifndef BOOST_PP_IS_ITERATING
- ///////////////////////////////////////////////////////////////////////////////
- /// \file generate.hpp
- /// Contains definition of generate\<\> class template, which end users can
- /// specialize for generating domain-specific expression wrappers.
- //
- // Copyright 2008 Eric Niebler. Distributed under the Boost
- // Software License, Version 1.0. (See accompanying file
- // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
-
- #ifndef BOOST_PROTO_GENERATE_HPP_EAN_02_13_2007
- #define BOOST_PROTO_GENERATE_HPP_EAN_02_13_2007
-
- #include <boost/config.hpp>
- #include <boost/version.hpp>
- #include <boost/preprocessor/cat.hpp>
- #include <boost/preprocessor/iteration/iterate.hpp>
- #include <boost/preprocessor/facilities/intercept.hpp>
- #include <boost/preprocessor/repetition/enum_params.hpp>
- #include <boost/preprocessor/repetition/enum_binary_params.hpp>
- #include <boost/preprocessor/repetition/enum_trailing_params.hpp>
- #include <boost/mpl/bool.hpp>
- #include <boost/utility/enable_if.hpp>
- #include <boost/utility/result_of.hpp>
- #include <boost/proto/proto_fwd.hpp>
- #include <boost/proto/args.hpp>
-
- namespace boost { namespace proto
+///////////////////////////////////////////////////////////////////////////////
+/// \file generate.hpp
+/// Contains definition of generate\<\> class template, which end users can
+/// specialize for generating domain-specific expression wrappers.
+//
+// Copyright 2008 Eric Niebler. Distributed under the Boost
+// Software License, Version 1.0. (See accompanying file
+// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_PROTO_GENERATE_HPP_EAN_02_13_2007
+#define BOOST_PROTO_GENERATE_HPP_EAN_02_13_2007
+
+#include <boost/config.hpp>
+#include <boost/version.hpp>
+#include <boost/preprocessor/cat.hpp>
+#include <boost/preprocessor/iteration/iterate.hpp>
+#include <boost/preprocessor/facilities/intercept.hpp>
+#include <boost/preprocessor/repetition/enum_params.hpp>
+#include <boost/preprocessor/repetition/enum_binary_params.hpp>
+#include <boost/preprocessor/repetition/enum_trailing_params.hpp>
+#include <boost/mpl/bool.hpp>
+#include <boost/utility/enable_if.hpp>
+#include <boost/utility/result_of.hpp>
+#include <boost/proto/proto_fwd.hpp>
+#include <boost/proto/args.hpp>
+
+namespace boost { namespace proto
+{
+
+ namespace detail
     {
+ template<typename Expr>
+ struct by_value_generator_;
 
- namespace detail
+ template<typename Tag, typename Arg>
+ struct by_value_generator_<proto::expr<Tag, term<Arg>, 0> >
         {
- template<typename Expr>
- struct by_value_generator_;
+ typedef
+ proto::expr<
+ Tag
+ , term<typename detail::term_traits<Arg>::value_type>
+ , 0
+ >
+ type;
 
- template<typename Tag, typename Arg>
- struct by_value_generator_<proto::expr<Tag, term<Arg>, 0> >
+ static type const call(proto::expr<Tag, term<Arg>, 0> const &e)
             {
- typedef
- proto::expr<
- Tag
- , term<typename detail::term_traits<Arg>::value_type>
- , 0
- >
- type;
-
- static type const call(proto::expr<Tag, term<Arg>, 0> const &e)
- {
- type that = {e.child0};
- return that;
- }
- };
-
- template<typename Tag, typename Arg>
- struct by_value_generator_<proto::basic_expr<Tag, term<Arg>, 0> >
- {
- typedef
- proto::basic_expr<
- Tag
- , term<typename detail::term_traits<Arg>::value_type>
- , 0
- >
- type;
-
- static type const call(proto::basic_expr<Tag, term<Arg>, 0> const &e)
- {
- type that = {e.child0};
- return that;
- }
- };
-
- // Include the other specializations of by_value_generator_
- #include <boost/proto/detail/generate_by_value.hpp>
- }
+ type that = {e.child0};
+ return that;
+ }
+ };
 
- /// \brief A simple generator that passes an expression
- /// through unchanged.
- ///
- /// Generators are intended for use as the first template parameter
- /// to the \c domain\<\> class template and control if and how
- /// expressions within that domain are to be customized.
- /// The \c default_generator makes no modifications to the expressions
- /// passed to it.
- struct default_generator
+ template<typename Tag, typename Arg>
+ struct by_value_generator_<proto::basic_expr<Tag, term<Arg>, 0> >
         {
- BOOST_PROTO_CALLABLE()
-
- template<typename Sig>
- struct result;
+ typedef
+ proto::basic_expr<
+ Tag
+ , term<typename detail::term_traits<Arg>::value_type>
+ , 0
+ >
+ type;
 
- template<typename This, typename Expr>
- struct result<This(Expr)>
+ static type const call(proto::basic_expr<Tag, term<Arg>, 0> const &e)
             {
- typedef Expr type;
- };
-
- /// \param expr A Proto expression
- /// \return expr
- template<typename Expr>
- #ifdef BOOST_PROTO_STRICT_RESULT_OF
- Expr
- #else
- Expr const &
- #endif
- operator ()(Expr const &e) const
- {
- return e;
+ type that = {e.child0};
+ return that;
             }
         };
 
- /// \brief A generator that wraps expressions passed
- /// to it in the specified extension wrapper.
- ///
- /// Generators are intended for use as the first template parameter
- /// to the \c domain\<\> class template and control if and how
- /// expressions within that domain are to be customized.
- /// \c generator\<\> wraps each expression passed to it in
- /// the \c Extends\<\> wrapper.
- template<template<typename> class Extends>
- struct generator
+ // Include the other specializations of by_value_generator_
+ #include <boost/proto/detail/generate_by_value.hpp>
+ }
+
+ /// \brief A simple generator that passes an expression
+ /// through unchanged.
+ ///
+ /// Generators are intended for use as the first template parameter
+ /// to the \c domain\<\> class template and control if and how
+ /// expressions within that domain are to be customized.
+ /// The \c default_generator makes no modifications to the expressions
+ /// passed to it.
+ struct default_generator
+ {
+ BOOST_PROTO_CALLABLE()
+
+ template<typename Sig>
+ struct result;
+
+ template<typename This, typename Expr>
+ struct result<This(Expr)>
         {
- BOOST_PROTO_CALLABLE()
- BOOST_PROTO_USE_BASIC_EXPR()
+ typedef Expr type;
+ };
 
- template<typename Sig>
- struct result;
+ /// \param expr A Proto expression
+ /// \return expr
+ template<typename Expr>
+ #ifdef BOOST_PROTO_STRICT_RESULT_OF
+ Expr
+ #else
+ Expr const &
+ #endif
+ operator ()(Expr const &e) const
+ {
+ return e;
+ }
+ };
 
- template<typename This, typename Expr>
- struct result<This(Expr)>
- {
- typedef Extends<Expr> type;
- };
+ /// \brief A generator that wraps expressions passed
+ /// to it in the specified extension wrapper.
+ ///
+ /// Generators are intended for use as the first template parameter
+ /// to the \c domain\<\> class template and control if and how
+ /// expressions within that domain are to be customized.
+ /// \c generator\<\> wraps each expression passed to it in
+ /// the \c Extends\<\> wrapper.
+ template<template<typename> class Extends>
+ struct generator
+ {
+ BOOST_PROTO_CALLABLE()
+ BOOST_PROTO_USE_BASIC_EXPR()
 
- template<typename This, typename Expr>
- struct result<This(Expr &)>
- {
- typedef Extends<Expr> type;
- };
+ template<typename Sig>
+ struct result;
 
- template<typename This, typename Expr>
- struct result<This(Expr const &)>
- {
- typedef Extends<Expr> type;
- };
+ template<typename This, typename Expr>
+ struct result<This(Expr)>
+ {
+ typedef Extends<Expr> type;
+ };
 
- /// \param expr A Proto expression
- /// \return Extends<Expr>(expr)
- template<typename Expr>
- Extends<Expr> operator ()(Expr const &e) const
- {
- return Extends<Expr>(e);
- }
+ template<typename This, typename Expr>
+ struct result<This(Expr &)>
+ {
+ typedef Extends<Expr> type;
         };
 
- /// \brief A generator that wraps expressions passed
- /// to it in the specified extension wrapper and uses
- /// aggregate initialization for the wrapper.
- ///
- /// Generators are intended for use as the first template parameter
- /// to the \c domain\<\> class template and control if and how
- /// expressions within that domain are to be customized.
- /// \c pod_generator\<\> wraps each expression passed to it in
- /// the \c Extends\<\> wrapper, and uses aggregate initialzation
- /// for the wrapped object.
- template<template<typename> class Extends>
- struct pod_generator
+ template<typename This, typename Expr>
+ struct result<This(Expr const &)>
         {
- BOOST_PROTO_CALLABLE()
- BOOST_PROTO_USE_BASIC_EXPR()
+ typedef Extends<Expr> type;
+ };
 
- template<typename Sig>
- struct result;
+ /// \param expr A Proto expression
+ /// \return Extends<Expr>(expr)
+ template<typename Expr>
+ Extends<Expr> operator ()(Expr const &e) const
+ {
+ return Extends<Expr>(e);
+ }
+ };
 
- template<typename This, typename Expr>
- struct result<This(Expr)>
- {
- typedef Extends<Expr> type;
- };
+ /// \brief A generator that wraps expressions passed
+ /// to it in the specified extension wrapper and uses
+ /// aggregate initialization for the wrapper.
+ ///
+ /// Generators are intended for use as the first template parameter
+ /// to the \c domain\<\> class template and control if and how
+ /// expressions within that domain are to be customized.
+ /// \c pod_generator\<\> wraps each expression passed to it in
+ /// the \c Extends\<\> wrapper, and uses aggregate initialzation
+ /// for the wrapped object.
+ template<template<typename> class Extends>
+ struct pod_generator
+ {
+ BOOST_PROTO_CALLABLE()
+ BOOST_PROTO_USE_BASIC_EXPR()
 
- template<typename This, typename Expr>
- struct result<This(Expr &)>
- {
- typedef Extends<Expr> type;
- };
+ template<typename Sig>
+ struct result;
 
- template<typename This, typename Expr>
- struct result<This(Expr const &)>
- {
- typedef Extends<Expr> type;
- };
+ template<typename This, typename Expr>
+ struct result<This(Expr)>
+ {
+ typedef Extends<Expr> type;
+ };
 
- /// \param expr The expression to wrap
- /// \return <tt>Extends\<Expr\> that = {expr}; return that;</tt>
- template<typename Expr>
- Extends<Expr> operator ()(Expr const &e) const
- {
- Extends<Expr> that = {e};
- return that;
- }
+ template<typename This, typename Expr>
+ struct result<This(Expr &)>
+ {
+ typedef Extends<Expr> type;
         };
 
- /// \brief A generator that replaces child nodes held by
- /// reference with ones held by value. Use with
- /// \c compose_generators to forward that result to another
- /// generator.
- ///
- /// Generators are intended for use as the first template parameter
- /// to the \c domain\<\> class template and control if and how
- /// expressions within that domain are to be customized.
- /// \c by_value_generator ensures all child nodes are
- /// held by value. This generator is typically composed with a
- /// second generator for further processing, as
- /// <tt>compose_generators\<by_value_generator, MyGenerator\></tt>.
- struct by_value_generator
+ template<typename This, typename Expr>
+ struct result<This(Expr const &)>
         {
- BOOST_PROTO_CALLABLE()
+ typedef Extends<Expr> type;
+ };
 
- template<typename Sig>
- struct result;
+ /// \param expr The expression to wrap
+ /// \return <tt>Extends\<Expr\> that = {expr}; return that;</tt>
+ template<typename Expr>
+ Extends<Expr> operator ()(Expr const &e) const
+ {
+ Extends<Expr> that = {e};
+ return that;
+ }
+ };
 
- template<typename This, typename Expr>
- struct result<This(Expr)>
- {
- typedef
- typename detail::by_value_generator_<Expr>::type
- type;
- };
+ /// \brief A generator that replaces child nodes held by
+ /// reference with ones held by value. Use with
+ /// \c compose_generators to forward that result to another
+ /// generator.
+ ///
+ /// Generators are intended for use as the first template parameter
+ /// to the \c domain\<\> class template and control if and how
+ /// expressions within that domain are to be customized.
+ /// \c by_value_generator ensures all child nodes are
+ /// held by value. This generator is typically composed with a
+ /// second generator for further processing, as
+ /// <tt>compose_generators\<by_value_generator, MyGenerator\></tt>.
+ struct by_value_generator
+ {
+ BOOST_PROTO_CALLABLE()
 
- template<typename This, typename Expr>
- struct result<This(Expr &)>
- {
- typedef
- typename detail::by_value_generator_<Expr>::type
- type;
- };
+ template<typename Sig>
+ struct result;
 
- template<typename This, typename Expr>
- struct result<This(Expr const &)>
- {
- typedef
- typename detail::by_value_generator_<Expr>::type
- type;
- };
-
- /// \param expr The expression to modify.
- /// \return <tt>deep_copy(expr)</tt>
- template<typename Expr>
- typename result<by_value_generator(Expr)>::type operator ()(Expr const &e) const
- {
- return detail::by_value_generator_<Expr>::call(e);
- }
+ template<typename This, typename Expr>
+ struct result<This(Expr)>
+ {
+ typedef
+ typename detail::by_value_generator_<Expr>::type
+ type;
         };
 
- /// \brief A composite generator that first applies one
- /// transform to an expression and then forwards the result
- /// on to another generator for further transformation.
- ///
- /// Generators are intended for use as the first template parameter
- /// to the \c domain\<\> class template and control if and how
- /// expressions within that domain are to be customized.
- /// \c compose_generators\<\> is a composite generator that first
- /// applies one transform to an expression and then forwards the
- /// result on to another generator for further transformation.
- template<typename First, typename Second>
- struct compose_generators
+ template<typename This, typename Expr>
+ struct result<This(Expr &)>
         {
- BOOST_PROTO_CALLABLE()
+ typedef
+ typename detail::by_value_generator_<Expr>::type
+ type;
+ };
 
- template<typename Sig>
- struct result;
+ template<typename This, typename Expr>
+ struct result<This(Expr const &)>
+ {
+ typedef
+ typename detail::by_value_generator_<Expr>::type
+ type;
+ };
 
- template<typename This, typename Expr>
- struct result<This(Expr)>
- {
- typedef
- typename Second::template result<
- Second(typename First::template result<First(Expr)>::type)
- >::type
- type;
- };
+ /// \param expr The expression to modify.
+ /// \return <tt>deep_copy(expr)</tt>
+ template<typename Expr>
+ typename result<by_value_generator(Expr)>::type operator ()(Expr const &e) const
+ {
+ return detail::by_value_generator_<Expr>::call(e);
+ }
+ };
 
- template<typename This, typename Expr>
- struct result<This(Expr &)>
- {
- typedef
- typename Second::template result<
- Second(typename First::template result<First(Expr)>::type)
- >::type
- type;
- };
+ /// \brief A composite generator that first applies one
+ /// transform to an expression and then forwards the result
+ /// on to another generator for further transformation.
+ ///
+ /// Generators are intended for use as the first template parameter
+ /// to the \c domain\<\> class template and control if and how
+ /// expressions within that domain are to be customized.
+ /// \c compose_generators\<\> is a composite generator that first
+ /// applies one transform to an expression and then forwards the
+ /// result on to another generator for further transformation.
+ template<typename First, typename Second>
+ struct compose_generators
+ {
+ BOOST_PROTO_CALLABLE()
 
- template<typename This, typename Expr>
- struct result<This(Expr const &)>
- {
- typedef
- typename Second::template result<
- Second(typename First::template result<First(Expr)>::type)
- >::type
- type;
- };
-
- /// \param expr The expression to modify.
- /// \return Second()(First()(expr))
- template<typename Expr>
- typename result<compose_generators(Expr)>::type operator ()(Expr const &e) const
- {
- return Second()(First()(e));
- }
- };
+ template<typename Sig>
+ struct result;
 
- /// \brief Annotate a generator to indicate that it would
- /// prefer to be passed instances of \c proto::basic_expr\<\> rather
- /// than \c proto::expr\<\>. <tt>use_basic_expr\<Generator\></tt> is
- /// itself a generator.
- ///
- template<typename Generator>
- struct use_basic_expr
- : Generator
- {
- BOOST_PROTO_USE_BASIC_EXPR()
- };
-
- /// \brief Tests a generator to see whether it would prefer
- /// to be passed instances of \c proto::basic_expr\<\> rather than
- /// \c proto::expr\<\>.
- ///
- template<typename Generator, typename Void>
- struct wants_basic_expr
- : mpl::false_
- {};
-
- template<typename Generator>
- struct wants_basic_expr<Generator, typename Generator::proto_use_basic_expr_>
- : mpl::true_
- {};
-
- /// INTERNAL ONLY
- template<>
- struct is_callable<default_generator>
- : mpl::true_
- {};
-
- /// INTERNAL ONLY
- template<template<typename> class Extends>
- struct is_callable<generator<Extends> >
- : mpl::true_
- {};
-
- /// INTERNAL ONLY
- template<template<typename> class Extends>
- struct is_callable<pod_generator<Extends> >
- : mpl::true_
- {};
-
- /// INTERNAL ONLY
- template<>
- struct is_callable<by_value_generator>
- : mpl::true_
- {};
-
- /// INTERNAL ONLY
- template<typename First, typename Second>
- struct is_callable<compose_generators<First, Second> >
- : mpl::true_
- {};
-
- }}
-
- // Specializations of boost::result_of and boost::tr1_result_of to eliminate
- // some unnecessary template instantiations
- namespace boost
- {
- template<typename Expr>
- struct result_of<proto::default_domain(Expr)>
+ template<typename This, typename Expr>
+ struct result<This(Expr)>
         {
- typedef Expr type;
+ typedef
+ typename Second::template result<
+ Second(typename First::template result<First(Expr)>::type)
+ >::type
+ type;
         };
 
- template<typename Expr>
- struct result_of<proto::default_generator(Expr)>
+ template<typename This, typename Expr>
+ struct result<This(Expr &)>
         {
- typedef Expr type;
+ typedef
+ typename Second::template result<
+ Second(typename First::template result<First(Expr)>::type)
+ >::type
+ type;
         };
 
- #if BOOST_VERSION >= 104400
- template<typename Expr>
- struct tr1_result_of<proto::default_domain(Expr)>
+ template<typename This, typename Expr>
+ struct result<This(Expr const &)>
         {
- typedef Expr type;
+ typedef
+ typename Second::template result<
+ Second(typename First::template result<First(Expr)>::type)
+ >::type
+ type;
         };
 
+ /// \param expr The expression to modify.
+ /// \return Second()(First()(expr))
         template<typename Expr>
- struct tr1_result_of<proto::default_generator(Expr)>
+ typename result<compose_generators(Expr)>::type operator ()(Expr const &e) const
         {
- typedef Expr type;
- };
- #endif
- }
+ return Second()(First()(e));
+ }
+ };
 
- #endif // BOOST_PROTO_GENERATE_HPP_EAN_02_13_2007
+ /// \brief Annotate a generator to indicate that it would
+ /// prefer to be passed instances of \c proto::basic_expr\<\> rather
+ /// than \c proto::expr\<\>. <tt>use_basic_expr\<Generator\></tt> is
+ /// itself a generator.
+ ///
+ template<typename Generator>
+ struct use_basic_expr
+ : Generator
+ {
+ BOOST_PROTO_USE_BASIC_EXPR()
+ };
 
-#else // BOOST_PP_IS_ITERATING
+ /// \brief Tests a generator to see whether it would prefer
+ /// to be passed instances of \c proto::basic_expr\<\> rather than
+ /// \c proto::expr\<\>.
+ ///
+ template<typename Generator, typename Void>
+ struct wants_basic_expr
+ : mpl::false_
+ {};
+
+ template<typename Generator>
+ struct wants_basic_expr<Generator, typename Generator::proto_use_basic_expr_>
+ : mpl::true_
+ {};
+
+ /// INTERNAL ONLY
+ template<>
+ struct is_callable<default_generator>
+ : mpl::true_
+ {};
+
+ /// INTERNAL ONLY
+ template<template<typename> class Extends>
+ struct is_callable<generator<Extends> >
+ : mpl::true_
+ {};
+
+ /// INTERNAL ONLY
+ template<template<typename> class Extends>
+ struct is_callable<pod_generator<Extends> >
+ : mpl::true_
+ {};
+
+ /// INTERNAL ONLY
+ template<>
+ struct is_callable<by_value_generator>
+ : mpl::true_
+ {};
+
+ /// INTERNAL ONLY
+ template<typename First, typename Second>
+ struct is_callable<compose_generators<First, Second> >
+ : mpl::true_
+ {};
+
+}}
+
+// Specializations of boost::result_of and boost::tr1_result_of to eliminate
+// some unnecessary template instantiations
+namespace boost
+{
+ template<typename Expr>
+ struct result_of<proto::default_domain(Expr)>
+ {
+ typedef Expr type;
+ };
 
- #define N BOOST_PP_ITERATION()
+ template<typename Expr>
+ struct result_of<proto::default_generator(Expr)>
+ {
+ typedef Expr type;
+ };
 
- template<typename Tag BOOST_PP_ENUM_TRAILING_PARAMS(N, typename Arg) >
- struct by_value_generator_<
- proto::expr<Tag, BOOST_PP_CAT(list, N)<BOOST_PP_ENUM_PARAMS(N, Arg)>, N>
- >
- {
- typedef
- BOOST_PP_CAT(list, N)<BOOST_PP_ENUM_PARAMS(N, Arg)>
- src_args;
-
- typedef
- BOOST_PP_CAT(list, N)<
- BOOST_PP_ENUM_BINARY_PARAMS(N, typename uncvref<Arg, >::type BOOST_PP_INTERCEPT)
- >
- dst_args;
-
- typedef proto::expr<Tag, src_args, N> src_type;
- typedef proto::expr<Tag, dst_args, N> type;
-
- static type const call(src_type const &e)
- {
- type that = {
- BOOST_PP_ENUM_PARAMS(N, e.child)
- };
- return that;
- }
- };
-
- template<typename Tag BOOST_PP_ENUM_TRAILING_PARAMS(N, typename Arg) >
- struct by_value_generator_<
- proto::basic_expr<Tag, BOOST_PP_CAT(list, N)<BOOST_PP_ENUM_PARAMS(N, Arg)>, N>
- >
- {
- typedef
- BOOST_PP_CAT(list, N)<BOOST_PP_ENUM_PARAMS(N, Arg)>
- src_args;
-
- typedef
- BOOST_PP_CAT(list, N)<
- BOOST_PP_ENUM_BINARY_PARAMS(N, typename uncvref<Arg, >::type BOOST_PP_INTERCEPT)
- >
- dst_args;
-
- typedef proto::basic_expr<Tag, src_args, N> src_type;
- typedef proto::basic_expr<Tag, dst_args, N> type;
-
- static type const call(src_type const &e)
- {
- type that = {
- BOOST_PP_ENUM_PARAMS(N, e.child)
- };
- return that;
- }
- };
+ #if BOOST_VERSION >= 104400
+ template<typename Expr>
+ struct tr1_result_of<proto::default_domain(Expr)>
+ {
+ typedef Expr type;
+ };
 
- #undef N
+ template<typename Expr>
+ struct tr1_result_of<proto::default_generator(Expr)>
+ {
+ typedef Expr type;
+ };
+ #endif
+}
 
-#endif
+#endif // BOOST_PROTO_GENERATE_HPP_EAN_02_13_2007

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

Modified: trunk/boost/proto/traits.hpp
==============================================================================
--- trunk/boost/proto/traits.hpp (original)
+++ trunk/boost/proto/traits.hpp 2011-05-06 11:55:17 EDT (Fri, 06 May 2011)
@@ -1,1405 +1,1213 @@
-#ifndef BOOST_PP_IS_ITERATING
- ///////////////////////////////////////////////////////////////////////////////
- /// \file traits.hpp
- /// Contains definitions for child\<\>, child_c\<\>, left\<\>,
- /// right\<\>, tag_of\<\>, and the helper functions child(), child_c(),
- /// value(), left() and right().
- //
- // Copyright 2008 Eric Niebler. Distributed under the Boost
- // Software License, Version 1.0. (See accompanying file
- // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
-
- #ifndef BOOST_PROTO_ARG_TRAITS_HPP_EAN_04_01_2005
- #define BOOST_PROTO_ARG_TRAITS_HPP_EAN_04_01_2005
-
- #include <boost/config.hpp>
- #include <boost/detail/workaround.hpp>
- #include <boost/preprocessor/iteration/iterate.hpp>
- #include <boost/preprocessor/repetition/enum.hpp>
- #include <boost/preprocessor/repetition/enum_params.hpp>
- #include <boost/preprocessor/repetition/enum_trailing_params.hpp>
- #include <boost/preprocessor/repetition/repeat.hpp>
- #include <boost/preprocessor/repetition/repeat_from_to.hpp>
- #include <boost/preprocessor/facilities/intercept.hpp>
- #include <boost/preprocessor/arithmetic/sub.hpp>
- #include <boost/static_assert.hpp>
- #include <boost/mpl/bool.hpp>
- #include <boost/mpl/aux_/template_arity.hpp>
- #include <boost/mpl/aux_/lambda_arity_param.hpp>
- #include <boost/type_traits/is_pod.hpp>
- #include <boost/type_traits/is_same.hpp>
- #include <boost/type_traits/add_const.hpp>
- #include <boost/proto/proto_fwd.hpp>
- #include <boost/proto/args.hpp>
- #include <boost/proto/domain.hpp>
- #include <boost/proto/transform/pass_through.hpp>
-
- #if BOOST_WORKAROUND( BOOST_MSVC, >= 1400 )
- #pragma warning(push)
- #pragma warning(disable: 4180) // warning C4180: qualifier applied to function type has no meaning; ignored
- #endif
+///////////////////////////////////////////////////////////////////////////////
+/// \file traits.hpp
+/// Contains definitions for child\<\>, child_c\<\>, left\<\>,
+/// right\<\>, tag_of\<\>, and the helper functions child(), child_c(),
+/// value(), left() and right().
+//
+// Copyright 2008 Eric Niebler. Distributed under the Boost
+// Software License, Version 1.0. (See accompanying file
+// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_PROTO_ARG_TRAITS_HPP_EAN_04_01_2005
+#define BOOST_PROTO_ARG_TRAITS_HPP_EAN_04_01_2005
+
+#include <boost/config.hpp>
+#include <boost/detail/workaround.hpp>
+#include <boost/preprocessor/iteration/iterate.hpp>
+#include <boost/preprocessor/repetition/enum.hpp>
+#include <boost/preprocessor/repetition/enum_params.hpp>
+#include <boost/preprocessor/repetition/enum_trailing_params.hpp>
+#include <boost/preprocessor/repetition/repeat.hpp>
+#include <boost/preprocessor/repetition/repeat_from_to.hpp>
+#include <boost/preprocessor/facilities/intercept.hpp>
+#include <boost/preprocessor/arithmetic/sub.hpp>
+#include <boost/static_assert.hpp>
+#include <boost/mpl/bool.hpp>
+#include <boost/mpl/aux_/template_arity.hpp>
+#include <boost/mpl/aux_/lambda_arity_param.hpp>
+#include <boost/type_traits/is_pod.hpp>
+#include <boost/type_traits/is_same.hpp>
+#include <boost/type_traits/add_const.hpp>
+#include <boost/proto/proto_fwd.hpp>
+#include <boost/proto/args.hpp>
+#include <boost/proto/domain.hpp>
+#include <boost/proto/transform/pass_through.hpp>
+
+#if BOOST_WORKAROUND( BOOST_MSVC, >= 1400 )
+ #pragma warning(push)
+ #pragma warning(disable: 4180) // warning C4180: qualifier applied to function type has no meaning; ignored
+#endif
 
- namespace boost { namespace proto
+namespace boost { namespace proto
+{
+ namespace detail
     {
- namespace detail
- {
- template<typename T, typename Void = void>
- struct if_vararg
- {};
-
- template<typename T>
- struct if_vararg<T, typename T::proto_is_vararg_>
- : T
- {};
-
- template<typename T, typename Void = void>
- struct is_callable2_
- : mpl::false_
- {};
-
- template<typename T>
- struct is_callable2_<T, typename T::proto_is_callable_>
- : mpl::true_
- {};
-
- template<typename T BOOST_MPL_AUX_LAMBDA_ARITY_PARAM(long Arity = mpl::aux::template_arity<T>::value)>
- struct is_callable_
- : is_callable2_<T>
- {};
-
- }
-
- /// \brief Boolean metafunction which detects whether a type is
- /// a callable function object type or not.
- ///
- /// <tt>is_callable\<\></tt> is used by the <tt>when\<\></tt> transform
- /// to determine whether a function type <tt>R(A1,A2,...AN)</tt> is a
- /// callable transform or an object transform. (The former are evaluated
- /// using <tt>call\<\></tt> and the later with <tt>make\<\></tt>.) If
- /// <tt>is_callable\<R\>::value</tt> is \c true, the function type is
- /// a callable transform; otherwise, it is an object transform.
- ///
- /// Unless specialized for a type \c T, <tt>is_callable\<T\>::value</tt>
- /// is computed as follows:
- ///
- /// \li If \c T is a template type <tt>X\<Y0,Y1,...YN\></tt>, where all \c Yx
- /// are types for \c x in <tt>[0,N]</tt>, <tt>is_callable\<T\>::value</tt>
- /// is <tt>is_same\<YN, proto::callable\>::value</tt>.
- /// \li If \c T has a nested type \c proto_is_callable_ that is a typedef
- /// for \c void, <tt>is_callable\<T\>::value</tt> is \c true. (Note: this is
- /// the case for any type that derives from \c proto::callable.)
- /// \li Otherwise, <tt>is_callable\<T\>::value</tt> is \c false.
- template<typename T>
- struct is_callable
- : proto::detail::is_callable_<T>
- {};
-
- /// INTERNAL ONLY
- ///
- template<>
- struct is_callable<proto::_>
- : mpl::true_
+ template<typename T, typename Void = void>
+ struct if_vararg
         {};
 
- /// INTERNAL ONLY
- ///
- template<>
- struct is_callable<proto::callable>
- : mpl::false_
- {};
-
- /// INTERNAL ONLY
- ///
- template<typename PrimitiveTransform, typename X>
- struct is_callable<proto::transform<PrimitiveTransform, X> >
- : mpl::false_
- {};
-
- #if BOOST_WORKAROUND(__GNUC__, == 3) || (__GNUC__ == 4 && __GNUC_MINOR__ == 0)
- // work around GCC bug
- template<typename Tag, typename Args, long N>
- struct is_callable<proto::expr<Tag, Args, N> >
- : mpl::false_
- {};
-
- // work around GCC bug
- template<typename Tag, typename Args, long N>
- struct is_callable<proto::basic_expr<Tag, Args, N> >
- : mpl::false_
+ template<typename T>
+ struct if_vararg<T, typename T::proto_is_vararg_>
+ : T
         {};
- #endif
 
- /// \brief Boolean metafunction which detects whether a type is
- /// a PrimitiveTransform type or not.
- ///
- /// <tt>is_transform\<\></tt> is used by the <tt>call\<\></tt> transform
- /// to determine whether the function types <tt>R()</tt>, <tt>R(A1)</tt>,
- /// and <tt>R(A1, A2)</tt> should be passed the expression, state and data
- /// parameters (as needed).
- ///
- /// Unless specialized for a type \c T, <tt>is_transform\<T\>::value</tt>
- /// is computed as follows:
- ///
- /// \li If \c T has a nested type \c proto_is_transform_ that is a typedef
- /// for \c void, <tt>is_transform\<T\>::value</tt> is \c true. (Note: this is
- /// the case for any type that derives from an instantiation of \c proto::transform.)
- /// \li Otherwise, <tt>is_transform\<T\>::value</tt> is \c false.
- template<typename T, typename Void /*= void*/>
- struct is_transform
+ template<typename T, typename Void = void>
+ struct is_callable2_
           : mpl::false_
         {};
 
         template<typename T>
- struct is_transform<T, typename T::proto_is_transform_>
+ struct is_callable2_<T, typename T::proto_is_callable_>
           : mpl::true_
         {};
 
- /// \brief A Boolean metafunction that indicates whether a type requires
- /// aggregate initialization.
- ///
- /// <tt>is_aggregate\<\></tt> is used by the <tt>make\<\></tt> transform
- /// to determine how to construct an object of some type \c T, given some
- /// initialization arguments <tt>a0,a1,...aN</tt>.
- /// If <tt>is_aggregate\<T\>::value</tt> is \c true, then an object of
- /// type T will be initialized as <tt>T t = {a0,a1,...aN};</tt>. Otherwise,
- /// it will be initialized as <tt>T t(a0,a1,...aN)</tt>.
- template<typename T, typename Void>
- struct is_aggregate
- : is_pod<T>
- {};
+ template<typename T BOOST_MPL_AUX_LAMBDA_ARITY_PARAM(long Arity = mpl::aux::template_arity<T>::value)>
+ struct is_callable_
+ : is_callable2_<T>
+ {};
+
+ }
+
+ /// \brief Boolean metafunction which detects whether a type is
+ /// a callable function object type or not.
+ ///
+ /// <tt>is_callable\<\></tt> is used by the <tt>when\<\></tt> transform
+ /// to determine whether a function type <tt>R(A1,A2,...AN)</tt> is a
+ /// callable transform or an object transform. (The former are evaluated
+ /// using <tt>call\<\></tt> and the later with <tt>make\<\></tt>.) If
+ /// <tt>is_callable\<R\>::value</tt> is \c true, the function type is
+ /// a callable transform; otherwise, it is an object transform.
+ ///
+ /// Unless specialized for a type \c T, <tt>is_callable\<T\>::value</tt>
+ /// is computed as follows:
+ ///
+ /// \li If \c T is a template type <tt>X\<Y0,Y1,...YN\></tt>, where all \c Yx
+ /// are types for \c x in <tt>[0,N]</tt>, <tt>is_callable\<T\>::value</tt>
+ /// is <tt>is_same\<YN, proto::callable\>::value</tt>.
+ /// \li If \c T has a nested type \c proto_is_callable_ that is a typedef
+ /// for \c void, <tt>is_callable\<T\>::value</tt> is \c true. (Note: this is
+ /// the case for any type that derives from \c proto::callable.)
+ /// \li Otherwise, <tt>is_callable\<T\>::value</tt> is \c false.
+ template<typename T>
+ struct is_callable
+ : proto::detail::is_callable_<T>
+ {};
+
+ /// INTERNAL ONLY
+ ///
+ template<>
+ struct is_callable<proto::_>
+ : mpl::true_
+ {};
+
+ /// INTERNAL ONLY
+ ///
+ template<>
+ struct is_callable<proto::callable>
+ : mpl::false_
+ {};
+
+ /// INTERNAL ONLY
+ ///
+ template<typename PrimitiveTransform, typename X>
+ struct is_callable<proto::transform<PrimitiveTransform, X> >
+ : mpl::false_
+ {};
+
+ #if BOOST_WORKAROUND(__GNUC__, == 3) || (__GNUC__ == 4 && __GNUC_MINOR__ == 0)
+ // work around GCC bug
+ template<typename Tag, typename Args, long N>
+ struct is_callable<proto::expr<Tag, Args, N> >
+ : mpl::false_
+ {};
+
+ // work around GCC bug
+ template<typename Tag, typename Args, long N>
+ struct is_callable<proto::basic_expr<Tag, Args, N> >
+ : mpl::false_
+ {};
+ #endif
 
- /// \brief Specialization of <tt>is_aggregate\<\></tt> that indicates
- /// that objects of <tt>expr\<\></tt> type require aggregate initialization.
- template<typename Tag, typename Args, long N>
- struct is_aggregate<proto::expr<Tag, Args, N>, void>
- : mpl::true_
- {};
+ /// \brief Boolean metafunction which detects whether a type is
+ /// a PrimitiveTransform type or not.
+ ///
+ /// <tt>is_transform\<\></tt> is used by the <tt>call\<\></tt> transform
+ /// to determine whether the function types <tt>R()</tt>, <tt>R(A1)</tt>,
+ /// and <tt>R(A1, A2)</tt> should be passed the expression, state and data
+ /// parameters (as needed).
+ ///
+ /// Unless specialized for a type \c T, <tt>is_transform\<T\>::value</tt>
+ /// is computed as follows:
+ ///
+ /// \li If \c T has a nested type \c proto_is_transform_ that is a typedef
+ /// for \c void, <tt>is_transform\<T\>::value</tt> is \c true. (Note: this is
+ /// the case for any type that derives from an instantiation of \c proto::transform.)
+ /// \li Otherwise, <tt>is_transform\<T\>::value</tt> is \c false.
+ template<typename T, typename Void /*= void*/>
+ struct is_transform
+ : mpl::false_
+ {};
+
+ template<typename T>
+ struct is_transform<T, typename T::proto_is_transform_>
+ : mpl::true_
+ {};
+
+ /// \brief A Boolean metafunction that indicates whether a type requires
+ /// aggregate initialization.
+ ///
+ /// <tt>is_aggregate\<\></tt> is used by the <tt>make\<\></tt> transform
+ /// to determine how to construct an object of some type \c T, given some
+ /// initialization arguments <tt>a0,a1,...aN</tt>.
+ /// If <tt>is_aggregate\<T\>::value</tt> is \c true, then an object of
+ /// type T will be initialized as <tt>T t = {a0,a1,...aN};</tt>. Otherwise,
+ /// it will be initialized as <tt>T t(a0,a1,...aN)</tt>.
+ template<typename T, typename Void>
+ struct is_aggregate
+ : is_pod<T>
+ {};
+
+ /// \brief Specialization of <tt>is_aggregate\<\></tt> that indicates
+ /// that objects of <tt>expr\<\></tt> type require aggregate initialization.
+ template<typename Tag, typename Args, long N>
+ struct is_aggregate<proto::expr<Tag, Args, N>, void>
+ : mpl::true_
+ {};
+
+ template<typename Tag, typename Args, long N>
+ struct is_aggregate<proto::basic_expr<Tag, Args, N>, void>
+ : mpl::true_
+ {};
+
+ /// INTERNAL ONLY
+ template<typename T>
+ struct is_aggregate<T, typename T::proto_is_aggregate_>
+ : mpl::true_
+ {};
+
+ /// \brief A Boolean metafunction that indicates whether a given
+ /// type \c T is a Proto expression type.
+ ///
+ /// If \c T has a nested type \c proto_is_expr_ that is a typedef
+ /// for \c void, <tt>is_expr\<T\>::value</tt> is \c true. (Note, this
+ /// is the case for <tt>proto::expr\<\></tt>, any type that is derived
+ /// from <tt>proto::extends\<\></tt> or that uses the
+ /// <tt>BOOST_PROTO_BASIC_EXTENDS()</tt> macro.) Otherwise,
+ /// <tt>is_expr\<T\>::value</tt> is \c false.
+ template<typename T, typename Void /* = void*/>
+ struct is_expr
+ : mpl::false_
+ {};
+
+ /// \brief A Boolean metafunction that indicates whether a given
+ /// type \c T is a Proto expression type.
+ ///
+ /// If \c T has a nested type \c proto_is_expr_ that is a typedef
+ /// for \c void, <tt>is_expr\<T\>::value</tt> is \c true. (Note, this
+ /// is the case for <tt>proto::expr\<\></tt>, any type that is derived
+ /// from <tt>proto::extends\<\></tt> or that uses the
+ /// <tt>BOOST_PROTO_BASIC_EXTENDS()</tt> macro.) Otherwise,
+ /// <tt>is_expr\<T\>::value</tt> is \c false.
+ template<typename T>
+ struct is_expr<T, typename T::proto_is_expr_>
+ : mpl::true_
+ {};
+
+ template<typename T>
+ struct is_expr<T &, void>
+ : is_expr<T>
+ {};
+
+ /// \brief A metafunction that returns the tag type of a
+ /// Proto expression.
+ template<typename Expr>
+ struct tag_of
+ {
+ typedef typename Expr::proto_tag type;
+ };
 
- template<typename Tag, typename Args, long N>
- struct is_aggregate<proto::basic_expr<Tag, Args, N>, void>
- : mpl::true_
- {};
+ template<typename Expr>
+ struct tag_of<Expr &>
+ {
+ typedef typename Expr::proto_tag type;
+ };
 
- /// INTERNAL ONLY
- template<typename T>
- struct is_aggregate<T, typename T::proto_is_aggregate_>
- : mpl::true_
- {};
+ /// \brief A metafunction that returns the arity of a
+ /// Proto expression.
+ template<typename Expr>
+ struct arity_of
+ : Expr::proto_arity
+ {};
+
+ template<typename Expr>
+ struct arity_of<Expr &>
+ : Expr::proto_arity
+ {};
 
- /// \brief A Boolean metafunction that indicates whether a given
- /// type \c T is a Proto expression type.
+ namespace result_of
+ {
+ /// \brief A metafunction that computes the return type of the \c as_expr()
+ /// function.
+ template<typename T, typename Domain /*= default_domain*/>
+ struct as_expr
+ {
+ typedef typename Domain::template as_expr<T>::result_type type;
+ };
+
+ /// \brief A metafunction that computes the return type of the \c as_child()
+ /// function.
+ template<typename T, typename Domain /*= default_domain*/>
+ struct as_child
+ {
+ typedef typename Domain::template as_child<T>::result_type type;
+ };
+
+ /// \brief A metafunction that returns the type of the Nth child
+ /// of a Proto expression, where N is an MPL Integral Constant.
         ///
- /// If \c T has a nested type \c proto_is_expr_ that is a typedef
- /// for \c void, <tt>is_expr\<T\>::value</tt> is \c true. (Note, this
- /// is the case for <tt>proto::expr\<\></tt>, any type that is derived
- /// from <tt>proto::extends\<\></tt> or that uses the
- /// <tt>BOOST_PROTO_BASIC_EXTENDS()</tt> macro.) Otherwise,
- /// <tt>is_expr\<T\>::value</tt> is \c false.
- template<typename T, typename Void /* = void*/>
- struct is_expr
- : mpl::false_
+ /// <tt>result_of::child\<Expr, N\></tt> is equivalent to
+ /// <tt>result_of::child_c\<Expr, N::value\></tt>.
+ template<typename Expr, typename N /* = mpl::long_<0>*/>
+ struct child
+ : child_c<Expr, N::value>
         {};
 
- /// \brief A Boolean metafunction that indicates whether a given
- /// type \c T is a Proto expression type.
+ /// \brief A metafunction that returns the type of the value
+ /// of a terminal Proto expression.
         ///
- /// If \c T has a nested type \c proto_is_expr_ that is a typedef
- /// for \c void, <tt>is_expr\<T\>::value</tt> is \c true. (Note, this
- /// is the case for <tt>proto::expr\<\></tt>, any type that is derived
- /// from <tt>proto::extends\<\></tt> or that uses the
- /// <tt>BOOST_PROTO_BASIC_EXTENDS()</tt> macro.) Otherwise,
- /// <tt>is_expr\<T\>::value</tt> is \c false.
- template<typename T>
- struct is_expr<T, typename T::proto_is_expr_>
- : mpl::true_
- {};
-
- template<typename T>
- struct is_expr<T &, void>
- : is_expr<T>
- {};
+ template<typename Expr>
+ struct value
+ {
+ /// Verify that we are actually operating on a terminal
+ BOOST_STATIC_ASSERT(0 == Expr::proto_arity_c);
+
+ /// The raw type of the Nth child as it is stored within
+ /// \c Expr. This may be a value or a reference
+ typedef typename Expr::proto_child0 value_type;
+
+ /// The "value" type of the child, suitable for storage by value,
+ /// computed as follows:
+ /// \li <tt>T const(&)[N]</tt> becomes <tt>T[N]</tt>
+ /// \li <tt>T[N]</tt> becomes <tt>T[N]</tt>
+ /// \li <tt>T(&)[N]</tt> becomes <tt>T[N]</tt>
+ /// \li <tt>R(&)(A0,...)</tt> becomes <tt>R(&)(A0,...)</tt>
+ /// \li <tt>T const &</tt> becomes <tt>T</tt>
+ /// \li <tt>T &</tt> becomes <tt>T</tt>
+ /// \li <tt>T</tt> becomes <tt>T</tt>
+ typedef typename detail::term_traits<typename Expr::proto_child0>::value_type type;
+ };
 
- /// \brief A metafunction that returns the tag type of a
- /// Proto expression.
         template<typename Expr>
- struct tag_of
+ struct value<Expr &>
         {
- typedef typename Expr::proto_tag type;
+ /// Verify that we are actually operating on a terminal
+ BOOST_STATIC_ASSERT(0 == Expr::proto_arity_c);
+
+ /// The raw type of the Nth child as it is stored within
+ /// \c Expr. This may be a value or a reference
+ typedef typename Expr::proto_child0 value_type;
+
+ /// The "reference" type of the child, suitable for storage by
+ /// reference, computed as follows:
+ /// \li <tt>T const(&)[N]</tt> becomes <tt>T const(&)[N]</tt>
+ /// \li <tt>T[N]</tt> becomes <tt>T(&)[N]</tt>
+ /// \li <tt>T(&)[N]</tt> becomes <tt>T(&)[N]</tt>
+ /// \li <tt>R(&)(A0,...)</tt> becomes <tt>R(&)(A0,...)</tt>
+ /// \li <tt>T const &</tt> becomes <tt>T const &</tt>
+ /// \li <tt>T &</tt> becomes <tt>T &</tt>
+ /// \li <tt>T</tt> becomes <tt>T &</tt>
+ typedef typename detail::term_traits<typename Expr::proto_child0>::reference type;
         };
 
         template<typename Expr>
- struct tag_of<Expr &>
+ struct value<Expr const &>
         {
- typedef typename Expr::proto_tag type;
+ /// Verify that we are actually operating on a terminal
+ BOOST_STATIC_ASSERT(0 == Expr::proto_arity_c);
+
+ /// The raw type of the Nth child as it is stored within
+ /// \c Expr. This may be a value or a reference
+ typedef typename Expr::proto_child0 value_type;
+
+ /// The "const reference" type of the child, suitable for storage by
+ /// const reference, computed as follows:
+ /// \li <tt>T const(&)[N]</tt> becomes <tt>T const(&)[N]</tt>
+ /// \li <tt>T[N]</tt> becomes <tt>T const(&)[N]</tt>
+ /// \li <tt>T(&)[N]</tt> becomes <tt>T(&)[N]</tt>
+ /// \li <tt>R(&)(A0,...)</tt> becomes <tt>R(&)(A0,...)</tt>
+ /// \li <tt>T const &</tt> becomes <tt>T const &</tt>
+ /// \li <tt>T &</tt> becomes <tt>T &</tt>
+ /// \li <tt>T</tt> becomes <tt>T const &</tt>
+ typedef typename detail::term_traits<typename Expr::proto_child0>::const_reference type;
         };
 
- /// \brief A metafunction that returns the arity of a
- /// Proto expression.
+ /// \brief A metafunction that returns the type of the left child
+ /// of a binary Proto expression.
+ ///
+ /// <tt>result_of::left\<Expr\></tt> is equivalent to
+ /// <tt>result_of::child_c\<Expr, 0\></tt>.
         template<typename Expr>
- struct arity_of
- : Expr::proto_arity
+ struct left
+ : child_c<Expr, 0>
         {};
 
+ /// \brief A metafunction that returns the type of the right child
+ /// of a binary Proto expression.
+ ///
+ /// <tt>result_of::right\<Expr\></tt> is equivalent to
+ /// <tt>result_of::child_c\<Expr, 1\></tt>.
         template<typename Expr>
- struct arity_of<Expr &>
- : Expr::proto_arity
+ struct right
+ : child_c<Expr, 1>
         {};
 
- namespace result_of
- {
- /// \brief A metafunction that computes the return type of the \c as_expr()
- /// function.
- template<typename T, typename Domain /*= default_domain*/>
- struct as_expr
- {
- typedef typename Domain::template as_expr<T>::result_type type;
- };
+ } // namespace result_of
 
- /// \brief A metafunction that computes the return type of the \c as_child()
- /// function.
- template<typename T, typename Domain /*= default_domain*/>
- struct as_child
- {
- typedef typename Domain::template as_child<T>::result_type type;
- };
+ /// \brief A metafunction for generating terminal expression types,
+ /// a grammar element for matching terminal expressions, and a
+ /// PrimitiveTransform that returns the current expression unchanged.
+ template<typename T>
+ struct terminal
+ : proto::transform<terminal<T>, int>
+ {
+ typedef proto::expr<proto::tag::terminal, term<T>, 0> type;
+ typedef proto::basic_expr<proto::tag::terminal, term<T>, 0> proto_grammar;
 
- /// \brief A metafunction that returns the type of the Nth child
- /// of a Proto expression, where N is an MPL Integral Constant.
- ///
- /// <tt>result_of::child\<Expr, N\></tt> is equivalent to
- /// <tt>result_of::child_c\<Expr, N::value\></tt>.
- template<typename Expr, typename N /* = mpl::long_<0>*/>
- struct child
- : child_c<Expr, N::value>
- {};
+ template<typename Expr, typename State, typename Data>
+ struct impl : transform_impl<Expr, State, Data>
+ {
+ typedef Expr result_type;
 
- /// \brief A metafunction that returns the type of the value
- /// of a terminal Proto expression.
- ///
- template<typename Expr>
- struct value
+ /// \param e The current expression
+ /// \pre <tt>matches\<Expr, terminal\<T\> \>::value</tt> is \c true.
+ /// \return \c e
+ /// \throw nothrow
+ #ifdef BOOST_PROTO_STRICT_RESULT_OF
+ result_type
+ #else
+ typename impl::expr_param
+ #endif
+ operator ()(
+ typename impl::expr_param e
+ , typename impl::state_param
+ , typename impl::data_param
+ ) const
             {
- /// Verify that we are actually operating on a terminal
- BOOST_STATIC_ASSERT(0 == Expr::proto_arity_c);
-
- /// The raw type of the Nth child as it is stored within
- /// \c Expr. This may be a value or a reference
- typedef typename Expr::proto_child0 value_type;
-
- /// The "value" type of the child, suitable for storage by value,
- /// computed as follows:
- /// \li <tt>T const(&)[N]</tt> becomes <tt>T[N]</tt>
- /// \li <tt>T[N]</tt> becomes <tt>T[N]</tt>
- /// \li <tt>T(&)[N]</tt> becomes <tt>T[N]</tt>
- /// \li <tt>R(&)(A0,...)</tt> becomes <tt>R(&)(A0,...)</tt>
- /// \li <tt>T const &</tt> becomes <tt>T</tt>
- /// \li <tt>T &</tt> becomes <tt>T</tt>
- /// \li <tt>T</tt> becomes <tt>T</tt>
- typedef typename detail::term_traits<typename Expr::proto_child0>::value_type type;
- };
+ return e;
+ }
+ };
 
- template<typename Expr>
- struct value<Expr &>
- {
- /// Verify that we are actually operating on a terminal
- BOOST_STATIC_ASSERT(0 == Expr::proto_arity_c);
+ /// INTERNAL ONLY
+ typedef proto::tag::terminal proto_tag;
+ /// INTERNAL ONLY
+ typedef T proto_child0;
+ };
 
- /// The raw type of the Nth child as it is stored within
- /// \c Expr. This may be a value or a reference
- typedef typename Expr::proto_child0 value_type;
-
- /// The "reference" type of the child, suitable for storage by
- /// reference, computed as follows:
- /// \li <tt>T const(&)[N]</tt> becomes <tt>T const(&)[N]</tt>
- /// \li <tt>T[N]</tt> becomes <tt>T(&)[N]</tt>
- /// \li <tt>T(&)[N]</tt> becomes <tt>T(&)[N]</tt>
- /// \li <tt>R(&)(A0,...)</tt> becomes <tt>R(&)(A0,...)</tt>
- /// \li <tt>T const &</tt> becomes <tt>T const &</tt>
- /// \li <tt>T &</tt> becomes <tt>T &</tt>
- /// \li <tt>T</tt> becomes <tt>T &</tt>
- typedef typename detail::term_traits<typename Expr::proto_child0>::reference type;
- };
+ /// \brief A metafunction for generating ternary conditional expression types,
+ /// a grammar element for matching ternary conditional expressions, and a
+ /// PrimitiveTransform that dispatches to the <tt>pass_through\<\></tt>
+ /// transform.
+ template<typename T, typename U, typename V>
+ struct if_else_
+ : proto::transform<if_else_<T, U, V>, int>
+ {
+ typedef proto::expr<proto::tag::if_else_, list3<T, U, V>, 3> type;
+ typedef proto::basic_expr<proto::tag::if_else_, list3<T, U, V>, 3> proto_grammar;
 
- template<typename Expr>
- struct value<Expr const &>
- {
- /// Verify that we are actually operating on a terminal
- BOOST_STATIC_ASSERT(0 == Expr::proto_arity_c);
+ template<typename Expr, typename State, typename Data>
+ struct impl
+ : detail::pass_through_impl<if_else_, Expr, State, Data>
+ {};
 
- /// The raw type of the Nth child as it is stored within
- /// \c Expr. This may be a value or a reference
- typedef typename Expr::proto_child0 value_type;
-
- /// The "const reference" type of the child, suitable for storage by
- /// const reference, computed as follows:
- /// \li <tt>T const(&)[N]</tt> becomes <tt>T const(&)[N]</tt>
- /// \li <tt>T[N]</tt> becomes <tt>T const(&)[N]</tt>
- /// \li <tt>T(&)[N]</tt> becomes <tt>T(&)[N]</tt>
- /// \li <tt>R(&)(A0,...)</tt> becomes <tt>R(&)(A0,...)</tt>
- /// \li <tt>T const &</tt> becomes <tt>T const &</tt>
- /// \li <tt>T &</tt> becomes <tt>T &</tt>
- /// \li <tt>T</tt> becomes <tt>T const &</tt>
- typedef typename detail::term_traits<typename Expr::proto_child0>::const_reference type;
- };
+ /// INTERNAL ONLY
+ typedef proto::tag::if_else_ proto_tag;
+ /// INTERNAL ONLY
+ typedef T proto_child0;
+ /// INTERNAL ONLY
+ typedef U proto_child1;
+ /// INTERNAL ONLY
+ typedef V proto_child2;
+ };
 
- /// \brief A metafunction that returns the type of the left child
- /// of a binary Proto expression.
- ///
- /// <tt>result_of::left\<Expr\></tt> is equivalent to
- /// <tt>result_of::child_c\<Expr, 0\></tt>.
- template<typename Expr>
- struct left
- : child_c<Expr, 0>
- {};
+ /// \brief A metafunction for generating nullary expression types with a
+ /// specified tag type,
+ /// a grammar element for matching nullary expressions, and a
+ /// PrimitiveTransform that returns the current expression unchanged.
+ ///
+ /// Use <tt>nullary_expr\<_, _\></tt> as a grammar element to match any
+ /// nullary expression.
+ template<typename Tag, typename T>
+ struct nullary_expr
+ : proto::transform<nullary_expr<Tag, T>, int>
+ {
+ typedef proto::expr<Tag, term<T>, 0> type;
+ typedef proto::basic_expr<Tag, term<T>, 0> proto_grammar;
 
- /// \brief A metafunction that returns the type of the right child
- /// of a binary Proto expression.
- ///
- /// <tt>result_of::right\<Expr\></tt> is equivalent to
- /// <tt>result_of::child_c\<Expr, 1\></tt>.
- template<typename Expr>
- struct right
- : child_c<Expr, 1>
- {};
-
- } // namespace result_of
-
- /// \brief A metafunction for generating terminal expression types,
- /// a grammar element for matching terminal expressions, and a
- /// PrimitiveTransform that returns the current expression unchanged.
- template<typename T>
- struct terminal
- : proto::transform<terminal<T>, int>
+ template<typename Expr, typename State, typename Data>
+ struct impl : transform_impl<Expr, State, Data>
         {
- typedef proto::expr<proto::tag::terminal, term<T>, 0> type;
- typedef proto::basic_expr<proto::tag::terminal, term<T>, 0> proto_grammar;
+ typedef Expr result_type;
 
- template<typename Expr, typename State, typename Data>
- struct impl : transform_impl<Expr, State, Data>
+ /// \param e The current expression
+ /// \pre <tt>matches\<Expr, nullary_expr\<Tag, T\> \>::value</tt> is \c true.
+ /// \return \c e
+ /// \throw nothrow
+ #ifdef BOOST_PROTO_STRICT_RESULT_OF
+ result_type
+ #else
+ typename impl::expr_param
+ #endif
+ operator ()(
+ typename impl::expr_param e
+ , typename impl::state_param
+ , typename impl::data_param
+ ) const
             {
- typedef Expr result_type;
+ return e;
+ }
+ };
 
- /// \param e The current expression
- /// \pre <tt>matches\<Expr, terminal\<T\> \>::value</tt> is \c true.
- /// \return \c e
- /// \throw nothrow
- #ifdef BOOST_PROTO_STRICT_RESULT_OF
- result_type
- #else
- typename impl::expr_param
- #endif
- operator ()(
- typename impl::expr_param e
- , typename impl::state_param
- , typename impl::data_param
- ) const
- {
- return e;
- }
- };
+ /// INTERNAL ONLY
+ typedef Tag proto_tag;
+ /// INTERNAL ONLY
+ typedef T proto_child0;
+ };
 
- /// INTERNAL ONLY
- typedef proto::tag::terminal proto_tag;
- /// INTERNAL ONLY
- typedef T proto_child0;
- };
+ /// \brief A metafunction for generating unary expression types with a
+ /// specified tag type,
+ /// a grammar element for matching unary expressions, and a
+ /// PrimitiveTransform that dispatches to the <tt>pass_through\<\></tt>
+ /// transform.
+ ///
+ /// Use <tt>unary_expr\<_, _\></tt> as a grammar element to match any
+ /// unary expression.
+ template<typename Tag, typename T>
+ struct unary_expr
+ : proto::transform<unary_expr<Tag, T>, int>
+ {
+ typedef proto::expr<Tag, list1<T>, 1> type;
+ typedef proto::basic_expr<Tag, list1<T>, 1> proto_grammar;
 
- /// \brief A metafunction for generating ternary conditional expression types,
- /// a grammar element for matching ternary conditional expressions, and a
- /// PrimitiveTransform that dispatches to the <tt>pass_through\<\></tt>
- /// transform.
- template<typename T, typename U, typename V>
- struct if_else_
- : proto::transform<if_else_<T, U, V>, int>
- {
- typedef proto::expr<proto::tag::if_else_, list3<T, U, V>, 3> type;
- typedef proto::basic_expr<proto::tag::if_else_, list3<T, U, V>, 3> proto_grammar;
+ template<typename Expr, typename State, typename Data>
+ struct impl
+ : detail::pass_through_impl<unary_expr, Expr, State, Data>
+ {};
 
- template<typename Expr, typename State, typename Data>
- struct impl
- : detail::pass_through_impl<if_else_, Expr, State, Data>
- {};
-
- /// INTERNAL ONLY
- typedef proto::tag::if_else_ proto_tag;
- /// INTERNAL ONLY
- typedef T proto_child0;
- /// INTERNAL ONLY
- typedef U proto_child1;
- /// INTERNAL ONLY
- typedef V proto_child2;
- };
+ /// INTERNAL ONLY
+ typedef Tag proto_tag;
+ /// INTERNAL ONLY
+ typedef T proto_child0;
+ };
 
- /// \brief A metafunction for generating nullary expression types with a
- /// specified tag type,
- /// a grammar element for matching nullary expressions, and a
- /// PrimitiveTransform that returns the current expression unchanged.
- ///
- /// Use <tt>nullary_expr\<_, _\></tt> as a grammar element to match any
- /// nullary expression.
- template<typename Tag, typename T>
- struct nullary_expr
- : proto::transform<nullary_expr<Tag, T>, int>
- {
- typedef proto::expr<Tag, term<T>, 0> type;
- typedef proto::basic_expr<Tag, term<T>, 0> proto_grammar;
+ /// \brief A metafunction for generating binary expression types with a
+ /// specified tag type,
+ /// a grammar element for matching binary expressions, and a
+ /// PrimitiveTransform that dispatches to the <tt>pass_through\<\></tt>
+ /// transform.
+ ///
+ /// Use <tt>binary_expr\<_, _, _\></tt> as a grammar element to match any
+ /// binary expression.
+ template<typename Tag, typename T, typename U>
+ struct binary_expr
+ : proto::transform<binary_expr<Tag, T, U>, int>
+ {
+ typedef proto::expr<Tag, list2<T, U>, 2> type;
+ typedef proto::basic_expr<Tag, list2<T, U>, 2> proto_grammar;
 
- template<typename Expr, typename State, typename Data>
- struct impl : transform_impl<Expr, State, Data>
- {
- typedef Expr result_type;
+ template<typename Expr, typename State, typename Data>
+ struct impl
+ : detail::pass_through_impl<binary_expr, Expr, State, Data>
+ {};
 
- /// \param e The current expression
- /// \pre <tt>matches\<Expr, nullary_expr\<Tag, T\> \>::value</tt> is \c true.
- /// \return \c e
- /// \throw nothrow
- #ifdef BOOST_PROTO_STRICT_RESULT_OF
- result_type
- #else
- typename impl::expr_param
- #endif
- operator ()(
- typename impl::expr_param e
- , typename impl::state_param
- , typename impl::data_param
- ) const
- {
- return e;
- }
- };
+ /// INTERNAL ONLY
+ typedef Tag proto_tag;
+ /// INTERNAL ONLY
+ typedef T proto_child0;
+ /// INTERNAL ONLY
+ typedef U proto_child1;
+ };
 
- /// INTERNAL ONLY
- typedef Tag proto_tag;
- /// INTERNAL ONLY
- typedef T proto_child0;
- };
+#define BOOST_PROTO_DEFINE_UNARY_METAFUNCTION(Op) \
+ template<typename T> \
+ struct Op \
+ : proto::transform<Op<T>, int> \
+ { \
+ typedef proto::expr<proto::tag::Op, list1<T>, 1> type; \
+ typedef proto::basic_expr<proto::tag::Op, list1<T>, 1> proto_grammar; \
+ \
+ template<typename Expr, typename State, typename Data> \
+ struct impl \
+ : detail::pass_through_impl<Op, Expr, State, Data> \
+ {}; \
+ \
+ typedef proto::tag::Op proto_tag; \
+ typedef T proto_child0; \
+ }; \
+ /**/
+
+#define BOOST_PROTO_DEFINE_BINARY_METAFUNCTION(Op) \
+ template<typename T, typename U> \
+ struct Op \
+ : proto::transform<Op<T, U>, int> \
+ { \
+ typedef proto::expr<proto::tag::Op, list2<T, U>, 2> type; \
+ typedef proto::basic_expr<proto::tag::Op, list2<T, U>, 2> proto_grammar; \
+ \
+ template<typename Expr, typename State, typename Data> \
+ struct impl \
+ : detail::pass_through_impl<Op, Expr, State, Data> \
+ {}; \
+ \
+ typedef proto::tag::Op proto_tag; \
+ typedef T proto_child0; \
+ typedef U proto_child1; \
+ }; \
+ /**/
+
+ BOOST_PROTO_DEFINE_UNARY_METAFUNCTION(unary_plus)
+ BOOST_PROTO_DEFINE_UNARY_METAFUNCTION(negate)
+ BOOST_PROTO_DEFINE_UNARY_METAFUNCTION(dereference)
+ BOOST_PROTO_DEFINE_UNARY_METAFUNCTION(complement)
+ BOOST_PROTO_DEFINE_UNARY_METAFUNCTION(address_of)
+ BOOST_PROTO_DEFINE_UNARY_METAFUNCTION(logical_not)
+ BOOST_PROTO_DEFINE_UNARY_METAFUNCTION(pre_inc)
+ BOOST_PROTO_DEFINE_UNARY_METAFUNCTION(pre_dec)
+ BOOST_PROTO_DEFINE_UNARY_METAFUNCTION(post_inc)
+ BOOST_PROTO_DEFINE_UNARY_METAFUNCTION(post_dec)
+
+ BOOST_PROTO_DEFINE_BINARY_METAFUNCTION(shift_left)
+ BOOST_PROTO_DEFINE_BINARY_METAFUNCTION(shift_right)
+ BOOST_PROTO_DEFINE_BINARY_METAFUNCTION(multiplies)
+ BOOST_PROTO_DEFINE_BINARY_METAFUNCTION(divides)
+ BOOST_PROTO_DEFINE_BINARY_METAFUNCTION(modulus)
+ BOOST_PROTO_DEFINE_BINARY_METAFUNCTION(plus)
+ BOOST_PROTO_DEFINE_BINARY_METAFUNCTION(minus)
+ BOOST_PROTO_DEFINE_BINARY_METAFUNCTION(less)
+ BOOST_PROTO_DEFINE_BINARY_METAFUNCTION(greater)
+ BOOST_PROTO_DEFINE_BINARY_METAFUNCTION(less_equal)
+ BOOST_PROTO_DEFINE_BINARY_METAFUNCTION(greater_equal)
+ BOOST_PROTO_DEFINE_BINARY_METAFUNCTION(equal_to)
+ BOOST_PROTO_DEFINE_BINARY_METAFUNCTION(not_equal_to)
+ BOOST_PROTO_DEFINE_BINARY_METAFUNCTION(logical_or)
+ BOOST_PROTO_DEFINE_BINARY_METAFUNCTION(logical_and)
+ BOOST_PROTO_DEFINE_BINARY_METAFUNCTION(bitwise_or)
+ BOOST_PROTO_DEFINE_BINARY_METAFUNCTION(bitwise_and)
+ BOOST_PROTO_DEFINE_BINARY_METAFUNCTION(bitwise_xor)
+ BOOST_PROTO_DEFINE_BINARY_METAFUNCTION(comma)
+ BOOST_PROTO_DEFINE_BINARY_METAFUNCTION(mem_ptr)
+ BOOST_PROTO_DEFINE_BINARY_METAFUNCTION(assign)
+ BOOST_PROTO_DEFINE_BINARY_METAFUNCTION(shift_left_assign)
+ BOOST_PROTO_DEFINE_BINARY_METAFUNCTION(shift_right_assign)
+ BOOST_PROTO_DEFINE_BINARY_METAFUNCTION(multiplies_assign)
+ BOOST_PROTO_DEFINE_BINARY_METAFUNCTION(divides_assign)
+ BOOST_PROTO_DEFINE_BINARY_METAFUNCTION(modulus_assign)
+ BOOST_PROTO_DEFINE_BINARY_METAFUNCTION(plus_assign)
+ BOOST_PROTO_DEFINE_BINARY_METAFUNCTION(minus_assign)
+ BOOST_PROTO_DEFINE_BINARY_METAFUNCTION(bitwise_or_assign)
+ BOOST_PROTO_DEFINE_BINARY_METAFUNCTION(bitwise_and_assign)
+ BOOST_PROTO_DEFINE_BINARY_METAFUNCTION(bitwise_xor_assign)
+ BOOST_PROTO_DEFINE_BINARY_METAFUNCTION(subscript)
+ BOOST_PROTO_DEFINE_BINARY_METAFUNCTION(member)
 
- /// \brief A metafunction for generating unary expression types with a
- /// specified tag type,
- /// a grammar element for matching unary expressions, and a
- /// PrimitiveTransform that dispatches to the <tt>pass_through\<\></tt>
- /// transform.
- ///
- /// Use <tt>unary_expr\<_, _\></tt> as a grammar element to match any
- /// unary expression.
- template<typename Tag, typename T>
- struct unary_expr
- : proto::transform<unary_expr<Tag, T>, int>
- {
- typedef proto::expr<Tag, list1<T>, 1> type;
- typedef proto::basic_expr<Tag, list1<T>, 1> proto_grammar;
+ #undef BOOST_PROTO_DEFINE_UNARY_METAFUNCTION
+ #undef BOOST_PROTO_DEFINE_BINARY_METAFUNCTION
 
- template<typename Expr, typename State, typename Data>
- struct impl
- : detail::pass_through_impl<unary_expr, Expr, State, Data>
- {};
-
- /// INTERNAL ONLY
- typedef Tag proto_tag;
- /// INTERNAL ONLY
- typedef T proto_child0;
- };
+ #include <boost/proto/detail/traits.hpp>
 
- /// \brief A metafunction for generating binary expression types with a
- /// specified tag type,
- /// a grammar element for matching binary expressions, and a
- /// PrimitiveTransform that dispatches to the <tt>pass_through\<\></tt>
- /// transform.
- ///
- /// Use <tt>binary_expr\<_, _, _\></tt> as a grammar element to match any
- /// binary expression.
- template<typename Tag, typename T, typename U>
- struct binary_expr
- : proto::transform<binary_expr<Tag, T, U>, int>
+ namespace functional
+ {
+ /// \brief A callable PolymorphicFunctionObject that is
+ /// equivalent to the \c as_expr() function.
+ template<typename Domain /* = default_domain*/>
+ struct as_expr
         {
- typedef proto::expr<Tag, list2<T, U>, 2> type;
- typedef proto::basic_expr<Tag, list2<T, U>, 2> proto_grammar;
+ BOOST_PROTO_CALLABLE()
 
- template<typename Expr, typename State, typename Data>
- struct impl
- : detail::pass_through_impl<binary_expr, Expr, State, Data>
- {};
-
- /// INTERNAL ONLY
- typedef Tag proto_tag;
- /// INTERNAL ONLY
- typedef T proto_child0;
- /// INTERNAL ONLY
- typedef U proto_child1;
- };
+ template<typename Sig>
+ struct result;
 
- #define BOOST_PROTO_DEFINE_UNARY_METAFUNCTION(Op) \
- template<typename T> \
- struct Op \
- : proto::transform<Op<T>, int> \
- { \
- typedef proto::expr<proto::tag::Op, list1<T>, 1> type; \
- typedef proto::basic_expr<proto::tag::Op, list1<T>, 1> proto_grammar; \
- \
- template<typename Expr, typename State, typename Data> \
- struct impl \
- : detail::pass_through_impl<Op, Expr, State, Data> \
- {}; \
- \
- typedef proto::tag::Op proto_tag; \
- typedef T proto_child0; \
- }; \
- /**/
-
- #define BOOST_PROTO_DEFINE_BINARY_METAFUNCTION(Op) \
- template<typename T, typename U> \
- struct Op \
- : proto::transform<Op<T, U>, int> \
- { \
- typedef proto::expr<proto::tag::Op, list2<T, U>, 2> type; \
- typedef proto::basic_expr<proto::tag::Op, list2<T, U>, 2> proto_grammar; \
- \
- template<typename Expr, typename State, typename Data> \
- struct impl \
- : detail::pass_through_impl<Op, Expr, State, Data> \
- {}; \
- \
- typedef proto::tag::Op proto_tag; \
- typedef T proto_child0; \
- typedef U proto_child1; \
- }; \
- /**/
-
- BOOST_PROTO_DEFINE_UNARY_METAFUNCTION(unary_plus)
- BOOST_PROTO_DEFINE_UNARY_METAFUNCTION(negate)
- BOOST_PROTO_DEFINE_UNARY_METAFUNCTION(dereference)
- BOOST_PROTO_DEFINE_UNARY_METAFUNCTION(complement)
- BOOST_PROTO_DEFINE_UNARY_METAFUNCTION(address_of)
- BOOST_PROTO_DEFINE_UNARY_METAFUNCTION(logical_not)
- BOOST_PROTO_DEFINE_UNARY_METAFUNCTION(pre_inc)
- BOOST_PROTO_DEFINE_UNARY_METAFUNCTION(pre_dec)
- BOOST_PROTO_DEFINE_UNARY_METAFUNCTION(post_inc)
- BOOST_PROTO_DEFINE_UNARY_METAFUNCTION(post_dec)
-
- BOOST_PROTO_DEFINE_BINARY_METAFUNCTION(shift_left)
- BOOST_PROTO_DEFINE_BINARY_METAFUNCTION(shift_right)
- BOOST_PROTO_DEFINE_BINARY_METAFUNCTION(multiplies)
- BOOST_PROTO_DEFINE_BINARY_METAFUNCTION(divides)
- BOOST_PROTO_DEFINE_BINARY_METAFUNCTION(modulus)
- BOOST_PROTO_DEFINE_BINARY_METAFUNCTION(plus)
- BOOST_PROTO_DEFINE_BINARY_METAFUNCTION(minus)
- BOOST_PROTO_DEFINE_BINARY_METAFUNCTION(less)
- BOOST_PROTO_DEFINE_BINARY_METAFUNCTION(greater)
- BOOST_PROTO_DEFINE_BINARY_METAFUNCTION(less_equal)
- BOOST_PROTO_DEFINE_BINARY_METAFUNCTION(greater_equal)
- BOOST_PROTO_DEFINE_BINARY_METAFUNCTION(equal_to)
- BOOST_PROTO_DEFINE_BINARY_METAFUNCTION(not_equal_to)
- BOOST_PROTO_DEFINE_BINARY_METAFUNCTION(logical_or)
- BOOST_PROTO_DEFINE_BINARY_METAFUNCTION(logical_and)
- BOOST_PROTO_DEFINE_BINARY_METAFUNCTION(bitwise_or)
- BOOST_PROTO_DEFINE_BINARY_METAFUNCTION(bitwise_and)
- BOOST_PROTO_DEFINE_BINARY_METAFUNCTION(bitwise_xor)
- BOOST_PROTO_DEFINE_BINARY_METAFUNCTION(comma)
- BOOST_PROTO_DEFINE_BINARY_METAFUNCTION(mem_ptr)
- BOOST_PROTO_DEFINE_BINARY_METAFUNCTION(assign)
- BOOST_PROTO_DEFINE_BINARY_METAFUNCTION(shift_left_assign)
- BOOST_PROTO_DEFINE_BINARY_METAFUNCTION(shift_right_assign)
- BOOST_PROTO_DEFINE_BINARY_METAFUNCTION(multiplies_assign)
- BOOST_PROTO_DEFINE_BINARY_METAFUNCTION(divides_assign)
- BOOST_PROTO_DEFINE_BINARY_METAFUNCTION(modulus_assign)
- BOOST_PROTO_DEFINE_BINARY_METAFUNCTION(plus_assign)
- BOOST_PROTO_DEFINE_BINARY_METAFUNCTION(minus_assign)
- BOOST_PROTO_DEFINE_BINARY_METAFUNCTION(bitwise_or_assign)
- BOOST_PROTO_DEFINE_BINARY_METAFUNCTION(bitwise_and_assign)
- BOOST_PROTO_DEFINE_BINARY_METAFUNCTION(bitwise_xor_assign)
- BOOST_PROTO_DEFINE_BINARY_METAFUNCTION(subscript)
- BOOST_PROTO_DEFINE_BINARY_METAFUNCTION(member)
+ template<typename This, typename T>
+ struct result<This(T)>
+ {
+ typedef typename Domain::template as_expr<T>::result_type type;
+ };
 
- #undef BOOST_PROTO_DEFINE_UNARY_METAFUNCTION
- #undef BOOST_PROTO_DEFINE_BINARY_METAFUNCTION
+ template<typename This, typename T>
+ struct result<This(T &)>
+ {
+ typedef typename Domain::template as_expr<T>::result_type type;
+ };
 
- #define BOOST_PROTO_CHILD(Z, N, DATA) \
- /** INTERNAL ONLY */ \
- typedef BOOST_PP_CAT(DATA, N) BOOST_PP_CAT(proto_child, N); \
- /**/
+ /// \brief Wrap an object in a Proto terminal if it isn't a
+ /// Proto expression already.
+ /// \param t The object to wrap.
+ /// \return <tt>proto::as_expr\<Domain\>(t)</tt>
+ template<typename T>
+ typename add_const<typename result<as_expr(T &)>::type>::type
+ operator ()(T &t) const
+ {
+ return typename Domain::template as_expr<T>()(t);
+ }
+
+ /// \overload
+ ///
+ template<typename T>
+ typename add_const<typename result<as_expr(T const &)>::type>::type
+ operator ()(T const &t) const
+ {
+ return typename Domain::template as_expr<T const>()(t);
+ }
 
- #define BOOST_PP_ITERATION_PARAMS_1 (3, (0, BOOST_PROTO_MAX_ARITY, <boost/proto/traits.hpp>))
- #include BOOST_PP_ITERATE()
+ #if BOOST_WORKAROUND(BOOST_MSVC, == 1310)
+ template<typename T, std::size_t N_>
+ typename add_const<typename result<as_expr(T (&)[N_])>::type>::type
+ operator ()(T (&t)[N_]) const
+ {
+ return typename Domain::template as_expr<T[N_]>()(t);
+ }
 
- #undef BOOST_PROTO_CHILD
- #undef BOOST_PROTO_IMPLICIT_ARG
+ template<typename T, std::size_t N_>
+ typename add_const<typename result<as_expr(T const (&)[N_])>::type>::type
+ operator ()(T const (&t)[N_]) const
+ {
+ return typename Domain::template as_expr<T const[N_]>()(t);
+ }
+ #endif
+ };
 
- namespace functional
+ /// \brief A callable PolymorphicFunctionObject that is
+ /// equivalent to the \c as_child() function.
+ template<typename Domain /* = default_domain*/>
+ struct as_child
         {
- /// \brief A callable PolymorphicFunctionObject that is
- /// equivalent to the \c as_expr() function.
- template<typename Domain /* = default_domain*/>
- struct as_expr
- {
- BOOST_PROTO_CALLABLE()
-
- template<typename Sig>
- struct result;
-
- template<typename This, typename T>
- struct result<This(T)>
- {
- typedef typename Domain::template as_expr<T>::result_type type;
- };
-
- template<typename This, typename T>
- struct result<This(T &)>
- {
- typedef typename Domain::template as_expr<T>::result_type type;
- };
-
- /// \brief Wrap an object in a Proto terminal if it isn't a
- /// Proto expression already.
- /// \param t The object to wrap.
- /// \return <tt>proto::as_expr\<Domain\>(t)</tt>
- template<typename T>
- typename add_const<typename result<as_expr(T &)>::type>::type
- operator ()(T &t) const
- {
- return typename Domain::template as_expr<T>()(t);
- }
-
- /// \overload
- ///
- template<typename T>
- typename add_const<typename result<as_expr(T const &)>::type>::type
- operator ()(T const &t) const
- {
- return typename Domain::template as_expr<T const>()(t);
- }
-
- #if BOOST_WORKAROUND(BOOST_MSVC, == 1310)
- template<typename T, std::size_t N_>
- typename add_const<typename result<as_expr(T (&)[N_])>::type>::type
- operator ()(T (&t)[N_]) const
- {
- return typename Domain::template as_expr<T[N_]>()(t);
- }
-
- template<typename T, std::size_t N_>
- typename add_const<typename result<as_expr(T const (&)[N_])>::type>::type
- operator ()(T const (&t)[N_]) const
- {
- return typename Domain::template as_expr<T const[N_]>()(t);
- }
- #endif
- };
+ BOOST_PROTO_CALLABLE()
+
+ template<typename Sig>
+ struct result;
 
- /// \brief A callable PolymorphicFunctionObject that is
- /// equivalent to the \c as_child() function.
- template<typename Domain /* = default_domain*/>
- struct as_child
- {
- BOOST_PROTO_CALLABLE()
-
- template<typename Sig>
- struct result;
-
- template<typename This, typename T>
- struct result<This(T)>
- {
- typedef typename Domain::template as_child<T>::result_type type;
- };
-
- template<typename This, typename T>
- struct result<This(T &)>
- {
- typedef typename Domain::template as_child<T>::result_type type;
- };
-
- /// \brief Wrap an object in a Proto terminal if it isn't a
- /// Proto expression already.
- /// \param t The object to wrap.
- /// \return <tt>proto::as_child\<Domain\>(t)</tt>
- template<typename T>
- typename add_const<typename result<as_child(T &)>::type>::type
- operator ()(T &t) const
- {
- return typename Domain::template as_child<T>()(t);
- }
-
- /// \overload
- ///
- template<typename T>
- typename add_const<typename result<as_child(T const &)>::type>::type
- operator ()(T const &t) const
- {
- return typename Domain::template as_child<T const>()(t);
- }
+ template<typename This, typename T>
+ struct result<This(T)>
+ {
+ typedef typename Domain::template as_child<T>::result_type type;
             };
 
- /// \brief A callable PolymorphicFunctionObject that is
- /// equivalent to the \c child_c() function.
- template<long N>
- struct child_c
- {
- BOOST_PROTO_CALLABLE()
-
- template<typename Sig>
- struct result;
-
- template<typename This, typename Expr>
- struct result<This(Expr)>
- {
- typedef typename result_of::child_c<Expr, N>::type type;
- };
-
- /// \brief Return the Nth child of the given expression.
- /// \param expr The expression node.
- /// \pre <tt>is_expr\<Expr\>::value</tt> is \c true
- /// \pre <tt>N \< Expr::proto_arity::value</tt>
- /// \return <tt>proto::child_c\<N\>(expr)</tt>
- /// \throw nothrow
- template<typename Expr>
- typename result_of::child_c<Expr &, N>::type
- operator ()(Expr &e) const
- {
- return result_of::child_c<Expr &, N>::call(e);
- }
-
- /// \overload
- ///
- template<typename Expr>
- typename result_of::child_c<Expr const &, N>::type
- operator ()(Expr const &e) const
- {
- return result_of::child_c<Expr const &, N>::call(e);
- }
+ template<typename This, typename T>
+ struct result<This(T &)>
+ {
+ typedef typename Domain::template as_child<T>::result_type type;
             };
 
- /// \brief A callable PolymorphicFunctionObject that is
- /// equivalent to the \c child() function.
+ /// \brief Wrap an object in a Proto terminal if it isn't a
+ /// Proto expression already.
+ /// \param t The object to wrap.
+ /// \return <tt>proto::as_child\<Domain\>(t)</tt>
+ template<typename T>
+ typename add_const<typename result<as_child(T &)>::type>::type
+ operator ()(T &t) const
+ {
+ return typename Domain::template as_child<T>()(t);
+ }
+
+ /// \overload
             ///
- /// A callable PolymorphicFunctionObject that is
- /// equivalent to the \c child() function. \c N is required
- /// to be an MPL Integral Constant.
- template<typename N /* = mpl::long_<0>*/>
- struct child
- {
- BOOST_PROTO_CALLABLE()
-
- template<typename Sig>
- struct result;
-
- template<typename This, typename Expr>
- struct result<This(Expr)>
- {
- typedef typename result_of::child<Expr, N>::type type;
- };
-
- /// \brief Return the Nth child of the given expression.
- /// \param expr The expression node.
- /// \pre <tt>is_expr\<Expr\>::value</tt> is \c true
- /// \pre <tt>N::value \< Expr::proto_arity::value</tt>
- /// \return <tt>proto::child\<N\>(expr)</tt>
- /// \throw nothrow
- template<typename Expr>
- typename result_of::child<Expr &, N>::type
- operator ()(Expr &e) const
- {
- return result_of::child<Expr &, N>::call(e);
- }
-
- /// \overload
- ///
- template<typename Expr>
- typename result_of::child<Expr const &, N>::type
- operator ()(Expr const &e) const
- {
- return result_of::child<Expr const &, N>::call(e);
- }
- };
+ template<typename T>
+ typename add_const<typename result<as_child(T const &)>::type>::type
+ operator ()(T const &t) const
+ {
+ return typename Domain::template as_child<T const>()(t);
+ }
+ };
 
- /// \brief A callable PolymorphicFunctionObject that is
- /// equivalent to the \c value() function.
- struct value
- {
- BOOST_PROTO_CALLABLE()
-
- template<typename Sig>
- struct result;
-
- template<typename This, typename Expr>
- struct result<This(Expr)>
- {
- typedef typename result_of::value<Expr>::type type;
- };
-
- /// \brief Return the value of the given terminal expression.
- /// \param expr The terminal expression node.
- /// \pre <tt>is_expr\<Expr\>::value</tt> is \c true
- /// \pre <tt>0 == Expr::proto_arity::value</tt>
- /// \return <tt>proto::value(expr)</tt>
- /// \throw nothrow
- template<typename Expr>
- typename result_of::value<Expr &>::type
- operator ()(Expr &e) const
- {
- return e.proto_base().child0;
- }
-
- /// \overload
- ///
- template<typename Expr>
- typename result_of::value<Expr const &>::type
- operator ()(Expr const &e) const
- {
- return e.proto_base().child0;
- }
- };
+ /// \brief A callable PolymorphicFunctionObject that is
+ /// equivalent to the \c child_c() function.
+ template<long N>
+ struct child_c
+ {
+ BOOST_PROTO_CALLABLE()
 
- /// \brief A callable PolymorphicFunctionObject that is
- /// equivalent to the \c left() function.
- struct left
- {
- BOOST_PROTO_CALLABLE()
-
- template<typename Sig>
- struct result;
-
- template<typename This, typename Expr>
- struct result<This(Expr)>
- {
- typedef typename result_of::left<Expr>::type type;
- };
-
- /// \brief Return the left child of the given binary expression.
- /// \param expr The expression node.
- /// \pre <tt>is_expr\<Expr\>::value</tt> is \c true
- /// \pre <tt>2 == Expr::proto_arity::value</tt>
- /// \return <tt>proto::left(expr)</tt>
- /// \throw nothrow
- template<typename Expr>
- typename result_of::left<Expr &>::type
- operator ()(Expr &e) const
- {
- return e.proto_base().child0;
- }
-
- /// \overload
- ///
- template<typename Expr>
- typename result_of::left<Expr const &>::type
- operator ()(Expr const &e) const
- {
- return e.proto_base().child0;
- }
- };
+ template<typename Sig>
+ struct result;
 
- /// \brief A callable PolymorphicFunctionObject that is
- /// equivalent to the \c right() function.
- struct right
- {
- BOOST_PROTO_CALLABLE()
-
- template<typename Sig>
- struct result;
-
- template<typename This, typename Expr>
- struct result<This(Expr)>
- {
- typedef typename result_of::right<Expr>::type type;
- };
-
- /// \brief Return the right child of the given binary expression.
- /// \param expr The expression node.
- /// \pre <tt>is_expr\<Expr\>::value</tt> is \c true
- /// \pre <tt>2 == Expr::proto_arity::value</tt>
- /// \return <tt>proto::right(expr)</tt>
- /// \throw nothrow
- template<typename Expr>
- typename result_of::right<Expr &>::type
- operator ()(Expr &e) const
- {
- return e.proto_base().child1;
- }
-
- template<typename Expr>
- typename result_of::right<Expr const &>::type
- operator ()(Expr const &e) const
- {
- return e.proto_base().child1;
- }
+ template<typename This, typename Expr>
+ struct result<This(Expr)>
+ {
+ typedef typename result_of::child_c<Expr, N>::type type;
             };
 
- }
+ /// \brief Return the Nth child of the given expression.
+ /// \param expr The expression node.
+ /// \pre <tt>is_expr\<Expr\>::value</tt> is \c true
+ /// \pre <tt>N \< Expr::proto_arity::value</tt>
+ /// \return <tt>proto::child_c\<N\>(expr)</tt>
+ /// \throw nothrow
+ template<typename Expr>
+ typename result_of::child_c<Expr &, N>::type
+ operator ()(Expr &e) const
+ {
+ return result_of::child_c<Expr &, N>::call(e);
+ }
 
- /// \brief A function that wraps non-Proto expression types in Proto
- /// terminals and leaves Proto expression types alone.
- ///
- /// The <tt>as_expr()</tt> function turns objects into Proto terminals if
- /// they are not Proto expression types already. Non-Proto types are
- /// held by value, if possible. Types which are already Proto types are
- /// left alone and returned by reference.
- ///
- /// This function can be called either with an explicitly specified
- /// \c Domain parameter (i.e., <tt>as_expr\<Domain\>(t)</tt>), or
- /// without (i.e., <tt>as_expr(t)</tt>). If no domain is
- /// specified, \c default_domain is assumed.
- ///
- /// If <tt>is_expr\<T\>::value</tt> is \c true, then the argument is
- /// returned unmodified, by reference. Otherwise, the argument is wrapped
- /// in a Proto terminal expression node according to the following rules.
- /// If \c T is a function type, let \c A be <tt>T &</tt>. Otherwise, let
- /// \c A be the type \c T stripped of cv-qualifiers. Then, \c as_expr()
- /// returns <tt>Domain()(terminal\<A\>::type::make(t))</tt>.
- ///
- /// \param t The object to wrap.
- template<typename T>
- typename add_const<typename result_of::as_expr<T, default_domain>::type>::type
- as_expr(T &t BOOST_PROTO_DISABLE_IF_IS_CONST(T) BOOST_PROTO_DISABLE_IF_IS_FUNCTION(T))
- {
- return default_domain::as_expr<T>()(t);
- }
+ /// \overload
+ ///
+ template<typename Expr>
+ typename result_of::child_c<Expr const &, N>::type
+ operator ()(Expr const &e) const
+ {
+ return result_of::child_c<Expr const &, N>::call(e);
+ }
+ };
 
- /// \overload
+ /// \brief A callable PolymorphicFunctionObject that is
+ /// equivalent to the \c child() function.
         ///
- template<typename T>
- typename add_const<typename result_of::as_expr<T const, default_domain>::type>::type
- as_expr(T const &t)
+ /// A callable PolymorphicFunctionObject that is
+ /// equivalent to the \c child() function. \c N is required
+ /// to be an MPL Integral Constant.
+ template<typename N /* = mpl::long_<0>*/>
+ struct child
         {
- return default_domain::as_expr<T const>()(t);
- }
+ BOOST_PROTO_CALLABLE()
 
- /// \overload
- ///
- template<typename Domain, typename T>
- typename add_const<typename result_of::as_expr<T, Domain>::type>::type
- as_expr(T &t BOOST_PROTO_DISABLE_IF_IS_CONST(T) BOOST_PROTO_DISABLE_IF_IS_FUNCTION(T))
- {
- return typename Domain::template as_expr<T>()(t);
- }
+ template<typename Sig>
+ struct result;
 
- /// \overload
- ///
- template<typename Domain, typename T>
- typename add_const<typename result_of::as_expr<T const, Domain>::type>::type
- as_expr(T const &t)
- {
- return typename Domain::template as_expr<T const>()(t);
- }
+ template<typename This, typename Expr>
+ struct result<This(Expr)>
+ {
+ typedef typename result_of::child<Expr, N>::type type;
+ };
 
- /// \brief A function that wraps non-Proto expression types in Proto
- /// terminals (by reference) and returns Proto expression types by
- /// reference
- ///
- /// The <tt>as_child()</tt> function turns objects into Proto terminals if
- /// they are not Proto expression types already. Non-Proto types are
- /// held by reference. Types which are already Proto types are simply
- /// returned as-is.
- ///
- /// This function can be called either with an explicitly specified
- /// \c Domain parameter (i.e., <tt>as_child\<Domain\>(t)</tt>), or
- /// without (i.e., <tt>as_child(t)</tt>). If no domain is
- /// specified, \c default_domain is assumed.
- ///
- /// If <tt>is_expr\<T\>::value</tt> is \c true, then the argument is
- /// returned as-is. Otherwise, \c as_child() returns
- /// <tt>Domain()(terminal\<T &\>::type::make(t))</tt>.
- ///
- /// \param t The object to wrap.
- template<typename T>
- typename add_const<typename result_of::as_child<T, default_domain>::type>::type
- as_child(T &t BOOST_PROTO_DISABLE_IF_IS_CONST(T) BOOST_PROTO_DISABLE_IF_IS_FUNCTION(T))
- {
- return default_domain::as_child<T>()(t);
- }
+ /// \brief Return the Nth child of the given expression.
+ /// \param expr The expression node.
+ /// \pre <tt>is_expr\<Expr\>::value</tt> is \c true
+ /// \pre <tt>N::value \< Expr::proto_arity::value</tt>
+ /// \return <tt>proto::child\<N\>(expr)</tt>
+ /// \throw nothrow
+ template<typename Expr>
+ typename result_of::child<Expr &, N>::type
+ operator ()(Expr &e) const
+ {
+ return result_of::child<Expr &, N>::call(e);
+ }
 
- /// \overload
- ///
- template<typename T>
- typename add_const<typename result_of::as_child<T const, default_domain>::type>::type
- as_child(T const &t)
- {
- return default_domain::as_child<T const>()(t);
- }
+ /// \overload
+ ///
+ template<typename Expr>
+ typename result_of::child<Expr const &, N>::type
+ operator ()(Expr const &e) const
+ {
+ return result_of::child<Expr const &, N>::call(e);
+ }
+ };
 
- /// \overload
- ///
- template<typename Domain, typename T>
- typename add_const<typename result_of::as_child<T, Domain>::type>::type
- as_child(T &t BOOST_PROTO_DISABLE_IF_IS_CONST(T) BOOST_PROTO_DISABLE_IF_IS_FUNCTION(T))
+ /// \brief A callable PolymorphicFunctionObject that is
+ /// equivalent to the \c value() function.
+ struct value
         {
- return typename Domain::template as_child<T>()(t);
- }
+ BOOST_PROTO_CALLABLE()
 
- /// \overload
- ///
- template<typename Domain, typename T>
- typename add_const<typename result_of::as_child<T const, Domain>::type>::type
- as_child(T const &t)
- {
- return typename Domain::template as_child<T const>()(t);
- }
+ template<typename Sig>
+ struct result;
 
- /// \brief Return the Nth child of the specified Proto expression.
- ///
- /// Return the Nth child of the specified Proto expression. If
- /// \c N is not specified, as in \c child(expr), then \c N is assumed
- /// to be <tt>mpl::long_\<0\></tt>. The child is returned by
- /// reference.
- ///
- /// \param expr The Proto expression.
- /// \pre <tt>is_expr\<Expr\>::value</tt> is \c true.
- /// \pre \c N is an MPL Integral Constant.
- /// \pre <tt>N::value \< Expr::proto_arity::value</tt>
- /// \throw nothrow
- /// \return A reference to the Nth child
- template<typename N, typename Expr>
- typename result_of::child<Expr &, N>::type
- child(Expr &e BOOST_PROTO_DISABLE_IF_IS_CONST(Expr))
- {
- return result_of::child<Expr &, N>::call(e);
- }
+ template<typename This, typename Expr>
+ struct result<This(Expr)>
+ {
+ typedef typename result_of::value<Expr>::type type;
+ };
 
- /// \overload
- ///
- template<typename N, typename Expr>
- typename result_of::child<Expr const &, N>::type
- child(Expr const &e)
- {
- return result_of::child<Expr const &, N>::call(e);
- }
+ /// \brief Return the value of the given terminal expression.
+ /// \param expr The terminal expression node.
+ /// \pre <tt>is_expr\<Expr\>::value</tt> is \c true
+ /// \pre <tt>0 == Expr::proto_arity::value</tt>
+ /// \return <tt>proto::value(expr)</tt>
+ /// \throw nothrow
+ template<typename Expr>
+ typename result_of::value<Expr &>::type
+ operator ()(Expr &e) const
+ {
+ return e.proto_base().child0;
+ }
 
- /// \overload
- ///
- template<typename Expr2>
- typename detail::expr_traits<typename Expr2::proto_base_expr::proto_child0>::reference
- child(Expr2 &expr2 BOOST_PROTO_DISABLE_IF_IS_CONST(Expr2))
- {
- return expr2.proto_base().child0;
- }
+ /// \overload
+ ///
+ template<typename Expr>
+ typename result_of::value<Expr const &>::type
+ operator ()(Expr const &e) const
+ {
+ return e.proto_base().child0;
+ }
+ };
 
- /// \overload
- ///
- template<typename Expr2>
- typename detail::expr_traits<typename Expr2::proto_base_expr::proto_child0>::const_reference
- child(Expr2 const &expr2)
+ /// \brief A callable PolymorphicFunctionObject that is
+ /// equivalent to the \c left() function.
+ struct left
         {
- return expr2.proto_base().child0;
- }
+ BOOST_PROTO_CALLABLE()
 
- /// \brief Return the Nth child of the specified Proto expression.
- ///
- /// Return the Nth child of the specified Proto expression. The child
- /// is returned by reference.
- ///
- /// \param expr The Proto expression.
- /// \pre <tt>is_expr\<Expr\>::value</tt> is \c true.
- /// \pre <tt>N \< Expr::proto_arity::value</tt>
- /// \throw nothrow
- /// \return A reference to the Nth child
- template<long N, typename Expr>
- typename result_of::child_c<Expr &, N>::type
- child_c(Expr &e BOOST_PROTO_DISABLE_IF_IS_CONST(Expr))
- {
- return result_of::child_c<Expr &, N>::call(e);
- }
+ template<typename Sig>
+ struct result;
 
- /// \overload
- ///
- template<long N, typename Expr>
- typename result_of::child_c<Expr const &, N>::type
- child_c(Expr const &e)
- {
- return result_of::child_c<Expr const &, N>::call(e);
- }
+ template<typename This, typename Expr>
+ struct result<This(Expr)>
+ {
+ typedef typename result_of::left<Expr>::type type;
+ };
 
- /// \brief Return the value stored within the specified Proto
- /// terminal expression.
- ///
- /// Return the the value stored within the specified Proto
- /// terminal expression. The value is returned by
- /// reference.
- ///
- /// \param expr The Proto terminal expression.
- /// \pre <tt>N::value == 0</tt>
- /// \throw nothrow
- /// \return A reference to the terminal's value
- template<typename Expr>
- typename result_of::value<Expr &>::type
- value(Expr &e BOOST_PROTO_DISABLE_IF_IS_CONST(Expr))
- {
- return e.proto_base().child0;
- }
+ /// \brief Return the left child of the given binary expression.
+ /// \param expr The expression node.
+ /// \pre <tt>is_expr\<Expr\>::value</tt> is \c true
+ /// \pre <tt>2 == Expr::proto_arity::value</tt>
+ /// \return <tt>proto::left(expr)</tt>
+ /// \throw nothrow
+ template<typename Expr>
+ typename result_of::left<Expr &>::type
+ operator ()(Expr &e) const
+ {
+ return e.proto_base().child0;
+ }
 
- /// \overload
- ///
- template<typename Expr>
- typename result_of::value<Expr const &>::type
- value(Expr const &e)
- {
- return e.proto_base().child0;
- }
+ /// \overload
+ ///
+ template<typename Expr>
+ typename result_of::left<Expr const &>::type
+ operator ()(Expr const &e) const
+ {
+ return e.proto_base().child0;
+ }
+ };
 
- /// \brief Return the left child of the specified binary Proto
- /// expression.
- ///
- /// Return the left child of the specified binary Proto expression. The
- /// child is returned by reference.
- ///
- /// \param expr The Proto expression.
- /// \pre <tt>is_expr\<Expr\>::value</tt> is \c true.
- /// \pre <tt>2 == Expr::proto_arity::value</tt>
- /// \throw nothrow
- /// \return A reference to the left child
- template<typename Expr>
- typename result_of::left<Expr &>::type
- left(Expr &e BOOST_PROTO_DISABLE_IF_IS_CONST(Expr))
+ /// \brief A callable PolymorphicFunctionObject that is
+ /// equivalent to the \c right() function.
+ struct right
         {
- return e.proto_base().child0;
- }
+ BOOST_PROTO_CALLABLE()
 
- /// \overload
- ///
- template<typename Expr>
- typename result_of::left<Expr const &>::type
- left(Expr const &e)
- {
- return e.proto_base().child0;
- }
+ template<typename Sig>
+ struct result;
 
- /// \brief Return the right child of the specified binary Proto
- /// expression.
- ///
- /// Return the right child of the specified binary Proto expression. The
- /// child is returned by reference.
- ///
- /// \param expr The Proto expression.
- /// \pre <tt>is_expr\<Expr\>::value</tt> is \c true.
- /// \pre <tt>2 == Expr::proto_arity::value</tt>
- /// \throw nothrow
- /// \return A reference to the right child
- template<typename Expr>
- typename result_of::right<Expr &>::type
- right(Expr &e BOOST_PROTO_DISABLE_IF_IS_CONST(Expr))
- {
- return e.proto_base().child1;
- }
+ template<typename This, typename Expr>
+ struct result<This(Expr)>
+ {
+ typedef typename result_of::right<Expr>::type type;
+ };
 
- /// \overload
- ///
- template<typename Expr>
- typename result_of::right<Expr const &>::type
- right(Expr const &e)
- {
- return e.proto_base().child1;
- }
+ /// \brief Return the right child of the given binary expression.
+ /// \param expr The expression node.
+ /// \pre <tt>is_expr\<Expr\>::value</tt> is \c true
+ /// \pre <tt>2 == Expr::proto_arity::value</tt>
+ /// \return <tt>proto::right(expr)</tt>
+ /// \throw nothrow
+ template<typename Expr>
+ typename result_of::right<Expr &>::type
+ operator ()(Expr &e) const
+ {
+ return e.proto_base().child1;
+ }
 
- /// INTERNAL ONLY
- ///
- template<typename Domain>
- struct is_callable<functional::as_expr<Domain> >
- : mpl::true_
- {};
+ template<typename Expr>
+ typename result_of::right<Expr const &>::type
+ operator ()(Expr const &e) const
+ {
+ return e.proto_base().child1;
+ }
+ };
 
- /// INTERNAL ONLY
- ///
- template<typename Domain>
- struct is_callable<functional::as_child<Domain> >
- : mpl::true_
- {};
+ }
 
- /// INTERNAL ONLY
- ///
- template<long N>
- struct is_callable<functional::child_c<N> >
- : mpl::true_
- {};
+ /// \brief A function that wraps non-Proto expression types in Proto
+ /// terminals and leaves Proto expression types alone.
+ ///
+ /// The <tt>as_expr()</tt> function turns objects into Proto terminals if
+ /// they are not Proto expression types already. Non-Proto types are
+ /// held by value, if possible. Types which are already Proto types are
+ /// left alone and returned by reference.
+ ///
+ /// This function can be called either with an explicitly specified
+ /// \c Domain parameter (i.e., <tt>as_expr\<Domain\>(t)</tt>), or
+ /// without (i.e., <tt>as_expr(t)</tt>). If no domain is
+ /// specified, \c default_domain is assumed.
+ ///
+ /// If <tt>is_expr\<T\>::value</tt> is \c true, then the argument is
+ /// returned unmodified, by reference. Otherwise, the argument is wrapped
+ /// in a Proto terminal expression node according to the following rules.
+ /// If \c T is a function type, let \c A be <tt>T &</tt>. Otherwise, let
+ /// \c A be the type \c T stripped of cv-qualifiers. Then, \c as_expr()
+ /// returns <tt>Domain()(terminal\<A\>::type::make(t))</tt>.
+ ///
+ /// \param t The object to wrap.
+ template<typename T>
+ typename add_const<typename result_of::as_expr<T, default_domain>::type>::type
+ as_expr(T &t BOOST_PROTO_DISABLE_IF_IS_CONST(T) BOOST_PROTO_DISABLE_IF_IS_FUNCTION(T))
+ {
+ return default_domain::as_expr<T>()(t);
+ }
 
- /// INTERNAL ONLY
- ///
- template<typename N>
- struct is_callable<functional::child<N> >
- : mpl::true_
- {};
+ /// \overload
+ ///
+ template<typename T>
+ typename add_const<typename result_of::as_expr<T const, default_domain>::type>::type
+ as_expr(T const &t)
+ {
+ return default_domain::as_expr<T const>()(t);
+ }
 
- }}
+ /// \overload
+ ///
+ template<typename Domain, typename T>
+ typename add_const<typename result_of::as_expr<T, Domain>::type>::type
+ as_expr(T &t BOOST_PROTO_DISABLE_IF_IS_CONST(T) BOOST_PROTO_DISABLE_IF_IS_FUNCTION(T))
+ {
+ return typename Domain::template as_expr<T>()(t);
+ }
 
- #if BOOST_WORKAROUND( BOOST_MSVC, >= 1400 )
- #pragma warning(pop)
- #endif
+ /// \overload
+ ///
+ template<typename Domain, typename T>
+ typename add_const<typename result_of::as_expr<T const, Domain>::type>::type
+ as_expr(T const &t)
+ {
+ return typename Domain::template as_expr<T const>()(t);
+ }
 
- #endif
+ /// \brief A function that wraps non-Proto expression types in Proto
+ /// terminals (by reference) and returns Proto expression types by
+ /// reference
+ ///
+ /// The <tt>as_child()</tt> function turns objects into Proto terminals if
+ /// they are not Proto expression types already. Non-Proto types are
+ /// held by reference. Types which are already Proto types are simply
+ /// returned as-is.
+ ///
+ /// This function can be called either with an explicitly specified
+ /// \c Domain parameter (i.e., <tt>as_child\<Domain\>(t)</tt>), or
+ /// without (i.e., <tt>as_child(t)</tt>). If no domain is
+ /// specified, \c default_domain is assumed.
+ ///
+ /// If <tt>is_expr\<T\>::value</tt> is \c true, then the argument is
+ /// returned as-is. Otherwise, \c as_child() returns
+ /// <tt>Domain()(terminal\<T &\>::type::make(t))</tt>.
+ ///
+ /// \param t The object to wrap.
+ template<typename T>
+ typename add_const<typename result_of::as_child<T, default_domain>::type>::type
+ as_child(T &t BOOST_PROTO_DISABLE_IF_IS_CONST(T) BOOST_PROTO_DISABLE_IF_IS_FUNCTION(T))
+ {
+ return default_domain::as_child<T>()(t);
+ }
 
-#else // PP_IS_ITERATING
+ /// \overload
+ ///
+ template<typename T>
+ typename add_const<typename result_of::as_child<T const, default_domain>::type>::type
+ as_child(T const &t)
+ {
+ return default_domain::as_child<T const>()(t);
+ }
 
- #define N BOOST_PP_ITERATION()
- #if N > 0
- /// \brief A metafunction for generating function-call expression types,
- /// a grammar element for matching function-call expressions, and a
- /// PrimitiveTransform that dispatches to the <tt>pass_through\<\></tt>
- /// transform.
- template<BOOST_PP_ENUM_PARAMS(N, typename A)>
- struct function
- #if N != BOOST_PROTO_MAX_ARITY
- <
- BOOST_PP_ENUM_PARAMS(N, A)
- BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PP_SUB(BOOST_PROTO_MAX_ARITY, N), void BOOST_PP_INTERCEPT)
- >
- #endif
- : proto::transform<
- function<
- BOOST_PP_ENUM_PARAMS(N, A)
- BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PP_SUB(BOOST_PROTO_MAX_ARITY, N), void BOOST_PP_INTERCEPT)
- >
- , int
- >
- {
- typedef proto::expr<proto::tag::function, BOOST_PP_CAT(list, N)<BOOST_PP_ENUM_PARAMS(N, A)>, N> type;
- typedef proto::basic_expr<proto::tag::function, BOOST_PP_CAT(list, N)<BOOST_PP_ENUM_PARAMS(N, A)>, N> proto_grammar;
+ /// \overload
+ ///
+ template<typename Domain, typename T>
+ typename add_const<typename result_of::as_child<T, Domain>::type>::type
+ as_child(T &t BOOST_PROTO_DISABLE_IF_IS_CONST(T) BOOST_PROTO_DISABLE_IF_IS_FUNCTION(T))
+ {
+ return typename Domain::template as_child<T>()(t);
+ }
 
- template<typename Expr, typename State, typename Data>
- struct impl
- : detail::pass_through_impl<function, Expr, State, Data>
- {};
-
- /// INTERNAL ONLY
- typedef proto::tag::function proto_tag;
- BOOST_PP_REPEAT(N, BOOST_PROTO_CHILD, A)
- BOOST_PP_REPEAT_FROM_TO(
- N
- , BOOST_PROTO_MAX_ARITY
- , BOOST_PROTO_CHILD
- , detail::if_vararg<BOOST_PP_CAT(A, BOOST_PP_DEC(N))> BOOST_PP_INTERCEPT
- )
- };
+ /// \overload
+ ///
+ template<typename Domain, typename T>
+ typename add_const<typename result_of::as_child<T const, Domain>::type>::type
+ as_child(T const &t)
+ {
+ return typename Domain::template as_child<T const>()(t);
+ }
 
- /// \brief A metafunction for generating n-ary expression types with a
- /// specified tag type,
- /// a grammar element for matching n-ary expressions, and a
- /// PrimitiveTransform that dispatches to the <tt>pass_through\<\></tt>
- /// transform.
- ///
- /// Use <tt>nary_expr\<_, vararg\<_\> \></tt> as a grammar element to match any
- /// n-ary expression; that is, any non-terminal.
- template<typename Tag BOOST_PP_ENUM_TRAILING_PARAMS(N, typename A)>
- struct nary_expr
- #if N != BOOST_PROTO_MAX_ARITY
- <
- Tag
- BOOST_PP_ENUM_TRAILING_PARAMS(N, A)
- BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PP_SUB(BOOST_PROTO_MAX_ARITY, N), void BOOST_PP_INTERCEPT)
- >
- #endif
- : proto::transform<
- nary_expr<
- Tag
- BOOST_PP_ENUM_TRAILING_PARAMS(N, A)
- BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PP_SUB(BOOST_PROTO_MAX_ARITY, N), void BOOST_PP_INTERCEPT)
- >
- , int
- >
- {
- typedef proto::expr<Tag, BOOST_PP_CAT(list, N)<BOOST_PP_ENUM_PARAMS(N, A)>, N> type;
- typedef proto::basic_expr<Tag, BOOST_PP_CAT(list, N)<BOOST_PP_ENUM_PARAMS(N, A)>, N> proto_grammar;
+ /// \brief Return the Nth child of the specified Proto expression.
+ ///
+ /// Return the Nth child of the specified Proto expression. If
+ /// \c N is not specified, as in \c child(expr), then \c N is assumed
+ /// to be <tt>mpl::long_\<0\></tt>. The child is returned by
+ /// reference.
+ ///
+ /// \param expr The Proto expression.
+ /// \pre <tt>is_expr\<Expr\>::value</tt> is \c true.
+ /// \pre \c N is an MPL Integral Constant.
+ /// \pre <tt>N::value \< Expr::proto_arity::value</tt>
+ /// \throw nothrow
+ /// \return A reference to the Nth child
+ template<typename N, typename Expr>
+ typename result_of::child<Expr &, N>::type
+ child(Expr &e BOOST_PROTO_DISABLE_IF_IS_CONST(Expr))
+ {
+ return result_of::child<Expr &, N>::call(e);
+ }
 
- template<typename Expr, typename State, typename Data>
- struct impl
- : detail::pass_through_impl<nary_expr, Expr, State, Data>
- {};
-
- /// INTERNAL ONLY
- typedef Tag proto_tag;
- BOOST_PP_REPEAT(N, BOOST_PROTO_CHILD, A)
- BOOST_PP_REPEAT_FROM_TO(
- N
- , BOOST_PROTO_MAX_ARITY
- , BOOST_PROTO_CHILD
- , detail::if_vararg<BOOST_PP_CAT(A, BOOST_PP_DEC(N))> BOOST_PP_INTERCEPT
- )
- };
+ /// \overload
+ ///
+ template<typename N, typename Expr>
+ typename result_of::child<Expr const &, N>::type
+ child(Expr const &e)
+ {
+ return result_of::child<Expr const &, N>::call(e);
+ }
 
- namespace detail
- {
- template<
- template<BOOST_PP_ENUM_PARAMS(N, typename BOOST_PP_INTERCEPT)> class T
- , BOOST_PP_ENUM_PARAMS(N, typename A)
- >
- struct is_callable_<T<BOOST_PP_ENUM_PARAMS(N, A)> BOOST_MPL_AUX_LAMBDA_ARITY_PARAM(N)>
- : is_same<BOOST_PP_CAT(A, BOOST_PP_DEC(N)), callable>
- {};
- }
+ /// \overload
+ ///
+ template<typename Expr2>
+ typename detail::expr_traits<typename Expr2::proto_base_expr::proto_child0>::reference
+ child(Expr2 &expr2 BOOST_PROTO_DISABLE_IF_IS_CONST(Expr2))
+ {
+ return expr2.proto_base().child0;
+ }
 
- #endif
+ /// \overload
+ ///
+ template<typename Expr2>
+ typename detail::expr_traits<typename Expr2::proto_base_expr::proto_child0>::const_reference
+ child(Expr2 const &expr2)
+ {
+ return expr2.proto_base().child0;
+ }
 
- namespace result_of
- {
- /// \brief A metafunction that returns the type of the Nth child
- /// of a Proto expression.
- ///
- /// A metafunction that returns the type of the Nth child
- /// of a Proto expression. \c N must be less than
- /// \c Expr::proto_arity::value.
- template<typename Expr>
- struct child_c<Expr, N>
- {
- /// Verify that we are not operating on a terminal
- BOOST_STATIC_ASSERT(0 != Expr::proto_arity_c);
+ /// \brief Return the Nth child of the specified Proto expression.
+ ///
+ /// Return the Nth child of the specified Proto expression. The child
+ /// is returned by reference.
+ ///
+ /// \param expr The Proto expression.
+ /// \pre <tt>is_expr\<Expr\>::value</tt> is \c true.
+ /// \pre <tt>N \< Expr::proto_arity::value</tt>
+ /// \throw nothrow
+ /// \return A reference to the Nth child
+ template<long N, typename Expr>
+ typename result_of::child_c<Expr &, N>::type
+ child_c(Expr &e BOOST_PROTO_DISABLE_IF_IS_CONST(Expr))
+ {
+ return result_of::child_c<Expr &, N>::call(e);
+ }
 
- /// The raw type of the Nth child as it is stored within
- /// \c Expr. This may be a value or a reference
- typedef typename Expr::BOOST_PP_CAT(proto_child, N) value_type;
-
- /// The "value" type of the child, suitable for return by value,
- /// computed as follows:
- /// \li <tt>T const &</tt> becomes <tt>T</tt>
- /// \li <tt>T &</tt> becomes <tt>T</tt>
- /// \li <tt>T</tt> becomes <tt>T</tt>
- typedef typename detail::expr_traits<typename Expr::BOOST_PP_CAT(proto_child, N)>::value_type type;
- };
+ /// \overload
+ ///
+ template<long N, typename Expr>
+ typename result_of::child_c<Expr const &, N>::type
+ child_c(Expr const &e)
+ {
+ return result_of::child_c<Expr const &, N>::call(e);
+ }
 
- template<typename Expr>
- struct child_c<Expr &, N>
- {
- /// Verify that we are not operating on a terminal
- BOOST_STATIC_ASSERT(0 != Expr::proto_arity_c);
+ /// \brief Return the value stored within the specified Proto
+ /// terminal expression.
+ ///
+ /// Return the the value stored within the specified Proto
+ /// terminal expression. The value is returned by
+ /// reference.
+ ///
+ /// \param expr The Proto terminal expression.
+ /// \pre <tt>N::value == 0</tt>
+ /// \throw nothrow
+ /// \return A reference to the terminal's value
+ template<typename Expr>
+ typename result_of::value<Expr &>::type
+ value(Expr &e BOOST_PROTO_DISABLE_IF_IS_CONST(Expr))
+ {
+ return e.proto_base().child0;
+ }
 
- /// The raw type of the Nth child as it is stored within
- /// \c Expr. This may be a value or a reference
- typedef typename Expr::BOOST_PP_CAT(proto_child, N) value_type;
-
- /// The "reference" type of the child, suitable for return by
- /// reference, computed as follows:
- /// \li <tt>T const &</tt> becomes <tt>T const &</tt>
- /// \li <tt>T &</tt> becomes <tt>T &</tt>
- /// \li <tt>T</tt> becomes <tt>T &</tt>
- typedef typename detail::expr_traits<typename Expr::BOOST_PP_CAT(proto_child, N)>::reference type;
-
- /// INTERNAL ONLY
- ///
- static type call(Expr &e)
- {
- return e.proto_base().BOOST_PP_CAT(child, N);
- }
- };
+ /// \overload
+ ///
+ template<typename Expr>
+ typename result_of::value<Expr const &>::type
+ value(Expr const &e)
+ {
+ return e.proto_base().child0;
+ }
 
- template<typename Expr>
- struct child_c<Expr const &, N>
- {
- /// Verify that we are not operating on a terminal
- BOOST_STATIC_ASSERT(0 != Expr::proto_arity_c);
+ /// \brief Return the left child of the specified binary Proto
+ /// expression.
+ ///
+ /// Return the left child of the specified binary Proto expression. The
+ /// child is returned by reference.
+ ///
+ /// \param expr The Proto expression.
+ /// \pre <tt>is_expr\<Expr\>::value</tt> is \c true.
+ /// \pre <tt>2 == Expr::proto_arity::value</tt>
+ /// \throw nothrow
+ /// \return A reference to the left child
+ template<typename Expr>
+ typename result_of::left<Expr &>::type
+ left(Expr &e BOOST_PROTO_DISABLE_IF_IS_CONST(Expr))
+ {
+ return e.proto_base().child0;
+ }
 
- /// The raw type of the Nth child as it is stored within
- /// \c Expr. This may be a value or a reference
- typedef typename Expr::BOOST_PP_CAT(proto_child, N) value_type;
-
- /// The "const reference" type of the child, suitable for return by
- /// const reference, computed as follows:
- /// \li <tt>T const &</tt> becomes <tt>T const &</tt>
- /// \li <tt>T &</tt> becomes <tt>T &</tt>
- /// \li <tt>T</tt> becomes <tt>T const &</tt>
- typedef typename detail::expr_traits<typename Expr::BOOST_PP_CAT(proto_child, N)>::const_reference type;
-
- /// INTERNAL ONLY
- ///
- static type call(Expr const &e)
- {
- return e.proto_base().BOOST_PP_CAT(child, N);
- }
- };
- }
+ /// \overload
+ ///
+ template<typename Expr>
+ typename result_of::left<Expr const &>::type
+ left(Expr const &e)
+ {
+ return e.proto_base().child0;
+ }
+
+ /// \brief Return the right child of the specified binary Proto
+ /// expression.
+ ///
+ /// Return the right child of the specified binary Proto expression. The
+ /// child is returned by reference.
+ ///
+ /// \param expr The Proto expression.
+ /// \pre <tt>is_expr\<Expr\>::value</tt> is \c true.
+ /// \pre <tt>2 == Expr::proto_arity::value</tt>
+ /// \throw nothrow
+ /// \return A reference to the right child
+ template<typename Expr>
+ typename result_of::right<Expr &>::type
+ right(Expr &e BOOST_PROTO_DISABLE_IF_IS_CONST(Expr))
+ {
+ return e.proto_base().child1;
+ }
 
- #undef N
+ /// \overload
+ ///
+ template<typename Expr>
+ typename result_of::right<Expr const &>::type
+ right(Expr const &e)
+ {
+ return e.proto_base().child1;
+ }
+
+ /// INTERNAL ONLY
+ ///
+ template<typename Domain>
+ struct is_callable<functional::as_expr<Domain> >
+ : mpl::true_
+ {};
+
+ /// INTERNAL ONLY
+ ///
+ template<typename Domain>
+ struct is_callable<functional::as_child<Domain> >
+ : mpl::true_
+ {};
+
+ /// INTERNAL ONLY
+ ///
+ template<long N>
+ struct is_callable<functional::child_c<N> >
+ : mpl::true_
+ {};
+
+ /// INTERNAL ONLY
+ ///
+ template<typename N>
+ struct is_callable<functional::child<N> >
+ : mpl::true_
+ {};
+
+}}
+
+#if BOOST_WORKAROUND( BOOST_MSVC, >= 1400 )
+ #pragma warning(pop)
+#endif
 
 #endif

Modified: trunk/libs/proto/preprocess/preprocess_proto.cpp
==============================================================================
--- trunk/libs/proto/preprocess/preprocess_proto.cpp (original)
+++ trunk/libs/proto/preprocess/preprocess_proto.cpp 2011-05-06 11:55:17 EDT (Fri, 06 May 2011)
@@ -15,3 +15,4 @@
 #include <boost/proto/deep_copy.hpp>
 #include <boost/proto/generate.hpp>
 #include <boost/proto/make_expr.hpp>
+#include <boost/proto/matches.hpp>


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