Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-11-02 09:21:45

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