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

Reply via email to