Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:46:33

0001 /*==============================================================================
0002     Copyright (c) 2001-2010 Joel de Guzman
0003     Copyright (c) 2004 Daniel Wallin
0004     Copyright (c) 2010 Thomas Heller
0005     Copyright (c) 2015 John Fletcher
0006 
0007     Distributed under the Boost Software License, Version 1.0. (See accompanying
0008     file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
0009 ==============================================================================*/
0010 #ifndef BOOST_PHOENIX_SCOPE_LET_HPP
0011 #define BOOST_PHOENIX_SCOPE_LET_HPP
0012 
0013 //#include <boost/assert.hpp>
0014 //#include <sstream>
0015 #include <boost/phoenix/core/limits.hpp>
0016 #include <boost/fusion/include/transform.hpp>
0017 #include <boost/fusion/include/as_vector.hpp>
0018 #include <boost/phoenix/core/call.hpp>
0019 #include <boost/phoenix/core/expression.hpp>
0020 #include <boost/phoenix/core/meta_grammar.hpp>
0021 #include <boost/phoenix/scope/scoped_environment.hpp>
0022 #include <boost/phoenix/scope/local_variable.hpp>
0023 #include <boost/phoenix/support/iterate.hpp>
0024 #include <boost/phoenix/support/vector.hpp>
0025 
0026 BOOST_PHOENIX_DEFINE_EXPRESSION(
0027     (boost)(phoenix)(let_)
0028   , (proto::terminal<proto::_>) // Locals
0029     (proto::terminal<proto::_>) // Map
0030     (meta_grammar)
0031 )
0032 
0033 namespace boost { namespace phoenix
0034 {
0035     struct let_eval
0036     {
0037           template <typename Sig>
0038           struct result;
0039 
0040           template <typename This, typename Vars, typename Map, typename Expr, typename Context>
0041           struct result<This(Vars, Map, Expr, Context)>
0042           {
0043             typedef
0044                 typename proto::detail::uncvref<
0045                     typename result_of::env<Context>::type
0046                 >::type
0047                 env_type;
0048             typedef
0049                 typename proto::detail::uncvref<
0050                     typename result_of::actions<Context>::type
0051                 >::type
0052                 actions_type;
0053             typedef
0054                 typename proto::detail::uncvref<
0055                     typename proto::result_of::value<Vars>::type
0056                      >::type
0057                      vars_type;
0058             typedef
0059                 typename proto::detail::uncvref<
0060                     typename proto::result_of::value<Map>::type
0061                      >::type
0062                      map_type;
0063 
0064             typedef
0065                 typename proto::detail::uncvref<Expr>::type
0066                      expr_type;
0067             
0068             typedef typename
0069                 detail::result_of::initialize_locals<
0070                     vars_type
0071                   , Context
0072                 >::type
0073             locals_type;
0074 
0075             typedef typename
0076                 result_of::eval<
0077                     expr_type
0078                   , typename result_of::context<
0079                         scoped_environment<
0080                             env_type
0081                           , env_type
0082                           , locals_type
0083                           , map_type
0084                         >
0085                       , actions_type
0086                     >::type
0087                 >::type
0088                 type;
0089           };
0090 
0091         template <typename Vars, typename Map, typename Expr, typename Context>
0092         typename result<let_eval(Vars const&, Map const&, Expr const &, Context const &)>::type const
0093         operator()(Vars const & vars, Map, Expr const & expr, Context const & ctx) const
0094         {
0095             Vars vars_(vars);
0096 
0097             typedef
0098                 typename proto::detail::uncvref<
0099                     typename result_of::env<Context>::type
0100                 >::type
0101                 env_type;
0102             typedef
0103                 typename proto::detail::uncvref<
0104                     typename proto::result_of::value<Vars>::type
0105                 >::type
0106                 vars_type;
0107             typedef
0108                 typename proto::detail::uncvref<
0109                     typename proto::result_of::value<Map>::type
0110                 >::type
0111                 map_type;
0112             
0113             typedef typename 
0114                 detail::result_of::initialize_locals<
0115                     vars_type
0116                   , Context
0117                 >::type
0118             locals_type;
0119 
0120             locals_type locals = initialize_locals(proto::value(vars_), ctx);
0121 
0122             //typedef typename result<let_eval(Vars const&, Map const&, Expr const &, Context const &)>::type result_type;
0123 
0124             scoped_environment<
0125                 env_type
0126               , env_type
0127               , locals_type
0128               , map_type
0129             >
0130             env(phoenix::env(ctx), phoenix::env(ctx), locals);
0131 
0132             // Fix for bugs (trial)
0133             // The idea is to do something which will not be optimised away.
0134             //int vsize = boost::fusion::size(vars);
0135             //std::stringstream strm;
0136             //strm << vsize << std::endl;
0137             //int size = strm.str().length();
0138             //BOOST_ASSERT(size >= 0);
0139             return eval(expr, phoenix::context(env, phoenix::actions(ctx)));
0140             // typedef is_value<result_type> is_val;
0141             //if(is_val::value) This seems always to be true
0142             //{
0143             //   std::cout << "let result has value type" << std::endl;
0144             // }
0145             //if (is_val(r) ) std::cout << "let returns val" << std::endl;
0146             //std::cout << "result is " << r << std::endl;
0147             //return r;
0148         }
0149     };
0150 
0151     template <typename Dummy>
0152     struct default_actions::when<rule::let_, Dummy>
0153         : call<let_eval, Dummy>
0154     {};
0155 
0156     template <typename Locals, typename Map>
0157     struct let_actor_gen
0158     {
0159         let_actor_gen(Locals const & locals_)
0160             : locals(locals_)
0161         {}
0162 
0163         let_actor_gen(let_actor_gen const & o)
0164             : locals(o.locals)
0165         {}
0166 
0167         template <typename Expr>
0168         typename expression::let_<
0169             Locals
0170           , Map
0171           , Expr
0172         >::type const
0173         operator[](Expr const & expr) const
0174         {
0175            typedef typename expression::let_<
0176               Locals
0177             , Map
0178             , Expr
0179            >::type let_type;
0180            //typedef is_value<let_type> is_val;
0181 
0182            let_type let_exp = expression::let_<Locals, Map, Expr>::make(locals, Map(), expr);
0183            //if(is_val::value) //This seems always to be true
0184            //{
0185            //  std::cout << "let has value type" << std::endl;
0186            //}
0187            return let_exp;
0188         }
0189 
0190         Locals locals;
0191     };
0192 
0193 #define BOOST_PHOENIX_SCOPE_ACTOR_GEN_NAME let_actor_gen
0194 #define BOOST_PHOENIX_SCOPE_ACTOR_GEN_FUNCTION let
0195 #define BOOST_PHOENIX_SCOPE_ACTOR_GEN_CONST
0196 #if defined(BOOST_PHOENIX_NO_VARIADIC_SCOPE)
0197     #include <boost/phoenix/scope/detail/cpp03/local_gen.hpp>
0198 #else
0199     #include <boost/phoenix/scope/detail/local_gen.hpp>
0200 #endif
0201 #undef BOOST_PHOENIX_SCOPE_ACTOR_GEN_NAME
0202 #undef BOOST_PHOENIX_SCOPE_ACTOR_GEN_FUNCTION
0203 #undef BOOST_PHOENIX_SCOPE_ACTOR_GEN_CONST
0204 
0205     template <typename Dummy>
0206     struct is_nullary::when<rule::let_, Dummy>
0207         : proto::make<
0208             mpl::and_<
0209                 proto::fold<
0210                     proto::call<proto::_value(proto::_child_c<0>)>
0211                   , proto::make<mpl::true_()>
0212                   , proto::make<
0213                         mpl::and_<
0214                             proto::_state
0215                           , proto::call<
0216                                 evaluator(
0217                                     proto::_
0218                                   , _context
0219                                   , proto::make<proto::empty_env()>
0220                                 )
0221                             >
0222                         >()
0223                     >
0224                 >
0225               , evaluator(
0226                     proto::_child_c<2>
0227                   , proto::call<
0228                         functional::context(
0229                             proto::make<
0230                                 mpl::true_()
0231                             >
0232                           , proto::make<
0233                                 detail::scope_is_nullary_actions()
0234                             >
0235                         )
0236                     >
0237                   , proto::make<
0238                         proto::empty_env()
0239                     >
0240                 )
0241             >()
0242         >
0243     {};
0244 }}
0245 
0246 #endif