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