Mercurial > hg > vamp-build-and-test
comparison DEPENDENCIES/generic/include/boost/proto/context/callable.hpp @ 16:2665513ce2d3
Add boost headers
author | Chris Cannam |
---|---|
date | Tue, 05 Aug 2014 11:11:38 +0100 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
15:663ca0da4350 | 16:2665513ce2d3 |
---|---|
1 /////////////////////////////////////////////////////////////////////////////// | |
2 /// \file callable.hpp | |
3 /// Definintion of callable_context\<\>, an evaluation context for | |
4 /// proto::eval() that explodes each node and calls the derived context | |
5 /// type with the expressions constituents. If the derived context doesn't | |
6 /// have an overload that handles this node, fall back to some other | |
7 /// context. | |
8 // | |
9 // Copyright 2008 Eric Niebler. Distributed under the Boost | |
10 // Software License, Version 1.0. (See accompanying file | |
11 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) | |
12 | |
13 #ifndef BOOST_PROTO_CONTEXT_CALLABLE_HPP_EAN_06_23_2007 | |
14 #define BOOST_PROTO_CONTEXT_CALLABLE_HPP_EAN_06_23_2007 | |
15 | |
16 #include <boost/config.hpp> | |
17 #include <boost/detail/workaround.hpp> | |
18 #include <boost/preprocessor/cat.hpp> | |
19 #include <boost/preprocessor/iteration/iterate.hpp> | |
20 #include <boost/preprocessor/facilities/intercept.hpp> | |
21 #include <boost/preprocessor/repetition/repeat.hpp> | |
22 #include <boost/preprocessor/repetition/enum_params.hpp> | |
23 #include <boost/preprocessor/repetition/enum_trailing.hpp> | |
24 #include <boost/preprocessor/repetition/enum_trailing_params.hpp> | |
25 #include <boost/preprocessor/arithmetic/inc.hpp> | |
26 #include <boost/preprocessor/selection/max.hpp> | |
27 #include <boost/mpl/if.hpp> | |
28 #include <boost/mpl/bool.hpp> | |
29 #include <boost/utility/result_of.hpp> | |
30 #include <boost/type_traits/remove_cv.hpp> | |
31 #include <boost/proto/proto_fwd.hpp> | |
32 #include <boost/proto/traits.hpp> // for child_c | |
33 | |
34 namespace boost { namespace proto | |
35 { | |
36 namespace detail | |
37 { | |
38 template<typename Context> | |
39 struct callable_context_wrapper | |
40 : remove_cv<Context>::type | |
41 { | |
42 callable_context_wrapper(); | |
43 typedef private_type_ fun_type(...); | |
44 operator fun_type *() const; | |
45 private: | |
46 callable_context_wrapper &operator =(callable_context_wrapper const &); | |
47 }; | |
48 | |
49 template<typename T> | |
50 yes_type check_is_expr_handled(T const &); | |
51 | |
52 no_type check_is_expr_handled(private_type_ const &); | |
53 | |
54 template<typename Expr, typename Context, long Arity = Expr::proto_arity_c> | |
55 struct is_expr_handled; | |
56 | |
57 template<typename Expr, typename Context> | |
58 struct is_expr_handled<Expr, Context, 0> | |
59 { | |
60 static callable_context_wrapper<Context> &sctx_; | |
61 static Expr &sexpr_; | |
62 static typename Expr::proto_tag &stag_; | |
63 | |
64 static const bool value = | |
65 sizeof(yes_type) == | |
66 sizeof( | |
67 detail::check_is_expr_handled( | |
68 (sctx_(stag_, proto::value(sexpr_)), 0) | |
69 ) | |
70 ); | |
71 | |
72 typedef mpl::bool_<value> type; | |
73 }; | |
74 } | |
75 | |
76 namespace context | |
77 { | |
78 /// \brief A BinaryFunction that accepts a Proto expression and a | |
79 /// callable context and calls the context with the expression tag | |
80 /// and children as arguments, effectively fanning the expression | |
81 /// out. | |
82 /// | |
83 /// <tt>callable_eval\<\></tt> requires that \c Context is a | |
84 /// PolymorphicFunctionObject that can be invoked with \c Expr's | |
85 /// tag and children as expressions, as follows: | |
86 /// | |
87 /// \code | |
88 /// context(Expr::proto_tag(), child_c<0>(expr), child_c<1>(expr), ...) | |
89 /// \endcode | |
90 template< | |
91 typename Expr | |
92 , typename Context | |
93 , long Arity // = Expr::proto_arity_c | |
94 > | |
95 struct callable_eval | |
96 {}; | |
97 | |
98 /// \brief A BinaryFunction that accepts a Proto expression and a | |
99 /// callable context and calls the context with the expression tag | |
100 /// and children as arguments, effectively fanning the expression | |
101 /// out. | |
102 /// | |
103 /// <tt>callable_eval\<\></tt> requires that \c Context is a | |
104 /// PolymorphicFunctionObject that can be invoked with \c Expr's | |
105 /// tag and children as expressions, as follows: | |
106 /// | |
107 /// \code | |
108 /// context(Expr::proto_tag(), value(expr)) | |
109 /// \endcode | |
110 template<typename Expr, typename Context> | |
111 struct callable_eval<Expr, Context, 0> | |
112 { | |
113 typedef typename proto::result_of::value<Expr const &>::type value_type; | |
114 | |
115 typedef | |
116 typename BOOST_PROTO_RESULT_OF< | |
117 Context(typename Expr::proto_tag, value_type) | |
118 >::type | |
119 result_type; | |
120 | |
121 /// \param expr The current expression | |
122 /// \param context The callable evaluation context | |
123 /// \return <tt>context(Expr::proto_tag(), value(expr))</tt> | |
124 result_type operator ()(Expr &expr, Context &context) const | |
125 { | |
126 return context(typename Expr::proto_tag(), proto::value(expr)); | |
127 } | |
128 }; | |
129 | |
130 /// \brief An evaluation context adaptor that makes authoring a | |
131 /// context a simple matter of writing function overloads, rather | |
132 /// then writing template specializations. | |
133 /// | |
134 /// <tt>callable_context\<\></tt> is a base class that implements | |
135 /// the context protocol by passing fanned-out expression nodes to | |
136 /// the derived context, making it easy to customize the handling | |
137 /// of expression types by writing function overloads. Only those | |
138 /// expression types needing special handling require explicit | |
139 /// handling. All others are dispatched to a user-specified | |
140 /// default context, \c DefaultCtx. | |
141 /// | |
142 /// <tt>callable_context\<\></tt> is defined simply as: | |
143 /// | |
144 /// \code | |
145 /// template<typename Context, typename DefaultCtx = default_context> | |
146 /// struct callable_context | |
147 /// { | |
148 /// template<typename Expr, typename ThisContext = Context> | |
149 /// struct eval | |
150 /// : mpl::if_< | |
151 /// is_expr_handled_<Expr, Context> // For exposition | |
152 /// , callable_eval<Expr, ThisContext> | |
153 /// , typename DefaultCtx::template eval<Expr, Context> | |
154 /// >::type | |
155 /// {}; | |
156 /// }; | |
157 /// \endcode | |
158 /// | |
159 /// The Boolean metafunction <tt>is_expr_handled_\<\></tt> uses | |
160 /// metaprogramming tricks to determine whether \c Context has | |
161 /// an overloaded function call operator that accepts the | |
162 /// fanned-out constituents of an expression of type \c Expr. | |
163 /// If so, the handling of the expression is dispatched to | |
164 /// <tt>callable_eval\<\></tt>. If not, it is dispatched to | |
165 /// the user-specified \c DefaultCtx. | |
166 /// | |
167 /// Below is an example of how to use <tt>callable_context\<\></tt>: | |
168 /// | |
169 /// \code | |
170 /// // An evaluation context that increments all | |
171 /// // integer terminals in-place. | |
172 /// struct increment_ints | |
173 /// : callable_context< | |
174 /// increment_ints const // derived context | |
175 /// , null_context const // fall-back context | |
176 /// > | |
177 /// { | |
178 /// typedef void result_type; | |
179 /// | |
180 /// // Handle int terminals here: | |
181 /// void operator()(proto::tag::terminal, int &i) const | |
182 /// { | |
183 /// ++i; | |
184 /// } | |
185 /// }; | |
186 /// \endcode | |
187 /// | |
188 /// With \c increment_ints, we can do the following: | |
189 /// | |
190 /// \code | |
191 /// literal<int> i = 0, j = 10; | |
192 /// proto::eval( i - j * 3.14, increment_ints() ); | |
193 /// | |
194 /// assert( i.get() == 1 && j.get() == 11 ); | |
195 /// \endcode | |
196 template< | |
197 typename Context | |
198 , typename DefaultCtx // = default_context | |
199 > | |
200 struct callable_context | |
201 { | |
202 /// A BinaryFunction that accepts an \c Expr and a | |
203 /// \c Context, and either fans out the expression and passes | |
204 /// it to the context, or else hands off the expression to | |
205 /// \c DefaultCtx. | |
206 /// | |
207 /// If \c Context is a PolymorphicFunctionObject such that | |
208 /// it can be invoked with the tag and children of \c Expr, | |
209 /// as <tt>ctx(Expr::proto_tag(), child_c\<0\>(expr), child_c\<1\>(expr)...)</tt>, | |
210 /// then <tt>eval\<Expr, ThisContext\></tt> inherits from | |
211 /// <tt>callable_eval\<Expr, ThisContext\></tt>. Otherwise, | |
212 /// <tt>eval\<Expr, ThisContext\></tt> inherits from | |
213 /// <tt>DefaultCtx::eval\<Expr, Context\></tt>. | |
214 template<typename Expr, typename ThisContext = Context> | |
215 struct eval | |
216 : mpl::if_c< | |
217 detail::is_expr_handled<Expr, Context>::value | |
218 , callable_eval<Expr, ThisContext> | |
219 , typename DefaultCtx::template eval<Expr, Context> | |
220 >::type | |
221 {}; | |
222 }; | |
223 } | |
224 | |
225 #include <boost/proto/context/detail/callable_eval.hpp> | |
226 | |
227 }} | |
228 | |
229 #endif |