| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587 | ////////////////////////////////////////////////////////////////////////////////// (C) Copyright Ion Gaztanaga 2012-2015.// Distributed under the Boost Software License, Version 1.0.// (See accompanying file LICENSE_1_0.txt or copy at// http://www.boost.org/LICENSE_1_0.txt)//// See http://www.boost.org/libs/move for documentation.//////////////////////////////////////////////////////////////////////////////////! \file#ifndef BOOST_MOVE_DETAIL_META_UTILS_HPP#define BOOST_MOVE_DETAIL_META_UTILS_HPP#if defined(BOOST_HAS_PRAGMA_ONCE)#  pragma once#endif#include <boost/move/detail/config_begin.hpp>#include <boost/move/detail/workaround.hpp>  //forceinline#include <boost/move/detail/meta_utils_core.hpp>#include <cstddef>   //for std::size_t//Small meta-typetraits to support movenamespace boost {//Forward declare boost::rvtemplate <class T> class rv;namespace move_detail {////////////////////////////////////////          is_different//////////////////////////////////////template<class T, class U>struct is_different{   static const bool value = !is_same<T, U>::value;};////////////////////////////////////////             apply//////////////////////////////////////template<class F, class Param>struct apply{   typedef typename F::template apply<Param>::type type;};////////////////////////////////////////             bool_//////////////////////////////////////template< bool C_ >struct bool_ : integral_constant<bool, C_>{     operator bool() const { return C_; }   bool operator()() const { return C_; }};typedef bool_<true>        true_;typedef bool_<false>       false_;////////////////////////////////////////              nat//////////////////////////////////////struct nat{};struct nat2{};struct nat3{};////////////////////////////////////////          yes_type/no_type//////////////////////////////////////typedef char yes_type;struct no_type{   char _[2];};////////////////////////////////////////            natify//////////////////////////////////////template <class T> struct natify{};////////////////////////////////////////          remove_reference//////////////////////////////////////template<class T>struct remove_reference{   typedef T type;};template<class T>struct remove_reference<T&>{   typedef T type;};#ifndef BOOST_NO_CXX11_RVALUE_REFERENCEStemplate<class T>struct remove_reference<T&&>{   typedef T type;};#elsetemplate<class T>struct remove_reference< rv<T> >{   typedef T type;};template<class T>struct remove_reference< rv<T> &>{   typedef T type;};template<class T>struct remove_reference< const rv<T> &>{   typedef T type;};#endif////////////////////////////////////////             remove_pointer//////////////////////////////////////template< class T > struct remove_pointer                    { typedef T type;   };template< class T > struct remove_pointer<T*>                { typedef T type;   };template< class T > struct remove_pointer<T* const>          { typedef T type;   };template< class T > struct remove_pointer<T* volatile>       { typedef T type;   };template< class T > struct remove_pointer<T* const volatile> { typedef T type;   };////////////////////////////////////////             add_pointer//////////////////////////////////////template< class T >struct add_pointer{   typedef typename remove_reference<T>::type* type;};////////////////////////////////////////             add_const//////////////////////////////////////template<class T>struct add_const{   typedef const T type;};template<class T>struct add_const<T&>{   typedef const T& type;};#ifndef BOOST_NO_CXX11_RVALUE_REFERENCEStemplate<class T>struct add_const<T&&>{   typedef T&& type;};#endif////////////////////////////////////////      add_lvalue_reference//////////////////////////////////////template<class T>struct add_lvalue_reference{  typedef T& type;  };template<class T> struct add_lvalue_reference<T&>                 {  typedef T& type;  };template<>        struct add_lvalue_reference<void>               {  typedef void type;   };template<>        struct add_lvalue_reference<const void>         {  typedef const void type;  };template<>        struct add_lvalue_reference<volatile void>      {  typedef volatile void type;   };template<>        struct add_lvalue_reference<const volatile void>{  typedef const volatile void type;   };template<class T>struct add_const_lvalue_reference{   typedef typename remove_reference<T>::type         t_unreferenced;   typedef typename add_const<t_unreferenced>::type   t_unreferenced_const;   typedef typename add_lvalue_reference      <t_unreferenced_const>::type                    type;};////////////////////////////////////////             is_lvalue_reference//////////////////////////////////////template<class T>struct is_lvalue_reference{    static const bool value = false;};template<class T>struct is_lvalue_reference<T&>{    static const bool value = true;};////////////////////////////////////////             identity//////////////////////////////////////template <class T>struct identity{   typedef T type;   typedef typename add_const_lvalue_reference<T>::type reference;   reference operator()(reference t)   {  return t;   }};////////////////////////////////////////          is_class_or_union//////////////////////////////////////template<class T>struct is_class_or_union{   struct twochar { char dummy[2]; };   template <class U>   static char is_class_or_union_tester(void(U::*)(void));   template <class U>   static twochar is_class_or_union_tester(...);   static const bool value = sizeof(is_class_or_union_tester<T>(0)) == sizeof(char);};////////////////////////////////////////             addressof//////////////////////////////////////template<class T>struct addr_impl_ref{   T & v_;   BOOST_MOVE_FORCEINLINE addr_impl_ref( T & v ): v_( v ) {}   BOOST_MOVE_FORCEINLINE operator T& () const { return v_; }   private:   addr_impl_ref & operator=(const addr_impl_ref &);};template<class T>struct addressof_impl{   BOOST_MOVE_FORCEINLINE static T * f( T & v, long )   {      return reinterpret_cast<T*>(         &const_cast<char&>(reinterpret_cast<const volatile char &>(v)));   }   BOOST_MOVE_FORCEINLINE static T * f( T * v, int )   {  return v;  }};template<class T>BOOST_MOVE_FORCEINLINE T * addressof( T & v ){   return ::boost::move_detail::addressof_impl<T>::f      ( ::boost::move_detail::addr_impl_ref<T>( v ), 0 );}////////////////////////////////////////          has_pointer_type//////////////////////////////////////template <class T>struct has_pointer_type{   struct two { char c[2]; };   template <class U> static two test(...);   template <class U> static char test(typename U::pointer* = 0);   static const bool value = sizeof(test<T>(0)) == 1;};////////////////////////////////////////           is_convertible//////////////////////////////////////#if defined(_MSC_VER) && (_MSC_VER >= 1400)//use intrinsic since in MSVC//overaligned types can't go through ellipsistemplate <class T, class U>struct is_convertible{   static const bool value = __is_convertible_to(T, U);};#elsetemplate <class T, class U>class is_convertible{   typedef typename add_lvalue_reference<T>::type t_reference;   typedef char true_t;   class false_t { char dummy[2]; };   static false_t dispatch(...);   static true_t  dispatch(U);   static t_reference       trigger();   public:   static const bool value = sizeof(dispatch(trigger())) == sizeof(true_t);};#endiftemplate <class T, class U, bool IsSame = is_same<T, U>::value>struct is_same_or_convertible   : is_convertible<T, U>{};template <class T, class U>struct is_same_or_convertible<T, U, true>{   static const bool value = true;};template<      bool C    , typename F1    , typename F2    >struct eval_if_c    : if_c<C,F1,F2>::type{};template<      typename C    , typename T1    , typename T2    >struct eval_if    : if_<C,T1,T2>::type{};#if defined(BOOST_GCC) && (BOOST_GCC <= 40000)#define BOOST_MOVE_HELPERS_RETURN_SFINAE_BROKEN#endiftemplate<class T, class U, class R = void>struct enable_if_convertible   : enable_if< is_convertible<T, U>, R>{};template<class T, class U, class R = void>struct disable_if_convertible   : disable_if< is_convertible<T, U>, R>{};template<class T, class U, class R = void>struct enable_if_same_or_convertible   : enable_if< is_same_or_convertible<T, U>, R>{};template<class T, class U, class R = void>struct disable_if_same_or_convertible   : disable_if< is_same_or_convertible<T, U>, R>{};//////////////////////////////////////////////////////////////////////////////////                         and_////////////////////////////////////////////////////////////////////////////////template<bool, class B = true_, class C = true_, class D = true_>struct and_impl   : and_impl<B::value, C, D>{};template<>struct and_impl<true, true_, true_, true_>{   static const bool value = true;};template<class B, class C, class D>struct and_impl<false, B, C, D>{   static const bool value = false;};template<class A, class B, class C = true_, class D = true_>struct and_   : and_impl<A::value, B, C, D>{};//////////////////////////////////////////////////////////////////////////////////                            or_////////////////////////////////////////////////////////////////////////////////template<bool, class B = false_, class C = false_, class D = false_>struct or_impl   : or_impl<B::value, C, D>{};template<>struct or_impl<false, false_, false_, false_>{   static const bool value = false;};template<class B, class C, class D>struct or_impl<true, B, C, D>{   static const bool value = true;};template<class A, class B, class C = false_, class D = false_>struct or_   : or_impl<A::value, B, C, D>{};//////////////////////////////////////////////////////////////////////////////////                         not_////////////////////////////////////////////////////////////////////////////////template<class T>struct not_{   static const bool value = !T::value;};////////////////////////////////////////////////////////////////////////////////// enable_if_and / disable_if_and / enable_if_or / disable_if_or////////////////////////////////////////////////////////////////////////////////template<class R, class A, class B, class C = true_, class D = true_>struct enable_if_and   : enable_if_c< and_<A, B, C, D>::value, R>{};template<class R, class A, class B, class C = true_, class D = true_>struct disable_if_and   : disable_if_c< and_<A, B, C, D>::value, R>{};template<class R, class A, class B, class C = false_, class D = false_>struct enable_if_or   : enable_if_c< or_<A, B, C, D>::value, R>{};template<class R, class A, class B, class C = false_, class D = false_>struct disable_if_or   : disable_if_c< or_<A, B, C, D>::value, R>{};//////////////////////////////////////////////////////////////////////////////////                      has_move_emulation_enabled_impl////////////////////////////////////////////////////////////////////////////////template<class T>struct has_move_emulation_enabled_impl   : is_convertible< T, ::boost::rv<T>& >{};template<class T>struct has_move_emulation_enabled_impl<T&>{  static const bool value = false;  };template<class T>struct has_move_emulation_enabled_impl< ::boost::rv<T> >{  static const bool value = false;  };//////////////////////////////////////////////////////////////////////////////////                            is_rv_impl////////////////////////////////////////////////////////////////////////////////template <class T>struct is_rv_impl{  static const bool value = false;  };template <class T>struct is_rv_impl< rv<T> >{  static const bool value = true;  };template <class T>struct is_rv_impl< const rv<T> >{  static const bool value = true;  };// Code from Jeffrey Lee Hellrung, many thankstemplate< class T >struct is_rvalue_reference{  static const bool value = false;  };#ifndef BOOST_NO_CXX11_RVALUE_REFERENCEStemplate< class T >struct is_rvalue_reference< T&& >{  static const bool value = true;  };#else // #ifndef BOOST_NO_CXX11_RVALUE_REFERENCEStemplate< class T >struct is_rvalue_reference< boost::rv<T>& >{  static const bool value = true;  };template< class T >struct is_rvalue_reference< const boost::rv<T>& >{  static const bool value = true;  };#endif // #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES#ifndef BOOST_NO_CXX11_RVALUE_REFERENCEStemplate< class T >struct add_rvalue_reference{ typedef T&& type; };#else // #ifndef BOOST_NO_CXX11_RVALUE_REFERENCESnamespace detail_add_rvalue_reference{   template< class T            , bool emulation = has_move_emulation_enabled_impl<T>::value            , bool rv        = is_rv_impl<T>::value  >   struct add_rvalue_reference_impl { typedef T type; };   template< class T, bool emulation>   struct add_rvalue_reference_impl< T, emulation, true > { typedef T & type; };   template< class T, bool rv >   struct add_rvalue_reference_impl< T, true, rv > { typedef ::boost::rv<T>& type; };} // namespace detail_add_rvalue_referencetemplate< class T >struct add_rvalue_reference   : detail_add_rvalue_reference::add_rvalue_reference_impl<T>{ };template< class T >struct add_rvalue_reference<T &>{  typedef T & type; };#endif // #ifndef BOOST_NO_CXX11_RVALUE_REFERENCEStemplate< class T > struct remove_rvalue_reference { typedef T type; };#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES   template< class T > struct remove_rvalue_reference< T&& >                  { typedef T type; };#else // #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES   template< class T > struct remove_rvalue_reference< rv<T> >                { typedef T type; };   template< class T > struct remove_rvalue_reference< const rv<T> >          { typedef T type; };   template< class T > struct remove_rvalue_reference< volatile rv<T> >       { typedef T type; };   template< class T > struct remove_rvalue_reference< const volatile rv<T> > { typedef T type; };   template< class T > struct remove_rvalue_reference< rv<T>& >               { typedef T type; };   template< class T > struct remove_rvalue_reference< const rv<T>& >         { typedef T type; };   template< class T > struct remove_rvalue_reference< volatile rv<T>& >      { typedef T type; };   template< class T > struct remove_rvalue_reference< const volatile rv<T>& >{ typedef T type; };#endif // #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES// Ideas from Boost.Move review, Jeffrey Lee Hellrung:////- TypeTraits metafunctions is_lvalue_reference, add_lvalue_reference, and remove_lvalue_reference ?//  Perhaps add_reference and remove_reference can be modified so that they behave wrt emulated rvalue//  references the same as wrt real rvalue references, i.e., add_reference< rv<T>& > -> T& rather than//  rv<T>& (since T&& & -> T&).////- Add'l TypeTraits has_[trivial_]move_{constructor,assign}...?////- An as_lvalue(T& x) function, which amounts to an identity operation in C++0x, but strips emulated//  rvalue references in C++03.  This may be necessary to prevent "accidental moves".}  //namespace move_detail {}  //namespace boost {#include <boost/move/detail/config_end.hpp>#endif //#ifndef BOOST_MOVE_DETAIL_META_UTILS_HPP
 |