Chris@16
|
1 ///////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
2 /// \file impl.hpp
|
Chris@16
|
3 /// Contains definition of transform<> and transform_impl<> helpers.
|
Chris@16
|
4 //
|
Chris@16
|
5 // Copyright 2008 Eric Niebler. Distributed under the Boost
|
Chris@16
|
6 // Software License, Version 1.0. (See accompanying file
|
Chris@16
|
7 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
Chris@16
|
8
|
Chris@16
|
9 #ifndef BOOST_PROTO_TRANSFORM_IMPL_HPP_EAN_04_03_2008
|
Chris@16
|
10 #define BOOST_PROTO_TRANSFORM_IMPL_HPP_EAN_04_03_2008
|
Chris@16
|
11
|
Chris@16
|
12 #include <boost/config.hpp>
|
Chris@16
|
13 #include <boost/mpl/bool.hpp>
|
Chris@16
|
14 #include <boost/type_traits/add_const.hpp>
|
Chris@16
|
15 #include <boost/type_traits/add_reference.hpp>
|
Chris@16
|
16 #include <boost/proto/proto_fwd.hpp>
|
Chris@16
|
17 #include <boost/proto/detail/any.hpp>
|
Chris@16
|
18 #include <boost/proto/detail/static_const.hpp>
|
Chris@16
|
19
|
Chris@101
|
20 #if defined(_MSC_VER)
|
Chris@16
|
21 # pragma warning(push)
|
Chris@16
|
22 # pragma warning(disable : 4714) // function 'xxx' marked as __forceinline not inlined
|
Chris@16
|
23 #endif
|
Chris@16
|
24
|
Chris@16
|
25 namespace boost { namespace proto
|
Chris@16
|
26 {
|
Chris@16
|
27 namespace envns_
|
Chris@16
|
28 {
|
Chris@16
|
29 ////////////////////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
30 struct key_not_found
|
Chris@16
|
31 {};
|
Chris@16
|
32
|
Chris@16
|
33 ////////////////////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
34 // empty_env
|
Chris@16
|
35 struct empty_env
|
Chris@16
|
36 {
|
Chris@16
|
37 typedef void proto_environment_;
|
Chris@16
|
38
|
Chris@16
|
39 template<typename OtherTag, typename OtherValue = key_not_found>
|
Chris@16
|
40 struct lookup
|
Chris@16
|
41 {
|
Chris@16
|
42 typedef OtherValue type;
|
Chris@16
|
43 typedef
|
Chris@16
|
44 typename add_reference<typename add_const<OtherValue>::type>::type
|
Chris@16
|
45 const_reference;
|
Chris@16
|
46 };
|
Chris@16
|
47
|
Chris@16
|
48 key_not_found operator[](detail::any) const
|
Chris@16
|
49 {
|
Chris@16
|
50 return key_not_found();
|
Chris@16
|
51 }
|
Chris@16
|
52
|
Chris@16
|
53 template<typename T>
|
Chris@16
|
54 T const &at(detail::any, T const &t) const
|
Chris@16
|
55 {
|
Chris@16
|
56 return t;
|
Chris@16
|
57 }
|
Chris@16
|
58 };
|
Chris@16
|
59 }
|
Chris@16
|
60
|
Chris@16
|
61 ////////////////////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
62 // is_env
|
Chris@16
|
63 template<typename T, typename Void>
|
Chris@16
|
64 struct is_env
|
Chris@16
|
65 : mpl::false_
|
Chris@16
|
66 {};
|
Chris@16
|
67
|
Chris@16
|
68 template<typename T>
|
Chris@16
|
69 struct is_env<T, typename T::proto_environment_>
|
Chris@16
|
70 : mpl::true_
|
Chris@16
|
71 {};
|
Chris@16
|
72
|
Chris@16
|
73 template<typename T>
|
Chris@16
|
74 struct is_env<T &, void>
|
Chris@16
|
75 : is_env<T>
|
Chris@16
|
76 {};
|
Chris@16
|
77
|
Chris@16
|
78 #ifdef BOOST_NO_CXX11_RVALUE_REFERENCES
|
Chris@16
|
79
|
Chris@16
|
80 /// INTERNAL ONLY
|
Chris@16
|
81 ///
|
Chris@16
|
82 #define BOOST_PROTO_TRANSFORM_(PrimitiveTransform, X) \
|
Chris@16
|
83 BOOST_PROTO_CALLABLE() \
|
Chris@16
|
84 typedef X proto_is_transform_; \
|
Chris@16
|
85 typedef PrimitiveTransform transform_type; \
|
Chris@16
|
86 \
|
Chris@16
|
87 template<typename Sig> \
|
Chris@16
|
88 struct result \
|
Chris@16
|
89 { \
|
Chris@16
|
90 typedef typename boost::proto::detail::apply_transform<Sig>::result_type type; \
|
Chris@16
|
91 }; \
|
Chris@16
|
92 \
|
Chris@16
|
93 template<typename Expr> \
|
Chris@16
|
94 BOOST_FORCEINLINE \
|
Chris@16
|
95 typename boost::proto::detail::apply_transform<transform_type(Expr &)>::result_type \
|
Chris@16
|
96 operator ()(Expr &e) const \
|
Chris@16
|
97 { \
|
Chris@16
|
98 boost::proto::empty_state s = 0; \
|
Chris@16
|
99 boost::proto::empty_env d; \
|
Chris@16
|
100 return boost::proto::detail::apply_transform<transform_type(Expr &)>()(e, s, d); \
|
Chris@16
|
101 } \
|
Chris@16
|
102 \
|
Chris@16
|
103 template<typename Expr> \
|
Chris@16
|
104 BOOST_FORCEINLINE \
|
Chris@16
|
105 typename boost::proto::detail::apply_transform<transform_type(Expr const &)>::result_type \
|
Chris@16
|
106 operator ()(Expr const &e) const \
|
Chris@16
|
107 { \
|
Chris@16
|
108 boost::proto::empty_state s = 0; \
|
Chris@16
|
109 boost::proto::empty_env d; \
|
Chris@16
|
110 return boost::proto::detail::apply_transform<transform_type(Expr const &)>()(e, s, d); \
|
Chris@16
|
111 } \
|
Chris@16
|
112 \
|
Chris@16
|
113 template<typename Expr, typename State> \
|
Chris@16
|
114 BOOST_FORCEINLINE \
|
Chris@16
|
115 typename boost::proto::detail::apply_transform<transform_type(Expr &, State &)>::result_type \
|
Chris@16
|
116 operator ()(Expr &e, State &s) const \
|
Chris@16
|
117 { \
|
Chris@16
|
118 boost::proto::empty_env d; \
|
Chris@16
|
119 return boost::proto::detail::apply_transform<transform_type(Expr &, State &)>()(e, s, d); \
|
Chris@16
|
120 } \
|
Chris@16
|
121 \
|
Chris@16
|
122 template<typename Expr, typename State> \
|
Chris@16
|
123 BOOST_FORCEINLINE \
|
Chris@16
|
124 typename boost::proto::detail::apply_transform<transform_type(Expr const &, State &)>::result_type \
|
Chris@16
|
125 operator ()(Expr const &e, State &s) const \
|
Chris@16
|
126 { \
|
Chris@16
|
127 boost::proto::empty_env d; \
|
Chris@16
|
128 return boost::proto::detail::apply_transform<transform_type(Expr const &, State &)>()(e, s, d); \
|
Chris@16
|
129 } \
|
Chris@16
|
130 \
|
Chris@16
|
131 template<typename Expr, typename State> \
|
Chris@16
|
132 BOOST_FORCEINLINE \
|
Chris@16
|
133 typename boost::proto::detail::apply_transform<transform_type(Expr &, State const &)>::result_type \
|
Chris@16
|
134 operator ()(Expr &e, State const &s) const \
|
Chris@16
|
135 { \
|
Chris@16
|
136 boost::proto::empty_env d; \
|
Chris@16
|
137 return boost::proto::detail::apply_transform<transform_type(Expr &, State const &)>()(e, s, d); \
|
Chris@16
|
138 } \
|
Chris@16
|
139 \
|
Chris@16
|
140 template<typename Expr, typename State> \
|
Chris@16
|
141 BOOST_FORCEINLINE \
|
Chris@16
|
142 typename boost::proto::detail::apply_transform<transform_type(Expr const &, State const &)>::result_type \
|
Chris@16
|
143 operator ()(Expr const &e, State const &s) const \
|
Chris@16
|
144 { \
|
Chris@16
|
145 boost::proto::empty_env d; \
|
Chris@16
|
146 return boost::proto::detail::apply_transform<transform_type(Expr const &, State const &)>()(e, s, d); \
|
Chris@16
|
147 } \
|
Chris@16
|
148 \
|
Chris@16
|
149 template<typename Expr, typename State, typename Data> \
|
Chris@16
|
150 BOOST_FORCEINLINE \
|
Chris@16
|
151 typename boost::proto::detail::apply_transform<transform_type(Expr &, State &, Data &)>::result_type \
|
Chris@16
|
152 operator ()(Expr &e, State &s, Data &d) const \
|
Chris@16
|
153 { \
|
Chris@16
|
154 return boost::proto::detail::apply_transform<transform_type(Expr &, State &, Data &)>()(e, s, d); \
|
Chris@16
|
155 } \
|
Chris@16
|
156 \
|
Chris@16
|
157 template<typename Expr, typename State, typename Data> \
|
Chris@16
|
158 BOOST_FORCEINLINE \
|
Chris@16
|
159 typename boost::proto::detail::apply_transform<transform_type(Expr const &, State &, Data &)>::result_type \
|
Chris@16
|
160 operator ()(Expr const &e, State &s, Data &d) const \
|
Chris@16
|
161 { \
|
Chris@16
|
162 return boost::proto::detail::apply_transform<transform_type(Expr const &, State &, Data &)>()(e, s, d); \
|
Chris@16
|
163 } \
|
Chris@16
|
164 \
|
Chris@16
|
165 template<typename Expr, typename State, typename Data> \
|
Chris@16
|
166 BOOST_FORCEINLINE \
|
Chris@16
|
167 typename boost::proto::detail::apply_transform<transform_type(Expr &, State const &, Data &)>::result_type \
|
Chris@16
|
168 operator ()(Expr &e, State const &s, Data &d) const \
|
Chris@16
|
169 { \
|
Chris@16
|
170 return boost::proto::detail::apply_transform<transform_type(Expr &, State const &, Data &)>()(e, s, d); \
|
Chris@16
|
171 } \
|
Chris@16
|
172 \
|
Chris@16
|
173 template<typename Expr, typename State, typename Data> \
|
Chris@16
|
174 BOOST_FORCEINLINE \
|
Chris@16
|
175 typename boost::proto::detail::apply_transform<transform_type(Expr const &, State const &, Data &)>::result_type \
|
Chris@16
|
176 operator ()(Expr const &e, State const &s, Data &d) const \
|
Chris@16
|
177 { \
|
Chris@16
|
178 return boost::proto::detail::apply_transform<transform_type(Expr const &, State const &, Data &)>()(e, s, d); \
|
Chris@16
|
179 } \
|
Chris@16
|
180 /**/
|
Chris@16
|
181
|
Chris@16
|
182 #else
|
Chris@16
|
183
|
Chris@16
|
184 /// INTERNAL ONLY
|
Chris@16
|
185 ///
|
Chris@16
|
186 #define BOOST_PROTO_TRANSFORM_(PrimitiveTransform, X) \
|
Chris@16
|
187 BOOST_PROTO_CALLABLE() \
|
Chris@16
|
188 typedef X proto_is_transform_; \
|
Chris@16
|
189 typedef PrimitiveTransform transform_type; \
|
Chris@16
|
190 \
|
Chris@16
|
191 template<typename Sig> \
|
Chris@16
|
192 struct result \
|
Chris@16
|
193 { \
|
Chris@16
|
194 typedef typename boost::proto::detail::apply_transform<Sig>::result_type type; \
|
Chris@16
|
195 }; \
|
Chris@16
|
196 \
|
Chris@16
|
197 template<typename Expr> \
|
Chris@16
|
198 BOOST_FORCEINLINE \
|
Chris@16
|
199 typename boost::proto::detail::apply_transform<transform_type(Expr const &)>::result_type \
|
Chris@16
|
200 operator ()(Expr &&e) const \
|
Chris@16
|
201 { \
|
Chris@16
|
202 boost::proto::empty_state s = 0; \
|
Chris@16
|
203 boost::proto::empty_env d; \
|
Chris@16
|
204 return boost::proto::detail::apply_transform<transform_type(Expr const &)>()(e, s, d); \
|
Chris@16
|
205 } \
|
Chris@16
|
206 \
|
Chris@16
|
207 template<typename Expr, typename State> \
|
Chris@16
|
208 BOOST_FORCEINLINE \
|
Chris@16
|
209 typename boost::proto::detail::apply_transform<transform_type(Expr const &, State const &)>::result_type \
|
Chris@16
|
210 operator ()(Expr &&e, State &&s) const \
|
Chris@16
|
211 { \
|
Chris@16
|
212 boost::proto::empty_env d; \
|
Chris@16
|
213 return boost::proto::detail::apply_transform<transform_type(Expr const &, State const &)>()(e, s, d); \
|
Chris@16
|
214 } \
|
Chris@16
|
215 \
|
Chris@16
|
216 template<typename Expr, typename State, typename Data> \
|
Chris@16
|
217 BOOST_FORCEINLINE \
|
Chris@16
|
218 typename boost::proto::detail::apply_transform<transform_type(Expr const &, State const &, Data const &)>::result_type \
|
Chris@16
|
219 operator ()(Expr &&e, State &&s, Data &&d) const \
|
Chris@16
|
220 { \
|
Chris@16
|
221 return boost::proto::detail::apply_transform<transform_type(Expr const &, State const &, Data const &)>()(e, s, d); \
|
Chris@16
|
222 } \
|
Chris@16
|
223 /**/
|
Chris@16
|
224
|
Chris@16
|
225 #endif
|
Chris@16
|
226
|
Chris@16
|
227 #define BOOST_PROTO_TRANSFORM(PrimitiveTransform) \
|
Chris@16
|
228 BOOST_PROTO_TRANSFORM_(PrimitiveTransform, void) \
|
Chris@16
|
229 /**/
|
Chris@16
|
230
|
Chris@16
|
231 namespace detail
|
Chris@16
|
232 {
|
Chris@16
|
233 template<typename Sig>
|
Chris@16
|
234 struct apply_transform;
|
Chris@16
|
235
|
Chris@16
|
236 template<typename PrimitiveTransform, typename Expr>
|
Chris@16
|
237 struct apply_transform<PrimitiveTransform(Expr)>
|
Chris@16
|
238 : PrimitiveTransform::template impl<Expr, empty_state, empty_env>
|
Chris@16
|
239 {};
|
Chris@16
|
240
|
Chris@16
|
241 template<typename PrimitiveTransform, typename Expr, typename State>
|
Chris@16
|
242 struct apply_transform<PrimitiveTransform(Expr, State)>
|
Chris@16
|
243 : PrimitiveTransform::template impl<Expr, State, empty_env>
|
Chris@16
|
244 {};
|
Chris@16
|
245
|
Chris@16
|
246 template<typename PrimitiveTransform, typename Expr, typename State, typename Data>
|
Chris@16
|
247 struct apply_transform<PrimitiveTransform(Expr, State, Data)>
|
Chris@16
|
248 : PrimitiveTransform::template impl<Expr, State, Data>
|
Chris@16
|
249 {};
|
Chris@16
|
250 }
|
Chris@16
|
251
|
Chris@16
|
252 template<typename PrimitiveTransform, typename X>
|
Chris@16
|
253 struct transform
|
Chris@16
|
254 {
|
Chris@16
|
255 BOOST_PROTO_TRANSFORM_(PrimitiveTransform, X)
|
Chris@16
|
256 };
|
Chris@16
|
257
|
Chris@16
|
258 template<typename Expr, typename State, typename Data>
|
Chris@16
|
259 struct transform_impl
|
Chris@16
|
260 {
|
Chris@16
|
261 typedef Expr const expr;
|
Chris@16
|
262 typedef Expr const &expr_param;
|
Chris@16
|
263 typedef State const state;
|
Chris@16
|
264 typedef State const &state_param;
|
Chris@16
|
265 typedef Data const data;
|
Chris@16
|
266 typedef Data const &data_param;
|
Chris@16
|
267 };
|
Chris@16
|
268
|
Chris@16
|
269 template<typename Expr, typename State, typename Data>
|
Chris@16
|
270 struct transform_impl<Expr &, State, Data>
|
Chris@16
|
271 {
|
Chris@16
|
272 typedef Expr expr;
|
Chris@16
|
273 typedef Expr &expr_param;
|
Chris@16
|
274 typedef State const state;
|
Chris@16
|
275 typedef State const &state_param;
|
Chris@16
|
276 typedef Data const data;
|
Chris@16
|
277 typedef Data const &data_param;
|
Chris@16
|
278 };
|
Chris@16
|
279
|
Chris@16
|
280 template<typename Expr, typename State, typename Data>
|
Chris@16
|
281 struct transform_impl<Expr, State &, Data>
|
Chris@16
|
282 {
|
Chris@16
|
283 typedef Expr const expr;
|
Chris@16
|
284 typedef Expr const &expr_param;
|
Chris@16
|
285 typedef State state;
|
Chris@16
|
286 typedef State &state_param;
|
Chris@16
|
287 typedef Data const data;
|
Chris@16
|
288 typedef Data const &data_param;
|
Chris@16
|
289 };
|
Chris@16
|
290
|
Chris@16
|
291 template<typename Expr, typename State, typename Data>
|
Chris@16
|
292 struct transform_impl<Expr, State, Data &>
|
Chris@16
|
293 {
|
Chris@16
|
294 typedef Expr const expr;
|
Chris@16
|
295 typedef Expr const &expr_param;
|
Chris@16
|
296 typedef State const state;
|
Chris@16
|
297 typedef State const &state_param;
|
Chris@16
|
298 typedef Data data;
|
Chris@16
|
299 typedef Data &data_param;
|
Chris@16
|
300 };
|
Chris@16
|
301
|
Chris@16
|
302 template<typename Expr, typename State, typename Data>
|
Chris@16
|
303 struct transform_impl<Expr &, State &, Data>
|
Chris@16
|
304 {
|
Chris@16
|
305 typedef Expr expr;
|
Chris@16
|
306 typedef Expr &expr_param;
|
Chris@16
|
307 typedef State state;
|
Chris@16
|
308 typedef State &state_param;
|
Chris@16
|
309 typedef Data const data;
|
Chris@16
|
310 typedef Data const &data_param;
|
Chris@16
|
311 };
|
Chris@16
|
312
|
Chris@16
|
313 template<typename Expr, typename State, typename Data>
|
Chris@16
|
314 struct transform_impl<Expr &, State, Data &>
|
Chris@16
|
315 {
|
Chris@16
|
316 typedef Expr expr;
|
Chris@16
|
317 typedef Expr &expr_param;
|
Chris@16
|
318 typedef State const state;
|
Chris@16
|
319 typedef State const &state_param;
|
Chris@16
|
320 typedef Data data;
|
Chris@16
|
321 typedef Data &data_param;
|
Chris@16
|
322 };
|
Chris@16
|
323
|
Chris@16
|
324 template<typename Expr, typename State, typename Data>
|
Chris@16
|
325 struct transform_impl<Expr, State &, Data &>
|
Chris@16
|
326 {
|
Chris@16
|
327 typedef Expr const expr;
|
Chris@16
|
328 typedef Expr const &expr_param;
|
Chris@16
|
329 typedef State state;
|
Chris@16
|
330 typedef State &state_param;
|
Chris@16
|
331 typedef Data data;
|
Chris@16
|
332 typedef Data &data_param;
|
Chris@16
|
333 };
|
Chris@16
|
334
|
Chris@16
|
335 template<typename Expr, typename State, typename Data>
|
Chris@16
|
336 struct transform_impl<Expr &, State &, Data &>
|
Chris@16
|
337 {
|
Chris@16
|
338 typedef Expr expr;
|
Chris@16
|
339 typedef Expr &expr_param;
|
Chris@16
|
340 typedef State state;
|
Chris@16
|
341 typedef State &state_param;
|
Chris@16
|
342 typedef Data data;
|
Chris@16
|
343 typedef Data &data_param;
|
Chris@16
|
344 };
|
Chris@16
|
345
|
Chris@16
|
346 }} // namespace boost::proto
|
Chris@16
|
347
|
Chris@101
|
348 #if defined(_MSC_VER)
|
Chris@16
|
349 # pragma warning(pop)
|
Chris@16
|
350 #endif
|
Chris@16
|
351
|
Chris@16
|
352 #endif
|