1 #if !defined(BOOST_PROTO_DONT_USE_PREPROCESSED_FILES)
2 
3     #ifndef BOOST_NO_VARIADIC_TEMPLATES
4         #include <boost/proto/detail/preprocessed/expr_variadic.hpp>
5     #else
6         #include <boost/proto/detail/preprocessed/expr.hpp>
7     #endif
8 
9 #elif !defined(BOOST_PP_IS_ITERATING)
10 
11     /// INTERNAL ONLY
12     ///
13     #define BOOST_PROTO_CHILD(Z, N, DATA)                                                       \
14         typedef BOOST_PP_CAT(Arg, N) BOOST_PP_CAT(proto_child, N);                              \
15         BOOST_PP_CAT(proto_child, N) BOOST_PP_CAT(child, N);                                    \
16         /**< INTERNAL ONLY */
17 
18     /// INTERNAL ONLY
19     ///
20     #define BOOST_PROTO_VOID(Z, N, DATA)                                                        \
21         typedef void BOOST_PP_CAT(proto_child, N);                                              \
22         /**< INTERNAL ONLY */
23 
24     // Generate variadic versions of expr
25     #if defined(__WAVE__) && defined(BOOST_PROTO_CREATE_PREPROCESSED_FILES)
26         #pragma wave option(preserve: 2, line: 0, output: "preprocessed/expr_variadic.hpp")
27     #endif
28 
29     ///////////////////////////////////////////////////////////////////////////////
30     /// \file expr_variadic.hpp
31     /// Contains definition of expr\<\> class template.
32     //
33     //  Copyright 2008 Eric Niebler. Distributed under the Boost
34     //  Software License, Version 1.0. (See accompanying file
35     //  LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
36 
37     #if defined(__WAVE__) && defined(BOOST_PROTO_CREATE_PREPROCESSED_FILES)
38         #pragma wave option(preserve: 1)
39     #endif
40 
41     // The expr<> specializations are actually defined here.
42     #define BOOST_PROTO_DEFINE_TERMINAL
43     #define BOOST_PP_ITERATION_PARAMS_1                                                         \
44         (3, (0, 0, <boost/proto/detail/expr.hpp>))
45     #include BOOST_PP_ITERATE()
46 
47     #undef BOOST_PROTO_DEFINE_TERMINAL
48     #define BOOST_PP_ITERATION_PARAMS_1                                                         \
49         (3, (1, BOOST_PROTO_MAX_ARITY, <boost/proto/detail/expr.hpp>))
50     #include BOOST_PP_ITERATE()
51 
52     // Generate non-variadic versions of expr
53     #if defined(__WAVE__) && defined(BOOST_PROTO_CREATE_PREPROCESSED_FILES)
54         #define BOOST_NO_VARIADIC_TEMPLATES
55         #pragma wave option(preserve: 2, line: 0, output: "preprocessed/expr.hpp")
56 
57         ///////////////////////////////////////////////////////////////////////////////
58         /// \file expr.hpp
59         /// Contains definition of expr\<\> class template.
60         //
61         //  Copyright 2008 Eric Niebler. Distributed under the Boost
62         //  Software License, Version 1.0. (See accompanying file
63         //  LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
64 
65         #pragma wave option(preserve: 1)
66 
67         // The expr<> specializations are actually defined here.
68         #define BOOST_PROTO_DEFINE_TERMINAL
69         #define BOOST_PP_ITERATION_PARAMS_1 (3, (0, 0, <boost/proto/detail/expr.hpp>))
70         #include BOOST_PP_ITERATE()
71 
72         #undef BOOST_PROTO_DEFINE_TERMINAL
73         #define BOOST_PP_ITERATION_PARAMS_1 (3, (1, BOOST_PROTO_MAX_ARITY, <boost/proto/detail/expr.hpp>))
74         #include BOOST_PP_ITERATE()
75 
76         #pragma wave option(output: null)
77         #undef BOOST_NO_VARIADIC_TEMPLATES
78     #endif
79 
80     #undef BOOST_PROTO_CHILD
81     #undef BOOST_PROTO_VOID
82 
83 #else
84 
85     #define ARG_COUNT BOOST_PP_MAX(1, BOOST_PP_ITERATION())
86 
87     /// \brief Representation of a node in an expression tree.
88     ///
89     /// \c proto::expr\<\> is a node in an expression template tree. It
90     /// is a container for its child sub-trees. It also serves as
91     /// the terminal nodes of the tree.
92     ///
93     /// \c Tag is type that represents the operation encoded by
94     ///             this expression. It is typically one of the structs
95     ///             in the \c boost::proto::tag namespace, but it doesn't
96     ///             have to be.
97     ///
98     /// \c Args is a type list representing the type of the children
99     ///             of this expression. It is an instantiation of one
100     ///             of \c proto::list1\<\>, \c proto::list2\<\>, etc. The
101     ///             child types must all themselves be either \c expr\<\>
102     ///             or <tt>proto::expr\<\>&</tt>. If \c Args is an
103     ///             instantiation of \c proto::term\<\> then this
104     ///             \c expr\<\> type represents a terminal expression;
105     ///             the parameter to the \c proto::term\<\> template
106     ///             represents the terminal's value type.
107     ///
108     /// \c Arity is an integral constant representing the number of child
109     ///             nodes this node contains. If \c Arity is 0, then this
110     ///             node is a terminal.
111     ///
112     /// \c proto::expr\<\> is a valid Fusion random-access sequence, where
113     /// the elements of the sequence are the child expressions.
114     #ifdef BOOST_PROTO_DEFINE_TERMINAL
115     template<typename Tag, typename Arg0>
116     struct expr<Tag, term<Arg0>, 0>
117     #else
118     template<typename Tag BOOST_PP_ENUM_TRAILING_PARAMS(ARG_COUNT, typename Arg)>
119     struct expr<Tag, BOOST_PP_CAT(list, BOOST_PP_ITERATION())<BOOST_PP_ENUM_PARAMS(ARG_COUNT, Arg)>, BOOST_PP_ITERATION() >
120     #endif
121     {
122         typedef Tag proto_tag;
123         static const long proto_arity_c = BOOST_PP_ITERATION();
124         typedef mpl::long_<BOOST_PP_ITERATION() > proto_arity;
125         typedef expr proto_base_expr;
126         #ifdef BOOST_PROTO_DEFINE_TERMINAL
127         typedef term<Arg0> proto_args;
128         #else
129         typedef BOOST_PP_CAT(list, BOOST_PP_ITERATION())<BOOST_PP_ENUM_PARAMS(ARG_COUNT, Arg)> proto_args;
130         #endif
131         typedef basic_expr<Tag, proto_args, BOOST_PP_ITERATION() > proto_grammar;
132         typedef default_domain proto_domain;
133         typedef default_generator proto_generator;
134         typedef proto::tag::proto_expr fusion_tag;
135         typedef expr proto_derived_expr;
136         typedef void proto_is_expr_; /**< INTERNAL ONLY */
137 
138         BOOST_PP_REPEAT(ARG_COUNT, BOOST_PROTO_CHILD, ~)
139         BOOST_PP_REPEAT_FROM_TO(ARG_COUNT, BOOST_PROTO_MAX_ARITY, BOOST_PROTO_VOID, ~)
140 
141         /// \return *this
142         ///
proto_baseexpr143         expr const &proto_base() const
144         {
145             return *this;
146         }
147 
148         /// \overload
149         ///
proto_baseexpr150         expr &proto_base()
151         {
152             return *this;
153         }
154 
155     #ifdef BOOST_PROTO_DEFINE_TERMINAL
156         /// \return A new \c expr\<\> object initialized with the specified
157         /// arguments.
158         ///
159         template<typename A0>
makeexpr160         static expr const make(A0 &a0)
161         {
162             return detail::make_terminal(a0, static_cast<expr *>(0), static_cast<proto_args *>(0));
163         }
164 
165         /// \overload
166         ///
167         template<typename A0>
makeexpr168         static expr const make(A0 const &a0)
169         {
170             return detail::make_terminal(a0, static_cast<expr *>(0), static_cast<proto_args *>(0));
171         }
172     #else
173         /// \return A new \c expr\<\> object initialized with the specified
174         /// arguments.
175         ///
176         template<BOOST_PP_ENUM_PARAMS(ARG_COUNT, typename A)>
makeexpr177         static expr const make(BOOST_PP_ENUM_BINARY_PARAMS(ARG_COUNT, A, const &a))
178         {
179             expr that = {BOOST_PP_ENUM_PARAMS(ARG_COUNT, a)};
180             return that;
181         }
182     #endif
183 
184     #if 1 == BOOST_PP_ITERATION()
185         /// If \c Tag is \c boost::proto::tag::address_of and \c proto_child0 is
186         /// <tt>T&</tt>, then \c address_of_hack_type_ is <tt>T*</tt>.
187         /// Otherwise, it is some undefined type.
188         typedef typename detail::address_of_hack<Tag, proto_child0>::type address_of_hack_type_;
189 
190         /// \return The address of <tt>this->child0</tt> if \c Tag is
191         /// \c boost::proto::tag::address_of. Otherwise, this function will
192         /// fail to compile.
193         ///
194         /// \attention Proto overloads <tt>operator&</tt>, which means that
195         /// proto-ified objects cannot have their addresses taken, unless we use
196         /// the following hack to make \c &x implicitly convertible to \c X*.
operator address_of_hack_type_expr197         operator address_of_hack_type_() const
198         {
199             return boost::addressof(this->child0);
200         }
201     #else
202         /// INTERNAL ONLY
203         ///
204         typedef detail::not_a_valid_type address_of_hack_type_;
205     #endif
206 
207         /// Assignment
208         ///
209         /// \param a The rhs.
210         /// \return A new \c expr\<\> node representing an assignment of \c that to \c *this.
211         proto::expr<
212             proto::tag::assign
213           , list2<expr &, expr const &>
214           , 2
215         > const
operator =expr216         operator =(expr const &a)
217         {
218             proto::expr<
219                 proto::tag::assign
220               , list2<expr &, expr const &>
221               , 2
222             > that = {*this, a};
223             return that;
224         }
225 
226         /// Assignment
227         ///
228         /// \param a The rhs.
229         /// \return A new \c expr\<\> node representing an assignment of \c a to \c *this.
230         template<typename A>
231         proto::expr<
232             proto::tag::assign
233           , list2<expr const &, typename result_of::as_child<A>::type>
234           , 2
235         > const
operator =expr236         operator =(A &a) const
237         {
238             proto::expr<
239                 proto::tag::assign
240               , list2<expr const &, typename result_of::as_child<A>::type>
241               , 2
242             > that = {*this, proto::as_child(a)};
243             return that;
244         }
245 
246         /// \overload
247         ///
248         template<typename A>
249         proto::expr<
250             proto::tag::assign
251           , list2<expr const &, typename result_of::as_child<A const>::type>
252           , 2
253         > const
operator =expr254         operator =(A const &a) const
255         {
256             proto::expr<
257                 proto::tag::assign
258               , list2<expr const &, typename result_of::as_child<A const>::type>
259               , 2
260             > that = {*this, proto::as_child(a)};
261             return that;
262         }
263 
264     #ifdef BOOST_PROTO_DEFINE_TERMINAL
265         /// \overload
266         ///
267         template<typename A>
268         proto::expr<
269             proto::tag::assign
270           , list2<expr &, typename result_of::as_child<A>::type>
271           , 2
272         > const
operator =expr273         operator =(A &a)
274         {
275             proto::expr<
276                 proto::tag::assign
277               , list2<expr &, typename result_of::as_child<A>::type>
278               , 2
279             > that = {*this, proto::as_child(a)};
280             return that;
281         }
282 
283         /// \overload
284         ///
285         template<typename A>
286         proto::expr<
287             proto::tag::assign
288           , list2<expr &, typename result_of::as_child<A const>::type>
289           , 2
290         > const
operator =expr291         operator =(A const &a)
292         {
293             proto::expr<
294                 proto::tag::assign
295               , list2<expr &, typename result_of::as_child<A const>::type>
296               , 2
297             > that = {*this, proto::as_child(a)};
298             return that;
299         }
300     #endif
301 
302         /// Subscript
303         ///
304         /// \param a The rhs.
305         /// \return A new \c expr\<\> node representing \c *this subscripted with \c a.
306         template<typename A>
307         proto::expr<
308             proto::tag::subscript
309           , list2<expr const &, typename result_of::as_child<A>::type>
310           , 2
311         > const
operator []expr312         operator [](A &a) const
313         {
314             proto::expr<
315                 proto::tag::subscript
316               , list2<expr const &, typename result_of::as_child<A>::type>
317               , 2
318             > that = {*this, proto::as_child(a)};
319             return that;
320         }
321 
322         /// \overload
323         ///
324         template<typename A>
325         proto::expr<
326             proto::tag::subscript
327           , list2<expr const &, typename result_of::as_child<A const>::type>
328           , 2
329         > const
operator []expr330         operator [](A const &a) const
331         {
332             proto::expr<
333                 proto::tag::subscript
334               , list2<expr const &, typename result_of::as_child<A const>::type>
335               , 2
336             > that = {*this, proto::as_child(a)};
337             return that;
338         }
339 
340     #ifdef BOOST_PROTO_DEFINE_TERMINAL
341         /// \overload
342         ///
343         template<typename A>
344         proto::expr<
345             proto::tag::subscript
346           , list2<expr &, typename result_of::as_child<A>::type>
347           , 2
348         > const
operator []expr349         operator [](A &a)
350         {
351             proto::expr<
352                 proto::tag::subscript
353               , list2<expr &, typename result_of::as_child<A>::type>
354               , 2
355             > that = {*this, proto::as_child(a)};
356             return that;
357         }
358 
359         /// \overload
360         ///
361         template<typename A>
362         proto::expr<
363             proto::tag::subscript
364           , list2<expr &, typename result_of::as_child<A const>::type>
365           , 2
366         > const
operator []expr367         operator [](A const &a)
368         {
369             proto::expr<
370                 proto::tag::subscript
371               , list2<expr &, typename result_of::as_child<A const>::type>
372               , 2
373             > that = {*this, proto::as_child(a)};
374             return that;
375         }
376     #endif
377 
378         /// Encodes the return type of \c expr\<\>::operator(), for use with \c boost::result_of\<\>
379         ///
380         template<typename Sig>
381         struct result
382         {
383             typedef typename result_of::funop<Sig, expr, default_domain>::type const type;
384         };
385 
386     #ifndef BOOST_NO_VARIADIC_TEMPLATES
387         /// \overload
388         ///
389         template<typename ...A>
390         typename result_of::funop<
391             expr const(A const &...)
392           , expr
393           , default_domain
394         >::type const
operator ()expr395         operator ()(A const &... a) const
396         {
397             return result_of::funop<
398                 expr const(A const &...)
399               , expr
400               , default_domain
401             >::call(*this, a...);
402         }
403 
404     #ifdef BOOST_PROTO_DEFINE_TERMINAL
405         /// \overload
406         ///
407         template<typename ...A>
408         typename result_of::funop<
409             expr(A const &...)
410           , expr
411           , default_domain
412         >::type const
operator ()expr413         operator ()(A const &... a)
414         {
415             return result_of::funop<
416                 expr(A const &...)
417               , expr
418               , default_domain
419             >::call(*this, a...);
420         }
421     #endif
422 
423     #else // BOOST_NO_VARIADIC_TEMPLATES
424 
425         /// Function call
426         ///
427         /// \return A new \c expr\<\> node representing the function invocation of \c (*this)().
428         proto::expr<proto::tag::function, list1<expr const &>, 1> const
operator ()expr429         operator ()() const
430         {
431             proto::expr<proto::tag::function, list1<expr const &>, 1> that = {*this};
432             return that;
433         }
434 
435     #ifdef BOOST_PROTO_DEFINE_TERMINAL
436         /// \overload
437         ///
438         proto::expr<proto::tag::function, list1<expr &>, 1> const
operator ()expr439         operator ()()
440         {
441             proto::expr<proto::tag::function, list1<expr &>, 1> that = {*this};
442             return that;
443         }
444     #endif
445 
446     #define BOOST_PP_ITERATION_PARAMS_2                                                             \
447         (3, (1, BOOST_PP_DEC(BOOST_PROTO_MAX_FUNCTION_CALL_ARITY), <boost/proto/detail/expr_funop.hpp>))
448     #include BOOST_PP_ITERATE()
449 
450 #endif
451     };
452 
453 #undef ARG_COUNT
454 
455 #endif
456