• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*=============================================================================
2     Copyright (c) 2005-2011 Joel de Guzman
3     Copyright (c) 2011 Thomas Heller
4 
5     Distributed under the Boost Software License, Version 1.0. (See accompanying
6     file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
7 ==============================================================================*/
8 #ifndef BOOST_PHOENIX_SCOPE_THIS_HPP
9 #define BOOST_PHOENIX_SCOPE_THIS_HPP
10 
11 #include <boost/phoenix/core/limits.hpp>
12 #include <boost/phoenix/core/actor.hpp>
13 #include <boost/phoenix/core/environment.hpp>
14 #include <boost/phoenix/core/expression.hpp>
15 #include <boost/phoenix/core/meta_grammar.hpp>
16 #include <boost/phoenix/core/terminal.hpp>
17 #include <boost/phoenix/scope/lambda.hpp>
18 #include <boost/type_traits/remove_pointer.hpp>
19 
20 BOOST_PHOENIX_DEFINE_EXPRESSION_VARARG(
21     (boost)(phoenix)(this_)
22   , (meta_grammar)(meta_grammar)
23   , BOOST_PHOENIX_LIMIT
24 )
25 
26 namespace boost { namespace phoenix {
27     namespace detail
28     {
29       /*
30         struct infinite_recursion_detected {};
31 
32         struct last_non_this_actor
33             : proto::or_<
34                 proto::when<
35                     proto::nary_expr<
36                         proto::_
37                       , proto::_
38                       , proto::_
39                     >
40                   , proto::_child_c<1>
41                 >
42               , proto::when<
43                     proto::nary_expr<
44                         proto::_
45                       , proto::_
46                       , proto::_
47                       , proto::_
48                     >
49                   , proto::_child_c<2>
50                 >
51             >
52         {};
53         */
54     }
55     struct this_eval
56     {
57         BOOST_PROTO_CALLABLE()
58 
59         template <typename Sig>
60         struct result;
61 
62         template <typename This, typename A0, typename Context>
63         struct result<This(A0, Context)>
64         {
65             typedef
66                 typename proto::detail::uncvref<
67                     typename result_of::env<
68                         Context
69                     >::type
70                 >::type
71             outer_env_type;
72 
73             typedef
74                 typename remove_pointer<
75                     typename remove_reference<
76                         typename fusion::result_of::at_c<
77                             outer_env_type
78                           , 0
79                         >::type
80                     >::type
81                 >::type
82             actor_type;
83 
84             typedef
85                 typename result_of::eval<
86                     A0 const &
87                   , Context const &
88                 >::type
89             a0_type;
90 
91             typedef
92                 vector2<actor_type const *, a0_type>
93             inner_env_type;
94 
95             typedef
96                 scoped_environment<
97                     inner_env_type
98                   , outer_env_type
99                   , vector0<>
100                   , detail::map_local_index_to_tuple<>
101                 >
102             env_type;
103 
104             typedef
105                 typename result_of::eval<
106                     actor_type const &
107                   , typename result_of::context<
108                         inner_env_type
109                       , typename result_of::actions<
110                             Context
111                         >::type
112                     >::type
113                 >::type
114             type;
115         };
116 
117         template <typename A0, typename Context>
118         typename result<this_eval(A0 const&, Context const &)>::type
operator ()boost::phoenix::this_eval119         operator()(A0 const & a0, Context const & ctx) const
120         {
121 
122             //std::cout << typeid(checker).name() << "\n";
123             //std::cout << typeid(checker).name() << "\n";
124             typedef
125                 typename proto::detail::uncvref<
126                     typename result_of::env<
127                         Context
128                     >::type
129                 >::type
130             outer_env_type;
131 
132             typedef
133                 typename remove_pointer<
134                     typename remove_reference<
135                         typename fusion::result_of::at_c<
136                             outer_env_type
137                           , 0
138                         >::type
139                      >::type
140                 >::type
141             actor_type;
142 
143             typedef
144                 typename result_of::eval<
145                     A0 const &
146                   , Context const &
147                 >::type
148             a0_type;
149 
150             typedef
151                 vector2<actor_type const *, a0_type>
152             inner_env_type;
153 
154             typedef
155                 scoped_environment<
156                     inner_env_type
157                   , outer_env_type
158                   , vector0<>
159                   , detail::map_local_index_to_tuple<>
160                 >
161             env_type;
162 
163             inner_env_type inner_env = {fusion::at_c<0>(phoenix::env(ctx)), phoenix::eval(a0, ctx)};
164             vector0<> locals;
165             env_type env(inner_env, phoenix::env(ctx), locals);
166 
167             return phoenix::eval(*fusion::at_c<0>(phoenix::env(ctx)), phoenix::context(inner_env, phoenix::actions(ctx)));
168             //return (*fusion::at_c<0>(phoenix::env(ctx)))(eval(a0, ctx));
169         }
170     };
171 
172     template <typename Dummy>
173     struct default_actions::when<rule::this_, Dummy>
174         : call<this_eval>
175     {};
176 
177     template <typename Dummy>
178     struct is_nullary::when<rule::this_, Dummy>
179         : proto::make<mpl::false_()>
180     {};
181 
182     template <typename A0>
183     typename expression::this_<A0>::type const
this_(A0 const & a0)184     this_(A0 const & a0)
185     {
186         return expression::this_<A0>::make(a0);
187     }
188 
189 }}
190 
191 #endif
192