Chris@16
|
1 ///////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
2 /// \file arg.hpp
|
Chris@16
|
3 /// Contains definition of the argN transforms.
|
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_ARG_HPP_EAN_11_01_2007
|
Chris@16
|
10 #define BOOST_PROTO_TRANSFORM_ARG_HPP_EAN_11_01_2007
|
Chris@16
|
11
|
Chris@16
|
12 #include <boost/mpl/if.hpp>
|
Chris@16
|
13 #include <boost/proto/proto_fwd.hpp>
|
Chris@16
|
14 #include <boost/proto/traits.hpp>
|
Chris@16
|
15 #include <boost/proto/transform/impl.hpp>
|
Chris@16
|
16 #include <boost/type_traits/is_array.hpp>
|
Chris@16
|
17 #include <boost/proto/transform/env.hpp>
|
Chris@16
|
18
|
Chris@16
|
19 namespace boost { namespace proto
|
Chris@16
|
20 {
|
Chris@16
|
21
|
Chris@16
|
22 /// \brief A PrimitiveTransform that returns the current expression
|
Chris@16
|
23 /// unmodified
|
Chris@16
|
24 ///
|
Chris@16
|
25 /// Example:
|
Chris@16
|
26 ///
|
Chris@16
|
27 /// \code
|
Chris@16
|
28 /// proto::terminal<int>::type i = {42};
|
Chris@16
|
29 /// proto::terminal<int>::type & j = proto::_expr()(i);
|
Chris@16
|
30 /// assert( boost::addressof(i) == boost::addressof(j) );
|
Chris@16
|
31 /// \endcode
|
Chris@16
|
32 struct _expr : transform<_expr>
|
Chris@16
|
33 {
|
Chris@16
|
34 template<typename Expr, typename State, typename Data>
|
Chris@16
|
35 struct impl : transform_impl<Expr, State, Data>
|
Chris@16
|
36 {
|
Chris@16
|
37 typedef Expr result_type;
|
Chris@16
|
38
|
Chris@16
|
39 /// Returns the current expression.
|
Chris@16
|
40 /// \param e The current expression.
|
Chris@16
|
41 /// \return \c e
|
Chris@16
|
42 /// \throw nothrow
|
Chris@16
|
43 BOOST_PROTO_RETURN_TYPE_STRICT_LOOSE(result_type, typename impl::expr_param)
|
Chris@16
|
44 operator()(
|
Chris@16
|
45 typename impl::expr_param e
|
Chris@16
|
46 , typename impl::state_param
|
Chris@16
|
47 , typename impl::data_param
|
Chris@16
|
48 ) const
|
Chris@16
|
49 {
|
Chris@16
|
50 return e;
|
Chris@16
|
51 }
|
Chris@16
|
52 };
|
Chris@16
|
53 };
|
Chris@16
|
54
|
Chris@16
|
55 /// \brief A PrimitiveTransform that returns the current state
|
Chris@16
|
56 /// unmodified
|
Chris@16
|
57 ///
|
Chris@16
|
58 /// Example:
|
Chris@16
|
59 ///
|
Chris@16
|
60 /// \code
|
Chris@16
|
61 /// proto::terminal<int>::type i = {42};
|
Chris@16
|
62 /// char ch = proto::_state()(i, 'a');
|
Chris@16
|
63 /// assert( ch == 'a' );
|
Chris@16
|
64 /// \endcode
|
Chris@16
|
65 struct _state : transform<_state>
|
Chris@16
|
66 {
|
Chris@16
|
67 template<typename Expr, typename State, typename Data>
|
Chris@16
|
68 struct impl : transform_impl<Expr, State, Data>
|
Chris@16
|
69 {
|
Chris@16
|
70 typedef State result_type;
|
Chris@16
|
71
|
Chris@16
|
72 /// Returns the current state.
|
Chris@16
|
73 /// \param s The current state.
|
Chris@16
|
74 /// \return \c s
|
Chris@16
|
75 /// \throw nothrow
|
Chris@16
|
76 BOOST_PROTO_RETURN_TYPE_STRICT_LOOSE(result_type, typename impl::state_param)
|
Chris@16
|
77 operator ()(
|
Chris@16
|
78 typename impl::expr_param
|
Chris@16
|
79 , typename impl::state_param s
|
Chris@16
|
80 , typename impl::data_param
|
Chris@16
|
81 ) const
|
Chris@16
|
82 {
|
Chris@16
|
83 return s;
|
Chris@16
|
84 }
|
Chris@16
|
85 };
|
Chris@16
|
86 };
|
Chris@16
|
87
|
Chris@16
|
88 /// \brief A PrimitiveTransform that returns the current data
|
Chris@16
|
89 /// unmodified
|
Chris@16
|
90 ///
|
Chris@16
|
91 /// Example:
|
Chris@16
|
92 ///
|
Chris@16
|
93 /// \code
|
Chris@16
|
94 /// proto::terminal<int>::type i = {42};
|
Chris@16
|
95 /// std::string str("hello");
|
Chris@16
|
96 /// std::string & data = proto::_data()(i, 'a', str);
|
Chris@16
|
97 /// assert( &str == &data );
|
Chris@16
|
98 /// \endcode
|
Chris@16
|
99 struct _data : transform<_data>
|
Chris@16
|
100 {
|
Chris@16
|
101 template<typename Expr, typename State, typename Data>
|
Chris@16
|
102 struct impl
|
Chris@16
|
103 : mpl::if_c<
|
Chris@16
|
104 is_env<Data>::value
|
Chris@16
|
105 , _env_var<data_type>
|
Chris@16
|
106 , _env
|
Chris@16
|
107 >::type::template impl<Expr, State, Data>
|
Chris@16
|
108 {};
|
Chris@16
|
109 };
|
Chris@16
|
110
|
Chris@16
|
111 /// \brief A PrimitiveTransform that returns N-th child of the current
|
Chris@16
|
112 /// expression.
|
Chris@16
|
113 ///
|
Chris@16
|
114 /// Example:
|
Chris@16
|
115 ///
|
Chris@16
|
116 /// \code
|
Chris@16
|
117 /// proto::terminal<int>::type i = {42};
|
Chris@16
|
118 /// proto::terminal<int>::type & j = proto::_child_c<0>()(-i);
|
Chris@16
|
119 /// assert( boost::addressof(i) == boost::addressof(j) );
|
Chris@16
|
120 /// \endcode
|
Chris@16
|
121 template<int N>
|
Chris@16
|
122 struct _child_c : transform<_child_c<N> >
|
Chris@16
|
123 {
|
Chris@16
|
124 template<typename Expr, typename State, typename Data>
|
Chris@16
|
125 struct impl : transform_impl<Expr, State, Data>
|
Chris@16
|
126 {
|
Chris@16
|
127 typedef
|
Chris@16
|
128 typename result_of::child_c<Expr, N>::type
|
Chris@16
|
129 result_type;
|
Chris@16
|
130
|
Chris@16
|
131 /// Returns the N-th child of \c e
|
Chris@16
|
132 /// \pre <tt>arity_of\<Expr\>::value \> N</tt>
|
Chris@16
|
133 /// \param e The current expression.
|
Chris@16
|
134 /// \return <tt>proto::child_c\<N\>(e)</tt>
|
Chris@16
|
135 /// \throw nothrow
|
Chris@16
|
136 #ifdef BOOST_PROTO_STRICT_RESULT_OF
|
Chris@16
|
137 result_type
|
Chris@16
|
138 #else
|
Chris@16
|
139 typename result_of::child_c<typename impl::expr_param, N>::type
|
Chris@16
|
140 #endif
|
Chris@16
|
141 operator ()(
|
Chris@16
|
142 typename impl::expr_param e
|
Chris@16
|
143 , typename impl::state_param
|
Chris@16
|
144 , typename impl::data_param
|
Chris@16
|
145 ) const
|
Chris@16
|
146 {
|
Chris@16
|
147 return proto::child_c<N>(e);
|
Chris@16
|
148 }
|
Chris@16
|
149 };
|
Chris@16
|
150 };
|
Chris@16
|
151
|
Chris@16
|
152 /// \brief A PrimitiveTransform that returns the value of the
|
Chris@16
|
153 /// current terminal expression.
|
Chris@16
|
154 ///
|
Chris@16
|
155 /// Example:
|
Chris@16
|
156 ///
|
Chris@16
|
157 /// \code
|
Chris@16
|
158 /// proto::terminal<int>::type i = {42};
|
Chris@16
|
159 /// int j = proto::_value()(i);
|
Chris@16
|
160 /// assert( 42 == j );
|
Chris@16
|
161 /// \endcode
|
Chris@16
|
162 struct _value : transform<_value>
|
Chris@16
|
163 {
|
Chris@16
|
164 template<typename Expr, typename State, typename Data>
|
Chris@16
|
165 struct impl : transform_impl<Expr, State, Data>
|
Chris@16
|
166 {
|
Chris@16
|
167 typedef
|
Chris@16
|
168 typename result_of::value<Expr>::type
|
Chris@16
|
169 result_type;
|
Chris@16
|
170
|
Chris@16
|
171 /// Returns the value of the specified terminal expression.
|
Chris@16
|
172 /// \pre <tt>arity_of\<Expr\>::value == 0</tt>.
|
Chris@16
|
173 /// \param e The current expression.
|
Chris@16
|
174 /// \return <tt>proto::value(e)</tt>
|
Chris@16
|
175 /// \throw nothrow
|
Chris@16
|
176 #ifdef BOOST_PROTO_STRICT_RESULT_OF
|
Chris@16
|
177 typename mpl::if_c<is_array<result_type>::value, result_type &, result_type>::type
|
Chris@16
|
178 #else
|
Chris@16
|
179 typename result_of::value<typename impl::expr_param>::type
|
Chris@16
|
180 #endif
|
Chris@16
|
181 operator ()(
|
Chris@16
|
182 typename impl::expr_param e
|
Chris@16
|
183 , typename impl::state_param
|
Chris@16
|
184 , typename impl::data_param
|
Chris@16
|
185 ) const
|
Chris@16
|
186 {
|
Chris@16
|
187 return proto::value(e);
|
Chris@16
|
188 }
|
Chris@16
|
189 };
|
Chris@16
|
190 };
|
Chris@16
|
191
|
Chris@16
|
192 /// \brief A PrimitiveTransform that does nothing
|
Chris@16
|
193 /// and returns void.
|
Chris@16
|
194 struct _void : transform<_void>
|
Chris@16
|
195 {
|
Chris@16
|
196 template<typename Expr, typename State, typename Data>
|
Chris@16
|
197 struct impl : transform_impl<Expr, State, Data>
|
Chris@16
|
198 {
|
Chris@16
|
199 typedef void result_type;
|
Chris@16
|
200
|
Chris@16
|
201 /// Does nothing and returns void
|
Chris@16
|
202 void operator ()(
|
Chris@16
|
203 typename impl::expr_param
|
Chris@16
|
204 , typename impl::state_param
|
Chris@16
|
205 , typename impl::data_param
|
Chris@16
|
206 ) const
|
Chris@16
|
207 {}
|
Chris@16
|
208 };
|
Chris@16
|
209 };
|
Chris@16
|
210
|
Chris@16
|
211 /// \brief A unary CallableTransform that wraps its argument
|
Chris@16
|
212 /// in a \c boost::reference_wrapper\<\>.
|
Chris@16
|
213 ///
|
Chris@16
|
214 /// Example:
|
Chris@16
|
215 ///
|
Chris@16
|
216 /// \code
|
Chris@16
|
217 /// proto::terminal<int>::type i = {42};
|
Chris@16
|
218 /// boost::reference_wrapper<proto::terminal<int>::type> j
|
Chris@16
|
219 /// = proto::when<_, proto::_byref(_)>()(i);
|
Chris@16
|
220 /// assert( boost::addressof(i) == boost::addressof(j.get()) );
|
Chris@16
|
221 /// \endcode
|
Chris@16
|
222 struct _byref : callable
|
Chris@16
|
223 {
|
Chris@16
|
224 template<typename Sig>
|
Chris@16
|
225 struct result;
|
Chris@16
|
226
|
Chris@16
|
227 template<typename This, typename T>
|
Chris@16
|
228 struct result<This(T)>
|
Chris@16
|
229 {
|
Chris@16
|
230 typedef boost::reference_wrapper<T const> const type;
|
Chris@16
|
231 };
|
Chris@16
|
232
|
Chris@16
|
233 template<typename This, typename T>
|
Chris@16
|
234 struct result<This(T &)>
|
Chris@16
|
235 {
|
Chris@16
|
236 typedef boost::reference_wrapper<T> const type;
|
Chris@16
|
237 };
|
Chris@16
|
238
|
Chris@16
|
239 /// Wrap the parameter \c t in a \c boost::reference_wrapper\<\>
|
Chris@16
|
240 /// \param t The object to wrap
|
Chris@16
|
241 /// \return <tt>boost::ref(t)</tt>
|
Chris@16
|
242 /// \throw nothrow
|
Chris@16
|
243 template<typename T>
|
Chris@16
|
244 boost::reference_wrapper<T> const operator ()(T &t) const
|
Chris@16
|
245 {
|
Chris@16
|
246 return boost::reference_wrapper<T>(t);
|
Chris@16
|
247 }
|
Chris@16
|
248
|
Chris@16
|
249 /// \overload
|
Chris@16
|
250 ///
|
Chris@16
|
251 template<typename T>
|
Chris@16
|
252 boost::reference_wrapper<T const> const operator ()(T const &t) const
|
Chris@16
|
253 {
|
Chris@16
|
254 return boost::reference_wrapper<T const>(t);
|
Chris@16
|
255 }
|
Chris@16
|
256 };
|
Chris@16
|
257
|
Chris@16
|
258 /// \brief A unary CallableTransform that strips references
|
Chris@16
|
259 /// and \c boost::reference_wrapper\<\> from its argument.
|
Chris@16
|
260 ///
|
Chris@16
|
261 /// Example:
|
Chris@16
|
262 ///
|
Chris@16
|
263 /// \code
|
Chris@16
|
264 /// proto::terminal<int>::type i = {42};
|
Chris@16
|
265 /// int j = 67;
|
Chris@16
|
266 /// int k = proto::when<_, proto::_byval(proto::_state)>()(i, boost::ref(j));
|
Chris@16
|
267 /// assert( 67 == k );
|
Chris@16
|
268 /// \endcode
|
Chris@16
|
269 struct _byval : callable
|
Chris@16
|
270 {
|
Chris@16
|
271 template<typename Sig>
|
Chris@16
|
272 struct result;
|
Chris@16
|
273
|
Chris@16
|
274 template<typename This, typename T>
|
Chris@16
|
275 struct result<This(T)>
|
Chris@16
|
276 {
|
Chris@16
|
277 typedef T type;
|
Chris@16
|
278 };
|
Chris@16
|
279
|
Chris@16
|
280 template<typename This, typename T>
|
Chris@16
|
281 struct result<This(T &)>
|
Chris@16
|
282 : result<This(T)>
|
Chris@16
|
283 {};
|
Chris@16
|
284
|
Chris@16
|
285 template<typename This, typename T>
|
Chris@16
|
286 struct result<This(boost::reference_wrapper<T>)>
|
Chris@16
|
287 : result<This(T)>
|
Chris@16
|
288 {};
|
Chris@16
|
289
|
Chris@16
|
290 /// \param t The object to unref
|
Chris@16
|
291 /// \return <tt>t</tt>
|
Chris@16
|
292 /// \throw nothrow
|
Chris@16
|
293 template<typename T>
|
Chris@16
|
294 T operator ()(T const &t) const
|
Chris@16
|
295 {
|
Chris@16
|
296 return t;
|
Chris@16
|
297 }
|
Chris@16
|
298
|
Chris@16
|
299 /// \overload
|
Chris@16
|
300 ///
|
Chris@16
|
301 template<typename T>
|
Chris@16
|
302 T operator ()(boost::reference_wrapper<T> const &t) const
|
Chris@16
|
303 {
|
Chris@16
|
304 return t;
|
Chris@16
|
305 }
|
Chris@16
|
306 };
|
Chris@16
|
307
|
Chris@16
|
308 /// INTERNAL ONLY
|
Chris@16
|
309 ///
|
Chris@16
|
310 template<>
|
Chris@16
|
311 struct is_callable<_expr>
|
Chris@16
|
312 : mpl::true_
|
Chris@16
|
313 {};
|
Chris@16
|
314
|
Chris@16
|
315 /// INTERNAL ONLY
|
Chris@16
|
316 ///
|
Chris@16
|
317 template<>
|
Chris@16
|
318 struct is_callable<_state>
|
Chris@16
|
319 : mpl::true_
|
Chris@16
|
320 {};
|
Chris@16
|
321
|
Chris@16
|
322 /// INTERNAL ONLY
|
Chris@16
|
323 ///
|
Chris@16
|
324 template<>
|
Chris@16
|
325 struct is_callable<_data>
|
Chris@16
|
326 : mpl::true_
|
Chris@16
|
327 {};
|
Chris@16
|
328
|
Chris@16
|
329 /// INTERNAL ONLY
|
Chris@16
|
330 ///
|
Chris@16
|
331 template<int N>
|
Chris@16
|
332 struct is_callable<_child_c<N> >
|
Chris@16
|
333 : mpl::true_
|
Chris@16
|
334 {};
|
Chris@16
|
335
|
Chris@16
|
336 /// INTERNAL ONLY
|
Chris@16
|
337 ///
|
Chris@16
|
338 template<>
|
Chris@16
|
339 struct is_callable<_value>
|
Chris@16
|
340 : mpl::true_
|
Chris@16
|
341 {};
|
Chris@16
|
342
|
Chris@16
|
343 /// INTERNAL ONLY
|
Chris@16
|
344 ///
|
Chris@16
|
345 template<>
|
Chris@16
|
346 struct is_callable<_byref>
|
Chris@16
|
347 : mpl::true_
|
Chris@16
|
348 {};
|
Chris@16
|
349
|
Chris@16
|
350 /// INTERNAL ONLY
|
Chris@16
|
351 ///
|
Chris@16
|
352 template<>
|
Chris@16
|
353 struct is_callable<_byval>
|
Chris@16
|
354 : mpl::true_
|
Chris@16
|
355 {};
|
Chris@16
|
356
|
Chris@16
|
357 }}
|
Chris@16
|
358
|
Chris@16
|
359 #endif
|