Mercurial > hg > vamp-build-and-test
comparison DEPENDENCIES/generic/include/boost/proto/transform/env.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 // env.hpp | |
3 // Helpers for producing and consuming tranform env variables. | |
4 // | |
5 // Copyright 2012 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_TRANSFORM_ENV_HPP_EAN_18_07_2012 | |
10 #define BOOST_PROTO_TRANSFORM_ENV_HPP_EAN_18_07_2012 | |
11 | |
12 #include <boost/config.hpp> | |
13 #include <boost/detail/workaround.hpp> | |
14 #include <boost/ref.hpp> | |
15 #include <boost/utility/enable_if.hpp> | |
16 #include <boost/type_traits/is_const.hpp> | |
17 #include <boost/type_traits/is_same.hpp> | |
18 #include <boost/type_traits/add_const.hpp> | |
19 #include <boost/type_traits/add_reference.hpp> | |
20 #include <boost/type_traits/remove_const.hpp> | |
21 #include <boost/mpl/assert.hpp> | |
22 #include <boost/mpl/bool.hpp> | |
23 #include <boost/mpl/if.hpp> | |
24 #include <boost/mpl/not.hpp> | |
25 #include <boost/proto/proto_fwd.hpp> | |
26 #include <boost/proto/transform/impl.hpp> | |
27 #include <boost/proto/detail/poly_function.hpp> | |
28 #include <boost/proto/detail/is_noncopyable.hpp> | |
29 | |
30 #ifdef _MSC_VER | |
31 # pragma warning(push) | |
32 # pragma warning(disable: 4180) // qualifier applied to function type has no meaning; ignored | |
33 #endif | |
34 | |
35 namespace boost | |
36 { | |
37 namespace proto | |
38 { | |
39 namespace detail | |
40 { | |
41 template<typename T> | |
42 struct value_type | |
43 { | |
44 typedef typename remove_const<T>::type value; | |
45 typedef typename add_reference<T>::type reference; | |
46 typedef typename mpl::if_c<is_noncopyable<T>::value, reference, value>::type type; | |
47 }; | |
48 | |
49 template<typename T> | |
50 struct value_type<T &> | |
51 { | |
52 typedef T &value; | |
53 typedef T &reference; | |
54 typedef T &type; | |
55 }; | |
56 } | |
57 | |
58 #define BOOST_PROTO_DEFINE_ENV_VAR(TAG, NAME) \ | |
59 struct TAG \ | |
60 { \ | |
61 template<typename Value> \ | |
62 boost::proto::env<TAG, Value &> const \ | |
63 operator =(boost::reference_wrapper<Value> &value) const \ | |
64 { \ | |
65 return boost::proto::env<TAG, Value &>(value.get()); \ | |
66 } \ | |
67 template<typename Value> \ | |
68 boost::proto::env<TAG, Value &> const \ | |
69 operator =(boost::reference_wrapper<Value> const &value) const \ | |
70 { \ | |
71 return boost::proto::env<TAG, Value &>(value.get()); \ | |
72 } \ | |
73 template<typename Value> \ | |
74 typename boost::disable_if_c< \ | |
75 boost::is_const<Value>::value \ | |
76 , boost::proto::env<TAG, typename boost::proto::detail::value_type<Value>::type> \ | |
77 >::type const operator =(Value &value) const \ | |
78 { \ | |
79 return boost::proto::env<TAG, typename boost::proto::detail::value_type<Value>::type>(value); \ | |
80 } \ | |
81 template<typename Value> \ | |
82 boost::proto::env<TAG, typename boost::proto::detail::value_type<Value const>::type> const \ | |
83 operator =(Value const &value) const \ | |
84 { \ | |
85 return boost::proto::env<TAG, typename boost::proto::detail::value_type<Value const>::type>(value); \ | |
86 } \ | |
87 }; \ | |
88 \ | |
89 TAG const NAME = {} \ | |
90 /**/ | |
91 | |
92 namespace envns_ | |
93 { | |
94 //////////////////////////////////////////////////////////////////////////////////////////// | |
95 // env | |
96 // A transform env is a slot-based storage mechanism, accessible by tag. | |
97 template<typename Key, typename Value, typename Base /*= empty_env*/> | |
98 struct env | |
99 : private Base | |
100 { | |
101 private: | |
102 Value value_; | |
103 | |
104 public: | |
105 typedef Value value_type; | |
106 typedef typename add_reference<Value>::type reference; | |
107 typedef typename add_reference<typename add_const<Value>::type>::type const_reference; | |
108 typedef void proto_environment_; ///< INTERNAL ONLY | |
109 | |
110 explicit env(const_reference value, Base const &base = Base()) | |
111 : Base(base) | |
112 , value_(value) | |
113 {} | |
114 | |
115 #if BOOST_WORKAROUND(__GNUC__, == 3) || (BOOST_WORKAROUND(__GNUC__, == 4) && __GNUC_MINOR__ <= 2) | |
116 /// INTERNAL ONLY | |
117 struct found | |
118 { | |
119 typedef Value type; | |
120 typedef typename add_reference<typename add_const<Value>::type>::type const_reference; | |
121 }; | |
122 | |
123 template<typename OtherKey, typename OtherValue = key_not_found> | |
124 struct lookup | |
125 : mpl::if_c< | |
126 is_same<OtherKey, Key>::value | |
127 , found | |
128 , typename Base::template lookup<OtherKey, OtherValue> | |
129 >::type | |
130 {}; | |
131 #else | |
132 /// INTERNAL ONLY | |
133 template<typename OtherKey, typename OtherValue = key_not_found> | |
134 struct lookup | |
135 : Base::template lookup<OtherKey, OtherValue> | |
136 {}; | |
137 | |
138 /// INTERNAL ONLY | |
139 template<typename OtherValue> | |
140 struct lookup<Key, OtherValue> | |
141 { | |
142 typedef Value type; | |
143 typedef typename add_reference<typename add_const<Value>::type>::type const_reference; | |
144 }; | |
145 #endif | |
146 | |
147 // For key-based lookups not intended to fail | |
148 using Base::operator[]; | |
149 const_reference operator[](Key) const | |
150 { | |
151 return this->value_; | |
152 } | |
153 | |
154 // For key-based lookups that can fail, use the default if key not found. | |
155 using Base::at; | |
156 template<typename T> | |
157 const_reference at(Key, T const &) const | |
158 { | |
159 return this->value_; | |
160 } | |
161 }; | |
162 | |
163 // define proto::data_type type and proto::data global | |
164 BOOST_PROTO_DEFINE_ENV_VAR(data_type, data); | |
165 } | |
166 | |
167 using envns_::data; | |
168 | |
169 namespace functional | |
170 { | |
171 //////////////////////////////////////////////////////////////////////////////////////// | |
172 // as_env | |
173 struct as_env | |
174 { | |
175 BOOST_PROTO_CALLABLE() | |
176 BOOST_PROTO_POLY_FUNCTION() | |
177 | |
178 /// INTERNAL ONLY | |
179 template<typename T, bool B = is_env<T>::value> | |
180 struct impl | |
181 { | |
182 typedef env<data_type, typename detail::value_type<T>::type> result_type; | |
183 | |
184 result_type const operator()(detail::arg<T> t) const | |
185 { | |
186 return result_type(t()); | |
187 } | |
188 }; | |
189 | |
190 /// INTERNAL ONLY | |
191 template<typename T> | |
192 struct impl<T, true> | |
193 { | |
194 typedef T result_type; | |
195 | |
196 typename add_const<T>::type operator()(detail::arg<T> t) const | |
197 { | |
198 return t(); | |
199 } | |
200 }; | |
201 | |
202 template<typename Sig> | |
203 struct result; | |
204 | |
205 template<typename This, typename T> | |
206 struct result<This(T)> | |
207 { | |
208 typedef typename impl<typename detail::normalize_arg<T>::type>::result_type type; | |
209 }; | |
210 | |
211 template<typename T> | |
212 typename impl<typename detail::normalize_arg<T &>::type>::result_type const | |
213 operator()(T &t BOOST_PROTO_DISABLE_IF_IS_CONST(T)) const | |
214 { | |
215 return impl<typename detail::normalize_arg<T &>::type>()( | |
216 static_cast<typename detail::normalize_arg<T &>::reference>(t) | |
217 ); | |
218 } | |
219 | |
220 template<typename T> | |
221 typename impl<typename detail::normalize_arg<T const &>::type>::result_type const | |
222 operator()(T const &t) const | |
223 { | |
224 return impl<typename detail::normalize_arg<T const &>::type>()( | |
225 static_cast<typename detail::normalize_arg<T const &>::reference>(t) | |
226 ); | |
227 } | |
228 }; | |
229 | |
230 //////////////////////////////////////////////////////////////////////////////////////// | |
231 // has_env_var | |
232 template<typename Key> | |
233 struct has_env_var | |
234 : detail::poly_function<has_env_var<Key> > | |
235 { | |
236 BOOST_PROTO_CALLABLE() | |
237 | |
238 template<typename Env, bool IsEnv = is_env<Env>::value> | |
239 struct impl | |
240 { | |
241 typedef | |
242 mpl::not_< | |
243 is_same< | |
244 typename remove_reference<Env>::type::template lookup<Key>::type | |
245 , key_not_found | |
246 > | |
247 > | |
248 result_type; | |
249 | |
250 result_type operator()(detail::arg<Env>) const | |
251 { | |
252 return result_type(); | |
253 } | |
254 }; | |
255 | |
256 template<typename Env> | |
257 struct impl<Env, false> | |
258 { | |
259 typedef mpl::false_ result_type; | |
260 | |
261 result_type operator()(detail::arg<Env>) const | |
262 { | |
263 return result_type(); | |
264 } | |
265 }; | |
266 }; | |
267 | |
268 template<> | |
269 struct has_env_var<data_type> | |
270 : detail::poly_function<has_env_var<data_type> > | |
271 { | |
272 BOOST_PROTO_CALLABLE() | |
273 | |
274 template<typename Env, bool IsEnv = is_env<Env>::value> | |
275 struct impl | |
276 { | |
277 typedef | |
278 mpl::not_< | |
279 is_same< | |
280 typename remove_reference<Env>::type::template lookup<data_type>::type | |
281 , key_not_found | |
282 > | |
283 > | |
284 result_type; | |
285 | |
286 result_type operator()(detail::arg<Env>) const | |
287 { | |
288 return result_type(); | |
289 } | |
290 }; | |
291 | |
292 template<typename Env> | |
293 struct impl<Env, false> | |
294 { | |
295 typedef mpl::true_ result_type; | |
296 | |
297 result_type operator()(detail::arg<Env>) const | |
298 { | |
299 return result_type(); | |
300 } | |
301 }; | |
302 }; | |
303 | |
304 //////////////////////////////////////////////////////////////////////////////////////// | |
305 // env_var | |
306 template<typename Key> | |
307 struct env_var | |
308 : detail::poly_function<env_var<Key> > | |
309 { | |
310 BOOST_PROTO_CALLABLE() | |
311 | |
312 template<typename Env> | |
313 struct impl | |
314 { | |
315 typedef | |
316 typename remove_reference<Env>::type::template lookup<Key>::type | |
317 result_type; | |
318 | |
319 result_type operator()(detail::arg<Env> e) const | |
320 { | |
321 return e()[Key()]; | |
322 } | |
323 }; | |
324 }; | |
325 | |
326 template<> | |
327 struct env_var<data_type> | |
328 : detail::poly_function<env_var<data_type> > | |
329 { | |
330 BOOST_PROTO_CALLABLE() | |
331 | |
332 template<typename Env, bool B = is_env<Env>::value> | |
333 struct impl | |
334 { | |
335 typedef Env result_type; | |
336 | |
337 result_type operator()(detail::arg<Env> e) const | |
338 { | |
339 return e(); | |
340 } | |
341 }; | |
342 | |
343 template<typename Env> | |
344 struct impl<Env, true> | |
345 { | |
346 typedef | |
347 typename remove_reference<Env>::type::template lookup<data_type>::type | |
348 result_type; | |
349 | |
350 result_type operator()(detail::arg<Env> e) const | |
351 { | |
352 return e()[proto::data]; | |
353 } | |
354 }; | |
355 }; | |
356 } | |
357 | |
358 namespace result_of | |
359 { | |
360 template<typename T> | |
361 struct as_env | |
362 : BOOST_PROTO_RESULT_OF<functional::as_env(T)> | |
363 {}; | |
364 | |
365 template<typename Env, typename Key> | |
366 struct has_env_var | |
367 : BOOST_PROTO_RESULT_OF<functional::has_env_var<Key>(Env)>::type | |
368 {}; | |
369 | |
370 template<typename Env, typename Key> | |
371 struct env_var | |
372 : BOOST_PROTO_RESULT_OF<functional::env_var<Key>(Env)> | |
373 {}; | |
374 } | |
375 | |
376 //////////////////////////////////////////////////////////////////////////////////////////// | |
377 // as_env | |
378 template<typename T> | |
379 typename proto::result_of::as_env<T &>::type const as_env(T &t BOOST_PROTO_DISABLE_IF_IS_CONST(T)) | |
380 { | |
381 return proto::functional::as_env()(t); | |
382 } | |
383 | |
384 template<typename T> | |
385 typename proto::result_of::as_env<T const &>::type const as_env(T const &t) | |
386 { | |
387 return proto::functional::as_env()(t); | |
388 } | |
389 | |
390 //////////////////////////////////////////////////////////////////////////////////////////// | |
391 // has_env_var | |
392 template<typename Key, typename Env> | |
393 typename proto::result_of::has_env_var<Env &, Key>::type has_env_var(Env &e BOOST_PROTO_DISABLE_IF_IS_CONST(Env)) | |
394 { | |
395 return functional::has_env_var<Key>()(e); | |
396 } | |
397 | |
398 template<typename Key, typename Env> | |
399 typename proto::result_of::has_env_var<Env const &, Key>::type has_env_var(Env const &e) | |
400 { | |
401 return functional::has_env_var<Key>()(e); | |
402 } | |
403 | |
404 //////////////////////////////////////////////////////////////////////////////////////////// | |
405 // env_var | |
406 template<typename Key, typename Env> | |
407 typename proto::result_of::env_var<Env &, Key>::type env_var(Env &e BOOST_PROTO_DISABLE_IF_IS_CONST(Env)) | |
408 { | |
409 return functional::env_var<Key>()(e); | |
410 } | |
411 | |
412 template<typename Key, typename Env> | |
413 typename proto::result_of::env_var<Env const &, Key>::type env_var(Env const &e) | |
414 { | |
415 return functional::env_var<Key>()(e); | |
416 } | |
417 | |
418 namespace envns_ | |
419 { | |
420 //////////////////////////////////////////////////////////////////////////////////////// | |
421 // env operator, | |
422 template<typename T, typename T1, typename V1> | |
423 inline typename disable_if_c< | |
424 is_const<T>::value | |
425 , env<T1, V1, BOOST_PROTO_UNCVREF(typename result_of::as_env<T &>::type)> | |
426 >::type const operator,(T &t, env<T1, V1> const &head) | |
427 { | |
428 return env<T1, V1, BOOST_PROTO_UNCVREF(typename result_of::as_env<T &>::type)>( | |
429 head[T1()] | |
430 , proto::as_env(t) | |
431 ); | |
432 } | |
433 | |
434 template<typename T, typename T1, typename V1> | |
435 inline env<T1, V1, BOOST_PROTO_UNCVREF(typename result_of::as_env<T const &>::type)> const | |
436 operator,(T const &t, env<T1, V1> const &head) | |
437 { | |
438 return env<T1, V1, BOOST_PROTO_UNCVREF(typename result_of::as_env<T const &>::type)>( | |
439 head[T1()] | |
440 , proto::as_env(t) | |
441 ); | |
442 } | |
443 } | |
444 | |
445 //////////////////////////////////////////////////////////////////////////////////////////// | |
446 // _env_var | |
447 template<typename Key> | |
448 struct _env_var | |
449 : proto::transform<_env_var<Key> > | |
450 { | |
451 template<typename Expr, typename State, typename Data> | |
452 struct impl | |
453 : transform_impl<Expr, State, Data> | |
454 { | |
455 typedef typename impl::data::template lookup<Key>::type result_type; | |
456 BOOST_MPL_ASSERT_NOT((is_same<result_type, key_not_found>)); // lookup failed | |
457 | |
458 BOOST_PROTO_RETURN_TYPE_STRICT_LOOSE(result_type, typename impl::data::template lookup<Key>::const_reference) | |
459 operator ()( | |
460 typename impl::expr_param | |
461 , typename impl::state_param | |
462 , typename impl::data_param d | |
463 ) const | |
464 { | |
465 return d[Key()]; | |
466 } | |
467 }; | |
468 }; | |
469 | |
470 struct _env | |
471 : transform<_env> | |
472 { | |
473 template<typename Expr, typename State, typename Data> | |
474 struct impl | |
475 : transform_impl<Expr, State, Data> | |
476 { | |
477 typedef Data result_type; | |
478 | |
479 BOOST_PROTO_RETURN_TYPE_STRICT_LOOSE(result_type, typename impl::data_param) | |
480 operator ()( | |
481 typename impl::expr_param | |
482 , typename impl::state_param | |
483 , typename impl::data_param d | |
484 ) const | |
485 { | |
486 return d; | |
487 } | |
488 }; | |
489 }; | |
490 | |
491 /// INTERNAL ONLY | |
492 template<typename Key> | |
493 struct is_callable<_env_var<Key> > | |
494 : mpl::true_ | |
495 {}; | |
496 | |
497 /// INTERNAL ONLY | |
498 template<typename Key> | |
499 struct is_callable<functional::has_env_var<Key> > | |
500 : mpl::true_ | |
501 {}; | |
502 | |
503 /// INTERNAL ONLY | |
504 template<typename Key> | |
505 struct is_callable<functional::env_var<Key> > | |
506 : mpl::true_ | |
507 {}; | |
508 } | |
509 } | |
510 | |
511 #ifdef _MSC_VER | |
512 # pragma warning(pop) | |
513 #endif | |
514 | |
515 #endif |