Back to home page

EIC code displayed by LXR

 
 

    


Warning, file /include/boost/move/detail/type_traits.hpp was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).

0001 //////////////////////////////////////////////////////////////////////////////
0002 // (C) Copyright John Maddock 2000.
0003 // (C) Copyright Ion Gaztanaga 2005-2015.
0004 //
0005 // Distributed under the Boost Software License, Version 1.0.
0006 // (See accompanying file LICENSE_1_0.txt or copy at
0007 // http://www.boost.org/LICENSE_1_0.txt)
0008 //
0009 // See http://www.boost.org/libs/move for documentation.
0010 //
0011 // The alignment and Type traits implementation comes from
0012 // John Maddock's TypeTraits library.
0013 //
0014 // Some other tricks come from Howard Hinnant's papers and StackOverflow replies
0015 //////////////////////////////////////////////////////////////////////////////
0016 #ifndef BOOST_MOVE_DETAIL_TYPE_TRAITS_HPP
0017 #define BOOST_MOVE_DETAIL_TYPE_TRAITS_HPP
0018 
0019 #ifndef BOOST_CONFIG_HPP
0020 #  include <boost/config.hpp>
0021 #endif
0022 #
0023 #if defined(BOOST_HAS_PRAGMA_ONCE)
0024 #  pragma once
0025 #endif
0026 
0027 #include <boost/move/detail/config_begin.hpp>
0028 #include <boost/move/detail/workaround.hpp>
0029 
0030 // move/detail
0031 #include <boost/move/detail/meta_utils.hpp>
0032 // other
0033 #include <cassert>
0034 // std
0035 #include <cstddef>
0036 
0037 //Use of Boost.TypeTraits leads to long preprocessed source code due to
0038 //MPL dependencies. We'll use intrinsics directly and make or own
0039 //simplified version of TypeTraits.
0040 //If someday Boost.TypeTraits dependencies are minimized, we should
0041 //revisit this file redirecting code to Boost.TypeTraits traits.
0042 
0043 //These traits don't care about volatile, reference or other checks
0044 //made by Boost.TypeTraits because no volatile or reference types
0045 //can be hold in Boost.Containers. This helps to avoid any Boost.TypeTraits
0046 //dependency.
0047 
0048 // Helper macros for builtin compiler support.
0049 // If your compiler has builtin support for any of the following
0050 // traits concepts, then redefine the appropriate macros to pick
0051 // up on the compiler support:
0052 //
0053 // (these should largely ignore cv-qualifiers)
0054 // BOOST_MOVE_IS_POD(T) should evaluate to true if T is a POD type
0055 // BOOST_MOVE_HAS_TRIVIAL_CONSTRUCTOR(T) should evaluate to true if "T x;" has no effect
0056 // BOOST_MOVE_HAS_TRIVIAL_COPY(T) should evaluate to true if T(t) <==> memcpy
0057 // (Note: this trait does not guarantee T is copy constructible, the copy constructor could be deleted but still be trivial)
0058 // BOOST_MOVE_HAS_TRIVIAL_MOVE_CONSTRUCTOR(T) should evaluate to true if T(boost::move(t)) <==> memcpy
0059 // BOOST_MOVE_HAS_TRIVIAL_ASSIGN(T) should evaluate to true if t = u <==> memcpy
0060 // (Note: this trait does not guarantee T is assignable , the copy assignmen could be deleted but still be trivial)
0061 // BOOST_MOVE_HAS_TRIVIAL_MOVE_ASSIGN(T) should evaluate to true if t = boost::move(u) <==> memcpy
0062 // BOOST_MOVE_HAS_TRIVIAL_DESTRUCTOR(T) should evaluate to true if ~T() has no effect
0063 // BOOST_MOVE_HAS_NOTHROW_CONSTRUCTOR(T) should evaluate to true if "T x;" can not throw
0064 // BOOST_MOVE_HAS_NOTHROW_COPY(T) should evaluate to true if T(t) can not throw
0065 // BOOST_MOVE_HAS_NOTHROW_ASSIGN(T) should evaluate to true if t = u can not throw
0066 // BOOST_MOVE_IS_ENUM(T) should evaluate to true it t is a union type.
0067 // BOOST_MOVE_HAS_NOTHROW_MOVE_CONSTRUCTOR(T) should evaluate to true if T has a non-throwing move constructor.
0068 // BOOST_MOVE_HAS_NOTHROW_MOVE_ASSIGN(T) should evaluate to true if T has a non-throwing move assignment operator.
0069 //
0070 // The following can also be defined: when detected our implementation is greatly simplified.
0071 //
0072 // BOOST_ALIGNMENT_OF(T) should evaluate to the alignment requirements of type T.
0073 
0074 #if defined(__MSL_CPP__) && (__MSL_CPP__ >= 0x8000)
0075     // Metrowerks compiler is acquiring intrinsic type traits support
0076     // post version 8.  We hook into the published interface to pick up
0077     // user defined specializations as well as compiler intrinsics as
0078     // and when they become available:
0079 #   include <msl_utility>
0080 #   define BOOST_MOVE_IS_UNION(T) BOOST_STD_EXTENSION_NAMESPACE::is_union<T>::value
0081 #   define BOOST_MOVE_IS_POD(T) BOOST_STD_EXTENSION_NAMESPACE::is_POD<T>::value
0082 #   define BOOST_MOVE_HAS_TRIVIAL_CONSTRUCTOR(T) BOOST_STD_EXTENSION_NAMESPACE::has_trivial_default_ctor<T>::value
0083 #   define BOOST_MOVE_HAS_TRIVIAL_COPY(T) BOOST_STD_EXTENSION_NAMESPACE::has_trivial_copy_ctor<T>::value
0084 #   define BOOST_MOVE_HAS_TRIVIAL_ASSIGN(T) BOOST_STD_EXTENSION_NAMESPACE::has_trivial_assignment<T>::value
0085 #   define BOOST_MOVE_HAS_TRIVIAL_DESTRUCTOR(T) BOOST_STD_EXTENSION_NAMESPACE::has_trivial_dtor<T>::value
0086 #endif
0087 
0088 #if (defined(BOOST_MSVC) && defined(BOOST_MSVC_FULL_VER) && (BOOST_MSVC_FULL_VER >=140050215))\
0089          || (defined(BOOST_INTEL) && defined(_MSC_VER) && (_MSC_VER >= 1500))
0090 #   define BOOST_MOVE_IS_UNION(T) __is_union(T)
0091 #   define BOOST_MOVE_IS_POD(T)                    (__is_pod(T) && __has_trivial_constructor(T))
0092 #   define BOOST_MOVE_IS_EMPTY(T)                  __is_empty(T)
0093 #   define BOOST_MOVE_HAS_TRIVIAL_CONSTRUCTOR(T)   __has_trivial_constructor(T)
0094 #   define BOOST_MOVE_HAS_TRIVIAL_COPY(T)          (__has_trivial_copy(T)|| ::boost::move_detail::is_pod<T>::value)
0095 #   define BOOST_MOVE_HAS_TRIVIAL_ASSIGN(T)        (__has_trivial_assign(T) || ::boost::move_detail::is_pod<T>::value)
0096 #   define BOOST_MOVE_HAS_TRIVIAL_DESTRUCTOR(T)    (__has_trivial_destructor(T) || ::boost::move_detail::is_pod<T>::value)
0097 #   define BOOST_MOVE_HAS_NOTHROW_CONSTRUCTOR(T)   (__has_nothrow_constructor(T) || ::boost::move_detail::is_trivially_default_constructible<T>::value)
0098 #   define BOOST_MOVE_HAS_NOTHROW_COPY(T)          (__has_nothrow_copy(T) || ::boost::move_detail::is_trivially_copy_constructible<T>::value)
0099 #   define BOOST_MOVE_HAS_NOTHROW_ASSIGN(T)        (__has_nothrow_assign(T) || ::boost::move_detail::is_trivially_copy_assignable<T>::value)
0100 
0101 #   define BOOST_MOVE_IS_ENUM(T) __is_enum(T)
0102 #   if defined(_MSC_VER) && (_MSC_VER >= 1700)
0103 #       define BOOST_MOVE_HAS_TRIVIAL_MOVE_CONSTRUCTOR(T)   (__has_trivial_move_constructor(T) || ::boost::move_detail::is_pod<T>::value)
0104 #       define BOOST_MOVE_HAS_TRIVIAL_MOVE_ASSIGN(T)        (__has_trivial_move_assign(T) || ::boost::move_detail::is_pod<T>::value)
0105 #   endif
0106 #  if _MSC_FULL_VER >= 180020827
0107 #     define BOOST_MOVE_HAS_NOTHROW_MOVE_ASSIGN(T) (__is_nothrow_assignable(T&, T&&))
0108 #     define BOOST_MOVE_HAS_NOTHROW_MOVE_CONSTRUCTOR(T) (__is_nothrow_constructible(T, T&&))
0109 #  endif
0110 #endif
0111 
0112 #if defined(BOOST_CLANG)
0113 //    BOOST_MOVE_HAS_TRAIT
0114 #   if defined __is_identifier
0115 #       define BOOST_MOVE_HAS_TRAIT(T) (__has_extension(T) || !__is_identifier(__##T))
0116 #   elif defined(__has_extension)
0117 #     define BOOST_MOVE_HAS_TRAIT(T) __has_extension(T)
0118 #   else
0119 #     define BOOST_MOVE_HAS_TRAIT(T) 0
0120 #   endif
0121 
0122 //    BOOST_MOVE_IS_UNION
0123 #   if BOOST_MOVE_HAS_TRAIT(is_union)
0124 #     define BOOST_MOVE_IS_UNION(T) __is_union(T)
0125 #   endif
0126 
0127 //    BOOST_MOVE_IS_ENUM
0128 #   if BOOST_MOVE_HAS_TRAIT(is_enum)
0129 #     define BOOST_MOVE_IS_ENUM(T) __is_enum(T)
0130 #   endif
0131 
0132 //    BOOST_MOVE_IS_POD
0133 #   if (!defined(__GLIBCXX__) || (__GLIBCXX__ >= 20080306 && __GLIBCXX__ != 20080519)) && BOOST_MOVE_HAS_TRAIT(is_pod)
0134 #     define BOOST_MOVE_IS_POD(T) __is_pod(T)
0135 #   endif
0136 
0137 //    BOOST_MOVE_IS_EMPTY
0138 #   if (!defined(__GLIBCXX__) || (__GLIBCXX__ >= 20080306 && __GLIBCXX__ != 20080519)) && BOOST_MOVE_HAS_TRAIT(is_empty)
0139 #     define BOOST_MOVE_IS_EMPTY(T) __is_empty(T)
0140 #   endif
0141 
0142 //    BOOST_MOVE_HAS_TRIVIAL_CONSTRUCTOR
0143 #   if BOOST_MOVE_HAS_TRAIT(is_constructible) && BOOST_MOVE_HAS_TRAIT(is_trivially_constructible)
0144 #     define BOOST_MOVE_HAS_TRIVIAL_CONSTRUCTOR(T) __is_trivially_constructible(T)
0145 #   elif BOOST_MOVE_HAS_TRAIT(has_trivial_constructor)
0146 #     define BOOST_MOVE_HAS_TRIVIAL_CONSTRUCTOR(T) __has_trivial_constructor(T)
0147 #   endif
0148 
0149 //    BOOST_MOVE_HAS_TRIVIAL_COPY
0150 #   if BOOST_MOVE_HAS_TRAIT(is_constructible) && BOOST_MOVE_HAS_TRAIT(is_trivially_constructible)
0151 #     define BOOST_MOVE_HAS_TRIVIAL_COPY(T) (__is_constructible(T, const T &) && __is_trivially_constructible(T, const T &))
0152 #   elif BOOST_MOVE_HAS_TRAIT(has_trivial_copy)
0153 #     define BOOST_MOVE_HAS_TRIVIAL_COPY(T) __has_trivial_copy(T)
0154 #   endif
0155 
0156 //    BOOST_MOVE_HAS_TRIVIAL_ASSIGN
0157 #   if BOOST_MOVE_HAS_TRAIT(is_assignable) && BOOST_MOVE_HAS_TRAIT(is_trivially_assignable)
0158 #     define BOOST_MOVE_HAS_TRIVIAL_ASSIGN(T) (__is_assignable(T, const T &) && __is_trivially_assignable(T, const T &))
0159 #   elif BOOST_MOVE_HAS_TRAIT(has_trivial_copy)
0160 #     define BOOST_MOVE_HAS_TRIVIAL_ASSIGN(T) __has_trivial_assign(T)
0161 #   endif
0162 
0163 //    BOOST_MOVE_HAS_TRIVIAL_DESTRUCTOR
0164 #   if BOOST_MOVE_HAS_TRAIT(is_trivially_destructible)
0165 #     define BOOST_MOVE_HAS_TRIVIAL_DESTRUCTOR(T) __is_trivially_destructible(T)
0166 #   elif BOOST_MOVE_HAS_TRAIT(has_trivial_destructor)
0167 #     define BOOST_MOVE_HAS_TRIVIAL_DESTRUCTOR(T) __has_trivial_destructor(T)
0168 #   endif
0169 
0170 //    BOOST_MOVE_HAS_NOTHROW_CONSTRUCTOR
0171 #   if BOOST_MOVE_HAS_TRAIT(is_nothrow_constructible)
0172 #     define BOOST_MOVE_HAS_NOTHROW_CONSTRUCTOR(T) __is_nothrow_constructible(T)
0173 #   elif BOOST_MOVE_HAS_TRAIT(has_nothrow_constructor)
0174 #     define BOOST_MOVE_HAS_NOTHROW_CONSTRUCTOR(T) __has_nothrow_constructor(T)
0175 #   endif
0176 
0177 //    BOOST_MOVE_HAS_NOTHROW_COPY
0178 #   if BOOST_MOVE_HAS_TRAIT(is_constructible) && BOOST_MOVE_HAS_TRAIT(is_nothrow_constructible)
0179 #     define BOOST_MOVE_HAS_NOTHROW_COPY(T) (__is_constructible(T, const T &) && __is_nothrow_constructible(T, const T &))
0180 #   elif BOOST_MOVE_HAS_TRAIT(has_nothrow_copy)
0181 #     define BOOST_MOVE_HAS_NOTHROW_COPY(T) (__has_nothrow_copy(T))
0182 #   endif
0183 
0184 //    BOOST_MOVE_HAS_NOTHROW_ASSIGN
0185 #   if BOOST_MOVE_HAS_TRAIT(is_assignable) && BOOST_MOVE_HAS_TRAIT(is_nothrow_assignable)
0186 #     define BOOST_MOVE_HAS_NOTHROW_ASSIGN(T) (__is_assignable(T, const T &) && __is_nothrow_assignable(T, const T &))
0187 #   elif BOOST_MOVE_HAS_TRAIT(has_nothrow_assign)
0188 #     define BOOST_MOVE_HAS_NOTHROW_ASSIGN(T) (__has_nothrow_assign(T))
0189 #   endif
0190 
0191 //    BOOST_MOVE_HAS_TRIVIAL_MOVE_CONSTRUCTOR
0192 #   if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) 
0193 
0194 #   if BOOST_MOVE_HAS_TRAIT(is_constructible) && BOOST_MOVE_HAS_TRAIT(is_trivially_constructible)
0195 #     define BOOST_MOVE_HAS_TRIVIAL_MOVE_CONSTRUCTOR(T) (__is_constructible(T, T&&) && __is_trivially_constructible(T, T&&))
0196 #   elif BOOST_MOVE_HAS_TRAIT(has_trivial_move_constructor)
0197 #     define BOOST_MOVE_HAS_TRIVIAL_MOVE_CONSTRUCTOR(T) __has_trivial_move_constructor(T)
0198 #   endif
0199 
0200 //    BOOST_MOVE_HAS_TRIVIAL_MOVE_ASSIGN
0201 #   if BOOST_MOVE_HAS_TRAIT(is_assignable) && BOOST_MOVE_HAS_TRAIT(is_trivially_assignable)
0202 #     define BOOST_MOVE_HAS_TRIVIAL_MOVE_ASSIGN(T) (__is_assignable(T, T&&) && __is_trivially_assignable(T, T&&))
0203 #   elif BOOST_MOVE_HAS_TRAIT(has_trivial_move_assign)
0204 #     define BOOST_MOVE_HAS_TRIVIAL_MOVE_ASSIGN(T) __has_trivial_move_assign(T)
0205 #   endif
0206 
0207 //    BOOST_MOVE_HAS_NOTHROW_MOVE_CONSTRUCTOR
0208 #   if BOOST_MOVE_HAS_TRAIT(is_constructible) && BOOST_MOVE_HAS_TRAIT(is_nothrow_constructible)
0209 #     define BOOST_MOVE_HAS_NOTHROW_MOVE_CONSTRUCTOR(T) (__is_constructible(T, T&&) && __is_nothrow_constructible(T, T&&))
0210 #   elif BOOST_MOVE_HAS_TRAIT(has_nothrow_move_constructor)
0211 #     define BOOST_MOVE_HAS_NOTHROW_MOVE_CONSTRUCTOR(T) __has_nothrow_move_constructor(T)
0212 #   endif
0213 
0214 //    BOOST_MOVE_HAS_NOTHROW_MOVE_ASSIGN
0215 #   if BOOST_MOVE_HAS_TRAIT(is_assignable) && BOOST_MOVE_HAS_TRAIT(is_nothrow_assignable)
0216 #     define BOOST_MOVE_HAS_NOTHROW_MOVE_ASSIGN(T) (__is_assignable(T, T&&) && __is_nothrow_assignable(T, T&&))
0217 #   elif BOOST_MOVE_HAS_TRAIT(has_nothrow_move_assign)
0218 #     define BOOST_MOVE_HAS_NOTHROW_MOVE_ASSIGN(T) __has_nothrow_move_assign(T)
0219 #   endif
0220 
0221 #   endif   //BOOST_NO_CXX11_RVALUE_REFERENCES
0222 
0223 //    BOOST_MOVE_ALIGNMENT_OF
0224 #   define BOOST_MOVE_ALIGNMENT_OF(T) __alignof(T)
0225 
0226 #endif   //#if defined(BOOST_CLANG)
0227 
0228 #if defined(__GNUC__) && ((__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 3) && !defined(__GCCXML__))) && !defined(BOOST_CLANG)
0229 
0230 #ifdef BOOST_INTEL
0231 #  define BOOST_MOVE_INTEL_TT_OPTS || ::boost::move_detail::is_pod<T>::value
0232 #else
0233 #  define BOOST_MOVE_INTEL_TT_OPTS
0234 #endif
0235 
0236 #   define BOOST_MOVE_IS_UNION(T) __is_union(T)
0237 #   define BOOST_MOVE_IS_POD(T) __is_pod(T)
0238 #   define BOOST_MOVE_IS_EMPTY(T) __is_empty(T)
0239 #   define BOOST_MOVE_HAS_TRIVIAL_CONSTRUCTOR(T) ((__has_trivial_constructor(T) BOOST_MOVE_INTEL_TT_OPTS))
0240 
0241 #   if defined(BOOST_GCC) && (BOOST_GCC > 50000)
0242 #     define BOOST_MOVE_HAS_TRIVIAL_COPY(T) (__is_trivially_constructible(T, const T &))
0243 #     define BOOST_MOVE_HAS_TRIVIAL_ASSIGN(T) (__is_trivially_assignable(T, const T &))
0244 #   else
0245 #     define BOOST_MOVE_HAS_TRIVIAL_COPY(T) ((__has_trivial_copy(T) BOOST_MOVE_INTEL_TT_OPTS))
0246 #     define BOOST_MOVE_HAS_TRIVIAL_ASSIGN(T) ((__has_trivial_assign(T) BOOST_MOVE_INTEL_TT_OPTS) )
0247 #   endif
0248 
0249 #   define BOOST_MOVE_HAS_TRIVIAL_DESTRUCTOR(T) (__has_trivial_destructor(T) BOOST_MOVE_INTEL_TT_OPTS)
0250 #   define BOOST_MOVE_HAS_NOTHROW_CONSTRUCTOR(T) (__has_nothrow_constructor(T) BOOST_MOVE_INTEL_TT_OPTS)
0251 #   define BOOST_MOVE_HAS_NOTHROW_COPY(T) ((__has_nothrow_copy(T) BOOST_MOVE_INTEL_TT_OPTS))
0252 #   define BOOST_MOVE_HAS_NOTHROW_ASSIGN(T) ((__has_nothrow_assign(T) BOOST_MOVE_INTEL_TT_OPTS))
0253 
0254 #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && !defined(BOOST_NO_CXX11_SFINAE_EXPR)
0255 
0256    template <typename T>
0257    T && boost_move_tt_declval() BOOST_NOEXCEPT;
0258 
0259 #  if defined(BOOST_GCC) && (BOOST_GCC >= 80000)
0260 // __is_assignable / __is_constructible implemented
0261 #     define BOOST_MOVE_IS_ASSIGNABLE(T, U)     __is_assignable(T, U)
0262 #     define BOOST_MOVE_IS_CONSTRUCTIBLE(T, U)  __is_constructible(T, U)
0263 #  else
0264 
0265    template<typename Tt, typename Ut>
0266    class boost_move_tt_is_assignable
0267    {
0268       struct twochar {  char dummy[2]; };
0269       template < class T
0270                , class U
0271                , class = decltype(boost_move_tt_declval<T>() = boost_move_tt_declval<U>())
0272                > static char test(int);
0273 
0274       template<class, class> static twochar test(...);
0275 
0276       public:
0277       static const bool value = sizeof(test<Tt, Ut>(0)) == sizeof(char);
0278    };
0279 
0280    template<typename Tt, typename Ut>
0281    class boost_move_tt_is_constructible
0282    {
0283       struct twochar {  char dummy[2]; };
0284       template < class T
0285                , class U
0286                , class = decltype(T(boost_move_tt_declval<U>()))
0287                > static char test(int);
0288 
0289       template<class, class> static twochar test(...);
0290 
0291       public:
0292       static const bool value = sizeof(test<Tt, Ut>(0)) == sizeof(char);
0293    };
0294 
0295 #     define BOOST_MOVE_IS_ASSIGNABLE(T, U)     boost_move_tt_is_assignable<T,U>::value
0296 #     define BOOST_MOVE_IS_CONSTRUCTIBLE(T, U)  boost_move_tt_is_constructible<T, U>::value
0297 
0298 #  endif
0299 
0300    template <typename T, typename U, bool = BOOST_MOVE_IS_ASSIGNABLE(T, U)>
0301    struct boost_move_tt_is_nothrow_assignable
0302    {
0303       static const bool value = false;
0304    };
0305 
0306    template <typename T, typename U>
0307    struct boost_move_tt_is_nothrow_assignable<T, U, true>
0308    {
0309       #if !defined(BOOST_NO_CXX11_NOEXCEPT)
0310       static const bool value = noexcept(boost_move_tt_declval<T>() = boost_move_tt_declval<U>());
0311       #else
0312       static const bool value = false;
0313       #endif
0314    };
0315 
0316    template <typename T, typename U, bool = BOOST_MOVE_IS_CONSTRUCTIBLE(T, U)>
0317    struct boost_move_tt_is_nothrow_constructible
0318    {
0319       static const bool value = false;
0320    };
0321 
0322    template <typename T, typename U>
0323    struct boost_move_tt_is_nothrow_constructible<T, U, true>
0324    {
0325       #if !defined(BOOST_NO_CXX11_NOEXCEPT)
0326       static const bool value = noexcept(T(boost_move_tt_declval<U>()));
0327       #else
0328       static const bool value = false;
0329       #endif
0330    };
0331 
0332 #     define BOOST_MOVE_HAS_NOTHROW_MOVE_ASSIGN(T)       boost_move_tt_is_nothrow_assignable<T, T&&>::value
0333 #     define BOOST_MOVE_HAS_NOTHROW_MOVE_CONSTRUCTOR(T)  boost_move_tt_is_nothrow_constructible<T, T&&>::value
0334 
0335 #  endif
0336 
0337 #   define BOOST_MOVE_IS_ENUM(T) __is_enum(T)
0338 
0339 // BOOST_MOVE_ALIGNMENT_OF
0340 #   if (!defined(unix) && !defined(__unix__)) || defined(__LP64__)
0341       // GCC sometimes lies about alignment requirements
0342       // of type double on 32-bit unix platforms, use the
0343       // old implementation instead in that case:
0344 #     define BOOST_MOVE_ALIGNMENT_OF(T) __alignof__(T)
0345 #   endif
0346 #endif
0347 
0348 #if defined(__ghs__) && (__GHS_VERSION_NUMBER >= 600)
0349 
0350 #   define BOOST_MOVE_IS_UNION(T) __is_union(T)
0351 #   define BOOST_MOVE_IS_POD(T) __is_pod(T)
0352 #   define BOOST_MOVE_IS_EMPTY(T) __is_empty(T)
0353 #   define BOOST_MOVE_HAS_TRIVIAL_CONSTRUCTOR(T) __has_trivial_constructor(T)
0354 #   define BOOST_MOVE_HAS_TRIVIAL_COPY(T) (__has_trivial_copy(T))
0355 #   define BOOST_MOVE_HAS_TRIVIAL_ASSIGN(T) (__has_trivial_assign(T))
0356 #   define BOOST_MOVE_HAS_TRIVIAL_DESTRUCTOR(T) __has_trivial_destructor(T)
0357 #   define BOOST_MOVE_HAS_NOTHROW_CONSTRUCTOR(T) __has_nothrow_constructor(T)
0358 #   define BOOST_MOVE_HAS_NOTHROW_COPY(T) (__has_nothrow_copy(T))
0359 #   define BOOST_MOVE_HAS_NOTHROW_ASSIGN(T) (__has_nothrow_assign(T))
0360 
0361 #   define BOOST_MOVE_IS_ENUM(T) __is_enum(T)
0362 #   define BOOST_MOVE_ALIGNMENT_OF(T) __alignof__(T)
0363 #endif
0364 
0365 # if defined(BOOST_CODEGEARC)
0366 #   define BOOST_MOVE_IS_UNION(T) __is_union(T)
0367 #   define BOOST_MOVE_IS_POD(T) __is_pod(T)
0368 #   define BOOST_MOVE_IS_EMPTY(T) __is_empty(T)
0369 #   define BOOST_MOVE_HAS_TRIVIAL_CONSTRUCTOR(T) (__has_trivial_default_constructor(T))
0370 #   define BOOST_MOVE_HAS_TRIVIAL_COPY(T) (__has_trivial_copy_constructor(T))
0371 #   define BOOST_MOVE_HAS_TRIVIAL_ASSIGN(T) (__has_trivial_assign(T))
0372 #   define BOOST_MOVE_HAS_TRIVIAL_DESTRUCTOR(T) (__has_trivial_destructor(T))
0373 #   define BOOST_MOVE_HAS_NOTHROW_CONSTRUCTOR(T) (__has_nothrow_default_constructor(T))
0374 #   define BOOST_MOVE_HAS_NOTHROW_COPY(T) (__has_nothrow_copy_constructor(T))
0375 #   define BOOST_MOVE_HAS_NOTHROW_ASSIGN(T) (__has_nothrow_assign(T))
0376 
0377 #   define BOOST_MOVE_IS_ENUM(T) __is_enum(T)
0378 #   define BOOST_MOVE_ALIGNMENT_OF(T) alignof(T)
0379 
0380 #endif
0381 
0382 //Fallback definitions
0383 
0384 #ifdef BOOST_MOVE_IS_UNION
0385    #define BOOST_MOVE_IS_UNION_IMPL(T) BOOST_MOVE_IS_UNION(T)
0386 #else
0387    #define BOOST_MOVE_IS_UNION_IMPL(T) false
0388 #endif
0389 
0390 #ifdef BOOST_MOVE_IS_POD
0391    //in some compilers the intrinsic is limited to class types so add scalar and void
0392    #define BOOST_MOVE_IS_POD_IMPL(T) (::boost::move_detail::is_scalar<T>::value ||\
0393                                       ::boost::move_detail::is_void<T>::value   ||\
0394                                        BOOST_MOVE_IS_POD(T))
0395 #else
0396    #define BOOST_MOVE_IS_POD_IMPL(T) \
0397       (::boost::move_detail::is_scalar<T>::value || ::boost::move_detail::is_void<T>::value)
0398 #endif
0399 
0400 #ifdef BOOST_MOVE_IS_EMPTY
0401    #define BOOST_MOVE_IS_EMPTY_IMPL(T) BOOST_MOVE_IS_EMPTY(T)
0402 #else
0403    #define BOOST_MOVE_IS_EMPTY_IMPL(T)    ::boost::move_detail::is_empty_nonintrinsic<T>::value
0404 #endif
0405 
0406 #ifdef BOOST_MOVE_HAS_TRIVIAL_COPY
0407    #define BOOST_MOVE_IS_TRIVIALLY_COPY_CONSTRUCTIBLE(T)   ::boost::move_detail::is_pod<T>::value ||\
0408                                                           (::boost::move_detail::is_copy_constructible<T>::value &&\
0409                                                            BOOST_MOVE_HAS_TRIVIAL_COPY(T))
0410 #else
0411    #define BOOST_MOVE_IS_TRIVIALLY_COPY_CONSTRUCTIBLE(T)   ::boost::move_detail::is_pod<T>::value
0412 #endif
0413 
0414 #ifdef BOOST_MOVE_HAS_TRIVIAL_CONSTRUCTOR
0415    #define BOOST_MOVE_IS_TRIVIALLY_DEFAULT_CONSTRUCTIBLE(T)  BOOST_MOVE_HAS_TRIVIAL_CONSTRUCTOR(T) || ::boost::move_detail::is_pod<T>::value
0416 #else
0417    #define BOOST_MOVE_IS_TRIVIALLY_DEFAULT_CONSTRUCTIBLE(T)  ::boost::move_detail::is_pod<T>::value
0418 #endif
0419 
0420 #ifdef BOOST_MOVE_HAS_TRIVIAL_MOVE_CONSTRUCTOR
0421    #define BOOST_MOVE_IS_TRIVIALLY_MOVE_CONSTRUCTIBLE(T)   BOOST_MOVE_HAS_TRIVIAL_MOVE_CONSTRUCTOR(T) || ::boost::move_detail::is_pod<T>::value
0422 #else
0423    #define BOOST_MOVE_IS_TRIVIALLY_MOVE_CONSTRUCTIBLE(T)   ::boost::move_detail::is_pod<T>::value
0424 #endif
0425 
0426 #ifdef BOOST_MOVE_HAS_TRIVIAL_ASSIGN
0427    #define BOOST_MOVE_IS_TRIVIALLY_COPY_ASSIGNABLE(T) ::boost::move_detail::is_pod<T>::value ||\
0428                                                       ( ::boost::move_detail::is_copy_assignable<T>::value &&\
0429                                                          BOOST_MOVE_HAS_TRIVIAL_ASSIGN(T))
0430 #else
0431    #define BOOST_MOVE_IS_TRIVIALLY_COPY_ASSIGNABLE(T) ::boost::move_detail::is_pod<T>::value
0432 #endif
0433 
0434 #ifdef BOOST_MOVE_HAS_TRIVIAL_MOVE_ASSIGN
0435    #define BOOST_MOVE_IS_TRIVIALLY_MOVE_ASSIGNABLE(T)  BOOST_MOVE_HAS_TRIVIAL_MOVE_ASSIGN(T) || ::boost::move_detail::is_pod<T>::value
0436 #else
0437    #define BOOST_MOVE_IS_TRIVIALLY_MOVE_ASSIGNABLE(T)  ::boost::move_detail::is_pod<T>::value
0438 #endif
0439 
0440 #ifdef BOOST_MOVE_HAS_TRIVIAL_DESTRUCTOR
0441    #define BOOST_MOVE_IS_TRIVIALLY_DESTRUCTIBLE(T)   BOOST_MOVE_HAS_TRIVIAL_DESTRUCTOR(T) || ::boost::move_detail::is_pod<T>::value
0442 #else
0443    #define BOOST_MOVE_IS_TRIVIALLY_DESTRUCTIBLE(T)   ::boost::move_detail::is_pod<T>::value
0444 #endif
0445 
0446 #ifdef BOOST_MOVE_HAS_NOTHROW_CONSTRUCTOR
0447    #define BOOST_MOVE_IS_NOTHROW_DEFAULT_CONSTRUCTIBLE(T)  BOOST_MOVE_HAS_NOTHROW_CONSTRUCTOR(T) || ::boost::move_detail::is_pod<T>::value
0448 #else
0449    #define BOOST_MOVE_IS_NOTHROW_DEFAULT_CONSTRUCTIBLE(T)  ::boost::move_detail::is_pod<T>::value
0450 #endif
0451 
0452 #ifdef BOOST_MOVE_HAS_NOTHROW_COPY
0453    #define BOOST_MOVE_IS_NOTHROW_COPY_CONSTRUCTIBLE(T)   BOOST_MOVE_HAS_NOTHROW_COPY(T) || ::boost::move_detail::is_pod<T>::value
0454 #else
0455    #define BOOST_MOVE_IS_NOTHROW_COPY_CONSTRUCTIBLE(T)   BOOST_MOVE_IS_TRIVIALLY_COPY_ASSIGNABLE(T)
0456 #endif
0457 
0458 #ifdef BOOST_MOVE_HAS_NOTHROW_ASSIGN
0459    #define BOOST_MOVE_IS_NOTHROW_COPY_ASSIGNABLE(T) BOOST_MOVE_HAS_NOTHROW_ASSIGN(T) || ::boost::move_detail::is_pod<T>::value
0460 #else
0461    #define BOOST_MOVE_IS_NOTHROW_COPY_ASSIGNABLE(T) BOOST_MOVE_IS_TRIVIALLY_COPY_ASSIGNABLE(T)
0462 #endif
0463 
0464 #ifdef BOOST_MOVE_HAS_NOTHROW_MOVE_CONSTRUCTOR
0465    #define BOOST_MOVE_IS_NOTHROW_MOVE_CONSTRUCTIBLE(T)   BOOST_MOVE_HAS_NOTHROW_MOVE_CONSTRUCTOR(T) || ::boost::move_detail::is_pod<T>::value
0466 #else
0467    #define BOOST_MOVE_IS_NOTHROW_MOVE_CONSTRUCTIBLE(T)   BOOST_MOVE_IS_TRIVIALLY_MOVE_ASSIGNABLE(T)
0468 #endif
0469 
0470 #ifdef BOOST_MOVE_HAS_NOTHROW_MOVE_ASSIGN
0471    #define BOOST_MOVE_IS_NOTHROW_MOVE_ASSIGNABLE(T) BOOST_MOVE_HAS_NOTHROW_MOVE_ASSIGN(T) || ::boost::move_detail::is_pod<T>::value
0472 #else
0473    #define BOOST_MOVE_IS_NOTHROW_MOVE_ASSIGNABLE(T) BOOST_MOVE_IS_TRIVIALLY_MOVE_ASSIGNABLE(T)
0474 #endif
0475 
0476 #ifdef BOOST_MOVE_IS_ENUM
0477    #define BOOST_MOVE_IS_ENUM_IMPL(T)   BOOST_MOVE_IS_ENUM(T)
0478 #else
0479    #define BOOST_MOVE_IS_ENUM_IMPL(T)   ::boost::move_detail::is_enum_nonintrinsic<T>::value
0480 #endif
0481 
0482 namespace boost {
0483 namespace move_detail {
0484 
0485 //////////////////////////
0486 //    is_reference
0487 //////////////////////////
0488 template<class T>
0489 struct is_reference
0490 {  static const bool value = false; };
0491 
0492 template<class T>
0493 struct is_reference<T&>
0494 {  static const bool value = true; };
0495 
0496 #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
0497 template<class T>
0498 struct is_reference<T&&>
0499 {  static const bool value = true; };
0500 #endif
0501 
0502 //////////////////////////
0503 //    is_pointer
0504 //////////////////////////
0505 template<class T>
0506 struct is_pointer
0507 {  static const bool value = false; };
0508 
0509 template<class T>
0510 struct is_pointer<T*>
0511 {  static const bool value = true; };
0512 
0513 //////////////////////////
0514 //       is_const
0515 //////////////////////////
0516 template<class T>
0517 struct is_const
0518 {  static const bool value = false; };
0519 
0520 template<class T>
0521 struct is_const<const T>
0522 {  static const bool value = true; };
0523 
0524 //////////////////////////
0525 //       unvoid_ref
0526 //////////////////////////
0527 template <typename T> struct unvoid_ref : add_lvalue_reference<T>{};
0528 template <> struct unvoid_ref<void>                { typedef unvoid_ref & type; };
0529 template <> struct unvoid_ref<const void>          { typedef unvoid_ref & type; };
0530 template <> struct unvoid_ref<volatile void>       { typedef unvoid_ref & type; };
0531 template <> struct unvoid_ref<const volatile void> { typedef unvoid_ref & type; };
0532 
0533 template <typename T>
0534 struct add_reference : add_lvalue_reference<T>
0535 {};
0536 
0537 //////////////////////////
0538 //    add_const_reference
0539 //////////////////////////
0540 template <class T>
0541 struct add_const_reference
0542 {  typedef const T &type;   };
0543 
0544 template <class T>
0545 struct add_const_reference<T&>
0546 {  typedef T& type;   };
0547 
0548 //////////////////////////
0549 //    add_const_if_c
0550 //////////////////////////
0551 template<class T, bool Add>
0552 struct add_const_if_c
0553    : if_c<Add, typename add_const<T>::type, T>
0554 {};
0555 
0556 //////////////////////////
0557 //    remove_const
0558 //////////////////////////
0559 template<class T>
0560 struct remove_const
0561 {  typedef T type;   };
0562 
0563 template<class T>
0564 struct remove_const< const T>
0565 {  typedef T type;   };
0566 
0567 //////////////////////////
0568 //    remove_cv
0569 //////////////////////////
0570 template<typename T> struct remove_cv                    {  typedef T type;   };
0571 template<typename T> struct remove_cv<const T>           {  typedef T type;   };
0572 template<typename T> struct remove_cv<const volatile T>  {  typedef T type;   };
0573 template<typename T> struct remove_cv<volatile T>        {  typedef T type;   };
0574 
0575 //////////////////////////
0576 //    remove_cvref
0577 //////////////////////////
0578 template<class T>
0579 struct remove_cvref
0580    : remove_cv<typename remove_reference<T>::type>
0581 {
0582 };
0583 
0584 //////////////////////////
0585 //    is_unsigned
0586 //////////////////////////
0587 template<class T> struct is_unsigned_cv               { static const bool value = true; };
0588 template <>       struct is_unsigned_cv<signed char>  { static const bool value = false; };
0589 template <>       struct is_unsigned_cv<signed short> { static const bool value = false; };
0590 template <>       struct is_unsigned_cv<signed int>   { static const bool value = false; };
0591 template <>       struct is_unsigned_cv<signed long>  { static const bool value = false; };
0592 #ifdef BOOST_HAS_LONG_LONG
0593 template <>       struct is_unsigned_cv< ::boost::long_long_type > { static const bool value = false; };
0594 #endif
0595 
0596 #ifdef BOOST_HAS_INT128
0597 template <>       struct is_unsigned_cv< ::boost::int128_type >    { static const bool value = false; };
0598 #endif
0599 
0600 template <class T>
0601 struct is_unsigned
0602    : is_unsigned_cv<typename remove_cv<T>::type>
0603 {};
0604 
0605 
0606 //////////////////////////
0607 //    make_unsigned
0608 //////////////////////////
0609 template <class T>
0610 struct make_unsigned_impl                                         {  typedef T type;   };
0611 template <> struct make_unsigned_impl<signed char>                {  typedef unsigned char  type; };
0612 template <> struct make_unsigned_impl<signed short>               {  typedef unsigned short type; };
0613 template <> struct make_unsigned_impl<signed int>                 {  typedef unsigned int   type; };
0614 template <> struct make_unsigned_impl<signed long>                {  typedef unsigned long  type; };
0615 #ifdef BOOST_HAS_LONG_LONG
0616 template <> struct make_unsigned_impl< ::boost::long_long_type >  {  typedef ::boost::ulong_long_type type; };
0617 #endif
0618 
0619 #ifdef BOOST_HAS_INT128
0620 template <> struct make_unsigned_impl< ::boost::int128_type > { typedef ::boost::uint128_type type; };
0621 #endif
0622 
0623 
0624 template <class T>
0625 struct make_unsigned
0626    : make_unsigned_impl<typename remove_cv<T>::type>
0627 {};
0628 
0629 //////////////////////////
0630 //    is_floating_point
0631 //////////////////////////
0632 template<class T> struct is_floating_point_cv               {  static const bool value = false; };
0633 template<>        struct is_floating_point_cv<float>        {  static const bool value = true; };
0634 template<>        struct is_floating_point_cv<double>       {  static const bool value = true; };
0635 template<>        struct is_floating_point_cv<long double>  {  static const bool value = true; };
0636 
0637 template<class T>
0638 struct is_floating_point
0639    : is_floating_point_cv<typename remove_cv<T>::type>
0640 {};
0641 
0642 //////////////////////////
0643 //    is_integral
0644 //////////////////////////
0645 template<class T> struct is_integral_cv                    {  static const bool value = false; };
0646 template<> struct is_integral_cv<                     bool>{  static const bool value = true; };
0647 template<> struct is_integral_cv<                     char>{  static const bool value = true; };
0648 template<> struct is_integral_cv<            unsigned char>{  static const bool value = true; };
0649 template<> struct is_integral_cv<              signed char>{  static const bool value = true; };
0650 #ifndef BOOST_NO_CXX11_CHAR16_T
0651 template<> struct is_integral_cv<                 char16_t>{  static const bool value = true; };
0652 #endif
0653 #ifndef BOOST_NO_CXX11_CHAR32_T
0654 template<> struct is_integral_cv<                 char32_t>{  static const bool value = true; };
0655 #endif
0656 #ifndef BOOST_NO_INTRINSIC_WCHAR_T
0657 template<> struct is_integral_cv<                  wchar_t>{  static const bool value = true; };
0658 #endif
0659 template<> struct is_integral_cv<                    short>{  static const bool value = true; };
0660 template<> struct is_integral_cv<           unsigned short>{  static const bool value = true; };
0661 template<> struct is_integral_cv<                      int>{  static const bool value = true; };
0662 template<> struct is_integral_cv<             unsigned int>{  static const bool value = true; };
0663 template<> struct is_integral_cv<                     long>{  static const bool value = true; };
0664 template<> struct is_integral_cv<            unsigned long>{  static const bool value = true; };
0665 #ifdef BOOST_HAS_LONG_LONG
0666 template<> struct is_integral_cv< ::boost:: long_long_type>{  static const bool value = true; };
0667 template<> struct is_integral_cv< ::boost::ulong_long_type>{  static const bool value = true; };
0668 #endif
0669 #ifdef BOOST_HAS_INT128
0670 template <> struct is_integral_cv< ::boost::int128_type >  {  static const bool value = true; };
0671 template <> struct is_integral_cv< ::boost::uint128_type > {  static const bool value = true; };
0672 #endif
0673 #if defined(__cpp_char8_t) && __cpp_char8_t >= 201811L
0674 template<> struct is_integral_cv<char8_t>  { static const bool value = true; };
0675 #endif
0676 
0677 template<class T>
0678 struct is_integral
0679    : public is_integral_cv<typename remove_cv<T>::type>
0680 {};
0681 
0682 //////////////////////////////////////
0683 //          remove_all_extents
0684 //////////////////////////////////////
0685 template <class T>
0686 struct remove_all_extents
0687 {  typedef T type;};
0688 
0689 template <class T>
0690 struct remove_all_extents<T[]>
0691 {  typedef typename remove_all_extents<T>::type type; };
0692 
0693 template <class T, std::size_t N>
0694 struct remove_all_extents<T[N]>
0695 {  typedef typename remove_all_extents<T>::type type;};
0696 
0697 //////////////////////////
0698 //       is_void
0699 //////////////////////////
0700 template<class T>
0701 struct is_void_cv
0702 {  static const bool value = false; };
0703 
0704 template<>
0705 struct is_void_cv<void>
0706 {  static const bool value = true; };
0707 
0708 template<class T>
0709 struct is_void
0710    : is_void_cv<typename remove_cv<T>::type>
0711 {};
0712 
0713 //////////////////////////////////////
0714 //          is_array
0715 //////////////////////////////////////
0716 template<class T>
0717 struct is_array
0718 {  static const bool value = false; };
0719 
0720 template<class T>
0721 struct is_array<T[]>
0722 {  static const bool value = true;  };
0723 
0724 template<class T, std::size_t N>
0725 struct is_array<T[N]>
0726 {  static const bool value = true;  };
0727 
0728 //////////////////////////////////////
0729 //           is_member_pointer
0730 //////////////////////////////////////
0731 template <class T>         struct is_member_pointer_cv         {  static const bool value = false; };
0732 template <class T, class U>struct is_member_pointer_cv<T U::*> {  static const bool value = true; };
0733 
0734 template <class T>
0735 struct is_member_pointer
0736     : is_member_pointer_cv<typename remove_cv<T>::type>
0737 {};
0738 
0739 //////////////////////////////////////
0740 //          is_nullptr_t
0741 //////////////////////////////////////
0742 template <class T>
0743 struct is_nullptr_t_cv
0744 {  static const bool value = false; };
0745 
0746 #if !defined(BOOST_NO_CXX11_NULLPTR)
0747 template <>
0748 struct is_nullptr_t_cv
0749    #if !defined(BOOST_NO_CXX11_DECLTYPE)
0750    <decltype(nullptr)>
0751    #else
0752    <std::nullptr_t>
0753    #endif
0754 {  static const bool value = true; };
0755 #endif
0756 
0757 template <class T>
0758 struct is_nullptr_t
0759    : is_nullptr_t_cv<typename remove_cv<T>::type>
0760 {};
0761 
0762 template <class T>
0763 struct is_null_pointer
0764    : is_nullptr_t_cv<typename remove_cv<T>::type>
0765 {};
0766 
0767 //////////////////////////////////////
0768 //          is_function
0769 //////////////////////////////////////
0770 //Inspired by libc++, thanks to Howard Hinnant
0771 //For a function to pointer an lvalue of function type T can be implicitly converted to a prvalue
0772 //pointer to that function. This does not apply to non-static member functions because lvalues
0773 //that refer to non-static member functions do not exist.
0774 template <class T>
0775 struct is_reference_convertible_to_pointer
0776 {
0777    struct twochar { char dummy[2]; };
0778    template <class U> static char    test(U*);
0779    template <class U> static twochar test(...);
0780    static T& source();
0781    static const bool value = sizeof(char) == sizeof(test<T>(source()));
0782 };
0783 //Filter out:
0784 // - class types that might have implicit conversions
0785 // - void (to avoid forming a reference to void later)
0786 // - references (e.g.: filtering reference to functions)
0787 // - nullptr_t (convertible to pointer)
0788 template < class T
0789          , bool Filter = is_class_or_union<T>::value  ||
0790                          is_void<T>::value            ||
0791                          is_reference<T>::value       ||
0792                          is_nullptr_t<T>::value       >
0793 struct is_function_impl
0794 {  static const bool value = is_reference_convertible_to_pointer<T>::value; };
0795 
0796 template <class T>
0797 struct is_function_impl<T, true>
0798 {  static const bool value = false; };
0799 
0800 template <class T>
0801 struct is_function
0802    : is_function_impl<T>
0803 {};
0804 
0805 //////////////////////////////////////
0806 //       is_union
0807 //////////////////////////////////////
0808 template<class T>
0809 struct is_union_noextents_cv
0810 {  static const bool value = BOOST_MOVE_IS_UNION_IMPL(T); };
0811 
0812 template<class T>
0813 struct is_union
0814    : is_union_noextents_cv<typename remove_cv<typename remove_all_extents<T>::type>::type>
0815 {};
0816 
0817 //////////////////////////////////////
0818 //             is_class
0819 //////////////////////////////////////
0820 template <class T>
0821 struct is_class
0822 {
0823    static const bool value = is_class_or_union<T>::value && ! is_union<T>::value;
0824 };
0825 
0826 
0827 //////////////////////////////////////
0828 //             is_arithmetic
0829 //////////////////////////////////////
0830 template <class T>
0831 struct is_arithmetic
0832 {
0833    static const bool value = is_floating_point<T>::value ||
0834                              is_integral<T>::value;
0835 };
0836 
0837 
0838 //////////////////////////////////////
0839 //    is_member_function_pointer
0840 //////////////////////////////////////
0841 template <class T>
0842 struct is_member_function_pointer_cv
0843 {
0844    static const bool value = false;
0845 };
0846 
0847 template <class T, class C>
0848 struct is_member_function_pointer_cv<T C::*>
0849    : is_function<T>
0850 {};
0851 
0852 template <class T>
0853 struct is_member_function_pointer
0854     : is_member_function_pointer_cv<typename remove_cv<T>::type>
0855 {};
0856 
0857 //////////////////////////////////////
0858 //             is_enum
0859 //////////////////////////////////////
0860 #if !defined(BOOST_MOVE_IS_ENUM)
0861 //Based on (http://howardhinnant.github.io/TypeHiearchy.pdf)
0862 template <class T>
0863 struct is_enum_nonintrinsic
0864 {
0865    static const bool value = !is_arithmetic<T>::value &&
0866       !is_reference<T>::value &&
0867       !is_class_or_union<T>::value &&
0868       !is_array<T>::value &&
0869       !is_void<T>::value &&
0870       !is_nullptr_t<T>::value &&
0871       !is_member_pointer<T>::value &&
0872       !is_pointer<T>::value &&
0873       !is_function<T>::value;
0874 };
0875 #endif
0876 
0877 template <class T>
0878 struct is_enum
0879 {
0880    static const bool value = BOOST_MOVE_IS_ENUM_IMPL(T);
0881 };
0882 
0883 
0884 //////////////////////////
0885 //    is_scalar
0886 //////////////////////////
0887 template<class T>
0888 struct is_scalar
0889 {
0890    static const bool value = is_arithmetic<T>::value ||
0891       is_enum<T>::value ||
0892       is_pointer<T>::value ||
0893       is_member_pointer<T>::value ||
0894       is_null_pointer<T>::value;
0895 };
0896 
0897 
0898 //////////////////////////////////////
0899 //       is_pod
0900 //////////////////////////////////////
0901 template<class T>
0902 struct is_pod_noextents_cv  //for non-c++11 compilers, a safe fallback
0903 {  static const bool value = BOOST_MOVE_IS_POD_IMPL(T); };
0904 
0905 template<class T>
0906 struct is_pod
0907    : is_pod_noextents_cv<typename remove_cv<typename remove_all_extents<T>::type>::type>
0908 {};
0909 
0910 //////////////////////////////////////
0911 //             is_empty
0912 //////////////////////////////////////
0913 #if !defined(BOOST_MOVE_IS_EMPTY)
0914 
0915 template <typename T>
0916 struct empty_helper_t1 : public T
0917 {
0918    empty_helper_t1();  // hh compiler bug workaround
0919    int i[256];
0920    private:
0921 
0922    empty_helper_t1(const empty_helper_t1&);
0923    empty_helper_t1& operator=(const empty_helper_t1&);
0924 };
0925 
0926 struct empty_helper_t2 { int i[256]; };
0927 
0928 template <typename T, bool IsClass = is_class<T>::value >
0929 struct is_empty_nonintrinsic
0930 {
0931    static const bool value = false;
0932 };
0933 
0934 template <typename T>
0935 struct is_empty_nonintrinsic<T, true>
0936 {
0937    static const bool value = sizeof(empty_helper_t1<T>) == sizeof(empty_helper_t2);
0938 };
0939 #endif
0940 
0941 template <class T>
0942 struct is_empty
0943 {  static const bool value = BOOST_MOVE_IS_EMPTY_IMPL(T);  };
0944 
0945 
0946 template<class T>
0947 struct has_boost_move_no_copy_constructor_or_assign_type
0948 {
0949    template <class U>
0950    static yes_type test(typename U::boost_move_no_copy_constructor_or_assign*);
0951 
0952    template <class U>
0953    static no_type test(...);
0954 
0955    static const bool value = sizeof(test<T>(0)) == sizeof(yes_type);
0956 };
0957 
0958 //////////////////////////////////////
0959 //       is_copy_constructible
0960 //////////////////////////////////////
0961 #if !defined(BOOST_NO_CXX11_DELETED_FUNCTIONS) && !defined(BOOST_NO_CXX11_DECLTYPE) \
0962    && !defined(BOOST_INTEL_CXX_VERSION) && \
0963       !(defined(BOOST_MSVC) && _MSC_VER == 1800)
0964 #define BOOST_MOVE_TT_CXX11_IS_COPY_CONSTRUCTIBLE
0965 #endif
0966 
0967 template<class T>
0968 struct is_copy_constructible
0969 {
0970    // Intel compiler has problems with SFINAE for copy constructors and deleted functions:
0971    //
0972    // error: function *function_name* cannot be referenced -- it is a deleted function
0973    // static yes_type test(U&, decltype(U(boost::declval<U&>()))* = 0);
0974    //                                                        ^ 
0975    // MSVC 12.0 (Visual 2013) has problems when the copy constructor has been deleted. See:
0976    // https://connect.microsoft.com/VisualStudio/feedback/details/800328/std-is-copy-constructible-is-broken
0977    #if defined(BOOST_MOVE_TT_CXX11_IS_COPY_CONSTRUCTIBLE)
0978       template<class U> static typename add_reference<U>::type source();
0979       static no_type test(...);
0980       #ifdef BOOST_NO_CXX11_DECLTYPE
0981          template <class U>
0982          static yes_type test(U&, bool_<sizeof(U(source<U>()))>* = 0);
0983       #else
0984          template <class U>
0985          static yes_type test(U&, decltype(U(source<U>()))* = 0);
0986       #endif
0987       static const bool value = sizeof(test(source<T>())) == sizeof(yes_type);
0988    #else
0989    static const bool value = !has_boost_move_no_copy_constructor_or_assign_type<T>::value;
0990    #endif
0991 };
0992 
0993 
0994 //////////////////////////////////////
0995 //       is_copy_assignable
0996 //////////////////////////////////////
0997 #if !defined(BOOST_NO_CXX11_DELETED_FUNCTIONS) && !defined(BOOST_NO_CXX11_DECLTYPE) \
0998    && !defined(BOOST_INTEL_CXX_VERSION) && \
0999       !(defined(BOOST_MSVC) && _MSC_VER == 1800)
1000 #define BOOST_MOVE_TT_CXX11_IS_COPY_ASSIGNABLE
1001 #endif
1002 
1003 template <class T>
1004 struct is_copy_assignable
1005 {
1006 // Intel compiler has problems with SFINAE for copy constructors and deleted functions:
1007 //
1008 // error: function *function_name* cannot be referenced -- it is a deleted function
1009 // static boost::type_traits::yes_type test(T1&, decltype(T1(boost::declval<T1&>()))* = 0);
1010 //                                                        ^ 
1011 //
1012 // MSVC 12.0 (Visual 2013) has problems when the copy constructor has been deleted. See:
1013 // https://connect.microsoft.com/VisualStudio/feedback/details/800328/std-is-copy-constructible-is-broken
1014 #if defined(BOOST_MOVE_TT_CXX11_IS_COPY_ASSIGNABLE)
1015    typedef char yes_type;
1016    struct no_type { char dummy[2]; };
1017    
1018    template <class U>   static typename add_reference<U>::type source();
1019    template <class U>   static decltype(source<U&>() = source<const U&>(), yes_type() ) test(int);
1020    template <class>     static no_type test(...);
1021 
1022    static const bool value = sizeof(test<T>(0)) == sizeof(yes_type);
1023 #else
1024    static const bool value = !has_boost_move_no_copy_constructor_or_assign_type<T>::value;
1025 #endif
1026 };
1027 
1028 //////////////////////////////////////
1029 //       is_trivially_destructible
1030 //////////////////////////////////////
1031 template<class T>
1032 struct is_trivially_destructible
1033 {  static const bool value = BOOST_MOVE_IS_TRIVIALLY_DESTRUCTIBLE(T); };
1034 
1035 //////////////////////////////////////
1036 //       is_trivially_default_constructible
1037 //////////////////////////////////////
1038 template<class T>
1039 struct is_trivially_default_constructible
1040 {  static const bool value = BOOST_MOVE_IS_TRIVIALLY_DEFAULT_CONSTRUCTIBLE(T); };
1041 
1042 //////////////////////////////////////
1043 //       is_trivially_copy_constructible
1044 //////////////////////////////////////
1045 template<class T>
1046 struct is_trivially_copy_constructible
1047 {
1048    static const bool value = BOOST_MOVE_IS_TRIVIALLY_COPY_CONSTRUCTIBLE(T);
1049 };
1050 
1051 //////////////////////////////////////
1052 //       is_trivially_move_constructible
1053 //////////////////////////////////////
1054 template<class T>
1055 struct is_trivially_move_constructible
1056 { static const bool value = BOOST_MOVE_IS_TRIVIALLY_MOVE_CONSTRUCTIBLE(T); };
1057 
1058 //////////////////////////////////////
1059 //       is_trivially_copy_assignable
1060 //////////////////////////////////////
1061 template<class T>
1062 struct is_trivially_copy_assignable
1063 {
1064    static const bool value = BOOST_MOVE_IS_TRIVIALLY_COPY_ASSIGNABLE(T);
1065 };                             
1066 
1067 //////////////////////////////////////
1068 //       is_trivially_move_assignable
1069 //////////////////////////////////////
1070 template<class T>
1071 struct is_trivially_move_assignable
1072 {  static const bool value = BOOST_MOVE_IS_TRIVIALLY_MOVE_ASSIGNABLE(T);  };
1073 
1074 //////////////////////////////////////
1075 //       is_nothrow_default_constructible
1076 //////////////////////////////////////
1077 template<class T>
1078 struct is_nothrow_default_constructible
1079 {  static const bool value = BOOST_MOVE_IS_NOTHROW_DEFAULT_CONSTRUCTIBLE(T);  };
1080 
1081 //////////////////////////////////////
1082 //    is_nothrow_copy_constructible
1083 //////////////////////////////////////
1084 template<class T>
1085 struct is_nothrow_copy_constructible
1086 {  static const bool value = BOOST_MOVE_IS_NOTHROW_COPY_CONSTRUCTIBLE(T);  };
1087 
1088 //////////////////////////////////////
1089 //    is_nothrow_move_constructible
1090 //////////////////////////////////////
1091 template<class T>
1092 struct is_nothrow_move_constructible
1093 {  static const bool value = BOOST_MOVE_IS_NOTHROW_MOVE_CONSTRUCTIBLE(T);  };
1094 
1095 //////////////////////////////////////
1096 //       is_nothrow_copy_assignable
1097 //////////////////////////////////////
1098 template<class T>
1099 struct is_nothrow_copy_assignable
1100 {  static const bool value = BOOST_MOVE_IS_NOTHROW_COPY_ASSIGNABLE(T);  };
1101 
1102 //////////////////////////////////////
1103 //    is_nothrow_move_assignable
1104 //////////////////////////////////////
1105 template<class T>
1106 struct is_nothrow_move_assignable
1107 {  static const bool value = BOOST_MOVE_IS_NOTHROW_MOVE_ASSIGNABLE(T);  };
1108 
1109 //////////////////////////////////////
1110 //    is_nothrow_swappable
1111 //////////////////////////////////////
1112 template<class T>
1113 struct is_nothrow_swappable
1114 {
1115    static const bool value = is_empty<T>::value || is_pod<T>::value;
1116 };
1117 
1118 //////////////////////////////////////
1119 //       alignment_of
1120 //////////////////////////////////////
1121 template <typename T>
1122 struct alignment_of_hack
1123 {
1124    T t1;
1125    char c;
1126    T t2;
1127    alignment_of_hack();
1128    ~alignment_of_hack();
1129 };
1130 
1131 template <unsigned A, unsigned S>
1132 struct alignment_logic
1133 {  static const std::size_t value = A < S ? A : S; };
1134 
1135 template< typename T >
1136 struct alignment_of_impl
1137 #if defined(BOOST_MSVC) && (BOOST_MSVC >= 1400)
1138     // With MSVC both the native __alignof operator
1139     // and our own logic gets things wrong from time to time :-(
1140     // Using a combination of the two seems to make the most of a bad job:
1141    : alignment_logic< sizeof(alignment_of_hack<T>) - 2*sizeof(T), __alignof(T)>
1142 {};
1143 #elif !defined(BOOST_MOVE_ALIGNMENT_OF)
1144    : alignment_logic< sizeof(alignment_of_hack<T>) - 2*sizeof(T), sizeof(T)>
1145 {};
1146 #else
1147 {  static const std::size_t value = BOOST_MOVE_ALIGNMENT_OF(T);  };
1148 #endif
1149 
1150 template< typename T >
1151 struct alignment_of
1152    : alignment_of_impl<T>
1153 {};
1154 
1155 class alignment_dummy;
1156 typedef void (*function_ptr)();
1157 typedef int (alignment_dummy::*member_ptr);
1158 
1159 struct alignment_struct
1160 {  long double dummy[4];  };
1161 
1162 /////////////////////////////
1163 //    max_align_t
1164 /////////////////////////////
1165 //This is not standard, but should work with all compilers
1166 union max_align
1167 {
1168    char        char_;
1169    short       short_;
1170    int         int_;
1171    long        long_;
1172    #ifdef BOOST_HAS_LONG_LONG
1173    ::boost::long_long_type   long_long_;
1174    #endif
1175    float       float_;
1176    double      double_;
1177    void *      void_ptr_;
1178    long double long_double_[4];
1179    alignment_dummy *unknown_class_ptr_;
1180    function_ptr function_ptr_;
1181    alignment_struct alignment_struct_;
1182 };
1183 
1184 typedef union max_align max_align_t;
1185 
1186 /////////////////////////////
1187 //    aligned_storage
1188 /////////////////////////////
1189 
1190 #if defined(_MSC_VER) && defined(_M_IX86)
1191 
1192 // Special version for usual alignments on x86 MSVC because it might crash
1193 // when passsing aligned types by value even for 8 byte alignment.
1194 template<std::size_t Align>
1195 struct aligned_struct;
1196 
1197 template <> struct aligned_struct<1> { char data; };
1198 template <> struct aligned_struct<2> { short data; };
1199 template <> struct aligned_struct<4> { int data; };
1200 //8 byte alignment does not propely work in x86 if attribute is not used.
1201 //If a user declares a variable with 8 byte alignment, such as a double
1202 //the compiler will not realign the stack.
1203 // 
1204 //If _declspec(align) is used MSVC will realign the stack.
1205 //
1206 //Disabled specialization
1207 //template <> struct aligned_struct<8> { double data; };
1208 
1209 #define BOOST_MOVE_ALIGNED_STRUCT(x) \
1210   template <> struct aligned_struct<x> { \
1211     __declspec(align(x)) char data; \
1212   }
1213 BOOST_MOVE_ALIGNED_STRUCT(8);
1214 BOOST_MOVE_ALIGNED_STRUCT(16);
1215 BOOST_MOVE_ALIGNED_STRUCT(32);
1216 BOOST_MOVE_ALIGNED_STRUCT(64);
1217 BOOST_MOVE_ALIGNED_STRUCT(128);
1218 BOOST_MOVE_ALIGNED_STRUCT(512);
1219 BOOST_MOVE_ALIGNED_STRUCT(1024);
1220 BOOST_MOVE_ALIGNED_STRUCT(2048);
1221 BOOST_MOVE_ALIGNED_STRUCT(4096);
1222 
1223 template<std::size_t Len, std::size_t Align>
1224 union aligned_union
1225 {
1226    typedef aligned_struct<Align> aligner_t;
1227    aligner_t aligner;
1228    unsigned char data[Len > sizeof(aligner_t) ? Len : sizeof(aligner_t)];
1229 };
1230 
1231 template<std::size_t Len, std::size_t Align>
1232 struct aligned_storage_impl
1233 {
1234    typedef aligned_union<Len, Align> type;
1235 };
1236 
1237 #elif !defined(BOOST_NO_ALIGNMENT)
1238 
1239 template<std::size_t Len, std::size_t Align>
1240 struct aligned_struct;
1241 
1242 #define BOOST_MOVE_ALIGNED_STORAGE_WITH_BOOST_ALIGNMENT(A)\
1243 template<std::size_t Len>\
1244 struct BOOST_ALIGNMENT(A) aligned_struct<Len, A>\
1245 {\
1246    unsigned char data[Len];\
1247 };\
1248 //
1249 
1250 //Up to 4K alignment (typical page size)
1251 BOOST_MOVE_ALIGNED_STORAGE_WITH_BOOST_ALIGNMENT(0x1)
1252 BOOST_MOVE_ALIGNED_STORAGE_WITH_BOOST_ALIGNMENT(0x2)
1253 BOOST_MOVE_ALIGNED_STORAGE_WITH_BOOST_ALIGNMENT(0x4)
1254 BOOST_MOVE_ALIGNED_STORAGE_WITH_BOOST_ALIGNMENT(0x8)
1255 BOOST_MOVE_ALIGNED_STORAGE_WITH_BOOST_ALIGNMENT(0x10)
1256 BOOST_MOVE_ALIGNED_STORAGE_WITH_BOOST_ALIGNMENT(0x20)
1257 BOOST_MOVE_ALIGNED_STORAGE_WITH_BOOST_ALIGNMENT(0x40)
1258 BOOST_MOVE_ALIGNED_STORAGE_WITH_BOOST_ALIGNMENT(0x80)
1259 BOOST_MOVE_ALIGNED_STORAGE_WITH_BOOST_ALIGNMENT(0x100)
1260 BOOST_MOVE_ALIGNED_STORAGE_WITH_BOOST_ALIGNMENT(0x200)
1261 BOOST_MOVE_ALIGNED_STORAGE_WITH_BOOST_ALIGNMENT(0x400)
1262 BOOST_MOVE_ALIGNED_STORAGE_WITH_BOOST_ALIGNMENT(0x800)
1263 BOOST_MOVE_ALIGNED_STORAGE_WITH_BOOST_ALIGNMENT(0x1000)
1264 
1265 #undef BOOST_MOVE_ALIGNED_STORAGE_WITH_BOOST_ALIGNMENT
1266 
1267 // Workaround for bogus [-Wignored-attributes] warning on GCC 6.x/7.x: don't use a type that "directly" carries the alignment attribute.
1268 // See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82270
1269 template<std::size_t Len, std::size_t Align>
1270 union aligned_struct_wrapper
1271 {
1272    typedef aligned_struct<Len, Align> aligner_t;
1273    aligned_struct<Len, Align> aligner;
1274    unsigned char data[Len > sizeof(aligner_t) ? Len : sizeof(aligner_t)];
1275 };
1276 
1277 template<std::size_t Len, std::size_t Align>
1278 struct aligned_storage_impl
1279 {
1280    typedef aligned_struct_wrapper<Len, Align> type;
1281 };
1282 
1283 #else //BOOST_NO_ALIGNMENT
1284 
1285 template<class T, std::size_t Len>
1286 union aligned_union
1287 {   
1288    T aligner;
1289    unsigned char data[Len > sizeof(T) ? Len : sizeof(T)];
1290 };
1291 
1292 template<std::size_t Len, std::size_t Align, class T, bool Ok>
1293 struct aligned_next;
1294 
1295 template<std::size_t Len, std::size_t Align, class T>
1296 struct aligned_next<Len, Align, T, true>
1297 {
1298    BOOST_MOVE_STATIC_ASSERT((alignment_of<T>::value == Align));
1299    typedef aligned_union<T, Len> type;
1300 };
1301 
1302 //End of search defaults to max_align_t
1303 template<std::size_t Len, std::size_t Align>
1304 struct aligned_next<Len, Align, max_align_t, false>
1305 {   typedef aligned_union<max_align_t, Len> type;   };
1306 
1307 //Now define a search list through types
1308 #define BOOST_MOVE_ALIGNED_NEXT_STEP(TYPE, NEXT_TYPE)\
1309    template<std::size_t Len, std::size_t Align>\
1310    struct aligned_next<Len, Align, TYPE, false>\
1311       : aligned_next<Len, Align, NEXT_TYPE, Align == alignment_of<NEXT_TYPE>::value>\
1312    {};\
1313    //
1314    BOOST_MOVE_ALIGNED_NEXT_STEP(long double, max_align_t)
1315    BOOST_MOVE_ALIGNED_NEXT_STEP(double, long double)
1316    #ifdef BOOST_HAS_LONG_LONG
1317       BOOST_MOVE_ALIGNED_NEXT_STEP(::boost::long_long_type, double)
1318       BOOST_MOVE_ALIGNED_NEXT_STEP(long, ::boost::long_long_type)
1319    #else
1320       BOOST_MOVE_ALIGNED_NEXT_STEP(long, double)
1321    #endif
1322    BOOST_MOVE_ALIGNED_NEXT_STEP(int, long)
1323    BOOST_MOVE_ALIGNED_NEXT_STEP(short, int)
1324    BOOST_MOVE_ALIGNED_NEXT_STEP(char, short)
1325 #undef BOOST_MOVE_ALIGNED_NEXT_STEP
1326 
1327 template<std::size_t Len, std::size_t Align>
1328 struct aligned_storage_impl
1329    : aligned_next<Len, Align, char, Align == alignment_of<char>::value>
1330 {};
1331 
1332 #endif
1333 
1334 template<std::size_t Len, std::size_t Align = alignment_of<max_align_t>::value>
1335 struct aligned_storage
1336 {
1337    //Sanity checks for input parameters
1338    BOOST_MOVE_STATIC_ASSERT(Align > 0);
1339 
1340    //Sanity checks for output type
1341    typedef typename aligned_storage_impl<Len ? Len : 1, Align>::type type;
1342    static const std::size_t value = alignment_of<type>::value;
1343    BOOST_MOVE_STATIC_ASSERT(value >= Align);
1344    BOOST_MOVE_STATIC_ASSERT((value % Align) == 0);
1345 
1346    //Just in case someone instantiates aligned_storage
1347    //instead of aligned_storage::type (typical error).
1348    private:
1349    aligned_storage();
1350 };
1351 
1352 }  //namespace move_detail {
1353 }  //namespace boost {
1354 
1355 #include <boost/move/detail/config_end.hpp>
1356 
1357 #endif   //#ifndef BOOST_MOVE_DETAIL_TYPE_TRAITS_HPP