]> git.lyx.org Git - lyx.git/blob - 3rdparty/boost/boost/move/detail/meta_utils.hpp
Replace Boost.Signals with Boost.Signals2
[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
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