1 ///////////////////////////////////////////////////////////////////////////////
2 /// \file proto_fwd.hpp
3 /// Forward declarations of all of proto's public types and functions.
4 //
5 //  Copyright 2008 Eric Niebler. Distributed under the Boost
6 //  Software License, Version 1.0. (See accompanying file
7 //  LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
8 
9 #ifndef BOOST_PROTO_FWD_HPP_EAN_04_01_2005
10 #define BOOST_PROTO_FWD_HPP_EAN_04_01_2005
11 
12 #include <cstddef>
13 #include <climits>
14 #include <boost/config.hpp>
15 #include <boost/detail/workaround.hpp>
16 #include <boost/preprocessor/cat.hpp>
17 #include <boost/preprocessor/arithmetic/inc.hpp>
18 #include <boost/preprocessor/punctuation/comma.hpp>
19 #include <boost/preprocessor/repetition/enum_params.hpp>
20 #include <boost/preprocessor/repetition/enum_params_with_a_default.hpp>
21 #include <boost/preprocessor/repetition/enum_trailing_binary_params.hpp>
22 #include <boost/preprocessor/repetition/repeat_from_to.hpp>
23 #include <boost/ref.hpp>
24 #include <boost/mpl/long.hpp>
25 #include <boost/type_traits/remove_const.hpp>
26 #include <boost/type_traits/remove_reference.hpp>
27 #include <boost/mpl/aux_/config/ttp.hpp>
28 #include <boost/utility/result_of.hpp>
29 
30 #ifndef BOOST_PROTO_MAX_ARITY
31 # define BOOST_PROTO_MAX_ARITY 10
32 #endif
33 
34 #ifndef BOOST_PROTO_MAX_LOGICAL_ARITY
35 # define BOOST_PROTO_MAX_LOGICAL_ARITY 10
36 #endif
37 
38 #ifndef BOOST_PROTO_MAX_FUNCTION_CALL_ARITY
39 # define BOOST_PROTO_MAX_FUNCTION_CALL_ARITY BOOST_PROTO_MAX_ARITY
40 #endif
41 
42 #if BOOST_PROTO_MAX_ARITY < 3
43 # error BOOST_PROTO_MAX_ARITY must be at least 3
44 #endif
45 
46 #if BOOST_PROTO_MAX_FUNCTION_CALL_ARITY > BOOST_PROTO_MAX_ARITY
47 # error BOOST_PROTO_MAX_FUNCTION_CALL_ARITY cannot be larger than BOOST_PROTO_MAX_ARITY
48 #endif
49 
50 #ifndef BOOST_PROTO_DONT_USE_PREPROCESSED_FILES
51   #if 10 < BOOST_PROTO_MAX_ARITY ||                                                                 \
52       10 < BOOST_PROTO_MAX_LOGICAL_ARITY ||                                                         \
53       10 < BOOST_PROTO_MAX_FUNCTION_CALL_ARITY
54     #define BOOST_PROTO_DONT_USE_PREPROCESSED_FILES
55   #endif
56 #endif
57 
58 #ifndef BOOST_PROTO_BROKEN_CONST_OVERLOADS
59 # if BOOST_WORKAROUND(__GNUC__, == 3) \
60   || BOOST_WORKAROUND(__EDG_VERSION__, BOOST_TESTED_AT(310))
61 #  define BOOST_PROTO_BROKEN_CONST_OVERLOADS
62 # endif
63 #endif
64 
65 #ifndef BOOST_PROTO_BROKEN_CONST_QUALIFIED_FUNCTIONS
66 # if BOOST_WORKAROUND(__GNUC__, == 3) \
67   || BOOST_WORKAROUND(__EDG_VERSION__, BOOST_TESTED_AT(310))
68 #  define BOOST_PROTO_BROKEN_CONST_QUALIFIED_FUNCTIONS
69 # endif
70 #endif
71 
72 #ifdef BOOST_PROTO_BROKEN_CONST_OVERLOADS
73 # include <boost/utility/enable_if.hpp>
74 # include <boost/type_traits/is_const.hpp>
75 # define BOOST_PROTO_DISABLE_IF_IS_CONST(T)\
76     , typename boost::disable_if_c<boost::is_const<T>::value, boost::proto::detail::undefined>::type * = 0
77 #else
78 # define BOOST_PROTO_DISABLE_IF_IS_CONST(T)
79 #endif
80 
81 #ifdef BOOST_PROTO_BROKEN_CONST_QUALIFIED_FUNCTIONS
82 # include <boost/utility/enable_if.hpp>
83 # include <boost/type_traits/is_function.hpp>
84 # define BOOST_PROTO_DISABLE_IF_IS_FUNCTION(T)\
85     , typename boost::disable_if_c<boost::is_function<T>::value, boost::proto::detail::undefined>::type * = 0
86 #else
87 # define BOOST_PROTO_DISABLE_IF_IS_FUNCTION(T)
88 #endif
89 
90 #ifndef BOOST_PROTO_BROKEN_PTS
91 # if BOOST_WORKAROUND(BOOST_MSVC, <= 1400)
92 #  define BOOST_PROTO_BROKEN_PTS
93 # endif
94 #endif
95 
96 #ifdef BOOST_NO_CXX11_DECLTYPE_N3276
97 # // Proto can only use the decltype-based result_of if N3276 has been
98 # // implemented by the compiler.
99 # // See http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2011/n3276.pdf
100 # ifndef BOOST_PROTO_USE_NORMAL_RESULT_OF
101 #  define BOOST_PROTO_USE_NORMAL_RESULT_OF
102 # endif
103 #endif
104 
105 // Unless compiler support is there, use tr1_result_of instead of
106 // result_of to avoid the problems addressed by N3276.
107 #ifdef BOOST_PROTO_USE_NORMAL_RESULT_OF
108 # define BOOST_PROTO_RESULT_OF boost::result_of
109 #else
110 # define BOOST_PROTO_RESULT_OF boost::tr1_result_of
111 #endif
112 
113 // If we're using the decltype-based result_of, we need to be a bit
114 // stricter about the return types of some functions.
115 #if defined(BOOST_RESULT_OF_USE_DECLTYPE) && defined(BOOST_PROTO_USE_NORMAL_RESULT_OF)
116 # define BOOST_PROTO_STRICT_RESULT_OF
117 # define BOOST_PROTO_RETURN_TYPE_STRICT_LOOSE(X, Y) X
118 #else
119 # define BOOST_PROTO_RETURN_TYPE_STRICT_LOOSE(X, Y) Y
120 #endif
121 
122 #ifdef BOOST_MPL_CFG_EXTENDED_TEMPLATE_PARAMETERS_MATCHING
123 # define BOOST_PROTO_EXTENDED_TEMPLATE_PARAMETERS_MATCHING
124 #endif
125 
126 #if defined(_MSC_VER)
127 # define BOOST_PROTO_DISABLE_MSVC_C4522 __pragma(warning(disable : 4522))  // 'class' : multiple assignment operators specified
128 # define BOOST_PROTO_DISABLE_MSVC_C4714 __pragma(warning(disable : 4714))  // function 'xxx' marked as __forceinline not inlined
129 #else
130 # define BOOST_PROTO_DISABLE_MSVC_C4522
131 # define BOOST_PROTO_DISABLE_MSVC_C4714
132 #endif
133 
134 namespace boost { namespace proto
135 {
136     namespace detail
137     {
138         typedef char yes_type;
139         typedef char (&no_type)[2];
140 
141         template<int N>
142         struct sized_type
143         {
144             typedef char (&type)[N];
145         };
146 
147         struct dont_care;
148         struct undefined; // leave this undefined
149         struct not_a_valid_type;
150 
151         struct private_type_
152         {
153             private_type_ operator ,(int) const;
154         };
155 
156         template<typename T>
157         struct uncvref
158         {
159             typedef T type;
160         };
161 
162         template<typename T>
163         struct uncvref<T const>
164         {
165             typedef T type;
166         };
167 
168         template<typename T>
169         struct uncvref<T &>
170         {
171             typedef T type;
172         };
173 
174         template<typename T>
175         struct uncvref<T const &>
176         {
177             typedef T type;
178         };
179 
180         template<typename T, std::size_t N>
181         struct uncvref<T const[N]>
182         {
183             typedef T type[N];
184         };
185 
186         template<typename T, std::size_t N>
187         struct uncvref<T (&)[N]>
188         {
189             typedef T type[N];
190         };
191 
192         template<typename T, std::size_t N>
193         struct uncvref<T const (&)[N]>
194         {
195             typedef T type[N];
196         };
197 
198         struct ignore
199         {
ignoreboost::proto::detail::ignore200             ignore()
201             {}
202 
203             template<typename T>
ignoreboost::proto::detail::ignore204             ignore(T const &)
205             {}
206         };
207 
208         /// INTERNAL ONLY
209         ///
210         #define BOOST_PROTO_UNCVREF(X)                                                              \
211             typename boost::proto::detail::uncvref<X>::type                                         \
212             /**/
213 
214         struct _default;
215 
216         struct not_a_domain;
217         struct not_a_grammar;
218         struct not_a_generator;
219 
220         template<typename T, typename Void = void>
221         struct is_transform_;
222 
223         template<typename T, typename Void = void>
224         struct is_aggregate_;
225 
226         template<typename Expr>
227         struct flat_view;
228     }
229 
230     typedef detail::ignore const ignore;
231 
232     namespace argsns_
233     {
234         template<typename Arg0>
235         struct term;
236 
237         #define M0(Z, N, DATA)                                                                      \
238         template<BOOST_PP_ENUM_PARAMS_Z(Z, N, typename Arg)> struct BOOST_PP_CAT(list, N);          \
239         /**/
240         BOOST_PP_REPEAT_FROM_TO(1, BOOST_PP_INC(BOOST_PROTO_MAX_ARITY), M0, ~)
241         #undef M0
242     }
243 
244     using namespace argsns_;
245 
246     ///////////////////////////////////////////////////////////////////////////////
247     // Operator tags
248     namespace tagns_
249     {
250         namespace tag
251         {
252             struct terminal;
253             struct unary_plus;
254             struct negate;
255             struct dereference;
256             struct complement;
257             struct address_of;
258             struct logical_not;
259             struct pre_inc;
260             struct pre_dec;
261             struct post_inc;
262             struct post_dec;
263 
264             struct shift_left;
265             struct shift_right;
266             struct multiplies;
267             struct divides;
268             struct modulus;
269             struct plus;
270             struct minus;
271             struct less;
272             struct greater;
273             struct less_equal;
274             struct greater_equal;
275             struct equal_to;
276             struct not_equal_to;
277             struct logical_or;
278             struct logical_and;
279             struct bitwise_and;
280             struct bitwise_or;
281             struct bitwise_xor;
282             struct comma;
283             struct mem_ptr;
284 
285             struct assign;
286             struct shift_left_assign;
287             struct shift_right_assign;
288             struct multiplies_assign;
289             struct divides_assign;
290             struct modulus_assign;
291             struct plus_assign;
292             struct minus_assign;
293             struct bitwise_and_assign;
294             struct bitwise_or_assign;
295             struct bitwise_xor_assign;
296             struct subscript;
297             struct member;
298             struct if_else_;
299             struct function;
300 
301             // Fusion tags
302             template<typename Tag, typename Domain> struct proto_expr;
303             template<typename Tag, typename Domain> struct proto_expr_iterator;
304             template<typename Tag, typename Domain> struct proto_flat_view;
305         }
306     }
307 
308     using namespace tagns_;
309 
310     template<typename Expr>
311     struct tag_of;
312 
313     ////////////////////////////////////////////////////////////////////////////////////////////////
314     struct _;
315 
316     ////////////////////////////////////////////////////////////////////////////////////////////////
317     struct default_generator;
318 
319     struct basic_default_generator;
320 
321     template<template<typename> class Extends>
322     struct generator;
323 
324     template<template<typename> class Extends>
325     struct pod_generator;
326 
327     struct by_value_generator;
328 
329     template<typename First, typename Second>
330     struct compose_generators;
331 
332     template<typename Generator, typename Void = void>
333     struct wants_basic_expr;
334 
335     template<typename Generator>
336     struct use_basic_expr;
337 
338     ////////////////////////////////////////////////////////////////////////////////////////////////
339     namespace domainns_
340     {
341         typedef detail::not_a_domain no_super_domain;
342 
343         template<
344             typename Generator  = default_generator
345           , typename Grammar    = proto::_
346           , typename Super      = no_super_domain
347         >
348         struct domain;
349 
350         struct default_domain;
351 
352         struct basic_default_domain;
353 
354         struct deduce_domain;
355 
356         template<typename Domain, typename Tag, typename Args, bool WantsBasicExpr = wants_basic_expr<typename Domain::proto_generator>::value>
357         struct base_expr;
358     }
359 
360     using namespace domainns_;
361 
362     ////////////////////////////////////////////////////////////////////////////////////////////////
363     namespace exprns_
364     {
365         template<typename Tag, typename Args, long Arity = Args::arity>
366         struct basic_expr;
367 
368         template<typename Tag, typename Args, long Arity = Args::arity>
369         struct expr;
370 
371         template<
372             typename Expr
373           , typename Derived
374           , typename Domain = default_domain
375           , long Arity = Expr::proto_arity_c
376         >
377         struct extends;
378 
379         template<typename This, typename Fun, typename Domain>
380         struct virtual_member;
381 
382         struct is_proto_expr;
383     }
384     ////////////////////////////////////////////////////////////////////////////////////////////////
385 
386     using exprns_::expr;
387     using exprns_::basic_expr;
388     using exprns_::extends;
389     using exprns_::is_proto_expr;
390 
391     template<BOOST_PP_ENUM_PARAMS_WITH_A_DEFAULT(BOOST_PROTO_MAX_LOGICAL_ARITY, typename G, void)>
392     struct or_;
393 
394     template<BOOST_PP_ENUM_PARAMS_WITH_A_DEFAULT(BOOST_PROTO_MAX_LOGICAL_ARITY, typename G, void)>
395     struct and_;
396 
397     template<typename Grammar>
398     struct not_;
399 
400     template<typename Condition, typename Then = _, typename Else = not_<_> >
401     struct if_;
402 
403     template<typename Cases, typename Transform = tag_of<_>()>
404     struct switch_;
405 
406     template<typename T>
407     struct exact;
408 
409     template<typename T>
410     struct convertible_to;
411 
412     template<typename Grammar>
413     struct vararg;
414 
415     struct pack;
416 
417     // Boost bug https://svn.boost.org/trac/boost/ticket/4602
418     //int const N = INT_MAX;
419     int const N = (INT_MAX >> 10);
420 
421     namespace context
422     {
423         struct null_context;
424 
425         template<typename Expr, typename Context, long Arity = Expr::proto_arity_c>
426         struct null_eval;
427 
428         struct default_context;
429 
430         template<typename Expr, typename Context, typename Tag = typename Expr::proto_tag, long Arity = Expr::proto_arity_c>
431         struct default_eval;
432 
433         template<typename Derived, typename DefaultCtx = default_context>
434         struct callable_context;
435 
436         template<typename Expr, typename Context, long Arity = Expr::proto_arity_c>
437         struct callable_eval;
438     }
439 
440     using context::null_context;
441     using context::null_eval;
442     using context::default_context;
443     using context::default_eval;
444     using context::callable_context;
445     using context::callable_eval;
446 
447     namespace utility
448     {
449         template<typename T, typename Domain = default_domain>
450         struct literal;
451     }
452 
453     using utility::literal;
454 
455     namespace result_of
456     {
457         template<typename T, typename Domain = default_domain>
458         struct as_expr;
459 
460         template<typename T, typename Domain = default_domain>
461         struct as_child;
462 
463         template<typename Expr, typename N = mpl::long_<0> >
464         struct child;
465 
466         template<typename Expr, long N>
467         struct child_c;
468 
469         template<typename Expr>
470         struct left;
471 
472         template<typename Expr>
473         struct right;
474 
475         template<typename Expr>
476         struct deep_copy;
477 
478         template<typename Expr, typename Context>
479         struct eval;
480 
481         template<
482             typename Tag
483           , typename DomainOrA0
484             BOOST_PP_ENUM_TRAILING_BINARY_PARAMS(
485                 BOOST_PROTO_MAX_ARITY
486               , typename A
487               , = void BOOST_PP_INTERCEPT
488             )
489           , typename Void = void
490         >
491         struct make_expr;
492 
493         template<typename Tag, typename DomainOrSequence, typename SequenceOrVoid = void, typename Void = void>
494         struct unpack_expr;
495 
496         template<typename T>
497         struct as_env;
498 
499         template<typename Env, typename Tag>
500         struct has_env_var;
501 
502         template<typename Env, typename Tag>
503         struct env_var;
504     }
505 
506     template<typename T, typename Void = void>
507     struct is_expr;
508 
509     template<typename T, typename Void = void>
510     struct is_domain;
511 
512     template<typename SubDomain, typename SuperDomain>
513     struct is_sub_domain_of;
514 
515     template<typename T, typename Void = void>
516     struct is_env;
517 
518     template<typename Expr>
519     struct arity_of;
520 
521     template<typename T, typename Void = void>
522     struct domain_of;
523 
524     template<typename Expr, typename Grammar>
525     struct matches;
526 
527     // Generic expression metafunctions and
528     // grammar elements
529     template<typename Tag, typename Arg>
530     struct unary_expr;
531 
532     template<typename Tag, typename Left, typename Right>
533     struct binary_expr;
534 
535     template<typename Tag, BOOST_PP_ENUM_PARAMS_WITH_A_DEFAULT(BOOST_PROTO_MAX_ARITY, typename A, void)>
536     struct nary_expr;
537 
538     // Specific expression metafunctions and
539     // grammar elements, for convenience
540     template<typename T> struct terminal;
541     template<typename T> struct unary_plus;
542     template<typename T> struct negate;
543     template<typename T> struct dereference;
544     template<typename T> struct complement;
545     template<typename T> struct address_of;
546     template<typename T> struct logical_not;
547     template<typename T> struct pre_inc;
548     template<typename T> struct pre_dec;
549     template<typename T> struct post_inc;
550     template<typename T> struct post_dec;
551 
552     template<typename T, typename U> struct shift_left;
553     template<typename T, typename U> struct shift_right;
554     template<typename T, typename U> struct multiplies;
555     template<typename T, typename U> struct divides;
556     template<typename T, typename U> struct modulus;
557     template<typename T, typename U> struct plus;
558     template<typename T, typename U> struct minus;
559     template<typename T, typename U> struct less;
560     template<typename T, typename U> struct greater;
561     template<typename T, typename U> struct less_equal;
562     template<typename T, typename U> struct greater_equal;
563     template<typename T, typename U> struct equal_to;
564     template<typename T, typename U> struct not_equal_to;
565     template<typename T, typename U> struct logical_or;
566     template<typename T, typename U> struct logical_and;
567     template<typename T, typename U> struct bitwise_and;
568     template<typename T, typename U> struct bitwise_or;
569     template<typename T, typename U> struct bitwise_xor;
570     template<typename T, typename U> struct comma;
571     template<typename T, typename U> struct mem_ptr;
572 
573     template<typename T, typename U> struct assign;
574     template<typename T, typename U> struct shift_left_assign;
575     template<typename T, typename U> struct shift_right_assign;
576     template<typename T, typename U> struct multiplies_assign;
577     template<typename T, typename U> struct divides_assign;
578     template<typename T, typename U> struct modulus_assign;
579     template<typename T, typename U> struct plus_assign;
580     template<typename T, typename U> struct minus_assign;
581     template<typename T, typename U> struct bitwise_and_assign;
582     template<typename T, typename U> struct bitwise_or_assign;
583     template<typename T, typename U> struct bitwise_xor_assign;
584     template<typename T, typename U> struct subscript;
585     template<typename T, typename U> struct member;
586     template<typename T, typename U, typename V> struct if_else_;
587 
588     template<BOOST_PP_ENUM_PARAMS_WITH_A_DEFAULT(BOOST_PROTO_MAX_ARITY, typename A, void)>
589     struct function;
590 
591     namespace functional
592     {
593         struct left;
594         struct right;
595         struct eval;
596         struct deep_copy;
597 
598         template<typename Domain = default_domain>
599         struct as_expr;
600 
601         template<typename Domain = default_domain>
602         struct as_child;
603 
604         template<typename N = mpl::long_<0> >
605         struct child;
606 
607         template<long N>
608         struct child_c;
609 
610         struct as_env;
611 
612         template<typename Tag>
613         struct has_env_var;
614 
615         template<typename Tag>
616         struct env_var;
617 
618         template<typename Tag, typename Domain = deduce_domain>
619         struct make_expr;
620 
621         template<typename Tag, typename Domain = deduce_domain>
622         struct unpack_expr;
623 
624         typedef make_expr<tag::terminal>            make_terminal;
625         typedef make_expr<tag::unary_plus>          make_unary_plus;
626         typedef make_expr<tag::negate>              make_negate;
627         typedef make_expr<tag::dereference>         make_dereference;
628         typedef make_expr<tag::complement>          make_complement;
629         typedef make_expr<tag::address_of>          make_address_of;
630         typedef make_expr<tag::logical_not>         make_logical_not;
631         typedef make_expr<tag::pre_inc>             make_pre_inc;
632         typedef make_expr<tag::pre_dec>             make_pre_dec;
633         typedef make_expr<tag::post_inc>            make_post_inc;
634         typedef make_expr<tag::post_dec>            make_post_dec;
635         typedef make_expr<tag::shift_left>          make_shift_left;
636         typedef make_expr<tag::shift_right>         make_shift_right;
637         typedef make_expr<tag::multiplies>          make_multiplies;
638         typedef make_expr<tag::divides>             make_divides;
639         typedef make_expr<tag::modulus>             make_modulus;
640         typedef make_expr<tag::plus>                make_plus;
641         typedef make_expr<tag::minus>               make_minus;
642         typedef make_expr<tag::less>                make_less;
643         typedef make_expr<tag::greater>             make_greater;
644         typedef make_expr<tag::less_equal>          make_less_equal;
645         typedef make_expr<tag::greater_equal>       make_greater_equal;
646         typedef make_expr<tag::equal_to>            make_equal_to;
647         typedef make_expr<tag::not_equal_to>        make_not_equal_to;
648         typedef make_expr<tag::logical_or>          make_logical_or;
649         typedef make_expr<tag::logical_and>         make_logical_and;
650         typedef make_expr<tag::bitwise_and>         make_bitwise_and;
651         typedef make_expr<tag::bitwise_or>          make_bitwise_or;
652         typedef make_expr<tag::bitwise_xor>         make_bitwise_xor;
653         typedef make_expr<tag::comma>               make_comma;
654         typedef make_expr<tag::mem_ptr>             make_mem_ptr;
655         typedef make_expr<tag::assign>              make_assign;
656         typedef make_expr<tag::shift_left_assign>   make_shift_left_assign;
657         typedef make_expr<tag::shift_right_assign>  make_shift_right_assign;
658         typedef make_expr<tag::multiplies_assign>   make_multiplies_assign;
659         typedef make_expr<tag::divides_assign>      make_divides_assign;
660         typedef make_expr<tag::modulus_assign>      make_modulus_assign;
661         typedef make_expr<tag::plus_assign>         make_plus_assign;
662         typedef make_expr<tag::minus_assign>        make_minus_assign;
663         typedef make_expr<tag::bitwise_and_assign>  make_bitwise_and_assign;
664         typedef make_expr<tag::bitwise_or_assign>   make_bitwise_or_assign;
665         typedef make_expr<tag::bitwise_xor_assign>  make_bitwise_xor_assign;
666         typedef make_expr<tag::subscript>           make_subscript;
667         typedef make_expr<tag::if_else_>            make_if_else;
668         typedef make_expr<tag::function>            make_function;
669 
670         struct flatten;
671         struct make_pair;
672         struct first;
673         struct second;
674         struct at;
675         struct pop_front;
676         struct push_front;
677         struct pop_back;
678         struct push_back;
679         struct reverse;
680     }
681 
682     typedef functional::flatten     _flatten;
683     typedef functional::make_pair   _make_pair;
684     typedef functional::first       _first;
685     typedef functional::second      _second;
686     typedef functional::pop_front   _at;
687     typedef functional::pop_front   _pop_front;
688     typedef functional::push_front  _push_front;
689     typedef functional::pop_back    _pop_back;
690     typedef functional::push_back   _push_back;
691     typedef functional::reverse     _reverse;
692     typedef functional::eval        _eval;
693     struct _deep_copy;
694 
695     typedef functional::make_expr<tag::terminal>           _make_terminal;
696     typedef functional::make_expr<tag::unary_plus>         _make_unary_plus;
697     typedef functional::make_expr<tag::negate>             _make_negate;
698     typedef functional::make_expr<tag::dereference>        _make_dereference;
699     typedef functional::make_expr<tag::complement>         _make_complement;
700     typedef functional::make_expr<tag::address_of>         _make_address_of;
701     typedef functional::make_expr<tag::logical_not>        _make_logical_not;
702     typedef functional::make_expr<tag::pre_inc>            _make_pre_inc;
703     typedef functional::make_expr<tag::pre_dec>            _make_pre_dec;
704     typedef functional::make_expr<tag::post_inc>           _make_post_inc;
705     typedef functional::make_expr<tag::post_dec>           _make_post_dec;
706     typedef functional::make_expr<tag::shift_left>         _make_shift_left;
707     typedef functional::make_expr<tag::shift_right>        _make_shift_right;
708     typedef functional::make_expr<tag::multiplies>         _make_multiplies;
709     typedef functional::make_expr<tag::divides>            _make_divides;
710     typedef functional::make_expr<tag::modulus>            _make_modulus;
711     typedef functional::make_expr<tag::plus>               _make_plus;
712     typedef functional::make_expr<tag::minus>              _make_minus;
713     typedef functional::make_expr<tag::less>               _make_less;
714     typedef functional::make_expr<tag::greater>            _make_greater;
715     typedef functional::make_expr<tag::less_equal>         _make_less_equal;
716     typedef functional::make_expr<tag::greater_equal>      _make_greater_equal;
717     typedef functional::make_expr<tag::equal_to>           _make_equal_to;
718     typedef functional::make_expr<tag::not_equal_to>       _make_not_equal_to;
719     typedef functional::make_expr<tag::logical_or>         _make_logical_or;
720     typedef functional::make_expr<tag::logical_and>        _make_logical_and;
721     typedef functional::make_expr<tag::bitwise_and>        _make_bitwise_and;
722     typedef functional::make_expr<tag::bitwise_or>         _make_bitwise_or;
723     typedef functional::make_expr<tag::bitwise_xor>        _make_bitwise_xor;
724     typedef functional::make_expr<tag::comma>              _make_comma;
725     typedef functional::make_expr<tag::mem_ptr>            _make_mem_ptr;
726     typedef functional::make_expr<tag::assign>             _make_assign;
727     typedef functional::make_expr<tag::shift_left_assign>  _make_shift_left_assign;
728     typedef functional::make_expr<tag::shift_right_assign> _make_shift_right_assign;
729     typedef functional::make_expr<tag::multiplies_assign>  _make_multiplies_assign;
730     typedef functional::make_expr<tag::divides_assign>     _make_divides_assign;
731     typedef functional::make_expr<tag::modulus_assign>     _make_modulus_assign;
732     typedef functional::make_expr<tag::plus_assign>        _make_plus_assign;
733     typedef functional::make_expr<tag::minus_assign>       _make_minus_assign;
734     typedef functional::make_expr<tag::bitwise_and_assign> _make_bitwise_and_assign;
735     typedef functional::make_expr<tag::bitwise_or_assign>  _make_bitwise_or_assign;
736     typedef functional::make_expr<tag::bitwise_xor_assign> _make_bitwise_xor_assign;
737     typedef functional::make_expr<tag::subscript>          _make_subscript;
738     typedef functional::make_expr<tag::if_else_>           _make_if_else;
739     typedef functional::make_expr<tag::function>           _make_function;
740 
741     template<typename T>
742     struct is_callable;
743 
744     template<typename T>
745     struct is_transform;
746 
747     template<typename T>
748     struct is_aggregate;
749 
750     #define BOOST_PROTO_UNEXPR() typedef int proto_is_expr_;
751     #define BOOST_PROTO_CALLABLE() typedef void proto_is_callable_;
752     #define BOOST_PROTO_AGGREGATE() typedef void proto_is_aggregate_;
753     #define BOOST_PROTO_USE_BASIC_EXPR() typedef void proto_use_basic_expr_;
754 
755     struct callable
756     {
757         BOOST_PROTO_CALLABLE()
758     };
759 
760     namespace envns_
761     {
762         struct key_not_found;
763 
764         struct empty_env;
765 
766         typedef int empty_state;
767 
768         template<typename Tag, typename Value, typename Base = empty_env>
769         struct env;
770 
771         struct data_type;
772 
773         struct transforms_type;
774     }
775 
776     using envns_::key_not_found;
777     using envns_::empty_env;
778     using envns_::empty_state;
779     using envns_::env;
780     using envns_::data_type;
781     using envns_::transforms_type;
782 
783     struct external_transform;
784 
785     template<typename PrimitiveTransform = void, typename X = void>
786     struct transform;
787 
788     template<typename Grammar, typename Fun = Grammar>
789     struct when;
790 
791     template<typename Fun>
792     struct otherwise;
793 
794     template<typename Fun>
795     struct call;
796 
797     template<typename Fun>
798     struct make;
799 
800     template<typename PrimitiveTransform>
801     struct protect;
802 
803     template<typename T>
804     struct noinvoke;
805 
806     template<typename Fun>
807     struct lazy;
808 
809     template<typename Sequence, typename State, typename Fun>
810     struct fold;
811 
812     template<typename Sequence, typename State, typename Fun>
813     struct reverse_fold;
814 
815     // Q: can we replace fold_tree with fold<flatten(_), state, fun> ?
816     // A: once segmented Fusion works well.
817     template<typename Sequence, typename State, typename Fun>
818     struct fold_tree;
819 
820     template<typename Sequence, typename State, typename Fun>
821     struct reverse_fold_tree;
822 
823     template<typename Grammar, typename Domain = deduce_domain>
824     struct pass_through;
825 
826     template<typename Grammar = detail::_default>
827     struct _default;
828 
829     struct _expr;
830     struct _state;
831     struct _data;
832 
833     struct _value;
834 
835     struct _void;
836 
837     template<typename T, T I>
838     struct integral_c;
839 
840     template<char I>
841     struct char_;
842 
843     template<int I>
844     struct int_;
845 
846     template<long I>
847     struct long_;
848 
849     template<std::size_t I>
850     struct size_t;
851 
852     template<int I>
853     struct _child_c;
854 
855     typedef _child_c<0> _child0;
856     typedef _child_c<1> _child1;
857     typedef _child0     _child;
858     typedef _child0     _left;
859     typedef _child1     _right;
860 
861     // _child2, _child3, _child4, ...
862     #define M0(Z, N, DATA) typedef _child_c<N> BOOST_PP_CAT(_child, N);
863     BOOST_PP_REPEAT_FROM_TO(
864         2
865       , BOOST_PP_DEC(BOOST_PROTO_MAX_ARITY)
866       , M0
867       , ~
868     )
869     #undef M0
870 
871     struct _byref;
872     struct _byval;
873 
874     template<typename Tag>
875     struct _env_var;
876 
877     struct _env;
878 
879     template<typename T>
880     struct is_extension;
881 
882     namespace exops = exprns_;
883 
884 }} // namespace boost::proto
885 
886 #endif
887