Chris@16
|
1 ///////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
2 /// \file make_expr.hpp
|
Chris@16
|
3 /// Definition of the \c make_expr() and \c unpack_expr() utilities for
|
Chris@16
|
4 /// building Proto expression nodes from child nodes or from a Fusion
|
Chris@16
|
5 /// sequence of child nodes, respectively.
|
Chris@16
|
6 //
|
Chris@16
|
7 // Copyright 2008 Eric Niebler. Distributed under the Boost
|
Chris@16
|
8 // Software License, Version 1.0. (See accompanying file
|
Chris@16
|
9 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
Chris@16
|
10
|
Chris@16
|
11 #ifndef BOOST_PROTO_MAKE_EXPR_HPP_EAN_04_01_2005
|
Chris@16
|
12 #define BOOST_PROTO_MAKE_EXPR_HPP_EAN_04_01_2005
|
Chris@16
|
13
|
Chris@16
|
14 #include <boost/preprocessor/cat.hpp>
|
Chris@16
|
15 #include <boost/preprocessor/arithmetic/inc.hpp>
|
Chris@16
|
16 #include <boost/preprocessor/arithmetic/dec.hpp>
|
Chris@16
|
17 #include <boost/preprocessor/arithmetic/sub.hpp>
|
Chris@16
|
18 #include <boost/preprocessor/punctuation/comma_if.hpp>
|
Chris@16
|
19 #include <boost/preprocessor/iteration/iterate.hpp>
|
Chris@16
|
20 #include <boost/preprocessor/facilities/intercept.hpp>
|
Chris@16
|
21 #include <boost/preprocessor/repetition/enum.hpp>
|
Chris@16
|
22 #include <boost/preprocessor/repetition/enum_params.hpp>
|
Chris@16
|
23 #include <boost/preprocessor/repetition/enum_binary_params.hpp>
|
Chris@16
|
24 #include <boost/preprocessor/repetition/enum_shifted_params.hpp>
|
Chris@16
|
25 #include <boost/preprocessor/repetition/enum_trailing_params.hpp>
|
Chris@16
|
26 #include <boost/preprocessor/repetition/enum_trailing_binary_params.hpp>
|
Chris@16
|
27 #include <boost/preprocessor/repetition/repeat.hpp>
|
Chris@16
|
28 #include <boost/ref.hpp>
|
Chris@16
|
29 #include <boost/mpl/if.hpp>
|
Chris@16
|
30 #include <boost/mpl/assert.hpp>
|
Chris@16
|
31 #include <boost/mpl/eval_if.hpp>
|
Chris@16
|
32 #include <boost/utility/enable_if.hpp>
|
Chris@16
|
33 #include <boost/type_traits/add_const.hpp>
|
Chris@16
|
34 #include <boost/type_traits/add_reference.hpp>
|
Chris@16
|
35 #include <boost/type_traits/remove_cv.hpp>
|
Chris@16
|
36 #include <boost/proto/proto_fwd.hpp>
|
Chris@16
|
37 #include <boost/proto/traits.hpp>
|
Chris@16
|
38 #include <boost/proto/domain.hpp>
|
Chris@16
|
39 #include <boost/proto/generate.hpp>
|
Chris@16
|
40 #include <boost/fusion/include/at_c.hpp>
|
Chris@16
|
41 #include <boost/fusion/include/begin.hpp>
|
Chris@16
|
42 #include <boost/fusion/include/next.hpp>
|
Chris@16
|
43 #include <boost/fusion/include/value_of.hpp>
|
Chris@16
|
44 #include <boost/fusion/include/size.hpp>
|
Chris@16
|
45 #include <boost/proto/detail/poly_function.hpp>
|
Chris@16
|
46 #include <boost/proto/detail/deprecated.hpp>
|
Chris@16
|
47
|
Chris@101
|
48 #if defined(_MSC_VER)
|
Chris@16
|
49 # pragma warning(push)
|
Chris@16
|
50 # pragma warning(disable : 4180) // qualifier applied to function type has no meaning; ignored
|
Chris@16
|
51 # pragma warning(disable : 4714) // function 'xxx' marked as __forceinline not inlined
|
Chris@16
|
52 #endif
|
Chris@16
|
53
|
Chris@16
|
54 namespace boost { namespace proto
|
Chris@16
|
55 {
|
Chris@16
|
56 /// INTERNAL ONLY
|
Chris@16
|
57 ///
|
Chris@16
|
58 #define BOOST_PROTO_AS_CHILD_TYPE(Z, N, DATA) \
|
Chris@16
|
59 typename boost::proto::detail::protoify< \
|
Chris@16
|
60 BOOST_PP_CAT(BOOST_PP_TUPLE_ELEM(3, 0, DATA), N) \
|
Chris@16
|
61 , BOOST_PP_TUPLE_ELEM(3, 2, DATA) \
|
Chris@16
|
62 >::result_type \
|
Chris@16
|
63 /**/
|
Chris@16
|
64
|
Chris@16
|
65 /// INTERNAL ONLY
|
Chris@16
|
66 ///
|
Chris@16
|
67 #define BOOST_PROTO_AS_CHILD(Z, N, DATA) \
|
Chris@16
|
68 boost::proto::detail::protoify< \
|
Chris@16
|
69 BOOST_PP_CAT(BOOST_PP_TUPLE_ELEM(3, 0, DATA), N) \
|
Chris@16
|
70 , BOOST_PP_TUPLE_ELEM(3, 2, DATA) \
|
Chris@16
|
71 >()(BOOST_PP_CAT(BOOST_PP_TUPLE_ELEM(3, 1, DATA), N)) \
|
Chris@16
|
72 /**/
|
Chris@16
|
73
|
Chris@16
|
74 namespace detail
|
Chris@16
|
75 {
|
Chris@16
|
76 template<typename T, typename Domain>
|
Chris@16
|
77 struct protoify
|
Chris@16
|
78 : Domain::template as_expr<T>
|
Chris@16
|
79 {};
|
Chris@16
|
80
|
Chris@16
|
81 template<typename T, typename Domain>
|
Chris@16
|
82 struct protoify<T &, Domain>
|
Chris@16
|
83 : Domain::template as_child<T>
|
Chris@16
|
84 {};
|
Chris@16
|
85
|
Chris@16
|
86 template<typename T, typename Domain>
|
Chris@16
|
87 struct protoify<boost::reference_wrapper<T>, Domain>
|
Chris@16
|
88 : Domain::template as_child<T>
|
Chris@16
|
89 {};
|
Chris@16
|
90
|
Chris@16
|
91 template<typename T, typename Domain>
|
Chris@16
|
92 struct protoify<boost::reference_wrapper<T> const, Domain>
|
Chris@16
|
93 : Domain::template as_child<T>
|
Chris@16
|
94 {};
|
Chris@16
|
95
|
Chris@16
|
96 // Definition of detail::unpack_expr_
|
Chris@16
|
97 #include <boost/proto/detail/unpack_expr_.hpp>
|
Chris@16
|
98
|
Chris@16
|
99 // Definition of detail::make_expr_
|
Chris@16
|
100 #include <boost/proto/detail/make_expr_.hpp>
|
Chris@16
|
101 }
|
Chris@16
|
102
|
Chris@16
|
103 namespace result_of
|
Chris@16
|
104 {
|
Chris@16
|
105 /// \brief Metafunction that computes the return type of the
|
Chris@16
|
106 /// \c make_expr() function, with a domain deduced from the
|
Chris@16
|
107 /// domains of the children.
|
Chris@16
|
108 ///
|
Chris@16
|
109 /// Use the <tt>result_of::make_expr\<\></tt> metafunction to
|
Chris@16
|
110 /// compute the return type of the \c make_expr() function.
|
Chris@16
|
111 ///
|
Chris@16
|
112 /// In this specialization, the domain is deduced from the
|
Chris@16
|
113 /// domains of the child types. (If
|
Chris@16
|
114 /// <tt>is_domain\<A0\>::value</tt> is \c true, then another
|
Chris@16
|
115 /// specialization is selected.)
|
Chris@16
|
116 template<
|
Chris@16
|
117 typename Tag
|
Chris@16
|
118 , BOOST_PP_ENUM_PARAMS(BOOST_PROTO_MAX_ARITY, typename A)
|
Chris@16
|
119 , typename Void1 // = void
|
Chris@16
|
120 , typename Void2 // = void
|
Chris@16
|
121 >
|
Chris@16
|
122 struct make_expr
|
Chris@16
|
123 {
|
Chris@16
|
124 /// Same as <tt>result_of::make_expr\<Tag, D, A0, ... AN\>::type</tt>
|
Chris@16
|
125 /// where \c D is the deduced domain, which is calculated as follows:
|
Chris@16
|
126 ///
|
Chris@16
|
127 /// For each \c x in <tt>[0,N)</tt> (proceeding in order beginning with
|
Chris@16
|
128 /// <tt>x=0</tt>), if <tt>domain_of\<Ax\>::type</tt> is not
|
Chris@16
|
129 /// \c default_domain, then \c D is <tt>domain_of\<Ax\>::type</tt>.
|
Chris@16
|
130 /// Otherwise, \c D is \c default_domain.
|
Chris@16
|
131 typedef
|
Chris@16
|
132 typename detail::make_expr_<
|
Chris@16
|
133 Tag
|
Chris@16
|
134 , deduce_domain
|
Chris@16
|
135 BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PROTO_MAX_ARITY, A)
|
Chris@16
|
136 >::result_type
|
Chris@16
|
137 type;
|
Chris@16
|
138 };
|
Chris@16
|
139
|
Chris@16
|
140 /// \brief Metafunction that computes the return type of the
|
Chris@16
|
141 /// \c make_expr() function, within the specified domain.
|
Chris@16
|
142 ///
|
Chris@16
|
143 /// Use the <tt>result_of::make_expr\<\></tt> metafunction to compute
|
Chris@16
|
144 /// the return type of the \c make_expr() function.
|
Chris@16
|
145 template<
|
Chris@16
|
146 typename Tag
|
Chris@16
|
147 , typename Domain
|
Chris@16
|
148 BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PROTO_MAX_ARITY, typename A)
|
Chris@16
|
149 >
|
Chris@16
|
150 struct make_expr<
|
Chris@16
|
151 Tag
|
Chris@16
|
152 , Domain
|
Chris@16
|
153 BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PROTO_MAX_ARITY, A)
|
Chris@16
|
154 , typename Domain::proto_is_domain_
|
Chris@16
|
155 >
|
Chris@16
|
156 {
|
Chris@16
|
157 /// If \c Tag is <tt>tag::terminal</tt>, then \c type is a
|
Chris@16
|
158 /// typedef for <tt>boost::result_of\<Domain(expr\<tag::terminal,
|
Chris@16
|
159 /// term\<A0\> \>)\>::type</tt>.
|
Chris@16
|
160 ///
|
Chris@16
|
161 /// Otherwise, \c type is a typedef for <tt>boost::result_of\<Domain(expr\<Tag,
|
Chris@16
|
162 /// listN\< as_child\<A0\>::type, ... as_child\<AN\>::type\>)
|
Chris@16
|
163 /// \>::type</tt>, where \c N is the number of non-void template
|
Chris@16
|
164 /// arguments, and <tt>as_child\<A\>::type</tt> is evaluated as
|
Chris@16
|
165 /// follows:
|
Chris@16
|
166 ///
|
Chris@16
|
167 /// \li If <tt>is_expr\<A\>::value</tt> is \c true, then the
|
Chris@16
|
168 /// child type is \c A.
|
Chris@16
|
169 /// \li If \c A is <tt>B &</tt> or <tt>cv boost::reference_wrapper\<B\></tt>,
|
Chris@16
|
170 /// and <tt>is_expr\<B\>::value</tt> is \c true, then the
|
Chris@16
|
171 /// child type is <tt>B &</tt>.
|
Chris@16
|
172 /// \li If <tt>is_expr\<A\>::value</tt> is \c false, then the
|
Chris@16
|
173 /// child type is <tt>boost::result_of\<Domain(expr\<tag::terminal, term\<A\> \>
|
Chris@16
|
174 /// )\>::type</tt>.
|
Chris@16
|
175 /// \li If \c A is <tt>B &</tt> or <tt>cv boost::reference_wrapper\<B\></tt>,
|
Chris@16
|
176 /// and <tt>is_expr\<B\>::value</tt> is \c false, then the
|
Chris@16
|
177 /// child type is <tt>boost::result_of\<Domain(expr\<tag::terminal, term\<B &\> \>
|
Chris@16
|
178 /// )\>::type</tt>.
|
Chris@16
|
179 typedef
|
Chris@16
|
180 typename detail::make_expr_<
|
Chris@16
|
181 Tag
|
Chris@16
|
182 , Domain
|
Chris@16
|
183 BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PROTO_MAX_ARITY, A)
|
Chris@16
|
184 >::result_type
|
Chris@16
|
185 type;
|
Chris@16
|
186 };
|
Chris@16
|
187
|
Chris@16
|
188 /// \brief Metafunction that computes the return type of the
|
Chris@16
|
189 /// \c unpack_expr() function, with a domain deduced from the
|
Chris@16
|
190 /// domains of the children.
|
Chris@16
|
191 ///
|
Chris@16
|
192 /// Use the <tt>result_of::unpack_expr\<\></tt> metafunction to
|
Chris@16
|
193 /// compute the return type of the \c unpack_expr() function.
|
Chris@16
|
194 ///
|
Chris@16
|
195 /// \c Sequence is a Fusion Forward Sequence.
|
Chris@16
|
196 ///
|
Chris@16
|
197 /// In this specialization, the domain is deduced from the
|
Chris@16
|
198 /// domains of the child types. (If
|
Chris@16
|
199 /// <tt>is_domain\<Sequence>::value</tt> is \c true, then another
|
Chris@16
|
200 /// specialization is selected.)
|
Chris@16
|
201 template<
|
Chris@16
|
202 typename Tag
|
Chris@16
|
203 , typename Sequence
|
Chris@16
|
204 , typename Void1 // = void
|
Chris@16
|
205 , typename Void2 // = void
|
Chris@16
|
206 >
|
Chris@16
|
207 struct unpack_expr
|
Chris@16
|
208 {
|
Chris@16
|
209 /// Let \c S be the type of a Fusion Random Access Sequence
|
Chris@16
|
210 /// equivalent to \c Sequence. Then \c type is the
|
Chris@16
|
211 /// same as <tt>result_of::make_expr\<Tag,
|
Chris@16
|
212 /// fusion::result_of::value_at_c\<S, 0\>::type, ...
|
Chris@16
|
213 /// fusion::result_of::value_at_c\<S, N-1\>::type\>::type</tt>,
|
Chris@16
|
214 /// where \c N is the size of \c S.
|
Chris@16
|
215 typedef
|
Chris@16
|
216 typename detail::unpack_expr_<
|
Chris@16
|
217 Tag
|
Chris@16
|
218 , deduce_domain
|
Chris@16
|
219 , Sequence
|
Chris@16
|
220 , fusion::result_of::size<Sequence>::type::value
|
Chris@16
|
221 >::type
|
Chris@16
|
222 type;
|
Chris@16
|
223 };
|
Chris@16
|
224
|
Chris@16
|
225 /// \brief Metafunction that computes the return type of the
|
Chris@16
|
226 /// \c unpack_expr() function, within the specified domain.
|
Chris@16
|
227 ///
|
Chris@16
|
228 /// Use the <tt>result_of::make_expr\<\></tt> metafunction to compute
|
Chris@16
|
229 /// the return type of the \c make_expr() function.
|
Chris@16
|
230 template<typename Tag, typename Domain, typename Sequence>
|
Chris@16
|
231 struct unpack_expr<Tag, Domain, Sequence, typename Domain::proto_is_domain_>
|
Chris@16
|
232 {
|
Chris@16
|
233 /// Let \c S be the type of a Fusion Random Access Sequence
|
Chris@16
|
234 /// equivalent to \c Sequence. Then \c type is the
|
Chris@16
|
235 /// same as <tt>result_of::make_expr\<Tag, Domain,
|
Chris@16
|
236 /// fusion::result_of::value_at_c\<S, 0\>::type, ...
|
Chris@16
|
237 /// fusion::result_of::value_at_c\<S, N-1\>::type\>::type</tt>,
|
Chris@16
|
238 /// where \c N is the size of \c S.
|
Chris@16
|
239 typedef
|
Chris@16
|
240 typename detail::unpack_expr_<
|
Chris@16
|
241 Tag
|
Chris@16
|
242 , Domain
|
Chris@16
|
243 , Sequence
|
Chris@16
|
244 , fusion::result_of::size<Sequence>::type::value
|
Chris@16
|
245 >::type
|
Chris@16
|
246 type;
|
Chris@16
|
247 };
|
Chris@16
|
248 }
|
Chris@16
|
249
|
Chris@16
|
250 namespace functional
|
Chris@16
|
251 {
|
Chris@16
|
252 /// \brief A callable function object equivalent to the
|
Chris@16
|
253 /// \c proto::make_expr() function.
|
Chris@16
|
254 ///
|
Chris@16
|
255 /// In all cases, <tt>functional::make_expr\<Tag, Domain\>()(a0, ... aN)</tt>
|
Chris@16
|
256 /// is equivalent to <tt>proto::make_expr\<Tag, Domain\>(a0, ... aN)</tt>.
|
Chris@16
|
257 ///
|
Chris@16
|
258 /// <tt>functional::make_expr\<Tag\>()(a0, ... aN)</tt>
|
Chris@16
|
259 /// is equivalent to <tt>proto::make_expr\<Tag\>(a0, ... aN)</tt>.
|
Chris@16
|
260 template<typename Tag, typename Domain /* = deduce_domain*/>
|
Chris@16
|
261 struct make_expr
|
Chris@16
|
262 {
|
Chris@16
|
263 BOOST_PROTO_CALLABLE()
|
Chris@16
|
264 BOOST_PROTO_POLY_FUNCTION()
|
Chris@16
|
265
|
Chris@16
|
266 template<typename Sig>
|
Chris@16
|
267 struct result;
|
Chris@16
|
268
|
Chris@16
|
269 template<typename This, typename A0>
|
Chris@16
|
270 struct result<This(A0)>
|
Chris@16
|
271 {
|
Chris@16
|
272 typedef
|
Chris@16
|
273 typename result_of::make_expr<
|
Chris@16
|
274 Tag
|
Chris@16
|
275 , Domain
|
Chris@16
|
276 , A0
|
Chris@16
|
277 >::type
|
Chris@16
|
278 type;
|
Chris@16
|
279 };
|
Chris@16
|
280
|
Chris@16
|
281 /// Construct an expression node with tag type \c Tag
|
Chris@16
|
282 /// and in the domain \c Domain.
|
Chris@16
|
283 ///
|
Chris@16
|
284 /// \return <tt>proto::make_expr\<Tag, Domain\>(a0,...aN)</tt>
|
Chris@16
|
285 template<typename A0>
|
Chris@16
|
286 BOOST_FORCEINLINE
|
Chris@16
|
287 typename result_of::make_expr<
|
Chris@16
|
288 Tag
|
Chris@16
|
289 , Domain
|
Chris@16
|
290 , A0 const
|
Chris@16
|
291 >::type const
|
Chris@16
|
292 operator ()(A0 const &a0) const
|
Chris@16
|
293 {
|
Chris@16
|
294 return proto::detail::make_expr_<
|
Chris@16
|
295 Tag
|
Chris@16
|
296 , Domain
|
Chris@16
|
297 , A0 const
|
Chris@16
|
298 >()(a0);
|
Chris@16
|
299 }
|
Chris@16
|
300
|
Chris@16
|
301 // Additional overloads generated by the preprocessor ...
|
Chris@16
|
302 #include <boost/proto/detail/make_expr_funop.hpp>
|
Chris@16
|
303
|
Chris@16
|
304 /// INTERNAL ONLY
|
Chris@16
|
305 ///
|
Chris@16
|
306 template<
|
Chris@16
|
307 BOOST_PP_ENUM_BINARY_PARAMS(
|
Chris@16
|
308 BOOST_PROTO_MAX_ARITY
|
Chris@16
|
309 , typename A
|
Chris@16
|
310 , = void BOOST_PP_INTERCEPT
|
Chris@16
|
311 )
|
Chris@16
|
312 >
|
Chris@16
|
313 struct impl
|
Chris@16
|
314 : detail::make_expr_<
|
Chris@16
|
315 Tag
|
Chris@16
|
316 , Domain
|
Chris@16
|
317 BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PROTO_MAX_ARITY, A)
|
Chris@16
|
318 >
|
Chris@16
|
319 {};
|
Chris@16
|
320 };
|
Chris@16
|
321
|
Chris@16
|
322 /// \brief A callable function object equivalent to the
|
Chris@16
|
323 /// \c proto::unpack_expr() function.
|
Chris@16
|
324 ///
|
Chris@16
|
325 /// In all cases, <tt>functional::unpack_expr\<Tag, Domain\>()(seq)</tt>
|
Chris@16
|
326 /// is equivalent to <tt>proto::unpack_expr\<Tag, Domain\>(seq)</tt>.
|
Chris@16
|
327 ///
|
Chris@16
|
328 /// <tt>functional::unpack_expr\<Tag\>()(seq)</tt>
|
Chris@16
|
329 /// is equivalent to <tt>proto::unpack_expr\<Tag\>(seq)</tt>.
|
Chris@16
|
330 template<typename Tag, typename Domain /* = deduce_domain*/>
|
Chris@16
|
331 struct unpack_expr
|
Chris@16
|
332 {
|
Chris@16
|
333 BOOST_PROTO_CALLABLE()
|
Chris@16
|
334
|
Chris@16
|
335 template<typename Sig>
|
Chris@16
|
336 struct result;
|
Chris@16
|
337
|
Chris@16
|
338 template<typename This, typename Sequence>
|
Chris@16
|
339 struct result<This(Sequence)>
|
Chris@16
|
340 {
|
Chris@16
|
341 typedef
|
Chris@16
|
342 typename result_of::unpack_expr<
|
Chris@16
|
343 Tag
|
Chris@16
|
344 , Domain
|
Chris@16
|
345 , typename remove_reference<Sequence>::type
|
Chris@16
|
346 >::type
|
Chris@16
|
347 type;
|
Chris@16
|
348 };
|
Chris@16
|
349
|
Chris@16
|
350 /// Construct an expression node with tag type \c Tag
|
Chris@16
|
351 /// and in the domain \c Domain.
|
Chris@16
|
352 ///
|
Chris@16
|
353 /// \param sequence A Fusion Forward Sequence
|
Chris@16
|
354 /// \return <tt>proto::unpack_expr\<Tag, Domain\>(sequence)</tt>
|
Chris@16
|
355 template<typename Sequence>
|
Chris@16
|
356 BOOST_FORCEINLINE
|
Chris@16
|
357 typename result_of::unpack_expr<Tag, Domain, Sequence const>::type const
|
Chris@16
|
358 operator ()(Sequence const &sequence) const
|
Chris@16
|
359 {
|
Chris@16
|
360 return proto::detail::unpack_expr_<
|
Chris@16
|
361 Tag
|
Chris@16
|
362 , Domain
|
Chris@16
|
363 , Sequence const
|
Chris@16
|
364 , fusion::result_of::size<Sequence>::type::value
|
Chris@16
|
365 >::call(sequence);
|
Chris@16
|
366 }
|
Chris@16
|
367 };
|
Chris@16
|
368
|
Chris@16
|
369 } // namespace functional
|
Chris@16
|
370
|
Chris@16
|
371 /// \brief Construct an expression of the requested tag type
|
Chris@16
|
372 /// with a domain and with the specified arguments as children.
|
Chris@16
|
373 ///
|
Chris@16
|
374 /// This function template may be invoked either with or without
|
Chris@16
|
375 /// specifying a \c Domain argument. If no domain is specified,
|
Chris@16
|
376 /// the domain is deduced by examining in order the domains of
|
Chris@16
|
377 /// the given arguments and taking the first that is not
|
Chris@16
|
378 /// \c default_domain, if any such domain exists, or
|
Chris@16
|
379 /// \c default_domain otherwise.
|
Chris@16
|
380 ///
|
Chris@16
|
381 /// Let \c wrap_(x) be defined such that:
|
Chris@16
|
382 /// \li If \c x is a <tt>boost::reference_wrapper\<\></tt>,
|
Chris@16
|
383 /// \c wrap_(x) is equivalent to <tt>as_child\<Domain\>(x.get())</tt>.
|
Chris@16
|
384 /// \li Otherwise, \c wrap_(x) is equivalent to
|
Chris@16
|
385 /// <tt>as_expr\<Domain\>(x)</tt>.
|
Chris@16
|
386 ///
|
Chris@16
|
387 /// Let <tt>make_\<Tag\>(b0,...bN)</tt> be defined as
|
Chris@16
|
388 /// <tt>expr\<Tag, listN\<C0,...CN\> \>::make(c0,...cN)</tt>
|
Chris@16
|
389 /// where \c Bx is the type of \c bx.
|
Chris@16
|
390 ///
|
Chris@16
|
391 /// \return <tt>Domain()(make_\<Tag\>(wrap_(a0),...wrap_(aN)))</tt>.
|
Chris@16
|
392 template<typename Tag, typename A0>
|
Chris@16
|
393 BOOST_FORCEINLINE
|
Chris@16
|
394 typename lazy_disable_if<
|
Chris@16
|
395 is_domain<A0>
|
Chris@16
|
396 , result_of::make_expr<
|
Chris@16
|
397 Tag
|
Chris@16
|
398 , A0 const
|
Chris@16
|
399 >
|
Chris@16
|
400 >::type const
|
Chris@16
|
401 make_expr(A0 const &a0)
|
Chris@16
|
402 {
|
Chris@16
|
403 return proto::detail::make_expr_<
|
Chris@16
|
404 Tag
|
Chris@16
|
405 , deduce_domain
|
Chris@16
|
406 , A0 const
|
Chris@16
|
407 >()(a0);
|
Chris@16
|
408 }
|
Chris@16
|
409
|
Chris@16
|
410 /// \overload
|
Chris@16
|
411 ///
|
Chris@16
|
412 template<typename Tag, typename Domain, typename C0>
|
Chris@16
|
413 BOOST_FORCEINLINE
|
Chris@16
|
414 typename result_of::make_expr<
|
Chris@16
|
415 Tag
|
Chris@16
|
416 , Domain
|
Chris@16
|
417 , C0 const
|
Chris@16
|
418 >::type const
|
Chris@16
|
419 make_expr(C0 const &c0)
|
Chris@16
|
420 {
|
Chris@16
|
421 return proto::detail::make_expr_<
|
Chris@16
|
422 Tag
|
Chris@16
|
423 , Domain
|
Chris@16
|
424 , C0 const
|
Chris@16
|
425 >()(c0);
|
Chris@16
|
426 }
|
Chris@16
|
427
|
Chris@16
|
428 // Additional overloads generated by the preprocessor...
|
Chris@16
|
429 #include <boost/proto/detail/make_expr.hpp>
|
Chris@16
|
430
|
Chris@16
|
431 /// \brief Construct an expression of the requested tag type
|
Chris@16
|
432 /// with a domain and with childres from the specified Fusion
|
Chris@16
|
433 /// Forward Sequence.
|
Chris@16
|
434 ///
|
Chris@16
|
435 /// This function template may be invoked either with or without
|
Chris@16
|
436 /// specifying a \c Domain argument. If no domain is specified,
|
Chris@16
|
437 /// the domain is deduced by examining in order the domains of the
|
Chris@16
|
438 /// elements of \c sequence and taking the first that is not
|
Chris@16
|
439 /// \c default_domain, if any such domain exists, or
|
Chris@16
|
440 /// \c default_domain otherwise.
|
Chris@16
|
441 ///
|
Chris@16
|
442 /// Let \c s be a Fusion Random Access Sequence equivalent to \c sequence.
|
Chris@16
|
443 /// Let <tt>wrap_\<N\>(s)</tt>, where \c s has type \c S, be defined
|
Chris@16
|
444 /// such that:
|
Chris@16
|
445 /// \li If <tt>fusion::result_of::value_at_c\<S,N\>::type</tt> is a reference,
|
Chris@16
|
446 /// <tt>wrap_\<N\>(s)</tt> is equivalent to
|
Chris@16
|
447 /// <tt>as_child\<Domain\>(fusion::at_c\<N\>(s))</tt>.
|
Chris@16
|
448 /// \li Otherwise, <tt>wrap_\<N\>(s)</tt> is equivalent to
|
Chris@16
|
449 /// <tt>as_expr\<Domain\>(fusion::at_c\<N\>(s))</tt>.
|
Chris@16
|
450 ///
|
Chris@16
|
451 /// Let <tt>make_\<Tag\>(b0,...bN)</tt> be defined as
|
Chris@16
|
452 /// <tt>expr\<Tag, listN\<B0,...BN\> \>::make(b0,...bN)</tt>
|
Chris@16
|
453 /// where \c Bx is the type of \c bx.
|
Chris@16
|
454 ///
|
Chris@16
|
455 /// \param sequence a Fusion Forward Sequence.
|
Chris@16
|
456 /// \return <tt>Domain()(make_\<Tag\>(wrap_\<0\>(s),...wrap_\<N-1\>(s)))</tt>,
|
Chris@16
|
457 /// where N is the size of \c Sequence.
|
Chris@16
|
458 template<typename Tag, typename Sequence>
|
Chris@16
|
459 BOOST_FORCEINLINE
|
Chris@16
|
460 typename lazy_disable_if<
|
Chris@16
|
461 is_domain<Sequence>
|
Chris@16
|
462 , result_of::unpack_expr<Tag, Sequence const>
|
Chris@16
|
463 >::type const
|
Chris@16
|
464 unpack_expr(Sequence const &sequence)
|
Chris@16
|
465 {
|
Chris@16
|
466 return proto::detail::unpack_expr_<
|
Chris@16
|
467 Tag
|
Chris@16
|
468 , deduce_domain
|
Chris@16
|
469 , Sequence const
|
Chris@16
|
470 , fusion::result_of::size<Sequence>::type::value
|
Chris@16
|
471 >::call(sequence);
|
Chris@16
|
472 }
|
Chris@16
|
473
|
Chris@16
|
474 /// \overload
|
Chris@16
|
475 ///
|
Chris@16
|
476 template<typename Tag, typename Domain, typename Sequence2>
|
Chris@16
|
477 BOOST_FORCEINLINE
|
Chris@16
|
478 typename result_of::unpack_expr<Tag, Domain, Sequence2 const>::type const
|
Chris@16
|
479 unpack_expr(Sequence2 const &sequence2)
|
Chris@16
|
480 {
|
Chris@16
|
481 return proto::detail::unpack_expr_<
|
Chris@16
|
482 Tag
|
Chris@16
|
483 , Domain
|
Chris@16
|
484 , Sequence2 const
|
Chris@16
|
485 , fusion::result_of::size<Sequence2>::type::value
|
Chris@16
|
486 >::call(sequence2);
|
Chris@16
|
487 }
|
Chris@16
|
488
|
Chris@16
|
489 /// INTERNAL ONLY
|
Chris@16
|
490 ///
|
Chris@16
|
491 template<typename Tag, typename Domain>
|
Chris@16
|
492 struct is_callable<functional::make_expr<Tag, Domain> >
|
Chris@16
|
493 : mpl::true_
|
Chris@16
|
494 {};
|
Chris@16
|
495
|
Chris@16
|
496 /// INTERNAL ONLY
|
Chris@16
|
497 ///
|
Chris@16
|
498 template<typename Tag, typename Domain>
|
Chris@16
|
499 struct is_callable<functional::unpack_expr<Tag, Domain> >
|
Chris@16
|
500 : mpl::true_
|
Chris@16
|
501 {};
|
Chris@16
|
502
|
Chris@16
|
503 }}
|
Chris@16
|
504
|
Chris@101
|
505 #if defined(_MSC_VER)
|
Chris@16
|
506 # pragma warning(pop)
|
Chris@16
|
507 #endif
|
Chris@16
|
508
|
Chris@16
|
509 #endif // BOOST_PROTO_MAKE_EXPR_HPP_EAN_04_01_2005
|