Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-04 08:24:02

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