1 /*==============================================================================
2     Copyright (c) 2005-2010 Joel de Guzman
3     Copyright (c) 2010-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_LOCAL_VARIABLE_HPP
9 #define BOOST_PHOENIX_SCOPE_LOCAL_VARIABLE_HPP
10 
11 #include <boost/phoenix/core/limits.hpp>
12 #include <boost/phoenix/core/call.hpp>
13 #include <boost/phoenix/core/expression.hpp>
14 #include <boost/phoenix/core/reference.hpp>
15 #include <boost/phoenix/core/value.hpp>
16 #include <boost/phoenix/scope/scoped_environment.hpp>
17 #include <boost/phoenix/scope/detail/local_variable.hpp>
18 #include <boost/phoenix/statement/sequence.hpp>
19 
20 namespace boost { namespace phoenix
21 {
22     namespace expression
23     {
24         template <typename Key>
25         struct local_variable
26             : expression::terminal<detail::local<Key> >
27         {
28             typedef typename expression::terminal<detail::local<Key> >::type type;
29 
makeboost::phoenix::expression::local_variable30             static type make()
31             {
32                 type const e = {};
33                 return e;
34             }
35         };
36     }
37 
38     namespace rule
39     {
40         struct local_variable
41             : expression::local_variable<proto::_>
42         {};
43 
44         struct local_var_def
45             : proto::assign<local_variable, meta_grammar>
46         {};
47     }
48 
49     namespace result_of
50     {
51         template <typename Key>
52         struct is_nullary<custom_terminal<detail::local<Key> > >
53             : mpl::false_
54         {};
55     }
56 
57     namespace detail
58     {
59         struct scope_is_nullary_actions
60         {
61             template <typename Rule, typename Dummy = void>
62             struct when
63                 : boost::phoenix::is_nullary::when<Rule, Dummy>
64             {};
65         };
66 
67         template <typename Dummy>
68         struct scope_is_nullary_actions::when<boost::phoenix::rule::custom_terminal, Dummy>
69             : proto::or_<
70                 proto::when<boost::phoenix::rule::local_variable, mpl::true_()>
71               , proto::otherwise<
72                     is_nullary::when<boost::phoenix::rule::custom_terminal, Dummy>
73                 >
74             >
75         {};
76 
77         struct local_var_not_found
78         {
79         };
80     }
81 
82     template<typename Key>
83     struct is_custom_terminal<detail::local<Key> >
84       : mpl::true_
85     {};
86 
87   template <typename Key>
88   struct custom_terminal<detail::local<Key> >
89     {
90         template <typename Sig>
91         struct result;
92 
93         template <typename This, typename Local, typename Context>
94         struct result<This(Local, Context)>
95             : result<This(Local const &, Context)>
96         {};
97 
98         template <typename This, typename Local, typename Context>
99         struct result<This(Local &, Context)>
100         {
101             typedef
102                 typename remove_reference<
103                     typename result_of::env<Context>::type
104                 >::type
105                 env_type;
106 
107                 typedef typename detail::apply_local<detail::local<Key>, env_type>::type type;
108         };
109 
110         template <typename Local, typename Context>
111         typename result<custom_terminal(Local const &, Context const&)>::type
operator ()boost::phoenix::custom_terminal112         operator()(Local, Context const & ctx)
113         {
114             typedef
115                 typename remove_reference<
116                     typename result_of::env<Context>::type
117                 >::type
118                 env_type;
119 
120                 typedef typename detail::apply_local<detail::local<Key>, env_type>::type return_type;
121 
122             static const int index_value = detail::get_index<typename env_type::map_type, detail::local<Key> >::value;
123 
124             typedef detail::eval_local<Key> eval_local;
125 
126             // Detect if the return_type is for a value.
127             //typedef typename is_value<return_type>::type is_value_type;
128 
129             return eval_local::template get<return_type, index_value>(
130                 phoenix::env(ctx));
131         }
132     };
133 
134     namespace local_names
135     {
136         typedef expression::local_variable<struct _a_key>::type _a_type;
137         typedef expression::local_variable<struct _b_key>::type _b_type;
138         typedef expression::local_variable<struct _c_key>::type _c_type;
139         typedef expression::local_variable<struct _d_key>::type _d_type;
140         typedef expression::local_variable<struct _e_key>::type _e_type;
141         typedef expression::local_variable<struct _f_key>::type _f_type;
142         typedef expression::local_variable<struct _g_key>::type _g_type;
143         typedef expression::local_variable<struct _h_key>::type _h_type;
144         typedef expression::local_variable<struct _i_key>::type _i_type;
145         typedef expression::local_variable<struct _j_key>::type _j_type;
146         typedef expression::local_variable<struct _k_key>::type _k_type;
147         typedef expression::local_variable<struct _l_key>::type _l_type;
148         typedef expression::local_variable<struct _m_key>::type _m_type;
149         typedef expression::local_variable<struct _n_key>::type _n_type;
150         typedef expression::local_variable<struct _o_key>::type _o_type;
151         typedef expression::local_variable<struct _p_key>::type _p_type;
152         typedef expression::local_variable<struct _q_key>::type _q_type;
153         typedef expression::local_variable<struct _r_key>::type _r_type;
154         typedef expression::local_variable<struct _s_key>::type _s_type;
155         typedef expression::local_variable<struct _t_key>::type _t_type;
156         typedef expression::local_variable<struct _u_key>::type _u_type;
157         typedef expression::local_variable<struct _v_key>::type _v_type;
158         typedef expression::local_variable<struct _w_key>::type _w_type;
159         typedef expression::local_variable<struct _x_key>::type _x_type;
160         typedef expression::local_variable<struct _y_key>::type _y_type;
161         typedef expression::local_variable<struct _z_key>::type _z_type;
162 
163 #ifndef BOOST_PHOENIX_NO_PREDEFINED_TERMINALS
164         BOOST_ATTRIBUTE_UNUSED _a_type const _a = {{{}}};
165         BOOST_ATTRIBUTE_UNUSED _b_type const _b = {{{}}};
166         BOOST_ATTRIBUTE_UNUSED _c_type const _c = {{{}}};
167         BOOST_ATTRIBUTE_UNUSED _d_type const _d = {{{}}};
168         BOOST_ATTRIBUTE_UNUSED _e_type const _e = {{{}}};
169         BOOST_ATTRIBUTE_UNUSED _f_type const _f = {{{}}};
170         BOOST_ATTRIBUTE_UNUSED _g_type const _g = {{{}}};
171         BOOST_ATTRIBUTE_UNUSED _h_type const _h = {{{}}};
172         BOOST_ATTRIBUTE_UNUSED _i_type const _i = {{{}}};
173         BOOST_ATTRIBUTE_UNUSED _j_type const _j = {{{}}};
174         BOOST_ATTRIBUTE_UNUSED _k_type const _k = {{{}}};
175         BOOST_ATTRIBUTE_UNUSED _l_type const _l = {{{}}};
176         BOOST_ATTRIBUTE_UNUSED _m_type const _m = {{{}}};
177         BOOST_ATTRIBUTE_UNUSED _n_type const _n = {{{}}};
178         BOOST_ATTRIBUTE_UNUSED _o_type const _o = {{{}}};
179         BOOST_ATTRIBUTE_UNUSED _p_type const _p = {{{}}};
180         BOOST_ATTRIBUTE_UNUSED _q_type const _q = {{{}}};
181         BOOST_ATTRIBUTE_UNUSED _r_type const _r = {{{}}};
182         BOOST_ATTRIBUTE_UNUSED _s_type const _s = {{{}}};
183         BOOST_ATTRIBUTE_UNUSED _t_type const _t = {{{}}};
184         BOOST_ATTRIBUTE_UNUSED _u_type const _u = {{{}}};
185         BOOST_ATTRIBUTE_UNUSED _v_type const _v = {{{}}};
186         BOOST_ATTRIBUTE_UNUSED _w_type const _w = {{{}}};
187         BOOST_ATTRIBUTE_UNUSED _x_type const _x = {{{}}};
188         BOOST_ATTRIBUTE_UNUSED _y_type const _y = {{{}}};
189         BOOST_ATTRIBUTE_UNUSED _z_type const _z = {{{}}};
190 #endif
191     }
192 }}
193 
194 #endif
195