$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
From: eric_at_[hidden]
Date: 2008-05-25 23:53:10
Author: eric_niebler
Date: 2008-05-25 23:53:09 EDT (Sun, 25 May 2008)
New Revision: 45762
URL: http://svn.boost.org/trac/boost/changeset/45762
Log:
better local_variable<> and let() implementation
Text files modified: 
   branches/proto/v4/boost/phoenix/core/value.hpp           |    25 ++++++++                                
   branches/proto/v4/boost/phoenix/scope/let.hpp            |   112 +++++++++++++++++++++++++++++++++------ 
   branches/proto/v4/boost/phoenix/scope/local_variable.hpp |    34 +++++------                             
   3 files changed, 134 insertions(+), 37 deletions(-)
Modified: branches/proto/v4/boost/phoenix/core/value.hpp
==============================================================================
--- branches/proto/v4/boost/phoenix/core/value.hpp	(original)
+++ branches/proto/v4/boost/phoenix/core/value.hpp	2008-05-25 23:53:09 EDT (Sun, 25 May 2008)
@@ -11,10 +11,17 @@
 #include <boost/phoenix/core/limits.hpp>
 #include <boost/phoenix/core/actor.hpp>
 #include <boost/phoenix/core/reference.hpp>
+#include <boost/type_traits/remove_reference.hpp>
 
 namespace boost { namespace phoenix
 {
     ////////////////////////////////////////////////////////////////////////////////////////////
+    namespace tag
+    {
+        struct byval {};
+    }
+
+    ////////////////////////////////////////////////////////////////////////////////////////////
     template<typename T>
     struct value
       : proto::terminal<T>::type
@@ -53,6 +60,24 @@
     {
         return reference<T const[N]>(t);
     }
+    
+    ////////////////////////////////////////////////////////////////////////////////////////////
+    template<typename Expr>
+    actor<typename proto::unary_expr<tag::byval, actor<Expr> const &>::type> const
+    val(actor<Expr> const &expr)
+    {
+        actor<typename proto::unary_expr<tag::byval, actor<Expr> const &>::type> that = {{expr}};
+        return that;
+    }
+    
+    ////////////////////////////////////////////////////////////////////////////////////////////
+    template<>
+    struct extension<tag::byval>
+      : proto::when<
+            proto::unary_expr<tag::byval, evaluator>
+          , remove_reference<evaluator(proto::_child)>(evaluator(proto::_child))
+        >
+    {};
 
 }}
 
Modified: branches/proto/v4/boost/phoenix/scope/let.hpp
==============================================================================
--- branches/proto/v4/boost/phoenix/scope/let.hpp	(original)
+++ branches/proto/v4/boost/phoenix/scope/let.hpp	2008-05-25 23:53:09 EDT (Sun, 25 May 2008)
@@ -12,6 +12,10 @@
     #include <boost/preprocessor.hpp>
     #include <boost/fusion/include/map.hpp>
     #include <boost/fusion/include/fold.hpp>
+    #include <boost/fusion/include/pair.hpp>
+    #include <boost/fusion/include/as_map.hpp>
+    #include <boost/fusion/include/at_key.hpp>
+    #include <boost/fusion/include/transform.hpp>
     #include <boost/phoenix/scope/local_variable.hpp>
 
     namespace boost { namespace phoenix
@@ -50,19 +54,100 @@
             };
 
             ////////////////////////////////////////////////////////////////////////////////////////
-            template<typename Map, typename State>
+            template<typename State, typename Data>
+            struct initialize_locals
+            {
+                explicit initialize_locals(State state, Data data)
+                  : state(state)
+                  , data(data)
+                {}
+
+                template<typename Sig>
+                struct result;
+
+                template<typename This, typename That>
+                struct result<This(That &)>
+                  : result<This(That)>
+                {};
+
+                template<typename This, typename First, typename Second>
+                struct result<This(fusion::pair<First, Second>)>
+                {
+                    typedef
+                        fusion::pair<
+                            First
+                          , typename boost::result_of<evaluator(Second, State, Data)>::type
+                        >
+                    type;
+                };
+
+                template<typename First, typename Second>
+                fusion::pair<
+                    First
+                  , typename boost::result_of<evaluator(Second, State, Data)>::type
+                > const
+                operator()(fusion::pair<First, Second> const &p) const
+                {
+                    typedef
+                        fusion::pair<
+                            First
+                          , typename boost::result_of<evaluator(Second, State, Data)>::type
+                        >
+                    pair_type;
+                    return pair_type(evaluator()(p.second, this->state, this->data));
+                }
+
+            private:
+                State state;
+                Data data;
+            };
+
+            ////////////////////////////////////////////////////////////////////////////////////////
+            template<typename Map, typename State, typename Data>
             struct scope
             {
-                scope(Map const &map, State const &state)
-                  : map(map)
-                  , state(state)
+                typedef typename remove_reference<State>::type state_type;
+
+                typedef typename
+                    fusion::result_of::as_map<typename
+                        fusion::result_of::transform<
+                            typename remove_reference<Map>::type
+                          , initialize_locals<State, Data>
+                        >::type
+                    >::type
+                locals_type;
+
+                scope(Map map, State state, Data data)
+                  : state(state)
+                  , data(data)
+                  , locals(fusion::as_map(fusion::transform(map, initialize_locals<State, Data>(state, data))))
                 {}
 
-                typedef Map const map_type;
-                typedef State const state_type;
+                State state;                // outer state
+                Data data;                  // outer data
+                mutable locals_type locals; // Local variables
+            };
 
-                Map const ↦        // local variables map
-                State const &state;    // outer state
+            ////////////////////////////////////////////////////////////////////////////////////////
+            struct make_scope
+              : proto::transform<make_scope>
+            {
+                template<typename Expr, typename State, typename Data>
+                struct impl
+                  : proto::transform_impl<Expr, State, Data>
+                {
+                    typedef typename proto::result_of::value<Expr>::type map_type;
+                    typedef scope<map_type, typename impl::state_param, Data> result_type;
+
+                    result_type operator()(
+                        typename impl::expr_param expr
+                      , typename impl::state_param state
+                      , typename impl::data_param data
+                    ) const
+                    {
+                        return result_type(proto::value(expr), state, data);
+                    }
+                };
             };
 
             ////////////////////////////////////////////////////////////////////////////////////////
@@ -88,16 +173,7 @@
         struct extension<tag::let_, void>
           : proto::when<
                 proto::binary_expr<tag::let_, proto::terminal<proto::_>, evaluator>
-              , evaluator(
-                    proto::_right
-                  , proto::make<
-                        detail::scope<proto::_value(proto::_left), proto::_state>(
-                            proto::_value(proto::_left)
-                          , proto::_state
-                        )
-                    >
-                  , proto::_data
-                )
+              , evaluator(proto::_right, detail::make_scope(proto::_left), proto::_data)
             >
         {};
 
Modified: branches/proto/v4/boost/phoenix/scope/local_variable.hpp
==============================================================================
--- branches/proto/v4/boost/phoenix/scope/local_variable.hpp	(original)
+++ branches/proto/v4/boost/phoenix/scope/local_variable.hpp	2008-05-25 23:53:09 EDT (Sun, 25 May 2008)
@@ -8,6 +8,7 @@
 #ifndef BOOST_PHOENIX_SCOPE_LOCAL_VARIABLE_HPP_EAN_2008_05_21
 #define BOOST_PHOENIX_SCOPE_LOCAL_VARIABLE_HPP_EAN_2008_05_21
 
+#include <boost/ref.hpp>
 #include <boost/phoenix/core/actor.hpp>
 #include <boost/fusion/include/map.hpp>
 
@@ -28,30 +29,32 @@
         template<
             typename Tag
           , typename State
-          , typename Map = typename State::map_type
-          , typename Elem = typename fusion::result_of::at_key<Map, Tag>::type
+          , bool HasKey = fusion::result_of::has_key<typename State::locals_type, Tag>::type::value
         >
-        struct lookup
+        struct find_local
         {
-            typedef Elem result_type;
+            typedef typename
+                fusion::result_of::at_key<typename State::locals_type, Tag>::type
+            result_type;
 
             result_type operator()(State &state) const
             {
-                return fusion::at_key<Tag>(state.map);
+                return fusion::at_key<Tag>(state.locals);
             }
         };
 
         ////////////////////////////////////////////////////////////////////////////////////////////
         // Find a variable in an outer scope
-        template<typename Tag, typename State, typename Map>
-        struct lookup<Tag, State, Map, fusion::void_ const &>
+        template<typename Tag, typename State>
+        struct find_local<Tag, State, false>
         {
-            typedef typename State::state_type that_state;
-            typedef typename lookup<Tag, that_state>::result_type result_type;
+            typedef typename
+                find_local<Tag, typename State::state_type>::result_type
+            result_type;
 
             result_type operator()(State &state) const
             {
-                return lookup<Tag, that_state>()(state.state);
+                return find_local<Tag, typename State::state_type>()(state.state);
             }
         };
 
@@ -64,15 +67,8 @@
             struct impl
               : proto::transform_impl<Expr, State, Data>
             {
-                typedef typename impl::state this_state;
-                typedef typename state::state_type that_state;
-
-                typedef
-                    typename lookup<Tag, this_state>::result_type
-                local_var_init;
-
                 typedef
-                    typename result_of<evaluator(local_var_init, that_state &, Data)>::type
+                    typename find_local<Tag, typename impl::state>::result_type
                 result_type;
 
                 result_type operator()(
@@ -81,7 +77,7 @@
                   , typename impl::data_param data
                 ) const
                 {
-                    return evaluator()(lookup<Tag, this_state>()(state), state.state, data);
+                    return find_local<Tag, typename impl::state>()(state);
                 }
             };
         };