Mercurial > hg > vamp-build-and-test
comparison DEPENDENCIES/generic/include/boost/proto/domain.hpp @ 16:2665513ce2d3
Add boost headers
author | Chris Cannam |
---|---|
date | Tue, 05 Aug 2014 11:11:38 +0100 |
parents | |
children | c530137014c0 |
comparison
equal
deleted
inserted
replaced
15:663ca0da4350 | 16:2665513ce2d3 |
---|---|
1 /////////////////////////////////////////////////////////////////////////////// | |
2 /// \file domain.hpp | |
3 /// Contains definition of domain\<\> class template and helpers for | |
4 /// defining domains with a generator and a grammar for controlling | |
5 /// operator overloading. | |
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_DOMAIN_HPP_EAN_02_13_2007 | |
12 #define BOOST_PROTO_DOMAIN_HPP_EAN_02_13_2007 | |
13 | |
14 #include <boost/ref.hpp> | |
15 #include <boost/type_traits/is_same.hpp> | |
16 #include <boost/proto/proto_fwd.hpp> | |
17 #include <boost/proto/generate.hpp> | |
18 #include <boost/proto/detail/as_expr.hpp> | |
19 #include <boost/proto/detail/deduce_domain.hpp> | |
20 | |
21 #if defined(_MSC_VER) && (_MSC_VER >= 1020) | |
22 # pragma warning(push) | |
23 # pragma warning(disable : 4714) // function 'xxx' marked as __forceinline not inlined | |
24 #endif | |
25 | |
26 namespace boost { namespace proto | |
27 { | |
28 | |
29 namespace detail | |
30 { | |
31 struct not_a_generator | |
32 {}; | |
33 | |
34 struct not_a_grammar | |
35 {}; | |
36 | |
37 struct not_a_domain | |
38 {}; | |
39 } | |
40 | |
41 namespace domainns_ | |
42 { | |
43 /// \brief For use in defining domain tags to be used | |
44 /// with \c proto::extends\<\>. A \e Domain associates | |
45 /// an expression type with a \e Generator, and optionally | |
46 /// a \e Grammar. | |
47 /// | |
48 /// The Generator determines how new expressions in the | |
49 /// domain are constructed. Typically, a generator wraps | |
50 /// all new expressions in a wrapper that imparts | |
51 /// domain-specific behaviors to expressions within its | |
52 /// domain. (See \c proto::extends\<\>.) | |
53 /// | |
54 /// The Grammar determines whether a given expression is | |
55 /// valid within the domain, and automatically disables | |
56 /// any operator overloads which would cause an invalid | |
57 /// expression to be created. By default, the Grammar | |
58 /// parameter defaults to the wildcard, \c proto::_, which | |
59 /// makes all expressions valid within the domain. | |
60 /// | |
61 /// The Super declares the domain currently being defined | |
62 /// to be a sub-domain of Super. Expressions in sub-domains | |
63 /// can be freely combined with expressions in its super- | |
64 /// domain (and <I>its</I> super-domain, etc.). | |
65 /// | |
66 /// Example: | |
67 /// \code | |
68 /// template<typename Expr> | |
69 /// struct MyExpr; | |
70 /// | |
71 /// struct MyGrammar | |
72 /// : or_< terminal<_>, plus<MyGrammar, MyGrammar> > | |
73 /// {}; | |
74 /// | |
75 /// // Define MyDomain, in which all expressions are | |
76 /// // wrapped in MyExpr<> and only expressions that | |
77 /// // conform to MyGrammar are allowed. | |
78 /// struct MyDomain | |
79 /// : domain<generator<MyExpr>, MyGrammar> | |
80 /// {}; | |
81 /// | |
82 /// // Use MyDomain to define MyExpr | |
83 /// template<typename Expr> | |
84 /// struct MyExpr | |
85 /// : extends<Expr, MyExpr<Expr>, MyDomain> | |
86 /// { | |
87 /// // ... | |
88 /// }; | |
89 /// \endcode | |
90 /// | |
91 template< | |
92 typename Generator // = default_generator | |
93 , typename Grammar // = proto::_ | |
94 , typename Super // = no_super_domain | |
95 > | |
96 struct domain | |
97 : Generator | |
98 { | |
99 typedef Generator proto_generator; | |
100 typedef Grammar proto_grammar; | |
101 typedef Super proto_super_domain; | |
102 typedef domain proto_base_domain; | |
103 | |
104 /// INTERNAL ONLY | |
105 typedef void proto_is_domain_; | |
106 | |
107 /// \brief A unary MonomorphicFunctionObject that turns objects into Proto | |
108 /// expression objects in this domain. | |
109 /// | |
110 /// The <tt>as_expr\<\></tt> function object turns objects into Proto expressions, if | |
111 /// they are not already, by making them Proto terminals held by value if | |
112 /// possible. Objects that are already Proto expressions are left alone. | |
113 /// | |
114 /// If <tt>wants_basic_expr\<Generator\>::value</tt> is true, then let \c E be \c basic_expr; | |
115 /// otherwise, let \t E be \c expr. Given an lvalue \c t of type \c T: | |
116 /// | |
117 /// If \c T is not a Proto expression type the resulting terminal is | |
118 /// calculated as follows: | |
119 /// | |
120 /// If \c T is a function type, an abstract type, or a type derived from | |
121 /// \c std::ios_base, let \c A be <tt>T &</tt>. | |
122 /// Otherwise, let \c A be the type \c T stripped of cv-qualifiers. | |
123 /// Then, the result of applying <tt>as_expr\<T\>()(t)</tt> is | |
124 /// <tt>Generator()(E\<tag::terminal, term\<A\> \>::make(t))</tt>. | |
125 /// | |
126 /// If \c T is a Proto expression type and its generator type is different from | |
127 /// \c Generator, the result is <tt>Generator()(t)</tt>. | |
128 /// | |
129 /// Otherwise, the result is \c t converted to an (un-const) rvalue. | |
130 /// | |
131 template<typename T, typename IsExpr = void, typename Callable = proto::callable> | |
132 struct as_expr | |
133 : detail::as_expr< | |
134 T | |
135 , typename detail::base_generator<Generator>::type | |
136 , wants_basic_expr<Generator>::value | |
137 > | |
138 { | |
139 BOOST_PROTO_CALLABLE() | |
140 }; | |
141 | |
142 /// INTERNAL ONLY | |
143 /// | |
144 template<typename T> | |
145 struct as_expr<T, typename T::proto_is_expr_, proto::callable> | |
146 { | |
147 BOOST_PROTO_CALLABLE() | |
148 typedef typename remove_const<T>::type result_type; | |
149 | |
150 BOOST_FORCEINLINE | |
151 result_type operator()(T &e) const | |
152 { | |
153 return e; | |
154 } | |
155 }; | |
156 | |
157 /// \brief A unary MonomorphicFunctionObject that turns objects into Proto | |
158 /// expression objects in this domain. | |
159 /// | |
160 /// The <tt>as_child\<\></tt> function object turns objects into Proto expressions, if | |
161 /// they are not already, by making them Proto terminals held by reference. | |
162 /// Objects that are already Proto expressions are simply returned by reference. | |
163 /// | |
164 /// If <tt>wants_basic_expr\<Generator\>::value</tt> is true, then let \c E be \c basic_expr; | |
165 /// otherwise, let \t E be \c expr. Given an lvalue \c t of type \c T: | |
166 /// | |
167 /// If \c T is not a Proto expression type the resulting terminal is | |
168 /// <tt>Generator()(E\<tag::terminal, term\<T &\> \>::make(t))</tt>. | |
169 /// | |
170 /// If \c T is a Proto expression type and its generator type is different from | |
171 /// \c Generator, the result is <tt>Generator()(t)</tt>. | |
172 /// | |
173 /// Otherwise, the result is the lvalue \c t. | |
174 /// | |
175 template<typename T, typename IsExpr = void, typename Callable = proto::callable> | |
176 struct as_child | |
177 : detail::as_child< | |
178 T | |
179 , typename detail::base_generator<Generator>::type | |
180 , wants_basic_expr<Generator>::value | |
181 > | |
182 { | |
183 BOOST_PROTO_CALLABLE() | |
184 }; | |
185 | |
186 /// INTERNAL ONLY | |
187 /// | |
188 template<typename T> | |
189 struct as_child<T, typename T::proto_is_expr_, proto::callable> | |
190 { | |
191 BOOST_PROTO_CALLABLE() | |
192 typedef T &result_type; | |
193 | |
194 BOOST_FORCEINLINE | |
195 result_type operator()(T &e) const | |
196 { | |
197 return e; | |
198 } | |
199 }; | |
200 }; | |
201 | |
202 /// \brief The domain expressions have by default, if | |
203 /// \c proto::extends\<\> has not been used to associate | |
204 /// a domain with an expression. | |
205 /// | |
206 struct default_domain | |
207 : domain<> | |
208 {}; | |
209 | |
210 /// \brief A domain to use when you prefer the use of | |
211 /// \c proto::basic_expr\<\> over \c proto::expr\<\>. | |
212 /// | |
213 struct basic_default_domain | |
214 : domain<basic_default_generator> | |
215 {}; | |
216 | |
217 /// \brief A pseudo-domain for use in functions and | |
218 /// metafunctions that require a domain parameter. It | |
219 /// indicates that the domain of the parent node should | |
220 /// be inferred from the domains of the child nodes. | |
221 /// | |
222 /// \attention \c deduce_domain is not itself a valid domain. | |
223 /// | |
224 struct deduce_domain | |
225 : domain<detail::not_a_generator, detail::not_a_grammar, detail::not_a_domain> | |
226 {}; | |
227 | |
228 /// \brief Given a domain, a tag type and an argument list, | |
229 /// compute the type of the expression to generate. This is | |
230 /// either an instance of \c proto::expr\<\> or | |
231 /// \c proto::basic_expr\<\>. | |
232 /// | |
233 template<typename Domain, typename Tag, typename Args, bool WantsBasicExpr> | |
234 struct base_expr | |
235 { | |
236 typedef proto::expr<Tag, Args, Args::arity> type; | |
237 }; | |
238 | |
239 /// INTERNAL ONLY | |
240 /// | |
241 template<typename Domain, typename Tag, typename Args> | |
242 struct base_expr<Domain, Tag, Args, true> | |
243 { | |
244 typedef proto::basic_expr<Tag, Args, Args::arity> type; | |
245 }; | |
246 | |
247 } | |
248 | |
249 /// A metafunction that returns \c mpl::true_ | |
250 /// if the type \c T is the type of a Proto domain; | |
251 /// \c mpl::false_ otherwise. If \c T inherits from | |
252 /// \c proto::domain\<\>, \c is_domain\<T\> is | |
253 /// \c mpl::true_. | |
254 template<typename T, typename Void /* = void*/> | |
255 struct is_domain | |
256 : mpl::false_ | |
257 {}; | |
258 | |
259 /// INTERNAL ONLY | |
260 /// | |
261 template<typename T> | |
262 struct is_domain<T, typename T::proto_is_domain_> | |
263 : mpl::true_ | |
264 {}; | |
265 | |
266 /// A metafunction that returns the domain of | |
267 /// a given type. If \c T is a Proto expression | |
268 /// type, it returns that expression's associated | |
269 /// domain. If not, it returns | |
270 /// \c proto::default_domain. | |
271 template<typename T, typename Void /* = void*/> | |
272 struct domain_of | |
273 { | |
274 typedef default_domain type; | |
275 }; | |
276 | |
277 /// INTERNAL ONLY | |
278 /// | |
279 template<typename T> | |
280 struct domain_of<T, typename T::proto_is_expr_> | |
281 { | |
282 typedef typename T::proto_domain type; | |
283 }; | |
284 | |
285 /// INTERNAL ONLY | |
286 /// | |
287 template<typename T> | |
288 struct domain_of<T &, void> | |
289 { | |
290 typedef typename domain_of<T>::type type; | |
291 }; | |
292 | |
293 /// INTERNAL ONLY | |
294 /// | |
295 template<typename T> | |
296 struct domain_of<boost::reference_wrapper<T>, void> | |
297 { | |
298 typedef typename domain_of<T>::type type; | |
299 }; | |
300 | |
301 /// INTERNAL ONLY | |
302 /// | |
303 template<typename T> | |
304 struct domain_of<boost::reference_wrapper<T> const, void> | |
305 { | |
306 typedef typename domain_of<T>::type type; | |
307 }; | |
308 | |
309 /// A metafunction that returns \c mpl::true_ | |
310 /// if the type \c SubDomain is a sub-domain of | |
311 /// \c SuperDomain; \c mpl::false_ otherwise. | |
312 template<typename SubDomain, typename SuperDomain> | |
313 struct is_sub_domain_of | |
314 : is_sub_domain_of<typename SubDomain::proto_super_domain, SuperDomain> | |
315 {}; | |
316 | |
317 /// INTERNAL ONLY | |
318 /// | |
319 template<typename SuperDomain> | |
320 struct is_sub_domain_of<proto::no_super_domain, SuperDomain> | |
321 : mpl::false_ | |
322 {}; | |
323 | |
324 /// INTERNAL ONLY | |
325 /// | |
326 template<typename SuperDomain> | |
327 struct is_sub_domain_of<SuperDomain, SuperDomain> | |
328 : mpl::true_ | |
329 {}; | |
330 | |
331 }} | |
332 | |
333 #if defined(_MSC_VER) && (_MSC_VER >= 1020) | |
334 # pragma warning(pop) | |
335 #endif | |
336 | |
337 #endif |