]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/move/include/boost/move/detail/meta_utils.hpp
bump version to 12.2.2-pve1
[ceph.git] / ceph / src / boost / libs / move / include / boost / move / detail / meta_utils.hpp
1 //////////////////////////////////////////////////////////////////////////////
2 //
3 // (C) Copyright Ion Gaztanaga 2012-2015.
4 // Distributed under the Boost Software License, Version 1.0.
5 // (See accompanying file LICENSE_1_0.txt or copy at
6 // http://www.boost.org/LICENSE_1_0.txt)
7 //
8 // See http://www.boost.org/libs/move for documentation.
9 //
10 //////////////////////////////////////////////////////////////////////////////
11
12 //! \file
13
14 #ifndef BOOST_MOVE_DETAIL_META_UTILS_HPP
15 #define BOOST_MOVE_DETAIL_META_UTILS_HPP
16
17 #if defined(BOOST_HAS_PRAGMA_ONCE)
18 # pragma once
19 #endif
20 #include <boost/move/detail/config_begin.hpp>
21 #include <boost/move/detail/workaround.hpp> //forceinline
22 #include <boost/move/detail/meta_utils_core.hpp>
23 #include <cstddef> //for std::size_t
24
25 //Small meta-typetraits to support move
26
27 namespace boost {
28
29 //Forward declare boost::rv
30 template <class T> class rv;
31
32 namespace move_detail {
33
34 //////////////////////////////////////
35 // is_different
36 //////////////////////////////////////
37 template<class T, class U>
38 struct is_different
39 {
40 static const bool value = !is_same<T, U>::value;
41 };
42
43 //////////////////////////////////////
44 // apply
45 //////////////////////////////////////
46 template<class F, class Param>
47 struct apply
48 {
49 typedef typename F::template apply<Param>::type type;
50 };
51
52 //////////////////////////////////////
53 // bool_
54 //////////////////////////////////////
55
56 template< bool C_ >
57 struct bool_ : integral_constant<bool, C_>
58 {
59 operator bool() const { return C_; }
60 bool operator()() const { return C_; }
61 };
62
63 typedef bool_<true> true_;
64 typedef bool_<false> false_;
65
66 //////////////////////////////////////
67 // nat
68 //////////////////////////////////////
69 struct nat{};
70
71 //////////////////////////////////////
72 // yes_type/no_type
73 //////////////////////////////////////
74 typedef char yes_type;
75
76 struct no_type
77 {
78 char _[2];
79 };
80
81 //////////////////////////////////////
82 // natify
83 //////////////////////////////////////
84 template <class T> struct natify{};
85
86 //////////////////////////////////////
87 // remove_reference
88 //////////////////////////////////////
89 template<class T>
90 struct remove_reference
91 {
92 typedef T type;
93 };
94
95 template<class T>
96 struct remove_reference<T&>
97 {
98 typedef T type;
99 };
100
101 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
102
103 template<class T>
104 struct remove_reference<T&&>
105 {
106 typedef T type;
107 };
108
109 #else
110
111 template<class T>
112 struct remove_reference< rv<T> >
113 {
114 typedef T type;
115 };
116
117 template<class T>
118 struct remove_reference< rv<T> &>
119 {
120 typedef T type;
121 };
122
123 template<class T>
124 struct remove_reference< const rv<T> &>
125 {
126 typedef T type;
127 };
128
129 #endif
130
131 //////////////////////////////////////
132 // remove_pointer
133 //////////////////////////////////////
134
135 template< class T > struct remove_pointer { typedef T type; };
136 template< class T > struct remove_pointer<T*> { typedef T type; };
137 template< class T > struct remove_pointer<T* const> { typedef T type; };
138 template< class T > struct remove_pointer<T* volatile> { typedef T type; };
139 template< class T > struct remove_pointer<T* const volatile> { typedef T type; };
140
141 //////////////////////////////////////
142 // add_pointer
143 //////////////////////////////////////
144 template< class T >
145 struct add_pointer
146 {
147 typedef typename remove_reference<T>::type* type;
148 };
149
150 //////////////////////////////////////
151 // add_const
152 //////////////////////////////////////
153 template<class T>
154 struct add_const
155 {
156 typedef const T type;
157 };
158
159 template<class T>
160 struct add_const<T&>
161 {
162 typedef const T& type;
163 };
164
165 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
166
167 template<class T>
168 struct add_const<T&&>
169 {
170 typedef T&& type;
171 };
172
173 #endif
174
175 //////////////////////////////////////
176 // add_lvalue_reference
177 //////////////////////////////////////
178 template<class T>
179 struct add_lvalue_reference
180 { typedef T& type; };
181
182 template<class T> struct add_lvalue_reference<T&> { typedef T& type; };
183 template<> struct add_lvalue_reference<void> { typedef void type; };
184 template<> struct add_lvalue_reference<const void> { typedef const void type; };
185 template<> struct add_lvalue_reference<volatile void> { typedef volatile void type; };
186 template<> struct add_lvalue_reference<const volatile void>{ typedef const volatile void type; };
187
188 template<class T>
189 struct add_const_lvalue_reference
190 {
191 typedef typename remove_reference<T>::type t_unreferenced;
192 typedef typename add_const<t_unreferenced>::type t_unreferenced_const;
193 typedef typename add_lvalue_reference
194 <t_unreferenced_const>::type type;
195 };
196
197 //////////////////////////////////////
198 // is_lvalue_reference
199 //////////////////////////////////////
200 template<class T>
201 struct is_lvalue_reference
202 {
203 static const bool value = false;
204 };
205
206 template<class T>
207 struct is_lvalue_reference<T&>
208 {
209 static const bool value = true;
210 };
211
212
213 //////////////////////////////////////
214 // identity
215 //////////////////////////////////////
216 template <class T>
217 struct identity
218 {
219 typedef T type;
220 typedef typename add_const_lvalue_reference<T>::type reference;
221 reference operator()(reference t)
222 { return t; }
223 };
224
225 //////////////////////////////////////
226 // is_class_or_union
227 //////////////////////////////////////
228 template<class T>
229 struct is_class_or_union
230 {
231 struct twochar { char dummy[2]; };
232 template <class U>
233 static char is_class_or_union_tester(void(U::*)(void));
234 template <class U>
235 static twochar is_class_or_union_tester(...);
236 static const bool value = sizeof(is_class_or_union_tester<T>(0)) == sizeof(char);
237 };
238
239 //////////////////////////////////////
240 // addressof
241 //////////////////////////////////////
242 template<class T>
243 struct addr_impl_ref
244 {
245 T & v_;
246 BOOST_MOVE_FORCEINLINE addr_impl_ref( T & v ): v_( v ) {}
247 BOOST_MOVE_FORCEINLINE operator T& () const { return v_; }
248
249 private:
250 addr_impl_ref & operator=(const addr_impl_ref &);
251 };
252
253 template<class T>
254 struct addressof_impl
255 {
256 BOOST_MOVE_FORCEINLINE static T * f( T & v, long )
257 {
258 return reinterpret_cast<T*>(
259 &const_cast<char&>(reinterpret_cast<const volatile char &>(v)));
260 }
261
262 BOOST_MOVE_FORCEINLINE static T * f( T * v, int )
263 { return v; }
264 };
265
266 template<class T>
267 BOOST_MOVE_FORCEINLINE T * addressof( T & v )
268 {
269 return ::boost::move_detail::addressof_impl<T>::f
270 ( ::boost::move_detail::addr_impl_ref<T>( v ), 0 );
271 }
272
273 //////////////////////////////////////
274 // has_pointer_type
275 //////////////////////////////////////
276 template <class T>
277 struct has_pointer_type
278 {
279 struct two { char c[2]; };
280 template <class U> static two test(...);
281 template <class U> static char test(typename U::pointer* = 0);
282 static const bool value = sizeof(test<T>(0)) == 1;
283 };
284
285 //////////////////////////////////////
286 // is_convertible
287 //////////////////////////////////////
288 #if defined(_MSC_VER) && (_MSC_VER >= 1400)
289
290 //use intrinsic since in MSVC
291 //overaligned types can't go through ellipsis
292 template <class T, class U>
293 struct is_convertible
294 {
295 static const bool value = __is_convertible_to(T, U);
296 };
297
298 #else
299
300 template <class T, class U>
301 class is_convertible
302 {
303 typedef typename add_lvalue_reference<T>::type t_reference;
304 typedef char true_t;
305 class false_t { char dummy[2]; };
306 static false_t dispatch(...);
307 static true_t dispatch(U);
308 static t_reference trigger();
309 public:
310 static const bool value = sizeof(dispatch(trigger())) == sizeof(true_t);
311 };
312
313 #endif
314
315 template <class T, class U, bool IsSame = is_same<T, U>::value>
316 struct is_same_or_convertible
317 : is_convertible<T, U>
318 {};
319
320 template <class T, class U>
321 struct is_same_or_convertible<T, U, true>
322 {
323 static const bool value = true;
324 };
325
326 template<
327 bool C
328 , typename F1
329 , typename F2
330 >
331 struct eval_if_c
332 : if_c<C,F1,F2>::type
333 {};
334
335 template<
336 typename C
337 , typename T1
338 , typename T2
339 >
340 struct eval_if
341 : if_<C,T1,T2>::type
342 {};
343
344
345 #if defined(BOOST_GCC) && (BOOST_GCC <= 40000)
346 #define BOOST_MOVE_HELPERS_RETURN_SFINAE_BROKEN
347 #endif
348
349 template<class T, class U, class R = void>
350 struct enable_if_convertible
351 : enable_if< is_convertible<T, U>, R>
352 {};
353
354 template<class T, class U, class R = void>
355 struct disable_if_convertible
356 : disable_if< is_convertible<T, U>, R>
357 {};
358
359 template<class T, class U, class R = void>
360 struct enable_if_same_or_convertible
361 : enable_if< is_same_or_convertible<T, U>, R>
362 {};
363
364 template<class T, class U, class R = void>
365 struct disable_if_same_or_convertible
366 : disable_if< is_same_or_convertible<T, U>, R>
367 {};
368
369 //////////////////////////////////////////////////////////////////////////////
370 //
371 // and_
372 //
373 //////////////////////////////////////////////////////////////////////////////
374 template<bool, class B = true_, class C = true_, class D = true_>
375 struct and_impl
376 : and_impl<B::value, C, D>
377 {};
378
379 template<>
380 struct and_impl<true, true_, true_, true_>
381 {
382 static const bool value = true;
383 };
384
385 template<class B, class C, class D>
386 struct and_impl<false, B, C, D>
387 {
388 static const bool value = false;
389 };
390
391 template<class A, class B, class C = true_, class D = true_>
392 struct and_
393 : and_impl<A::value, B, C, D>
394 {};
395
396 //////////////////////////////////////////////////////////////////////////////
397 //
398 // or_
399 //
400 //////////////////////////////////////////////////////////////////////////////
401 template<bool, class B = false_, class C = false_, class D = false_>
402 struct or_impl
403 : or_impl<B::value, C, D>
404 {};
405
406 template<>
407 struct or_impl<false, false_, false_, false_>
408 {
409 static const bool value = false;
410 };
411
412 template<class B, class C, class D>
413 struct or_impl<true, B, C, D>
414 {
415 static const bool value = true;
416 };
417
418 template<class A, class B, class C = false_, class D = false_>
419 struct or_
420 : or_impl<A::value, B, C, D>
421 {};
422
423 //////////////////////////////////////////////////////////////////////////////
424 //
425 // not_
426 //
427 //////////////////////////////////////////////////////////////////////////////
428 template<class T>
429 struct not_
430 {
431 static const bool value = !T::value;
432 };
433
434 //////////////////////////////////////////////////////////////////////////////
435 //
436 // enable_if_and / disable_if_and / enable_if_or / disable_if_or
437 //
438 //////////////////////////////////////////////////////////////////////////////
439
440 template<class R, class A, class B, class C = true_, class D = true_>
441 struct enable_if_and
442 : enable_if_c< and_<A, B, C, D>::value, R>
443 {};
444
445 template<class R, class A, class B, class C = true_, class D = true_>
446 struct disable_if_and
447 : disable_if_c< and_<A, B, C, D>::value, R>
448 {};
449
450 template<class R, class A, class B, class C = false_, class D = false_>
451 struct enable_if_or
452 : enable_if_c< or_<A, B, C, D>::value, R>
453 {};
454
455 template<class R, class A, class B, class C = false_, class D = false_>
456 struct disable_if_or
457 : disable_if_c< or_<A, B, C, D>::value, R>
458 {};
459
460 //////////////////////////////////////////////////////////////////////////////
461 //
462 // has_move_emulation_enabled_impl
463 //
464 //////////////////////////////////////////////////////////////////////////////
465 template<class T>
466 struct has_move_emulation_enabled_impl
467 : is_convertible< T, ::boost::rv<T>& >
468 {};
469
470 template<class T>
471 struct has_move_emulation_enabled_impl<T&>
472 { static const bool value = false; };
473
474 template<class T>
475 struct has_move_emulation_enabled_impl< ::boost::rv<T> >
476 { static const bool value = false; };
477
478 //////////////////////////////////////////////////////////////////////////////
479 //
480 // is_rv_impl
481 //
482 //////////////////////////////////////////////////////////////////////////////
483
484 template <class T>
485 struct is_rv_impl
486 { static const bool value = false; };
487
488 template <class T>
489 struct is_rv_impl< rv<T> >
490 { static const bool value = true; };
491
492 template <class T>
493 struct is_rv_impl< const rv<T> >
494 { static const bool value = true; };
495
496 // Code from Jeffrey Lee Hellrung, many thanks
497
498 template< class T >
499 struct is_rvalue_reference
500 { static const bool value = false; };
501
502 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
503
504 template< class T >
505 struct is_rvalue_reference< T&& >
506 { static const bool value = true; };
507
508 #else // #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
509
510 template< class T >
511 struct is_rvalue_reference< boost::rv<T>& >
512 { static const bool value = true; };
513
514 template< class T >
515 struct is_rvalue_reference< const boost::rv<T>& >
516 { static const bool value = true; };
517
518 #endif // #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
519
520 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
521
522 template< class T >
523 struct add_rvalue_reference
524 { typedef T&& type; };
525
526 #else // #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
527
528 namespace detail_add_rvalue_reference
529 {
530 template< class T
531 , bool emulation = has_move_emulation_enabled_impl<T>::value
532 , bool rv = is_rv_impl<T>::value >
533 struct add_rvalue_reference_impl { typedef T type; };
534
535 template< class T, bool emulation>
536 struct add_rvalue_reference_impl< T, emulation, true > { typedef T & type; };
537
538 template< class T, bool rv >
539 struct add_rvalue_reference_impl< T, true, rv > { typedef ::boost::rv<T>& type; };
540 } // namespace detail_add_rvalue_reference
541
542 template< class T >
543 struct add_rvalue_reference
544 : detail_add_rvalue_reference::add_rvalue_reference_impl<T>
545 { };
546
547 template< class T >
548 struct add_rvalue_reference<T &>
549 { typedef T & type; };
550
551 #endif // #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
552
553 template< class T > struct remove_rvalue_reference { typedef T type; };
554
555 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
556 template< class T > struct remove_rvalue_reference< T&& > { typedef T type; };
557 #else // #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
558 template< class T > struct remove_rvalue_reference< rv<T> > { typedef T type; };
559 template< class T > struct remove_rvalue_reference< const rv<T> > { typedef T type; };
560 template< class T > struct remove_rvalue_reference< volatile rv<T> > { typedef T type; };
561 template< class T > struct remove_rvalue_reference< const volatile rv<T> > { typedef T type; };
562 template< class T > struct remove_rvalue_reference< rv<T>& > { typedef T type; };
563 template< class T > struct remove_rvalue_reference< const rv<T>& > { typedef T type; };
564 template< class T > struct remove_rvalue_reference< volatile rv<T>& > { typedef T type; };
565 template< class T > struct remove_rvalue_reference< const volatile rv<T>& >{ typedef T type; };
566 #endif // #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
567
568 // Ideas from Boost.Move review, Jeffrey Lee Hellrung:
569 //
570 //- TypeTraits metafunctions is_lvalue_reference, add_lvalue_reference, and remove_lvalue_reference ?
571 // Perhaps add_reference and remove_reference can be modified so that they behave wrt emulated rvalue
572 // references the same as wrt real rvalue references, i.e., add_reference< rv<T>& > -> T& rather than
573 // rv<T>& (since T&& & -> T&).
574 //
575 //- Add'l TypeTraits has_[trivial_]move_{constructor,assign}...?
576 //
577 //- An as_lvalue(T& x) function, which amounts to an identity operation in C++0x, but strips emulated
578 // rvalue references in C++03. This may be necessary to prevent "accidental moves".
579
580 } //namespace move_detail {
581 } //namespace boost {
582
583 #include <boost/move/detail/config_end.hpp>
584
585 #endif //#ifndef BOOST_MOVE_DETAIL_META_UTILS_HPP