Boost logo

Boost-Commit :

From: eric_at_[hidden]
Date: 2007-11-07 23:54:12


Author: eric_niebler
Date: 2007-11-07 23:54:11 EST (Wed, 07 Nov 2007)
New Revision: 40920
URL: http://svn.boost.org/trac/boost/changeset/40920

Log:
work around gcc bugs, generalize default_context
Text files modified:
   branches/proto/v3/boost/xpressive/proto3/context/default.hpp | 689 +++++++++++++++++++--------------------
   branches/proto/v3/boost/xpressive/proto3/expr.hpp | 24 +
   branches/proto/v3/boost/xpressive/proto3/operators.hpp | 12
   branches/proto/v3/boost/xpressive/proto3/proto_fwd.hpp | 2
   4 files changed, 361 insertions(+), 366 deletions(-)

Modified: branches/proto/v3/boost/xpressive/proto3/context/default.hpp
==============================================================================
--- branches/proto/v3/boost/xpressive/proto3/context/default.hpp (original)
+++ branches/proto/v3/boost/xpressive/proto3/context/default.hpp 2007-11-07 23:54:11 EST (Wed, 07 Nov 2007)
@@ -1,388 +1,369 @@
-#ifndef BOOST_PP_IS_ITERATING
- ///////////////////////////////////////////////////////////////////////////////
- /// \file default.hpp
- /// Definintion of default_context, a default evaluation context for
- /// proto::eval() that uses Boost.Typeof to deduce return types
- /// of the built-in operators.
- //
- // Copyright 2007 Eric Niebler. Distributed under the Boost
- // Software License, Version 1.0. (See accompanying file
- // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
-
- #ifndef BOOST_PROTO_CONTEXT_DEFAULT_HPP_EAN_01_08_2007
- #define BOOST_PROTO_CONTEXT_DEFAULT_HPP_EAN_01_08_2007
-
- //#include <boost/xpressive/proto/detail/prefix.hpp> // must be first include
- #include <boost/config.hpp>
- #include <boost/detail/workaround.hpp>
- #include <boost/preprocessor/cat.hpp>
- #include <boost/preprocessor/iteration/iterate.hpp>
- #include <boost/preprocessor/facilities/intercept.hpp>
- #include <boost/preprocessor/repetition/enum_shifted.hpp>
- #include <boost/preprocessor/repetition/enum_params.hpp>
- #include <boost/preprocessor/repetition/enum_trailing.hpp>
- #include <boost/preprocessor/arithmetic/inc.hpp>
- #include <boost/preprocessor/tuple/elem.hpp>
- #include <boost/mpl/if.hpp>
- #include <boost/typeof/typeof.hpp>
- #include <boost/utility/result_of.hpp>
- #include <boost/type_traits/is_const.hpp>
- #include <boost/type_traits/is_function.hpp>
- #include <boost/type_traits/remove_cv.hpp>
- #include <boost/xpressive/proto3/proto_fwd.hpp>
- #include <boost/xpressive/proto3/tags.hpp>
- #include <boost/xpressive/proto3/eval.hpp>
- #include <boost/xpressive/proto3/traits.hpp> // for proto::arg_c()
- //#include <boost/xpressive/proto/detail/suffix.hpp> // must be last include
-
- // If we're generating doxygen documentation, hide all the nasty
- // Boost.Typeof gunk.
- #ifndef BOOST_PROTO_DOXYGEN_INVOKED
- #define BOOST_PROTO_DECLTYPE_NESTED_TYPEDEF_TPL_(Nested, Expr)\
- BOOST_TYPEOF_NESTED_TYPEDEF_TPL(BOOST_PP_CAT(nested_and_hidden_, Nested), Expr)\
- struct Nested\
- : mpl::if_c<\
- 1==sizeof(detail_::check_reference(Expr))\
- , typename BOOST_PP_CAT(nested_and_hidden_, Nested)::type &\
- , typename BOOST_PP_CAT(nested_and_hidden_, Nested)::type\
- >\
- {};
-
- #define BOOST_PROTO_DECLTYPE_(Expr, Type)\
- BOOST_PROTO_DECLTYPE_NESTED_TYPEDEF_TPL_(BOOST_PP_CAT(nested_, Type), (Expr))\
- typedef typename BOOST_PP_CAT(nested_, Type)::type Type;
- #else
- /// INTERNAL ONLY
- ///
- #define BOOST_PROTO_DECLTYPE_NESTED_TYPEDEF_TPL_(Nested, Expr)
- /// INTERNAL ONLY
- ///
- #define BOOST_PROTO_DECLTYPE_(Expr, Type)\
- typedef detail_::unspecified Type;
- #endif
+///////////////////////////////////////////////////////////////////////////////
+/// \file default.hpp
+/// Definintion of default_context, a default evaluation context for
+/// proto::eval() that uses Boost.Typeof to deduce return types
+/// of the built-in operators.
+//
+// Copyright 2007 Eric Niebler. Distributed under the Boost
+// Software License, Version 1.0. (See accompanying file
+// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_PROTO3_CONTEXT_DEFAULT_HPP_EAN_01_08_2007
+#define BOOST_PROTO3_CONTEXT_DEFAULT_HPP_EAN_01_08_2007
+
+#include <boost/config.hpp>
+#include <boost/detail/workaround.hpp>
+#include <boost/mpl/if.hpp>
+#include <boost/typeof/typeof.hpp>
+#include <boost/utility/result_of.hpp>
+#include <boost/type_traits.hpp>
+#include <boost/xpressive/proto3/proto_fwd.hpp>
+#include <boost/xpressive/proto3/tags.hpp>
+#include <boost/xpressive/proto3/eval.hpp>
+#include <boost/xpressive/proto3/traits.hpp> // for proto::arg_c()
+
+// If we're generating doxygen documentation, hide all the nasty
+// Boost.Typeof gunk.
+#ifndef BOOST_PROTO_DOXYGEN_INVOKED
+ #define BOOST_PROTO_DECLTYPE_NESTED_TYPEDEF_TPL_(Nested, Expr)\
+ BOOST_TYPEOF_NESTED_TYPEDEF_TPL(BOOST_PP_CAT(nested_and_hidden_, Nested), Expr)\
+ struct Nested\
+ : mpl::if_c<\
+ 1==sizeof(proto::detail::check_reference(Expr))\
+ , typename BOOST_PP_CAT(nested_and_hidden_, Nested)::type &\
+ , typename BOOST_PP_CAT(nested_and_hidden_, Nested)::type\
+ >\
+ {};
+
+ #define BOOST_PROTO_DECLTYPE_(Expr, Type)\
+ BOOST_PROTO_DECLTYPE_NESTED_TYPEDEF_TPL_(BOOST_PP_CAT(nested_, Type), (Expr))\
+ typedef typename BOOST_PP_CAT(nested_, Type)::type Type;
+#else
+ /// INTERNAL ONLY
+ ///
+ #define BOOST_PROTO_DECLTYPE_NESTED_TYPEDEF_TPL_(Nested, Expr)
+ /// INTERNAL ONLY
+ ///
+ #define BOOST_PROTO_DECLTYPE_(Expr, Type)\
+ typedef detail::unspecified Type;
+#endif
 
- namespace boost { namespace proto
+namespace boost { namespace proto
+{
+ namespace detail
     {
- namespace detail_
- {
- template<typename T> T make();
-
- template<typename T>
- char check_reference(T &);
+ template<typename T> T make();
 
- template<typename T>
- char (&check_reference(T const &))[2];
+ template<typename T>
+ char check_reference(T &);
 
- template<typename A0, typename A1>
- struct comma_result
- {
- BOOST_PROTO_DECLTYPE_((detail_::make<A0>(), detail_::make<A1>()), type)
- };
-
- template<typename A0>
- struct comma_result<A0, void>
- {
- typedef void type;
- };
+ template<typename T>
+ char (&check_reference(T const &))[2];
 
- template<typename A1>
- struct comma_result<void, A1>
- {
- typedef A1 type;
- };
-
- template<>
- struct comma_result<void, void>
- {
- typedef void type;
- };
-
- template<typename T, typename U = T>
- struct result_of_fixup
- : mpl::if_<is_function<T>, T *, U>
- {};
-
- template<typename T, typename U>
- struct result_of_fixup<T &, U>
- : result_of_fixup<T, T>
- {};
-
- template<typename T, typename U>
- struct result_of_fixup<T *, U>
- : result_of_fixup<T, U>
- {};
+ template<typename A0, typename A1>
+ struct comma_result
+ {
+ BOOST_PROTO_DECLTYPE_((proto::detail::make<A0>(), proto::detail::make<A1>()), type)
+ };
 
- template<typename T, typename U>
- struct result_of_fixup<T const, U>
- : result_of_fixup<T, U>
- {};
+ template<typename A0>
+ struct comma_result<A0, void>
+ {
+ typedef void type;
+ };
 
- //// Tests for result_of_fixup
- //struct bar {};
- //BOOST_MPL_ASSERT((is_same<bar, result_of_fixup<bar>::type>));
- //BOOST_MPL_ASSERT((is_same<bar const, result_of_fixup<bar const>::type>));
- //BOOST_MPL_ASSERT((is_same<bar, result_of_fixup<bar &>::type>));
- //BOOST_MPL_ASSERT((is_same<bar const, result_of_fixup<bar const &>::type>));
- //BOOST_MPL_ASSERT((is_same<void(*)(), result_of_fixup<void(*)()>::type>));
- //BOOST_MPL_ASSERT((is_same<void(*)(), result_of_fixup<void(* const)()>::type>));
- //BOOST_MPL_ASSERT((is_same<void(*)(), result_of_fixup<void(* const &)()>::type>));
- //BOOST_MPL_ASSERT((is_same<void(*)(), result_of_fixup<void(&)()>::type>));
-
- #if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
- template<typename T> T &make_ref_(T &t);
- template<typename T> T const &make_ref_(T const &t);
- #define BOOST_PROTO_REF(x) detail_::make_ref_(x)
- #else
- #define BOOST_PROTO_REF(x) x
- #endif
- }
+ template<typename A1>
+ struct comma_result<void, A1>
+ {
+ typedef A1 type;
+ };
 
- namespace context
+ template<>
+ struct comma_result<void, void>
         {
- template<typename Expr, typename Context, typename Tag, long Arity>
- struct default_eval
- {};
+ typedef void type;
+ };
 
- /// INTERNAL ONLY
- ///
- #define BOOST_PROTO_UNARY_OP_RESULT(Op, Tag) \
- template<typename Expr, typename Context> \
- struct default_eval<Expr, Context, Tag, 1> \
- { \
- private: \
- static Expr &sexpr; \
- static Context &sctx; \
- public: \
- BOOST_PROTO_DECLTYPE_(Op proto::eval(BOOST_PROTO_REF(proto::arg_c<0>(sexpr)), sctx), result_type)\
- result_type operator()(Expr &expr, Context &ctx) const \
- { \
- return Op proto::eval(proto::arg_c<0>(expr), ctx); \
- } \
- }; \
- /**/
+ template<typename T, typename U = T>
+ struct result_of_fixup
+ : mpl::if_<is_function<T>, T *, U>
+ {};
+
+ template<typename T, typename U>
+ struct result_of_fixup<T &, U>
+ : result_of_fixup<T, T>
+ {};
+
+ template<typename T, typename U>
+ struct result_of_fixup<T *, U>
+ : result_of_fixup<T, U>
+ {};
+
+ template<typename T, typename U>
+ struct result_of_fixup<T const, U>
+ : result_of_fixup<T, U>
+ {};
+
+ //// Tests for result_of_fixup
+ //struct bar {};
+ //BOOST_MPL_ASSERT((is_same<bar, result_of_fixup<bar>::type>));
+ //BOOST_MPL_ASSERT((is_same<bar const, result_of_fixup<bar const>::type>));
+ //BOOST_MPL_ASSERT((is_same<bar, result_of_fixup<bar &>::type>));
+ //BOOST_MPL_ASSERT((is_same<bar const, result_of_fixup<bar const &>::type>));
+ //BOOST_MPL_ASSERT((is_same<void(*)(), result_of_fixup<void(*)()>::type>));
+ //BOOST_MPL_ASSERT((is_same<void(*)(), result_of_fixup<void(* const)()>::type>));
+ //BOOST_MPL_ASSERT((is_same<void(*)(), result_of_fixup<void(* const &)()>::type>));
+ //BOOST_MPL_ASSERT((is_same<void(*)(), result_of_fixup<void(&)()>::type>));
+
+ #if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
+ template<typename T> T &make_ref_(T &t);
+ template<typename T> T const &make_ref_(T const &t);
+ #define BOOST_PROTO_REF(x) proto::detail::make_ref_(x)
+ #else
+ #define BOOST_PROTO_REF(x) x
+ #endif
 
- /// INTERNAL ONLY
- ///
- #define BOOST_PROTO_BINARY_OP_RESULT(Op, Tag) \
- template<typename Expr, typename Context> \
- struct default_eval<Expr, Context, Tag, 2> \
- { \
- private: \
- static Expr &sexpr; \
- static Context &sctx; \
- public: \
- BOOST_PROTO_DECLTYPE_(proto::eval(BOOST_PROTO_REF(proto::arg_c<0>(sexpr)), sctx) Op proto::eval(BOOST_PROTO_REF(proto::arg_c<1>(sexpr)), sctx), result_type)\
- result_type operator()(Expr &expr, Context &ctx) const \
- { \
- return proto::eval(proto::arg_c<0>(expr), ctx) Op proto::eval(proto::arg_c<1>(expr), ctx);\
- } \
- }; \
- /**/
-
- BOOST_PROTO_UNARY_OP_RESULT(+, proto::tag::posit)
- BOOST_PROTO_UNARY_OP_RESULT(-, proto::tag::negate)
- BOOST_PROTO_UNARY_OP_RESULT(*, proto::tag::dereference)
- BOOST_PROTO_UNARY_OP_RESULT(~, proto::tag::complement)
- BOOST_PROTO_UNARY_OP_RESULT(&, proto::tag::address_of)
- BOOST_PROTO_UNARY_OP_RESULT(!, proto::tag::logical_not)
- BOOST_PROTO_UNARY_OP_RESULT(++, proto::tag::pre_inc)
- BOOST_PROTO_UNARY_OP_RESULT(--, proto::tag::pre_dec)
-
- BOOST_PROTO_BINARY_OP_RESULT(<<, proto::tag::shift_left)
- BOOST_PROTO_BINARY_OP_RESULT(>>, proto::tag::shift_right)
- BOOST_PROTO_BINARY_OP_RESULT(*, proto::tag::multiplies)
- BOOST_PROTO_BINARY_OP_RESULT(/, proto::tag::divides)
- BOOST_PROTO_BINARY_OP_RESULT(%, proto::tag::modulus)
- BOOST_PROTO_BINARY_OP_RESULT(+, proto::tag::plus)
- BOOST_PROTO_BINARY_OP_RESULT(-, proto::tag::minus)
- BOOST_PROTO_BINARY_OP_RESULT(<, proto::tag::less)
- BOOST_PROTO_BINARY_OP_RESULT(>, proto::tag::greater)
- BOOST_PROTO_BINARY_OP_RESULT(<=, proto::tag::less_equal)
- BOOST_PROTO_BINARY_OP_RESULT(>=, proto::tag::greater_equal)
- BOOST_PROTO_BINARY_OP_RESULT(==, proto::tag::equal_to)
- BOOST_PROTO_BINARY_OP_RESULT(!=, proto::tag::not_equal_to)
- BOOST_PROTO_BINARY_OP_RESULT(||, proto::tag::logical_or)
- BOOST_PROTO_BINARY_OP_RESULT(&&, proto::tag::logical_and)
- BOOST_PROTO_BINARY_OP_RESULT(&, proto::tag::bitwise_and)
- BOOST_PROTO_BINARY_OP_RESULT(|, proto::tag::bitwise_or)
- BOOST_PROTO_BINARY_OP_RESULT(^, proto::tag::bitwise_xor)
- BOOST_PROTO_BINARY_OP_RESULT(->*, proto::tag::mem_ptr)
-
- BOOST_PROTO_BINARY_OP_RESULT(=, proto::tag::assign)
- BOOST_PROTO_BINARY_OP_RESULT(<<=, proto::tag::shift_left_assign)
- BOOST_PROTO_BINARY_OP_RESULT(>>=, proto::tag::shift_right_assign)
- BOOST_PROTO_BINARY_OP_RESULT(*=, proto::tag::multiplies_assign)
- BOOST_PROTO_BINARY_OP_RESULT(/=, proto::tag::divides_assign)
- BOOST_PROTO_BINARY_OP_RESULT(%=, proto::tag::modulus_assign)
- BOOST_PROTO_BINARY_OP_RESULT(+=, proto::tag::plus_assign)
- BOOST_PROTO_BINARY_OP_RESULT(-=, proto::tag::minus_assign)
- BOOST_PROTO_BINARY_OP_RESULT(&=, proto::tag::bitwise_and_assign)
- BOOST_PROTO_BINARY_OP_RESULT(|=, proto::tag::bitwise_or_assign)
- BOOST_PROTO_BINARY_OP_RESULT(^=, proto::tag::bitwise_xor_assign)
+ template<typename Expr, typename Context, typename Indices>
+ struct default_eval_function_;
 
- template<typename Expr, typename Context>
- struct default_eval<Expr, Context, proto::tag::terminal, 0>
- {
- typedef
- typename mpl::if_<
- is_const<Expr>
- , typename proto::result_of::arg<Expr>::const_reference
- , typename proto::result_of::arg<Expr>::reference
+ template<typename Expr, typename Context, int Zero, int... Indices>
+ struct default_eval_function_<Expr, Context, op::detail::indices<Zero, Indices...> >
+ {
+ typedef
+ typename proto::detail::result_of_fixup<
+ typename proto::result_of::eval<
+ typename proto::result_of::arg_c<Expr, 0>::type
+ , Context
>::type
- result_type;
+ >::type
+ function_type;
 
- result_type operator()(Expr &expr, Context &) const
- {
- return proto::arg(expr);
- }
- };
-
- // Handle post-increment specially.
- template<typename Expr, typename Context>
- struct default_eval<Expr, Context, proto::tag::post_inc, 1>
- {
- private:
- static Expr &sexpr;
- static Context &sctx;
- public:
- BOOST_PROTO_DECLTYPE_(proto::eval(BOOST_PROTO_REF(proto::arg_c<0>(sexpr)), sctx) ++, result_type)
- result_type operator()(Expr &expr, Context &ctx) const
- {
- return proto::eval(proto::arg_c<0>(expr), ctx) ++;
- }
- };
-
- // Handle post-decrement specially.
- template<typename Expr, typename Context>
- struct default_eval<Expr, Context, proto::tag::post_dec, 1>
- {
- private:
- static Expr &sexpr;
- static Context &sctx;
- public:
- BOOST_PROTO_DECLTYPE_(proto::eval(BOOST_PROTO_REF(proto::arg_c<0>(sexpr)), sctx) --, result_type)
- result_type operator()(Expr &expr, Context &ctx) const
- {
- return proto::eval(proto::arg_c<0>(expr), ctx) --;
- }
- };
-
- // Handle subscript specially.
- template<typename Expr, typename Context>
- struct default_eval<Expr, Context, proto::tag::subscript, 2>
- {
- private:
- static Expr &sexpr;
- static Context &sctx;
- public:
- BOOST_PROTO_DECLTYPE_(proto::eval(BOOST_PROTO_REF(proto::arg_c<0>(sexpr)), sctx)[proto::eval(BOOST_PROTO_REF(proto::arg_c<1>(sexpr)), sctx)], result_type)
- result_type operator()(Expr &expr, Context &ctx) const
- {
- return proto::eval(proto::arg_c<0>(expr), ctx)[proto::eval(proto::arg_c<1>(expr), ctx)];
- }
- };
-
- // Handle if_else_ specially.
- template<typename Expr, typename Context>
- struct default_eval<Expr, Context, proto::tag::if_else_, 3>
- {
- private:
- static Expr &sexpr;
- static Context &sctx;
- public:
- BOOST_PROTO_DECLTYPE_(
- proto::eval(BOOST_PROTO_REF(proto::arg_c<0>(sexpr)), sctx)
- ? proto::eval(BOOST_PROTO_REF(proto::arg_c<1>(sexpr)), sctx)
- : proto::eval(BOOST_PROTO_REF(proto::arg_c<2>(sexpr)), sctx)
- , result_type
- )
- result_type operator()(Expr &expr, Context &ctx) const
- {
- return proto::eval(proto::arg_c<0>(expr), ctx)
- ? proto::eval(proto::arg_c<1>(expr), ctx)
- : proto::eval(proto::arg_c<2>(expr), ctx);
- }
- };
-
- // Handle comma specially.
- template<typename Expr, typename Context>
- struct default_eval<Expr, Context, proto::tag::comma, 2>
- {
- typedef typename proto::result_of::eval<typename proto::result_of::arg_c<Expr, 0>::type, Context>::type proto_arg0;
- typedef typename proto::result_of::eval<typename proto::result_of::arg_c<Expr, 1>::type, Context>::type proto_arg1;
- typedef typename detail_::comma_result<proto_arg0, proto_arg1>::type result_type;
- result_type operator()(Expr &expr, Context &ctx) const
- {
- return proto::eval(proto::arg_c<0>(expr), ctx), proto::eval(proto::arg_c<1>(expr), ctx);
- }
- };
-
- #define BOOST_PROTO_EVAL_N_TYPE(Z, N, Data)\
- typename proto::result_of::eval<\
- typename proto::result_of::arg_c<BOOST_PP_TUPLE_ELEM(2, 0, Data), N>::type\
- , BOOST_PP_TUPLE_ELEM(2, 1, Data)\
- >::type
-
- #define BOOST_PROTO_EVAL_N(Z, N, Data)\
- proto::eval(proto::arg_c<N>(BOOST_PP_TUPLE_ELEM(2, 0, Data)), BOOST_PP_TUPLE_ELEM(2, 1, Data))
+ typedef
+ typename boost::result_of<
+ function_type(
+ typename proto::result_of::eval<
+ typename proto::result_of::arg_c<Expr, Indices>::type
+ , Context
+ >::type...
+ )
+ >::type
+ result_type;
 
- #define BOOST_PP_ITERATION_PARAMS_1 (3, (1, BOOST_PROTO_MAX_ARITY, <boost/xpressive/proto/context/default.hpp>))
- #include BOOST_PP_ITERATE()
+ result_type operator ()(Expr &expr, Context &context) const
+ {
+ return proto::eval(proto::arg_c<0>(expr), context)(
+ proto::eval(proto::arg_c<Indices>(expr), context)...
+ );
+ }
+ };
 
- #undef BOOST_PROTO_EVAL_N_TYPE
- #undef BOOST_PROTO_EVAL_N
+ } // namespace detail
 
- /// default_context
- ///
- struct default_context
- {
- /// default_context::eval
- ///
- template<typename Expr, typename ThisContext = default_context const>
- struct eval
- : default_eval<Expr, ThisContext>
- {};
- };
+ namespace context
+ {
+ template<typename Expr, typename Context, typename Tag>
+ struct default_eval
+ {};
 
- } // namespace context
+ /// INTERNAL ONLY
+ ///
+ #define BOOST_PROTO_UNARY_OP_RESULT(Op, Tag) \
+ template<typename Expr, typename Context> \
+ struct default_eval<Expr, Context, Tag> \
+ { \
+ private: \
+ static Expr &sexpr; \
+ static Context &sctx; \
+ public: \
+ BOOST_PROTO_DECLTYPE_(Op proto::eval(BOOST_PROTO_REF(proto::arg_c<0>(sexpr)), sctx), result_type)\
+ result_type operator()(Expr &expr, Context &ctx) const \
+ { \
+ return Op proto::eval(proto::arg_c<0>(expr), ctx); \
+ } \
+ }; \
+ /**/
 
- }} // namespace boost::proto
+ /// INTERNAL ONLY
+ ///
+ #define BOOST_PROTO_BINARY_OP_RESULT(Op, Tag) \
+ template<typename Expr, typename Context> \
+ struct default_eval<Expr, Context, Tag> \
+ { \
+ private: \
+ static Expr &sexpr; \
+ static Context &sctx; \
+ public: \
+ BOOST_PROTO_DECLTYPE_(proto::eval(BOOST_PROTO_REF(proto::arg_c<0>(sexpr)), sctx) Op proto::eval(BOOST_PROTO_REF(proto::arg_c<1>(sexpr)), sctx), result_type)\
+ result_type operator()(Expr &expr, Context &ctx) const \
+ { \
+ return proto::eval(proto::arg_c<0>(expr), ctx) Op proto::eval(proto::arg_c<1>(expr), ctx);\
+ } \
+ }; \
+ /**/
+
+ BOOST_PROTO_UNARY_OP_RESULT(+, proto::tag::posit)
+ BOOST_PROTO_UNARY_OP_RESULT(-, proto::tag::negate)
+ BOOST_PROTO_UNARY_OP_RESULT(*, proto::tag::dereference)
+ BOOST_PROTO_UNARY_OP_RESULT(~, proto::tag::complement)
+ BOOST_PROTO_UNARY_OP_RESULT(&, proto::tag::address_of)
+ BOOST_PROTO_UNARY_OP_RESULT(!, proto::tag::logical_not)
+ BOOST_PROTO_UNARY_OP_RESULT(++, proto::tag::pre_inc)
+ BOOST_PROTO_UNARY_OP_RESULT(--, proto::tag::pre_dec)
+
+ BOOST_PROTO_BINARY_OP_RESULT(<<, proto::tag::shift_left)
+ BOOST_PROTO_BINARY_OP_RESULT(>>, proto::tag::shift_right)
+ BOOST_PROTO_BINARY_OP_RESULT(*, proto::tag::multiplies)
+ BOOST_PROTO_BINARY_OP_RESULT(/, proto::tag::divides)
+ BOOST_PROTO_BINARY_OP_RESULT(%, proto::tag::modulus)
+ BOOST_PROTO_BINARY_OP_RESULT(+, proto::tag::plus)
+ BOOST_PROTO_BINARY_OP_RESULT(-, proto::tag::minus)
+ BOOST_PROTO_BINARY_OP_RESULT(<, proto::tag::less)
+ BOOST_PROTO_BINARY_OP_RESULT(>, proto::tag::greater)
+ BOOST_PROTO_BINARY_OP_RESULT(<=, proto::tag::less_equal)
+ BOOST_PROTO_BINARY_OP_RESULT(>=, proto::tag::greater_equal)
+ BOOST_PROTO_BINARY_OP_RESULT(==, proto::tag::equal_to)
+ BOOST_PROTO_BINARY_OP_RESULT(!=, proto::tag::not_equal_to)
+ BOOST_PROTO_BINARY_OP_RESULT(||, proto::tag::logical_or)
+ BOOST_PROTO_BINARY_OP_RESULT(&&, proto::tag::logical_and)
+ BOOST_PROTO_BINARY_OP_RESULT(&, proto::tag::bitwise_and)
+ BOOST_PROTO_BINARY_OP_RESULT(|, proto::tag::bitwise_or)
+ BOOST_PROTO_BINARY_OP_RESULT(^, proto::tag::bitwise_xor)
+ BOOST_PROTO_BINARY_OP_RESULT(->*, proto::tag::mem_ptr)
+
+ BOOST_PROTO_BINARY_OP_RESULT(=, proto::tag::assign)
+ BOOST_PROTO_BINARY_OP_RESULT(<<=, proto::tag::shift_left_assign)
+ BOOST_PROTO_BINARY_OP_RESULT(>>=, proto::tag::shift_right_assign)
+ BOOST_PROTO_BINARY_OP_RESULT(*=, proto::tag::multiplies_assign)
+ BOOST_PROTO_BINARY_OP_RESULT(/=, proto::tag::divides_assign)
+ BOOST_PROTO_BINARY_OP_RESULT(%=, proto::tag::modulus_assign)
+ BOOST_PROTO_BINARY_OP_RESULT(+=, proto::tag::plus_assign)
+ BOOST_PROTO_BINARY_OP_RESULT(-=, proto::tag::minus_assign)
+ BOOST_PROTO_BINARY_OP_RESULT(&=, proto::tag::bitwise_and_assign)
+ BOOST_PROTO_BINARY_OP_RESULT(|=, proto::tag::bitwise_or_assign)
+ BOOST_PROTO_BINARY_OP_RESULT(^=, proto::tag::bitwise_xor_assign)
 
- #undef BOOST_PROTO_DECLTYPE_NESTED_TYPEDEF_TPL_
- #undef BOOST_PROTO_DECLTYPE_
+ template<typename Expr, typename Context>
+
+ struct default_eval<Expr, Context, proto::tag::terminal>
+ {
+ typedef
+ typename mpl::if_<
+ is_const<Expr>
+ , typename proto::result_of::arg<Expr>::const_reference
+ , typename proto::result_of::arg<Expr>::reference
+ >::type
+ result_type;
 
- #endif
+ result_type operator()(Expr &expr, Context &) const
+ {
+ return proto::arg(expr);
+ }
+ };
 
-#else
+ // Handle post-increment specially.
+ template<typename Expr, typename Context>
+ struct default_eval<Expr, Context, proto::tag::post_inc>
+ {
+ private:
+ static Expr &sexpr;
+ static Context &sctx;
+ public:
+ BOOST_PROTO_DECLTYPE_(proto::eval(BOOST_PROTO_REF(proto::arg_c<0>(sexpr)), sctx) ++, result_type)
+ result_type operator()(Expr &expr, Context &ctx) const
+ {
+ return proto::eval(proto::arg_c<0>(expr), ctx) ++;
+ }
+ };
 
- #define N BOOST_PP_ITERATION()
+ // Handle post-decrement specially.
+ template<typename Expr, typename Context>
+ struct default_eval<Expr, Context, proto::tag::post_dec>
+ {
+ private:
+ static Expr &sexpr;
+ static Context &sctx;
+ public:
+ BOOST_PROTO_DECLTYPE_(proto::eval(BOOST_PROTO_REF(proto::arg_c<0>(sexpr)), sctx) --, result_type)
+ result_type operator()(Expr &expr, Context &ctx) const
+ {
+ return proto::eval(proto::arg_c<0>(expr), ctx) --;
+ }
+ };
 
- // Handle function specially
+ // Handle subscript specially.
         template<typename Expr, typename Context>
- struct default_eval<Expr, Context, proto::tag::function, N>
+ struct default_eval<Expr, Context, proto::tag::subscript>
         {
- typedef
- typename detail_::result_of_fixup<
- BOOST_PROTO_EVAL_N_TYPE(1, 0, (Expr, Context))
- >::type
- function_type;
+ private:
+ static Expr &sexpr;
+ static Context &sctx;
+ public:
+ BOOST_PROTO_DECLTYPE_(proto::eval(BOOST_PROTO_REF(proto::arg_c<0>(sexpr)), sctx)[proto::eval(BOOST_PROTO_REF(proto::arg_c<1>(sexpr)), sctx)], result_type)
+ result_type operator()(Expr &expr, Context &ctx) const
+ {
+ return proto::eval(proto::arg_c<0>(expr), ctx)[proto::eval(proto::arg_c<1>(expr), ctx)];
+ }
+ };
 
- typedef
- typename boost::result_of<
- function_type(
- BOOST_PP_ENUM_SHIFTED(N, BOOST_PROTO_EVAL_N_TYPE, (Expr, Context))
- )
- >::type
- result_type;
+ // Handle if_else_ specially.
+ template<typename Expr, typename Context>
+ struct default_eval<Expr, Context, proto::tag::if_else_>
+ {
+ private:
+ static Expr &sexpr;
+ static Context &sctx;
+ public:
+ BOOST_PROTO_DECLTYPE_(
+ proto::eval(BOOST_PROTO_REF(proto::arg_c<0>(sexpr)), sctx)
+ ? proto::eval(BOOST_PROTO_REF(proto::arg_c<1>(sexpr)), sctx)
+ : proto::eval(BOOST_PROTO_REF(proto::arg_c<2>(sexpr)), sctx)
+ , result_type
+ )
+ result_type operator()(Expr &expr, Context &ctx) const
+ {
+ return proto::eval(proto::arg_c<0>(expr), ctx)
+ ? proto::eval(proto::arg_c<1>(expr), ctx)
+ : proto::eval(proto::arg_c<2>(expr), ctx);
+ }
+ };
 
- result_type operator ()(Expr &expr, Context &context) const
+ // Handle comma specially.
+ template<typename Expr, typename Context>
+ struct default_eval<Expr, Context, proto::tag::comma>
+ {
+ typedef typename proto::result_of::eval<typename proto::result_of::arg_c<Expr, 0>::type, Context>::type proto_arg0;
+ typedef typename proto::result_of::eval<typename proto::result_of::arg_c<Expr, 1>::type, Context>::type proto_arg1;
+ typedef typename proto::detail::comma_result<proto_arg0, proto_arg1>::type result_type;
+ result_type operator()(Expr &expr, Context &ctx) const
             {
- return BOOST_PROTO_EVAL_N(1, 0, (expr, context))(
- BOOST_PP_ENUM_SHIFTED(N, BOOST_PROTO_EVAL_N, (expr, context))
- );
+ return proto::eval(proto::arg_c<0>(expr), ctx), proto::eval(proto::arg_c<1>(expr), ctx);
             }
         };
 
- #undef N
+ // Handle function specially
+ template<typename Expr, typename Context>
+ struct default_eval<Expr, Context, tag::function>
+ : proto::detail::default_eval_function_<
+ Expr
+ , Context
+ , typename op::detail::make_indices<Expr::proto_arity>::type
+ >
+ {};
+
+ /// default_context
+ ///
+ struct default_context
+ {
+ /// default_context::eval
+ ///
+ template<typename Expr, typename ThisContext = default_context const>
+ struct eval
+ : default_eval<Expr, ThisContext>
+ {};
+ };
+
+ } // namespace context
+
+}} // namespace boost::proto
 
 #endif

Modified: branches/proto/v3/boost/xpressive/proto3/expr.hpp
==============================================================================
--- branches/proto/v3/boost/xpressive/proto3/expr.hpp (original)
+++ branches/proto/v3/boost/xpressive/proto3/expr.hpp 2007-11-07 23:54:11 EST (Wed, 07 Nov 2007)
@@ -16,6 +16,11 @@
 
     namespace exprns_
     {
+ template<typename T, typename U>
+ void is_same_type(U const &)
+ {
+ BOOST_MPL_ASSERT((is_same<T,U>));
+ }
 
         template<typename Tag, typename Args, long Arity>
         struct expr
@@ -46,6 +51,7 @@
             template<typename... A>
             static expr make(A &&... a)
             {
+
                 expr that = {{a...}};
                 return that;
             }
@@ -65,7 +71,8 @@
             operator=(A &&a)
             {
                 expr<tag::assign, args<expr &, typename result_of::as_arg<A>::type> > that =
- {{*this, {proto::result_of::as_arg<A>::call(a)}}};
+ //{{*this, {proto::as_arg(std::forward<A>(a))}}};
+ {{*this, {a}}};
                 return that;
             }
 
@@ -74,7 +81,8 @@
             operator=(A &&a) const
             {
                 expr<tag::assign, args<expr const &, typename result_of::as_arg<A>::type> > that =
- {{*this, {proto::result_of::as_arg<A>::call(a)}}};
+ //{{*this, {proto::as_arg(std::forward<A>(a))}}};
+ {{*this, {a}}};
                 return that;
             }
 
@@ -83,7 +91,8 @@
             operator[](A &&a)
             {
                 expr<tag::subscript, args<expr &, typename result_of::as_arg<A>::type> > that =
- {{*this, {proto::result_of::as_arg<A>::call(a)}}};
+ //{{*this, {proto::as_arg(std::forward<A>(a))}}};
+ {{*this, {a}}};
                 return that;
             }
 
@@ -92,7 +101,8 @@
             operator[](A &&a) const
             {
                 expr<tag::subscript, args<expr const &, typename result_of::as_arg<A>::type> > that =
- {{*this, {proto::result_of::as_arg<A>::call(a)}}};
+ //{{*this, {proto::as_arg(std::forward<A>(a))}}};
+ {{*this, {a}}};
                 return that;
             }
 
@@ -101,7 +111,8 @@
             operator()(A &&... a)
             {
                 expr<tag::function, args<expr &, typename result_of::as_arg<A>::type...> > that =
- {argsns_::make_cons(*this, proto::result_of::as_arg<A>::call(a)...)};
+ {{*this, a...}};
+ //{argsns_::make_cons(*this, proto::as_arg(std::forward<A>(a))...)};
                 return that;
             }
 
@@ -110,7 +121,8 @@
             operator()(A &&... a) const
             {
                 expr<tag::function, args<expr const &, typename result_of::as_arg<A>::type...> > that =
- {argsns_::make_cons(*this, proto::result_of::as_arg<A>::call(a)...)};
+ {{*this, a...}};
+ //{argsns_::make_cons(*this, proto::as_arg(std::forward<A>(a))...)};
                 return that;
             }
         };

Modified: branches/proto/v3/boost/xpressive/proto3/operators.hpp
==============================================================================
--- branches/proto/v3/boost/xpressive/proto3/operators.hpp (original)
+++ branches/proto/v3/boost/xpressive/proto3/operators.hpp 2007-11-07 23:54:11 EST (Wed, 07 Nov 2007)
@@ -79,6 +79,8 @@
     #define BOOST_PROTO_UNARY_OP_IS_POSTFIX_0
     #define BOOST_PROTO_UNARY_OP_IS_POSTFIX_1 , int
 
+ // BUGBUG these are borken because of gcc bug wrt forwarding
+ // of built-in temporaries
     #define BOOST_PROTO_DEFINE_UNARY_OPERATOR(OP, TAG, POST) \
         template<typename A> \
         typename detail::generate_if< \
@@ -93,8 +95,8 @@
             typedef UNREF(A)::proto_domain D; \
             expr<TAG, args< \
                 typename result_of::as_arg<A, D>::type \
- > > that = {{proto::as_arg<D>(std::forward<A>(a))}}; \
- return that; \
+ > > that = {{a /*proto::as_arg<D>(std::forward<A>(a))*/}}; \
+ return D::make(that); \
         } \
         /**/
 
@@ -115,10 +117,10 @@
                 typename result_of::as_arg<A, D>::type \
               , typename result_of::as_arg<B, D>::type \
> > that = {{ \
- proto::as_arg<D>(std::forward<A>(a)) \
- , {proto::as_arg<D>(std::forward<B>(b))} \
+ a /*proto::as_arg<D>(std::forward<A>(a))*/ \
+ , {b /*proto::as_arg<D>(std::forward<B>(b))*/ } \
             }}; \
- return that; \
+ return D::make(that); \
         } \
         /**/
 

Modified: branches/proto/v3/boost/xpressive/proto3/proto_fwd.hpp
==============================================================================
--- branches/proto/v3/boost/xpressive/proto3/proto_fwd.hpp (original)
+++ branches/proto/v3/boost/xpressive/proto3/proto_fwd.hpp 2007-11-07 23:54:11 EST (Wed, 07 Nov 2007)
@@ -390,7 +390,7 @@
 
         struct default_context;
 
- template<typename Expr, typename Context, typename Tag = typename Expr::proto_tag, long Arity = Expr::proto_arity>
+ template<typename Expr, typename Context, typename Tag = typename Expr::proto_tag>
         struct default_eval;
 
         template<typename Derived, typename DefaultCtx = default_context>


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