Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:40:52

0001 //////////////////////////////////////////////////////////////////////////////
0002 //
0003 // (C) Copyright Ion Gaztanaga 2012-2015.
0004 // Distributed under the Boost Software License, Version 1.0.
0005 // (See accompanying file LICENSE_1_0.txt or copy at
0006 // http://www.boost.org/LICENSE_1_0.txt)
0007 //
0008 // See http://www.boost.org/libs/move for documentation.
0009 //
0010 //////////////////////////////////////////////////////////////////////////////
0011 
0012 //! \file
0013 
0014 #ifndef BOOST_MOVE_DETAIL_META_UTILS_HPP
0015 #define BOOST_MOVE_DETAIL_META_UTILS_HPP
0016 
0017 #if defined(BOOST_HAS_PRAGMA_ONCE)
0018 #  pragma once
0019 #endif
0020 #include <boost/move/detail/config_begin.hpp>
0021 #include <boost/move/detail/workaround.hpp>  //forceinline
0022 #include <boost/move/detail/meta_utils_core.hpp>
0023 #include <cstddef>   //for std::size_t
0024 #include <boost/move/detail/addressof.hpp>
0025 
0026 //Small meta-typetraits to support move
0027 
0028 namespace boost {
0029 
0030 //Forward declare boost::rv
0031 template <class T> class rv;
0032 
0033 namespace move_detail {
0034 
0035 //////////////////////////////////////
0036 //          is_different
0037 //////////////////////////////////////
0038 template<class T, class U>
0039 struct is_different
0040 {
0041    static const bool value = !is_same<T, U>::value;
0042 };
0043 
0044 //////////////////////////////////////
0045 //             apply
0046 //////////////////////////////////////
0047 template<class F, class Param>
0048 struct apply
0049 {
0050    typedef typename F::template apply<Param>::type type;
0051 };
0052 
0053 //////////////////////////////////////
0054 //             bool_
0055 //////////////////////////////////////
0056 
0057 template< bool C_ >
0058 struct bool_ : integral_constant<bool, C_>
0059 {
0060    BOOST_MOVE_FORCEINLINE operator bool() const { return C_; }
0061    BOOST_MOVE_FORCEINLINE bool operator()() const { return C_; }
0062 };
0063 
0064 typedef bool_<true>        true_;
0065 typedef bool_<false>       false_;
0066 
0067 //////////////////////////////////////
0068 //              nat
0069 //////////////////////////////////////
0070 struct nat{};
0071 struct nat2{};
0072 struct nat3{};
0073 
0074 template <unsigned N>
0075 struct natN
0076 {};
0077 
0078 //////////////////////////////////////
0079 //          yes_type/no_type
0080 //////////////////////////////////////
0081 typedef char yes_type;
0082 
0083 struct no_type
0084 {
0085    char _[2];
0086 };
0087 
0088 //////////////////////////////////////
0089 //            natify
0090 //////////////////////////////////////
0091 template <class T> struct natify{};
0092 
0093 //////////////////////////////////////
0094 //          remove_reference
0095 //////////////////////////////////////
0096 template<class T>
0097 struct remove_reference
0098 {
0099    typedef T type;
0100 };
0101 
0102 template<class T>
0103 struct remove_reference<T&>
0104 {
0105    typedef T type;
0106 };
0107 
0108 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
0109 
0110 template<class T>
0111 struct remove_reference<T&&>
0112 {
0113    typedef T type;
0114 };
0115 
0116 #else
0117 
0118 template<class T>
0119 struct remove_reference< rv<T> >
0120 {
0121    typedef T type;
0122 };
0123 
0124 template<class T>
0125 struct remove_reference< rv<T> &>
0126 {
0127    typedef T type;
0128 };
0129 
0130 template<class T>
0131 struct remove_reference< const rv<T> &>
0132 {
0133    typedef T type;
0134 };
0135 
0136 #endif
0137 
0138 //////////////////////////////////////
0139 //             remove_pointer
0140 //////////////////////////////////////
0141 
0142 template< class T > struct remove_pointer                    { typedef T type;   };
0143 template< class T > struct remove_pointer<T*>                { typedef T type;   };
0144 template< class T > struct remove_pointer<T* const>          { typedef T type;   };
0145 template< class T > struct remove_pointer<T* volatile>       { typedef T type;   };
0146 template< class T > struct remove_pointer<T* const volatile> { typedef T type;   };
0147 
0148 //////////////////////////////////////
0149 //             add_pointer
0150 //////////////////////////////////////
0151 template< class T >
0152 struct add_pointer
0153 {
0154    typedef typename remove_reference<T>::type* type;
0155 };
0156 
0157 //////////////////////////////////////
0158 //             add_const
0159 //////////////////////////////////////
0160 template<class T>
0161 struct add_const
0162 {
0163    typedef const T type;
0164 };
0165 
0166 template<class T>
0167 struct add_const<T&>
0168 {
0169    typedef const T& type;
0170 };
0171 
0172 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
0173 
0174 template<class T>
0175 struct add_const<T&&>
0176 {
0177    typedef T&& type;
0178 };
0179 
0180 #endif
0181 
0182 //////////////////////////////////////
0183 //      add_lvalue_reference
0184 //////////////////////////////////////
0185 template<class T>
0186 struct add_lvalue_reference
0187 {  typedef T& type;  };
0188 
0189 template<class T> struct add_lvalue_reference<T&>                 {  typedef T& type;  };
0190 template<>        struct add_lvalue_reference<void>               {  typedef void type;   };
0191 template<>        struct add_lvalue_reference<const void>         {  typedef const void type;  };
0192 template<>        struct add_lvalue_reference<volatile void>      {  typedef volatile void type;   };
0193 template<>        struct add_lvalue_reference<const volatile void>{  typedef const volatile void type;   };
0194 
0195 template<class T>
0196 struct add_const_lvalue_reference
0197 {
0198    typedef typename remove_reference<T>::type         t_unreferenced;
0199    typedef typename add_const<t_unreferenced>::type   t_unreferenced_const;
0200    typedef typename add_lvalue_reference
0201       <t_unreferenced_const>::type                    type;
0202 };
0203 
0204 //////////////////////////////////////
0205 //             is_lvalue_reference
0206 //////////////////////////////////////
0207 template<class T>
0208 struct is_lvalue_reference
0209 {
0210     static const bool value = false;
0211 };
0212 
0213 template<class T>
0214 struct is_lvalue_reference<T&>
0215 {
0216     static const bool value = true;
0217 };
0218 
0219 
0220 //////////////////////////////////////
0221 //             identity
0222 //////////////////////////////////////
0223 template <class T>
0224 struct identity
0225 {
0226    typedef T type;
0227    typedef typename add_const_lvalue_reference<T>::type reference;
0228    BOOST_MOVE_FORCEINLINE reference operator()(reference t) const
0229    {  return t;   }
0230 };
0231 
0232 //////////////////////////////////////
0233 //          is_class_or_union
0234 //////////////////////////////////////
0235 template<class T>
0236 struct is_class_or_union
0237 {
0238    struct twochar { char dummy[2]; };
0239    template <class U>
0240    static char is_class_or_union_tester(void(U::*)(void));
0241    template <class U>
0242    static twochar is_class_or_union_tester(...);
0243    static const bool value = sizeof(is_class_or_union_tester<T>(0)) == sizeof(char);
0244 };
0245 
0246 //////////////////////////////////////
0247 //             addressof
0248 //////////////////////////////////////
0249 
0250 
0251 //////////////////////////////////////
0252 //          has_pointer_type
0253 //////////////////////////////////////
0254 template <class T>
0255 struct has_pointer_type
0256 {
0257    struct two { char c[2]; };
0258    template <class U> static two test(...);
0259    template <class U> static char test(typename U::pointer* = 0);
0260    static const bool value = sizeof(test<T>(0)) == 1;
0261 };
0262 
0263 //////////////////////////////////////
0264 //           is_convertible
0265 //////////////////////////////////////
0266 #if defined(_MSC_VER) && (_MSC_VER >= 1400)
0267 
0268 //use intrinsic since in MSVC
0269 //overaligned types can't go through ellipsis
0270 template <class T, class U>
0271 struct is_convertible
0272 {
0273    static const bool value = __is_convertible_to(T, U);
0274 };
0275 
0276 #else
0277 
0278 template <class T, class U>
0279 class is_convertible
0280 {
0281    typedef typename add_lvalue_reference<T>::type t_reference;
0282    typedef char true_t;
0283    class false_t { char dummy[2]; };
0284    static false_t dispatch(...);
0285    static true_t  dispatch(U);
0286    static t_reference       trigger();
0287    public:
0288    static const bool value = sizeof(dispatch(trigger())) == sizeof(true_t);
0289 };
0290 
0291 #endif
0292 
0293 template <class T, class U, bool IsSame = is_same<T, U>::value>
0294 struct is_same_or_convertible
0295    : is_convertible<T, U>
0296 {};
0297 
0298 template <class T, class U>
0299 struct is_same_or_convertible<T, U, true>
0300 {
0301    static const bool value = true;
0302 };
0303 
0304 template<
0305       bool C
0306     , typename F1
0307     , typename F2
0308     >
0309 struct eval_if_c
0310     : if_c<C,F1,F2>::type
0311 {};
0312 
0313 template<
0314       typename C
0315     , typename T1
0316     , typename T2
0317     >
0318 struct eval_if
0319     : if_<C,T1,T2>::type
0320 {};
0321 
0322 
0323 #if defined(BOOST_GCC) && (BOOST_GCC <= 40000)
0324 #define BOOST_MOVE_HELPERS_RETURN_SFINAE_BROKEN
0325 #endif
0326 
0327 template<class T, class U, class R = void>
0328 struct enable_if_convertible
0329    : enable_if< is_convertible<T, U>, R>
0330 {};
0331 
0332 template<class T, class U, class R = void>
0333 struct disable_if_convertible
0334    : disable_if< is_convertible<T, U>, R>
0335 {};
0336 
0337 template<class T, class U, class R = void>
0338 struct enable_if_same_or_convertible
0339    : enable_if< is_same_or_convertible<T, U>, R>
0340 {};
0341 
0342 template<class T, class U, class R = void>
0343 struct disable_if_same_or_convertible
0344    : disable_if< is_same_or_convertible<T, U>, R>
0345 {};
0346 
0347 //////////////////////////////////////////////////////////////////////////////
0348 //
0349 //                         and_
0350 //
0351 //////////////////////////////////////////////////////////////////////////////
0352 template<bool, class B = true_, class C = true_, class D = true_>
0353 struct and_impl
0354    : and_impl<B::value, C, D>
0355 {};
0356 
0357 template<>
0358 struct and_impl<true, true_, true_, true_>
0359 {
0360    static const bool value = true;
0361 };
0362 
0363 template<class B, class C, class D>
0364 struct and_impl<false, B, C, D>
0365 {
0366    static const bool value = false;
0367 };
0368 
0369 template<class A, class B, class C = true_, class D = true_>
0370 struct and_
0371    : and_impl<A::value, B, C, D>
0372 {};
0373 
0374 //////////////////////////////////////////////////////////////////////////////
0375 //
0376 //                            or_
0377 //
0378 //////////////////////////////////////////////////////////////////////////////
0379 template<bool, class B = false_, class C = false_, class D = false_>
0380 struct or_impl
0381    : or_impl<B::value, C, D>
0382 {};
0383 
0384 template<>
0385 struct or_impl<false, false_, false_, false_>
0386 {
0387    static const bool value = false;
0388 };
0389 
0390 template<class B, class C, class D>
0391 struct or_impl<true, B, C, D>
0392 {
0393    static const bool value = true;
0394 };
0395 
0396 template<class A, class B, class C = false_, class D = false_>
0397 struct or_
0398    : or_impl<A::value, B, C, D>
0399 {};
0400 
0401 //////////////////////////////////////////////////////////////////////////////
0402 //
0403 //                         not_
0404 //
0405 //////////////////////////////////////////////////////////////////////////////
0406 template<class T>
0407 struct not_
0408 {
0409    static const bool value = !T::value;
0410 };
0411 
0412 //////////////////////////////////////////////////////////////////////////////
0413 //
0414 // enable_if_and / disable_if_and / enable_if_or / disable_if_or
0415 //
0416 //////////////////////////////////////////////////////////////////////////////
0417 
0418 template<class R, class A, class B, class C = true_, class D = true_>
0419 struct enable_if_and
0420    : enable_if_c< and_<A, B, C, D>::value, R>
0421 {};
0422 
0423 template<class R, class A, class B, class C = true_, class D = true_>
0424 struct disable_if_and
0425    : disable_if_c< and_<A, B, C, D>::value, R>
0426 {};
0427 
0428 template<class R, class A, class B, class C = false_, class D = false_>
0429 struct enable_if_or
0430    : enable_if_c< or_<A, B, C, D>::value, R>
0431 {};
0432 
0433 template<class R, class A, class B, class C = false_, class D = false_>
0434 struct disable_if_or
0435    : disable_if_c< or_<A, B, C, D>::value, R>
0436 {};
0437 
0438 //////////////////////////////////////////////////////////////////////////////
0439 //
0440 //                      has_move_emulation_enabled_impl
0441 //
0442 //////////////////////////////////////////////////////////////////////////////
0443 template<class T>
0444 struct has_move_emulation_enabled_impl
0445    : is_convertible< T, ::boost::rv<T>& >
0446 {};
0447 
0448 template<class T>
0449 struct has_move_emulation_enabled_impl<T&>
0450 {  static const bool value = false;  };
0451 
0452 template<class T>
0453 struct has_move_emulation_enabled_impl< ::boost::rv<T> >
0454 {  static const bool value = false;  };
0455 
0456 //////////////////////////////////////////////////////////////////////////////
0457 //
0458 //                            is_rv_impl
0459 //
0460 //////////////////////////////////////////////////////////////////////////////
0461 
0462 template <class T>
0463 struct is_rv_impl
0464 {  static const bool value = false;  };
0465 
0466 template <class T>
0467 struct is_rv_impl< rv<T> >
0468 {  static const bool value = true;  };
0469 
0470 template <class T>
0471 struct is_rv_impl< const rv<T> >
0472 {  static const bool value = true;  };
0473 
0474 // Code from Jeffrey Lee Hellrung, many thanks
0475 
0476 template< class T >
0477 struct is_rvalue_reference
0478 {  static const bool value = false;  };
0479 
0480 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
0481 
0482 template< class T >
0483 struct is_rvalue_reference< T&& >
0484 {  static const bool value = true;  };
0485 
0486 #else // #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
0487 
0488 template< class T >
0489 struct is_rvalue_reference< boost::rv<T>& >
0490 {  static const bool value = true;  };
0491 
0492 template< class T >
0493 struct is_rvalue_reference< const boost::rv<T>& >
0494 {  static const bool value = true;  };
0495 
0496 #endif // #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
0497 
0498 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
0499 
0500 template< class T >
0501 struct add_rvalue_reference
0502 { typedef T&& type; };
0503 
0504 #else // #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
0505 
0506 namespace detail_add_rvalue_reference
0507 {
0508    template< class T
0509             , bool emulation = has_move_emulation_enabled_impl<T>::value
0510             , bool rv        = is_rv_impl<T>::value  >
0511    struct add_rvalue_reference_impl { typedef T type; };
0512 
0513    template< class T, bool emulation>
0514    struct add_rvalue_reference_impl< T, emulation, true > { typedef T & type; };
0515 
0516    template< class T, bool rv >
0517    struct add_rvalue_reference_impl< T, true, rv > { typedef ::boost::rv<T>& type; };
0518 } // namespace detail_add_rvalue_reference
0519 
0520 template< class T >
0521 struct add_rvalue_reference
0522    : detail_add_rvalue_reference::add_rvalue_reference_impl<T>
0523 { };
0524 
0525 template< class T >
0526 struct add_rvalue_reference<T &>
0527 {  typedef T & type; };
0528 
0529 #endif // #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
0530 
0531 template< class T > struct remove_rvalue_reference { typedef T type; };
0532 
0533 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
0534    template< class T > struct remove_rvalue_reference< T&& >                  { typedef T type; };
0535 #else // #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
0536    template< class T > struct remove_rvalue_reference< rv<T> >                { typedef T type; };
0537    template< class T > struct remove_rvalue_reference< const rv<T> >          { typedef T type; };
0538    template< class T > struct remove_rvalue_reference< volatile rv<T> >       { typedef T type; };
0539    template< class T > struct remove_rvalue_reference< const volatile rv<T> > { typedef T type; };
0540    template< class T > struct remove_rvalue_reference< rv<T>& >               { typedef T type; };
0541    template< class T > struct remove_rvalue_reference< const rv<T>& >         { typedef T type; };
0542    template< class T > struct remove_rvalue_reference< volatile rv<T>& >      { typedef T type; };
0543    template< class T > struct remove_rvalue_reference< const volatile rv<T>& >{ typedef T type; };
0544 #endif // #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
0545 
0546 // Ideas from Boost.Move review, Jeffrey Lee Hellrung:
0547 //
0548 //- TypeTraits metafunctions is_lvalue_reference, add_lvalue_reference, and remove_lvalue_reference ?
0549 //  Perhaps add_reference and remove_reference can be modified so that they behave wrt emulated rvalue
0550 //  references the same as wrt real rvalue references, i.e., add_reference< rv<T>& > -> T& rather than
0551 //  rv<T>& (since T&& & -> T&).
0552 //
0553 //- Add'l TypeTraits has_[trivial_]move_{constructor,assign}...?
0554 //
0555 //- An as_lvalue(T& x) function, which amounts to an identity operation in C++0x, but strips emulated
0556 //  rvalue references in C++03.  This may be necessary to prevent "accidental moves".
0557 
0558 }  //namespace move_detail {
0559 }  //namespace boost {
0560 
0561 #include <boost/move/detail/config_end.hpp>
0562 
0563 #endif //#ifndef BOOST_MOVE_DETAIL_META_UTILS_HPP