Update of /cvsroot/boost/boost/boost/xpressive/proto
In directory
sc8-pr-cvs3.sourceforge.net:/tmp/cvs-serv15702/boost/xpressive/proto
Modified Files:
context.hpp expr.hpp fusion.hpp proto_fwd.hpp traits.hpp
Log Message:
redesign eval() and context to avoid premature return type calculation errors
Index: context.hpp
===================================================================
RCS file: /cvsroot/boost/boost/boost/xpressive/proto/context.hpp,v
retrieving revision 1.11
retrieving revision 1.12
diff -u -d -r1.11 -r1.12
--- context.hpp 24 Mar 2007 21:50:23 -0000 1.11
+++ context.hpp 26 Mar 2007 06:06:25 -0000 1.12
@@ -1,381 +1,370 @@
-#ifndef BOOST_PP_IS_ITERATING
-
///////////////////////////////////////////////////////////////////////////////
- /// \file context.hpp
- /// Definintion of context\<\>, a default evaluation context for
- /// expr\<\>::eval() that uses Boost.Typeof to deduce return types
- /// of the built-in operators.
- //
- // Copyright 2004 Eric Niebler. Distributed under the Boost
- // Software License, Version 1.0. (See accompanying file
- // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
-
- #ifndef BOOST_PROTO_CONTEXT_HPP_EAN_01_08_2007
- #define BOOST_PROTO_CONTEXT_HPP_EAN_01_08_2007
+///////////////////////////////////////////////////////////////////////////////
+/// \file context.hpp
+/// Definintion of context\<\>, a default evaluation context for
+/// expr\<\>::eval() that uses Boost.Typeof to deduce return types
+/// of the built-in operators.
+//
+// Copyright 2004 Eric Niebler. Distributed under the Boost
+// Software License, Version 1.0. (See accompanying file
+// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
- #include <boost/xpressive/proto/detail/prefix.hpp>
- #include <boost/preprocessor/cat.hpp>
- #include <boost/preprocessor/iteration/iterate.hpp>
- #include <boost/preprocessor/facilities/apply.hpp>
- #include <boost/preprocessor/facilities/intercept.hpp>
- #include <boost/preprocessor/repetition/enum_trailing_params.hpp>
- #include <boost/preprocessor/repetition/enum_binary_params.hpp>
- #include <boost/preprocessor/repetition/enum_trailing_binary_params.hpp>
- #include <boost/preprocessor/repetition/enum_shifted_params.hpp>
- #include <boost/preprocessor/repetition/enum_shifted_binary_params.hpp>
- #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/is_same.hpp>
- #include <boost/type_traits/is_function.hpp>
- #include <boost/type_traits/add_const.hpp>
- #include <boost/type_traits/add_reference.hpp>
- #include <boost/xpressive/proto/proto_fwd.hpp>
- #include <boost/xpressive/proto/tags.hpp>
- #include <boost/xpressive/proto/detail/suffix.hpp>
+#ifndef BOOST_PROTO_CONTEXT_HPP_EAN_01_08_2007
+#define BOOST_PROTO_CONTEXT_HPP_EAN_01_08_2007
- /// INTERNAL ONLY
- ///
- #define BOOST_PROTO_DECLTYPE_NESTED_TYPEDEF_TPL(Nested, Expr)\
- BOOST_TYPEOF_NESTED_TYPEDEF_TPL(nested_and_hidden, Expr)\
- struct Nested\
- : mpl::if_c<\
- 1==sizeof(detail::check_reference(Expr))\
- , typename nested_and_hidden::type &\
- , typename nested_and_hidden::type\
- >\
- {};\
- /**/
+#include <boost/xpressive/proto/detail/prefix.hpp>
+#include <boost/preprocessor/cat.hpp>
+#include <boost/preprocessor/iteration/iterate.hpp>
+#include <boost/preprocessor/facilities/apply.hpp>
+#include <boost/preprocessor/facilities/intercept.hpp>
+#include <boost/preprocessor/repetition/enum_trailing_params.hpp>
+#include <boost/preprocessor/repetition/enum_binary_params.hpp>
+#include <boost/preprocessor/repetition/enum_trailing_binary_params.hpp>
+#include <boost/preprocessor/repetition/enum_shifted_params.hpp>
+#include <boost/preprocessor/repetition/enum_shifted_binary_params.hpp>
+#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/is_same.hpp>
+#include <boost/type_traits/is_function.hpp>
+#include <boost/type_traits/add_const.hpp>
+#include <boost/type_traits/add_reference.hpp>
+#include <boost/xpressive/proto/proto_fwd.hpp>
+#include <boost/xpressive/proto/tags.hpp>
+#include <boost/xpressive/proto/detail/suffix.hpp>
- namespace boost { namespace proto
- {
- namespace detail
- {
- template<typename T> T make();
+#include <boost/xpressive/proto/fusion.hpp>
+#include <boost/fusion/functional/adapter/fused.hpp>
+#include <boost/fusion/sequence/view/transform_view.hpp>
+#include <boost/fusion/algorithm/transformation/pop_front.hpp>
+#include <boost/fusion/algorithm/transformation/push_front.hpp>
- template<typename T>
- char check_reference(T &);
+/// INTERNAL ONLY
+///
+#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\
+ >\
+ {};\
+ /**/
- template<typename T>
- char (&check_reference(T const &))[2];
+namespace boost { namespace proto
+{
+ namespace detail
+ {
+ template<typename T> T make();
- template<typename T>
- struct as_param
- : add_reference<typename add_const<T>::type>
- {};
+ template<typename T>
+ char check_reference(T &);
- template<typename T, typename U = T>
- struct result_of_fixup
- : mpl::if_<is_function<T>, T *, U>
- {};
+ template<typename T>
+ char (&check_reference(T const &))[2];
- template<typename T, typename U>
- struct result_of_fixup<T &, U>
- : result_of_fixup<T, T>
- {};
+ template<typename T>
+ struct as_param
+ : add_reference<typename add_const<T>::type>
+ {};
- template<typename T, typename U>
- struct result_of_fixup<T *, U>
- : result_of_fixup<T, U>
- {};
+ 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 const, U>
- : result_of_fixup<T, U>
- {};
+ template<typename T, typename U>
+ struct result_of_fixup<T &, U>
+ : result_of_fixup<T, T>
+ {};
- //// 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>));
+ 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_NESTED_TYPEDEF_TPL(nested,
(detail::make<A0>(), detail::make<A1>()))
- typedef typename nested::type 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>));
- template<typename A1>
- struct comma_result<void, A1>
- {
- typedef A1 type;
- };
+ template<typename A0, typename A1>
+ struct comma_result
+ {
+ BOOST_PROTO_DECLTYPE_NESTED_TYPEDEF_TPL(nested,
(detail::make<A0>(), detail::make<A1>()))
+ typedef typename nested::type type;
+ };
- template<>
- struct comma_result<void, void>
- {
- typedef void type;
- };
- }
+ template<typename A0>
+ struct comma_result<A0, void>
+ {
+ typedef void type;
+ };
- /// INTERNAL ONLY
- ///
- #define BOOST_PROTO_TYPEOF_UNARY(Op, Arg0, Type)\
- BOOST_PROTO_DECLTYPE_NESTED_TYPEDEF_TPL(nested, (Op
detail::make<Arg0>()))\
- typedef typename nested::type Type;\
- /**/
+ template<typename A1>
+ struct comma_result<void, A1>
+ {
+ typedef A1 type;
+ };
- /// INTERNAL ONLY
- ///
- #define BOOST_PROTO_TYPEOF_BINARY(Op, Arg0, Arg1, Type)\
- BOOST_PROTO_DECLTYPE_NESTED_TYPEDEF_TPL(nested, (detail::make<Arg0>()
Op detail::make<Arg1>()))\
- typedef typename nested::type Type;\
- /**/
+ template<>
+ struct comma_result<void, void>
+ {
+ typedef void type;
+ };
- template<typename Derived>
- struct context
+ template<typename Context>
+ struct eval_transform
{
- typedef typename mpl::if_<
- is_same<Derived, void>
- , context
- , Derived
- >::type derived_type;
+ eval_transform(Context &ctx)
+ : ctx_(ctx)
+ {}
- derived_type &cast()
+ template<typename Arg>
+ struct result
{
- return *static_cast<derived_type *>(this);
- }
-
- // BUGBUG Doxygen can't make any sense of the nested result<>
templates
- #ifndef BOOST_PROTO_DOXYGEN_INVOKED
-
- template<typename Sig>
- struct result;
+ typedef typename Context::template eval<typename
remove_cv_ref<Arg>::type>::result_type type;
+ };
- template<typename This, typename A0>
- struct result<This(proto::tag::terminal, A0 &)>
+ template<typename Arg>
+ typename result<Arg>::type operator()(Arg &arg) const
{
- typedef A0 &type;
- };
+ return arg.eval(ctx_);
+ }
- #define BOOST_PROTO_UNARY_OP_RESULT(Op, Tag)\
- template<typename This, typename A0>\
- struct result<This(Tag, A0 &)>\
- {\
- typedef typename proto::result_of::eval<A0,
derived_type>::type eval_type0;\
- BOOST_PROTO_TYPEOF_UNARY(Op, eval_type0, type)\
- static type call(typename detail::as_param<eval_type0>::type
a0)\
- {\
- return Op a0;\
- }\
- };\
- /**/
+ Context &ctx_;
+ };
+ }
- #define BOOST_PROTO_BINARY_OP_RESULT(Op, Tag)\
- template<typename This, typename A0, typename A1>\
- struct result<This(Tag, A0 &, A1 &)>\
- {\
- typedef typename proto::result_of::eval<A0,
derived_type>::type eval_type0;\
- typedef typename proto::result_of::eval<A1,
derived_type>::type eval_type1;\
- BOOST_PROTO_TYPEOF_BINARY(Op, eval_type0, eval_type1, type)\
- static type\
- call(typename detail::as_param<eval_type0>::type a0,
typename detail::as_param<eval_type1>::type a1)\
- {\
- return a0 Op a1;\
- }\
- };\
- /**/
+ /// INTERNAL ONLY
+ ///
+#define BOOST_PROTO_TYPEOF_2(Expr, Type)\
+ BOOST_PROTO_DECLTYPE_NESTED_TYPEDEF_TPL(BOOST_PP_CAT(nested_, Type),
(Expr))\
+ typedef typename BOOST_PP_CAT(nested_, Type)::type Type;\
+ /**/
- // GCC will ICE if we try to evaluate the typeof an op=
expression, like (i += 1)
- #if !BOOST_WORKAROUND(__GNUC__, BOOST_TESTED_AT(4))
- #define BOOST_PROTO_BINARY_OP_ASSIGN_RESULT(Op, Tag)\
- BOOST_PROTO_BINARY_OP_RESULT(Op, Tag)
- #else
- #define BOOST_PROTO_BINARY_OP_ASSIGN_RESULT(Op, Tag)\
- template<typename This, typename A0, typename A1>\
- struct result<This(Tag, A0 &, A1 &)>\
- {\
- typedef typename proto::result_of::eval<A0,
derived_type>::type eval_type0;\
- typedef typename proto::result_of::eval<A1,
derived_type>::type eval_type1;\
- typedef eval_type0 type;\
- static type\
- call(typename detail::as_param<eval_type0>::type a0,
typename detail::as_param<eval_type1>::type a1)\
- {\
- return a0 Op a1;\
- }\
- };\
- /**/
- #endif
+ template<typename Expr, typename Context, typename Tag = typename
Expr::tag_type>
+ struct default_eval;
- BOOST_PROTO_UNARY_OP_RESULT(+, proto::tag::unary_plus)
- BOOST_PROTO_UNARY_OP_RESULT(-, proto::tag::unary_minus)
- BOOST_PROTO_UNARY_OP_RESULT(*, proto::tag::unary_star)
- 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)
+ /// INTERNAL ONLY
+ ///
+#define BOOST_PROTO_UNARY_OP_RESULT_2(Op, Tag)\
+ template<typename Expr, typename Context>\
+ struct default_eval<Expr, Context, Tag>\
+ {\
+ static Expr const &sexpr;\
+ static Context &sctx;\
+ BOOST_PROTO_TYPEOF_2(Op proto::arg_c<0>(sexpr).eval(sctx),
result_type)\
+ result_type operator()(Expr const &expr, Context &ctx) const\
+ {\
+ return Op proto::arg_c<0>(expr).eval(ctx);\
+ }\
+ };\
+ /**/
- BOOST_PROTO_BINARY_OP_RESULT(<<, proto::tag::left_shift)
- BOOST_PROTO_BINARY_OP_RESULT(>>, proto::tag::right_shift)
- BOOST_PROTO_BINARY_OP_RESULT(*, proto::tag::multiply)
- BOOST_PROTO_BINARY_OP_RESULT(/, proto::tag::divide)
- BOOST_PROTO_BINARY_OP_RESULT(%, proto::tag::modulus)
- BOOST_PROTO_BINARY_OP_RESULT(+, proto::tag::add)
- BOOST_PROTO_BINARY_OP_RESULT(-, proto::tag::subtract)
- 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)
- BOOST_PROTO_BINARY_OP_RESULT(!=, proto::tag::not_equal)
- 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)
+ /// INTERNAL ONLY
+ ///
+#define BOOST_PROTO_BINARY_OP_RESULT_2(Op, Tag)\
+ template<typename Expr, typename Context>\
+ struct default_eval<Expr, Context, Tag>\
+ {\
+ static Expr const &sexpr;\
+ static Context &sctx;\
+ BOOST_PROTO_TYPEOF_2(proto::arg_c<0>(sexpr).eval(sctx) Op
proto::arg_c<1>(sexpr).eval(sctx), result_type)\
+ result_type operator()(Expr const &expr, Context &ctx) const\
+ {\
+ return proto::arg_c<0>(expr).eval(ctx) Op
proto::arg_c<1>(expr).eval(ctx);\
+ }\
+ };\
+ /**/
- BOOST_PROTO_BINARY_OP_ASSIGN_RESULT(<<=,
proto::tag::left_shift_assign)
- BOOST_PROTO_BINARY_OP_ASSIGN_RESULT(>>=,
proto::tag::right_shift_assign)
- BOOST_PROTO_BINARY_OP_ASSIGN_RESULT(*=,
proto::tag::multiply_assign)
- BOOST_PROTO_BINARY_OP_ASSIGN_RESULT(/=, proto::tag::divide_assign)
- BOOST_PROTO_BINARY_OP_ASSIGN_RESULT(%=, proto::tag::modulus_assign)
- BOOST_PROTO_BINARY_OP_ASSIGN_RESULT(+=, proto::tag::add_assign)
- BOOST_PROTO_BINARY_OP_ASSIGN_RESULT(-=,
proto::tag::subtract_assign)
- BOOST_PROTO_BINARY_OP_ASSIGN_RESULT(&=,
proto::tag::bitwise_and_assign)
- BOOST_PROTO_BINARY_OP_ASSIGN_RESULT(|=,
proto::tag::bitwise_or_assign)
- BOOST_PROTO_BINARY_OP_ASSIGN_RESULT(^=,
proto::tag::bitwise_xor_assign)
+ BOOST_PROTO_UNARY_OP_RESULT_2(+, proto::tag::unary_plus)
+ BOOST_PROTO_UNARY_OP_RESULT_2(-, proto::tag::unary_minus)
+ BOOST_PROTO_UNARY_OP_RESULT_2(*, proto::tag::unary_star)
+ BOOST_PROTO_UNARY_OP_RESULT_2(~, proto::tag::complement)
+ BOOST_PROTO_UNARY_OP_RESULT_2(&, proto::tag::address_of)
+ BOOST_PROTO_UNARY_OP_RESULT_2(!, proto::tag::logical_not)
+ BOOST_PROTO_UNARY_OP_RESULT_2(++, proto::tag::pre_inc)
+ BOOST_PROTO_UNARY_OP_RESULT_2(--, proto::tag::pre_dec)
- #undef BOOST_PROTO_UNARY_OP_RESULT
- #undef BOOST_PROTO_BINARY_OP_RESULT
- #undef BOOST_PROTO_BINARY_OP_ASSIGN_RESULT
+ BOOST_PROTO_BINARY_OP_RESULT_2(<<, proto::tag::left_shift)
+ BOOST_PROTO_BINARY_OP_RESULT_2(>>, proto::tag::right_shift)
+ BOOST_PROTO_BINARY_OP_RESULT_2(*, proto::tag::multiply)
+ BOOST_PROTO_BINARY_OP_RESULT_2(/, proto::tag::divide)
+ BOOST_PROTO_BINARY_OP_RESULT_2(%, proto::tag::modulus)
+ BOOST_PROTO_BINARY_OP_RESULT_2(+, proto::tag::add)
+ BOOST_PROTO_BINARY_OP_RESULT_2(-, proto::tag::subtract)
+ BOOST_PROTO_BINARY_OP_RESULT_2(<, proto::tag::less)
+ BOOST_PROTO_BINARY_OP_RESULT_2(>, proto::tag::greater)
+ BOOST_PROTO_BINARY_OP_RESULT_2(<=, proto::tag::less_equal)
+ BOOST_PROTO_BINARY_OP_RESULT_2(>=, proto::tag::greater_equal)
+ BOOST_PROTO_BINARY_OP_RESULT_2(==, proto::tag::equal)
+ BOOST_PROTO_BINARY_OP_RESULT_2(!=, proto::tag::not_equal)
+ BOOST_PROTO_BINARY_OP_RESULT_2(||, proto::tag::logical_or)
+ BOOST_PROTO_BINARY_OP_RESULT_2(&&, proto::tag::logical_and)
+ BOOST_PROTO_BINARY_OP_RESULT_2(&, proto::tag::bitwise_and)
+ BOOST_PROTO_BINARY_OP_RESULT_2(|, proto::tag::bitwise_or)
+ BOOST_PROTO_BINARY_OP_RESULT_2(^, proto::tag::bitwise_xor)
+ BOOST_PROTO_BINARY_OP_RESULT_2(->*, proto::tag::mem_ptr)
+ BOOST_PROTO_BINARY_OP_RESULT_2(=, proto::tag::assign)
- // Handle comma specially.
- template<typename This, typename A0, typename A1>
- struct result<This(proto::tag::comma, A0 &, A1 &)>
- {
- typedef typename proto::result_of::eval<A0,
derived_type>::type eval_type0;
- typedef typename proto::result_of::eval<A1,
derived_type>::type eval_type1;
- typedef typename detail::comma_result<eval_type0,
eval_type1>::type type;
- };
+ BOOST_PROTO_BINARY_OP_RESULT_2(<<=, proto::tag::left_shift_assign)
+ BOOST_PROTO_BINARY_OP_RESULT_2(>>=, proto::tag::right_shift_assign)
+ BOOST_PROTO_BINARY_OP_RESULT_2(*=, proto::tag::multiply_assign)
+ BOOST_PROTO_BINARY_OP_RESULT_2(/=, proto::tag::divide_assign)
+ BOOST_PROTO_BINARY_OP_RESULT_2(%=, proto::tag::modulus_assign)
+ BOOST_PROTO_BINARY_OP_RESULT_2(+=, proto::tag::add_assign)
+ BOOST_PROTO_BINARY_OP_RESULT_2(-=, proto::tag::subtract_assign)
+ BOOST_PROTO_BINARY_OP_RESULT_2(&=, proto::tag::bitwise_and_assign)
+ BOOST_PROTO_BINARY_OP_RESULT_2(|=, proto::tag::bitwise_or_assign)
+ BOOST_PROTO_BINARY_OP_RESULT_2(^=, proto::tag::bitwise_xor_assign)
- // Handle post-increment specially.
- template<typename This, typename A0>
- struct result<This(proto::tag::post_inc, A0 &)>
- {
- typedef typename proto::result_of::eval<A0,
derived_type>::type eval_type0;
- BOOST_PROTO_DECLTYPE_NESTED_TYPEDEF_TPL(nested,
(detail::make<eval_type0>() ++))
- typedef typename nested::type type;
- static type call(typename detail::as_param<eval_type0>::type
a0)
- {
- return a0 ++;
- }
- };
+ template<typename Expr, typename Context>
+ struct default_eval<Expr, Context, proto::tag::terminal>
+ {
+ typedef typename proto::result_of::arg<Expr>::const_reference
result_type;
+ result_type operator()(Expr const &expr, Context &) const
+ {
+ return proto::arg(expr);
+ }
+ };
- // Handle post-decrement specially.
- template<typename This, typename A0>
- struct result<This(proto::tag::post_dec, A0 &)>
- {
- typedef typename proto::result_of::eval<A0,
derived_type>::type eval_type0;
- BOOST_PROTO_DECLTYPE_NESTED_TYPEDEF_TPL(nested,
(detail::make<eval_type0>() --))
- typedef typename nested::type type;
- static type call(typename detail::as_param<eval_type0>::type
a0)
- {
- return a0 --;
- }
- };
+ // Handle comma specially.
+ template<typename Expr, typename Context>
+ struct default_eval<Expr, Context, proto::tag::comma>
+ {
+ typedef typename result_of::eval<typename result_of::arg_c<Expr,
0>::type, Context>::type arg0_type;
+ typedef typename result_of::eval<typename result_of::arg_c<Expr,
1>::type, Context>::type arg1_type;
+ typedef typename detail::comma_result<arg0_type, arg1_type>::type
result_type;
- // Handle subscript specially.
- template<typename This, typename A0, typename A1>
- struct result<This(proto::tag::subscript, A0 &, A1 &)>
- {
- typedef typename proto::result_of::eval<A0,
derived_type>::type eval_type0;
- typedef typename proto::result_of::eval<A1,
derived_type>::type eval_type1;
- BOOST_PROTO_DECLTYPE_NESTED_TYPEDEF_TPL(nested,
(detail::make<eval_type0>() [ detail::make<eval_type1>() ] ))
- typedef typename nested::type type;
- static type call(typename detail::as_param<eval_type0>::type
a0, typename detail::as_param<eval_type1>::type a1)
- {
- return a0 [ a1 ];
- }
- };
+ result_type operator()(Expr const &expr, Context &ctx) const
+ {
+ return proto::arg_c<0>(expr).eval(ctx),
proto::arg_c<1>(expr).eval(ctx);
+ }
+ };
- #else // BOOST_PROTO_DOXYGEN_INVOKED
+ // Handle post-increment specially.
+ template<typename Expr, typename Context>
+ struct default_eval<Expr, Context, proto::tag::post_inc>
+ {
+ static Expr const &sexpr;
+ static Context &sctx;
+ BOOST_PROTO_TYPEOF_2(proto::arg_c<0>(sexpr).eval(sctx) ++, result_type)
+ result_type operator()(Expr const &expr, Context &ctx) const
+ {
+ return proto::arg_c<0>(expr).eval(ctx) ++;
+ }
+ };
- /// Calculates the return type of context\<\>::operator()
- ///
- template<typename Sig>
- struct result
- {
- typedef detail::unspecified type;
- };
+ // Handle post-decrement specially.
+ template<typename Expr, typename Context>
+ struct default_eval<Expr, Context, proto::tag::post_dec>
+ {
+ static Expr const &sexpr;
+ static Context &sctx;
+ BOOST_PROTO_TYPEOF_2(proto::arg_c<0>(sexpr).eval(sctx) --, result_type)
+ result_type operator()(Expr const &expr, Context &ctx) const
+ {
+ return proto::arg_c<0>(expr).eval(ctx) --;
+ }
+ };
- #endif // BOOST_PROTO_DOXYGEN_INVOKED
+ // Handle subscript specially.
+ template<typename Expr, typename Context>
+ struct default_eval<Expr, Context, proto::tag::subscript>
+ {
+ static Expr const &sexpr;
+ static Context &sctx;
+
BOOST_PROTO_TYPEOF_2(proto::arg_c<0>(sexpr).eval(sctx)[proto::arg_c<1>(sexpr).eval(sctx)],
result_type)
+ result_type operator()(Expr const &expr, Context &ctx) const
+ {
+ return
proto::arg_c<0>(expr).eval(ctx)[proto::arg_c<1>(expr).eval(ctx)];
+ }
+ };
- template<typename A0>
- A0 &
- operator()(proto::tag::terminal, A0 &a0)
- {
- return a0;
- }
+ // Handle function specially.
+ template<typename Expr, typename Context>
+ struct default_eval<Expr, Context, proto::tag::function>
+ {
+ static Expr const &sexpr;
+ static Context &sctx;
+ BOOST_PROTO_TYPEOF_2(proto::arg_c<0>(sexpr).eval(sctx), function_type)
+ typedef
+ typename fusion::fused<function_type>
+ ::template result<
+ fusion::transform_view<
+ typename fusion::result_of::pop_front<ref<Expr const>
>::type const
+ , detail::eval_transform<Context>
+ >
+ >
+ ::type
+ result_type;
+ result_type operator()(Expr const &expr, Context &ctx) const
+ {
+ ref<Expr const> ref_expr = {expr};
+ return
fusion::fused<function_type>(proto::arg_c<0>(expr).eval(ctx))
+ (
+ fusion::transform_view<
+ typename fusion::result_of::pop_front<ref<Expr const>
>::type const
+ , detail::eval_transform<Context>
+ >(
+ fusion::pop_front(ref_expr)
+ , detail::eval_transform<Context>(ctx)
+ )
+ );
+ }
+ };
- #define BOOST_PROTO_ARG(z, n, data)\
- typedef\
- typename proto::result_of::eval<BOOST_PP_CAT(A, n),
derived_type>::type\
- BOOST_PP_CAT(eval_type, n);\
- /**/
+ /// default_context
+ ///
+ struct default_context
+ {
+ template<typename Expr>
+ struct eval
+ : default_eval<Expr, default_context>
+ {};
+ };
- #define BOOST_PP_ITERATION_PARAMS_1 (3, (1, BOOST_PROTO_MAX_ARITY,
<boost/xpressive/proto/context.hpp>))
- #include BOOST_PP_ITERATE()
- #undef BOOST_PROTO_ARG
+ /// fanout_context
+ ///
+ template<typename Derived>
+ struct fanout_context
+ {
+ template<typename Expr>
+ struct eval
+ {
+ typedef typename fusion::fused<Derived &>::template result<
+ typename fusion::result_of::push_front<proto::ref<Expr const>,
typename Expr::tag_type>::type const
+ >::type result_type;
- template<typename A0, typename A1>
- typename boost::result_of<derived_type(proto::tag::comma, A0 &, A1
&)>::type
- operator()(proto::tag::comma, A0 &a0, A1 &a1)
+ result_type operator()(Expr const &expr, Derived &ctx)
{
- return a0.eval(this->cast()), a1.eval(this->cast());
+ proto::ref<Expr const> ref = {expr};
+ return fusion::fused<Derived &>(ctx)(fusion::push_front(ref,
typename Expr::tag_type()));
}
- };
-
- }}
-
- #endif
-
-#else
-
- #define N BOOST_PP_ITERATION()
-
- // BUGBUG Doxygen can't make any sense of the nested result<>
templates
- #ifndef BOOST_PROTO_DOXYGEN_INVOKED
- template<typename This BOOST_PP_ENUM_TRAILING_PARAMS(N, typename
A)>
- struct result<This(proto::tag::function
BOOST_PP_ENUM_TRAILING_BINARY_PARAMS(N, A, & BOOST_PP_INTERCEPT))>
- {
- BOOST_PP_REPEAT(N, BOOST_PROTO_ARG, ~)
- typedef typename detail::result_of_fixup<eval_type0>::type
function_type;
- typedef typename boost::result_of<function_type(
BOOST_PP_ENUM_SHIFTED_PARAMS(N, eval_type) )>::type type;
- static type call(
- BOOST_PP_ENUM_BINARY_PARAMS(N, typename
detail::as_param<eval_type, >::type a)
- )
- {
- return a0 ( BOOST_PP_ENUM_SHIFTED_PARAMS(N, a) );
- }
- };
- #endif
- template<typename Tag BOOST_PP_ENUM_TRAILING_PARAMS(N, typename A)>
- typename boost::result_of<derived_type(Tag
BOOST_PP_ENUM_TRAILING_BINARY_PARAMS(N, A, & BOOST_PP_INTERCEPT))>::type
- operator()(Tag BOOST_PP_ENUM_TRAILING_BINARY_PARAMS(N, A, & a))
+ result_type operator()(Expr const &expr, Derived const &ctx)
{
- return result<derived_type(Tag, BOOST_PP_ENUM_BINARY_PARAMS(N,
A, & BOOST_PP_INTERCEPT))>::call(
- BOOST_PP_ENUM_BINARY_PARAMS(N, a, .eval(this->cast())
BOOST_PP_INTERCEPT)
- );
+ proto::ref<Expr const> ref = {expr};
+ return fusion::fused<Derived const
&>(ctx)(fusion::push_front(ref, typename Expr::tag_type()));
}
+ };
+ };
- #undef N
+}}
#endif
+
Index: expr.hpp
===================================================================
RCS file: /cvsroot/boost/boost/boost/xpressive/proto/expr.hpp,v
retrieving revision 1.26
retrieving revision 1.27
diff -u -d -r1.26 -r1.27
--- expr.hpp 18 Mar 2007 00:29:11 -0000 1.26
+++ expr.hpp 26 Mar 2007 06:06:25 -0000 1.27
@@ -143,17 +143,17 @@
}
template<typename Fun>
- typename boost::result_of<Fun(Tag
BOOST_PP_ENUM_TRAILING(BOOST_PP_ITERATION(), BOOST_PROTO_UNREF_ARG_TYPE,
~))>::type
+ typename Fun::template eval<expr>::result_type
eval(Fun &fun) const
{
- return fun(Tag() BOOST_PP_ENUM_TRAILING(BOOST_PP_ITERATION(),
BOOST_PROTO_UNREF_ARG, ~));
+ return typename Fun::template eval<expr>()(*this, fun);
}
template<typename Fun>
- typename boost::result_of<Fun const(Tag
BOOST_PP_ENUM_TRAILING(BOOST_PP_ITERATION(), BOOST_PROTO_UNREF_ARG_TYPE,
~))>::type
+ typename Fun::template eval<expr>::result_type
eval(Fun const &fun) const
{
- return fun(Tag(), BOOST_PP_ENUM(BOOST_PP_ITERATION(),
BOOST_PROTO_UNREF_ARG, ~));
+ return typename Fun::template eval<expr>()(*this, fun);
}
template<typename A>
Index: fusion.hpp
===================================================================
RCS file: /cvsroot/boost/boost/boost/xpressive/proto/fusion.hpp,v
retrieving revision 1.21
retrieving revision 1.22
diff -u -d -r1.21 -r1.22
--- fusion.hpp 3 Feb 2007 00:14:33 -0000 1.21
+++ fusion.hpp 26 Mar 2007 06:06:25 -0000 1.22
@@ -189,9 +189,8 @@
{
template<typename Sequence>
struct apply
- {
- typedef typename Sequence::arity type;
- };
+ : Sequence::arity
+ {};
};
template<typename Tag>
Index: proto_fwd.hpp
===================================================================
RCS file: /cvsroot/boost/boost/boost/xpressive/proto/proto_fwd.hpp,v
retrieving revision 1.55
retrieving revision 1.56
diff -u -d -r1.55 -r1.56
--- proto_fwd.hpp 20 Mar 2007 03:04:14 -0000 1.55
+++ proto_fwd.hpp 26 Mar 2007 06:06:25 -0000 1.56
@@ -250,8 +250,10 @@
template<typename Expr, typename Derived, typename Domain = default_domain>
struct extends;
- template<typename Derived = void>
- struct context;
+ struct default_context;
+
+ template<typename Derived>
+ struct fanout_context;
template<typename T, typename Domain = default_domain>
struct literal;
@@ -291,7 +293,7 @@
template<typename T>
struct unref;
- template<typename Expr, typename Fun, long Arity = Expr::arity::value>
+ template<typename Expr, typename Context>
struct eval;
}
Index: traits.hpp
===================================================================
RCS file: /cvsroot/boost/boost/boost/xpressive/proto/traits.hpp,v
retrieving revision 1.43
retrieving revision 1.44
diff -u -d -r1.43 -r1.44
--- traits.hpp 12 Mar 2007 22:11:30 -0000 1.43
+++ traits.hpp 26 Mar 2007 06:06:25 -0000 1.44
@@ -137,6 +137,13 @@
: unref<typename Expr::arg1_type>
{};
+ // eval
+ template<typename Expr, typename Context>
+ struct eval
+ {
+ typedef typename Context::template eval<Expr>::result_type
type;
+ };
+
}
namespace detail
@@ -535,13 +542,6 @@
namespace result_of
{
- #if N > 0
- template<typename Expr, typename Fun>
- struct eval<Expr, Fun, N>
- : boost::result_of<Fun(typename Expr::tag_type
BOOST_PP_ENUM_TRAILING(N, BOOST_PROTO_ARG_N_TYPE, ~))>
- {};
- #endif
-
template<typename Expr>
struct arg_c<Expr, N>
: unref<typename Expr::BOOST_PP_CAT(BOOST_PP_CAT(arg, N), _type)>
-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys-and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
_______________________________________________
Boost-cvs mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/boost-cvs