]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/proto/include/boost/proto/transform/env.hpp
bump version to 12.2.2-pve1
[ceph.git] / ceph / src / boost / libs / proto / include / boost / proto / transform / env.hpp
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