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