1// Copyright (c) 2001-2011 Hartmut Kaiser
2// Copyright (c) 2011 Thomas Heller
3//
4// Distributed under the Boost Software License, Version 1.0. (See accompanying
5// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6
7#if !defined(BOOST_SPIRIT_LEX_ARGUMENT_PHEONIX_MARCH_25_2011_1841PM)
8#define BOOST_SPIRIT_LEX_ARGUMENT_PHEONIX_MARCH_25_2011_1841PM
9
10#if defined(_MSC_VER)
11#pragma once
12#endif
13
14#include <boost/phoenix/core/actor.hpp>
15#include <boost/phoenix/core/as_actor.hpp>
16#include <boost/phoenix/core/expression.hpp>
17#include <boost/phoenix/core/v2_eval.hpp>
18#include <boost/phoenix/core/value.hpp> // includes as_actor specialization
19#include <boost/proto/traits.hpp>
20#include <boost/proto/proto_fwd.hpp> // for transform placeholders
21
22namespace boost { namespace spirit { namespace lex
23{
24 ///////////////////////////////////////////////////////////////////////////
25 // The value_context is used as a noop Phoenix actor to create the
26 // placeholder '_val' (see below). It is a noop actor because it is used
27 // as a placeholder only, while it is being converted either to a
28 // value_getter (if used as a rvalue) or to a value_setter (if used as a
29 // lvalue). The conversion is achieved by specializing and overloading a
30 // couple of the Phoenix templates from the Phoenix expression composition
31 // engine (see the end of this file).
32 struct value_context
33 {
34 typedef mpl::true_ no_nullary;
35
36 typedef unused_type result_type;
37
38 template <typename Env>
39 struct result
40 {
41 typedef unused_type type;
42 };
43
44 template <typename Env>
45 unused_type
46 eval(Env const&) const
47 {
48 return unused;
49 }
50 };
51
52 // forward declarations
53 struct value_getter;
54 template <typename> struct value_setter;
55
56 ///////////////////////////////////////////////////////////////////////////
57 // The state_context is used as a noop Phoenix actor to create the
58 // placeholder '_state' (see below). It is a noop actor because it is used
59 // as a placeholder only, while it is being converted either to a
60 // state_getter (if used as a rvalue) or to a state_setter (if used as a
61 // lvalue). The conversion is achieved by specializing and overloading a
62 // couple of the Phoenix templates from the Phoenix expression composition
63 // engine (see the end of this file).
64 struct state_context
65 {
66 typedef mpl::true_ no_nullary;
67
68 typedef unused_type result_type;
69
70 template <typename Env>
71 struct result
72 {
73 typedef unused_type type;
74 };
75
76 template <typename Env>
77 unused_type
78 eval(Env const&) const
79 {
80 return unused;
81 }
82 };
83
84 // forward declarations
85 struct state_getter;
86 template <typename> struct state_setter;
87 struct eoi_getter;
88}}}
89
90///////////////////////////////////////////////////////////////////////////////
91
92BOOST_PHOENIX_DEFINE_EXPRESSION(
93 (boost)(spirit)(lex)(value_setter)
94 , (boost::phoenix::meta_grammar)
95)
96
97BOOST_PHOENIX_DEFINE_EXPRESSION(
98 (boost)(spirit)(lex)(state_setter)
99 , (boost::phoenix::meta_grammar)
100)
101
102namespace boost { namespace phoenix
103{
104 namespace result_of
105 {
106 template <>
107 struct is_nullary<custom_terminal<boost::spirit::lex::value_context> >
108 : mpl::false_
109 {};
110 }
111
112 template <typename Dummy>
113 struct is_custom_terminal<boost::spirit::lex::value_context, Dummy>: mpl::true_ {};
114
115 template <typename Dummy>
116 struct custom_terminal<boost::spirit::lex::value_context, Dummy>
117 : proto::call<
118 v2_eval(
119 proto::make<boost::spirit::lex::value_getter()>
120 , proto::call<functional::env(proto::_state)>
121 )
122 >
123 {};
124
125 template <typename Dummy>
126 struct is_nullary::when<spirit::lex::rule::value_setter, Dummy>
127 : proto::make<mpl::false_()>
128 {};
129
130 template <typename Dummy>
131 struct default_actions::when<spirit::lex::rule::value_setter, Dummy>
132 : proto::call<
133 v2_eval(
134 proto::make<
135 spirit::lex::value_setter<proto::_child0>(
136 proto::_child0
137 )
138 >
139 , _env
140 )
141 >
142 {};
143
144 template <>
145 struct actor<spirit::lex::value_context>
146 : boost::phoenix::actor<proto::terminal<spirit::lex::value_context>::type>
147 {
148 typedef boost::phoenix::actor<
149 proto::terminal<spirit::lex::value_context>::type
150 > base_type;
151
152 actor(base_type const & base = base_type())
153 : base_type(base)
154 {}
155
156 template <typename Expr>
157 typename spirit::lex::expression::value_setter<
158 typename phoenix::as_actor<Expr>::type>::type const
159 operator=(Expr const & expr) const
160 {
161 return
162 spirit::lex::expression::value_setter<
163 typename phoenix::as_actor<Expr>::type
164 >::make(phoenix::as_actor<Expr>::convert(expr));
165 }
166 };
167
168 namespace result_of
169 {
170 template <>
171 struct is_nullary<custom_terminal<boost::spirit::lex::state_context> >
172 : mpl::false_
173 {};
174 }
175
176 template <typename Dummy>
177 struct is_custom_terminal<boost::spirit::lex::state_context, Dummy>: mpl::true_ {};
178
179 template <typename Dummy>
180 struct custom_terminal<boost::spirit::lex::state_context, Dummy>
181 : proto::call<
182 v2_eval(
183 proto::make<boost::spirit::lex::state_getter()>
184 , proto::call<functional::env(proto::_state)>
185 )
186 >
187 {};
188
189 template <typename Dummy>
190 struct is_nullary::when<spirit::lex::rule::state_setter, Dummy>
191 : proto::make<mpl::false_()>
192 {};
193
194 template <typename Dummy>
195 struct default_actions::when<spirit::lex::rule::state_setter, Dummy>
196 : proto::call<
197 v2_eval(
198 proto::make<
199 spirit::lex::state_setter<proto::_child0>(
200 proto::_child0
201 )
202 >
203 , _env
204 )
205 >
206 {};
207
208 template <>
209 struct actor<spirit::lex::state_context>
210 : boost::phoenix::actor<proto::terminal<spirit::lex::state_context>::type>
211 {
212 typedef boost::phoenix::actor<
213 proto::terminal<spirit::lex::state_context>::type
214 > base_type;
215
216 actor(base_type const & base = base_type())
217 : base_type(base)
218 {}
219
220 template <typename Expr>
221 typename spirit::lex::expression::state_setter<
222 typename phoenix::as_actor<Expr>::type>::type const
223 operator=(Expr const & expr) const
224 {
225 return
226 spirit::lex::expression::state_setter<
227 typename phoenix::as_actor<Expr>::type
228 >::make(phoenix::as_actor<Expr>::convert(expr));
229 }
230 };
231
232 namespace result_of
233 {
234 template <>
235 struct is_nullary<custom_terminal<boost::spirit::lex::eoi_getter> >
236 : mpl::false_
237 {};
238 }
239
240 template <typename Dummy>
241 struct is_custom_terminal<boost::spirit::lex::eoi_getter, Dummy>: mpl::true_ {};
242
243 template <typename Dummy>
244 struct custom_terminal<boost::spirit::lex::eoi_getter, Dummy>
245 : proto::call<
246 v2_eval(
247 proto::make<boost::spirit::lex::eoi_getter()>
248 , proto::call<functional::env(proto::_state)>
249 )
250 >
251 {};
252}}
253
254#endif
255

source code of boost/libs/spirit/include/boost/spirit/home/lex/argument_phoenix.hpp