Boost logo

Boost-Commit :

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 &map; // 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);
                 }
             };
         };


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