| 1 | ////////////////////////////////////////////////////////////////////////////// | 
| 2 | // (C) Copyright John Maddock 2000. | 
| 3 | // (C) Copyright Ion Gaztanaga 2005-2015. | 
| 4 | // | 
| 5 | // Distributed under the Boost Software License, Version 1.0. | 
| 6 | // (See accompanying file LICENSE_1_0.txt or copy at | 
| 7 | // http://www.boost.org/LICENSE_1_0.txt) | 
| 8 | // | 
| 9 | // See http://www.boost.org/libs/move for documentation. | 
| 10 | // | 
| 11 | // The alignment and Type traits implementation comes from | 
| 12 | // John Maddock's TypeTraits library. | 
| 13 | // | 
| 14 | // Some other tricks come from Howard Hinnant's papers and StackOverflow replies | 
| 15 | ////////////////////////////////////////////////////////////////////////////// | 
| 16 | #ifndef BOOST_MOVE_DETAIL_TYPE_TRAITS_HPP | 
| 17 | #define BOOST_MOVE_DETAIL_TYPE_TRAITS_HPP | 
| 18 |  | 
| 19 | #ifndef BOOST_CONFIG_HPP | 
| 20 | #  include <boost/config.hpp> | 
| 21 | #endif | 
| 22 | # | 
| 23 | #if defined(BOOST_HAS_PRAGMA_ONCE) | 
| 24 | #  pragma once | 
| 25 | #endif | 
| 26 |  | 
| 27 | #include <boost/move/detail/config_begin.hpp> | 
| 28 | #include <boost/move/detail/workaround.hpp> | 
| 29 |  | 
| 30 | // move/detail | 
| 31 | #include <boost/move/detail/meta_utils.hpp> | 
| 32 | // other | 
| 33 | #include <boost/assert.hpp> | 
| 34 | #include <boost/static_assert.hpp> | 
| 35 | // std | 
| 36 | #include <cstddef> | 
| 37 |  | 
| 38 | //Use of Boost.TypeTraits leads to long preprocessed source code due to | 
| 39 | //MPL dependencies. We'll use intrinsics directly and make or own | 
| 40 | //simplified version of TypeTraits. | 
| 41 | //If someday Boost.TypeTraits dependencies are minimized, we should | 
| 42 | //revisit this file redirecting code to Boost.TypeTraits traits. | 
| 43 |  | 
| 44 | //These traits don't care about volatile, reference or other checks | 
| 45 | //made by Boost.TypeTraits because no volatile or reference types | 
| 46 | //can be hold in Boost.Containers. This helps to avoid any Boost.TypeTraits | 
| 47 | //dependency. | 
| 48 |  | 
| 49 | // Helper macros for builtin compiler support. | 
| 50 | // If your compiler has builtin support for any of the following | 
| 51 | // traits concepts, then redefine the appropriate macros to pick | 
| 52 | // up on the compiler support: | 
| 53 | // | 
| 54 | // (these should largely ignore cv-qualifiers) | 
| 55 | // BOOST_MOVE_IS_POD(T) should evaluate to true if T is a POD type | 
| 56 | // BOOST_MOVE_HAS_TRIVIAL_CONSTRUCTOR(T) should evaluate to true if "T x;" has no effect | 
| 57 | // BOOST_MOVE_HAS_TRIVIAL_COPY(T) should evaluate to true if T(t) <==> memcpy | 
| 58 | // (Note: this trait does not guarantee T is copy constructible, the copy constructor could be deleted but still be trivial) | 
| 59 | // BOOST_MOVE_HAS_TRIVIAL_MOVE_CONSTRUCTOR(T) should evaluate to true if T(boost::move(t)) <==> memcpy | 
| 60 | // BOOST_MOVE_HAS_TRIVIAL_ASSIGN(T) should evaluate to true if t = u <==> memcpy | 
| 61 | // (Note: this trait does not guarantee T is assignable , the copy assignmen could be deleted but still be trivial) | 
| 62 | // BOOST_MOVE_HAS_TRIVIAL_MOVE_ASSIGN(T) should evaluate to true if t = boost::move(u) <==> memcpy | 
| 63 | // BOOST_MOVE_HAS_TRIVIAL_DESTRUCTOR(T) should evaluate to true if ~T() has no effect | 
| 64 | // BOOST_MOVE_HAS_NOTHROW_CONSTRUCTOR(T) should evaluate to true if "T x;" can not throw | 
| 65 | // BOOST_MOVE_HAS_NOTHROW_COPY(T) should evaluate to true if T(t) can not throw | 
| 66 | // BOOST_MOVE_HAS_NOTHROW_ASSIGN(T) should evaluate to true if t = u can not throw | 
| 67 | // BOOST_MOVE_IS_ENUM(T) should evaluate to true it t is a union type. | 
| 68 | // | 
| 69 | // The following can also be defined: when detected our implementation is greatly simplified. | 
| 70 | // | 
| 71 | // BOOST_ALIGNMENT_OF(T) should evaluate to the alignment requirements of type T. | 
| 72 |  | 
| 73 | #if defined(__MSL_CPP__) && (__MSL_CPP__ >= 0x8000) | 
| 74 |     // Metrowerks compiler is acquiring intrinsic type traits support | 
| 75 |     // post version 8.  We hook into the published interface to pick up | 
| 76 |     // user defined specializations as well as compiler intrinsics as | 
| 77 |     // and when they become available: | 
| 78 | #   include <msl_utility> | 
| 79 | #   define BOOST_MOVE_IS_UNION(T) BOOST_STD_EXTENSION_NAMESPACE::is_union<T>::value | 
| 80 | #   define BOOST_MOVE_IS_POD(T) BOOST_STD_EXTENSION_NAMESPACE::is_POD<T>::value | 
| 81 | #   define BOOST_MOVE_HAS_TRIVIAL_CONSTRUCTOR(T) BOOST_STD_EXTENSION_NAMESPACE::has_trivial_default_ctor<T>::value | 
| 82 | #   define BOOST_MOVE_HAS_TRIVIAL_COPY(T) BOOST_STD_EXTENSION_NAMESPACE::has_trivial_copy_ctor<T>::value | 
| 83 | #   define BOOST_MOVE_HAS_TRIVIAL_ASSIGN(T) BOOST_STD_EXTENSION_NAMESPACE::has_trivial_assignment<T>::value | 
| 84 | #   define BOOST_MOVE_HAS_TRIVIAL_DESTRUCTOR(T) BOOST_STD_EXTENSION_NAMESPACE::has_trivial_dtor<T>::value | 
| 85 | #endif | 
| 86 |  | 
| 87 | #if (defined(BOOST_MSVC) && defined(BOOST_MSVC_FULL_VER) && (BOOST_MSVC_FULL_VER >=140050215))\ | 
| 88 |          || (defined(BOOST_INTEL) && defined(_MSC_VER) && (_MSC_VER >= 1500)) | 
| 89 | #   define BOOST_MOVE_IS_UNION(T) __is_union(T) | 
| 90 | #   define BOOST_MOVE_IS_POD(T)                    (__is_pod(T) && __has_trivial_constructor(T)) | 
| 91 | #   define BOOST_MOVE_IS_EMPTY(T)                  __is_empty(T) | 
| 92 | #   define BOOST_MOVE_HAS_TRIVIAL_CONSTRUCTOR(T)   __has_trivial_constructor(T) | 
| 93 | #   define BOOST_MOVE_HAS_TRIVIAL_COPY(T)          (__has_trivial_copy(T)|| ::boost::move_detail::is_pod<T>::value) | 
| 94 | #   define BOOST_MOVE_HAS_TRIVIAL_ASSIGN(T)        (__has_trivial_assign(T) || ::boost::move_detail::is_pod<T>::value) | 
| 95 | #   define BOOST_MOVE_HAS_TRIVIAL_DESTRUCTOR(T)    (__has_trivial_destructor(T) || ::boost::move_detail::is_pod<T>::value) | 
| 96 | #   define BOOST_MOVE_HAS_NOTHROW_CONSTRUCTOR(T)   (__has_nothrow_constructor(T) || ::boost::move_detail::is_trivially_default_constructible<T>::value) | 
| 97 | #   define BOOST_MOVE_HAS_NOTHROW_COPY(T)          (__has_nothrow_copy(T) || ::boost::move_detail::is_trivially_copy_constructible<T>::value) | 
| 98 | #   define BOOST_MOVE_HAS_NOTHROW_ASSIGN(T)        (__has_nothrow_assign(T) || ::boost::move_detail::is_trivially_copy_assignable<T>::value) | 
| 99 |  | 
| 100 | #   define BOOST_MOVE_IS_ENUM(T) __is_enum(T) | 
| 101 | #   if defined(_MSC_VER) && (_MSC_VER >= 1700) | 
| 102 | #       define BOOST_MOVE_HAS_TRIVIAL_MOVE_CONSTRUCTOR(T)   (__has_trivial_move_constructor(T) || ::boost::move_detail::is_pod<T>::value) | 
| 103 | #       define BOOST_MOVE_HAS_TRIVIAL_MOVE_ASSIGN(T)        (__has_trivial_move_assign(T) || ::boost::move_detail::is_pod<T>::value) | 
| 104 | #   endif | 
| 105 | #endif | 
| 106 |  | 
| 107 | #if defined(BOOST_CLANG) && defined(__has_feature) | 
| 108 |  | 
| 109 | #   if __has_feature(is_union) | 
| 110 | #     define BOOST_MOVE_IS_UNION(T) __is_union(T) | 
| 111 | #   endif | 
| 112 | #   if (!defined(__GLIBCXX__) || (__GLIBCXX__ >= 20080306 && __GLIBCXX__ != 20080519)) && __has_feature(is_pod) | 
| 113 | #     define BOOST_MOVE_IS_POD(T) __is_pod(T) | 
| 114 | #   endif | 
| 115 | #   if (!defined(__GLIBCXX__) || (__GLIBCXX__ >= 20080306 && __GLIBCXX__ != 20080519)) && __has_feature(is_empty) | 
| 116 | #     define BOOST_MOVE_IS_EMPTY(T) __is_empty(T) | 
| 117 | #   endif | 
| 118 | #   if __has_feature(has_trivial_constructor) | 
| 119 | #     define BOOST_MOVE_HAS_TRIVIAL_CONSTRUCTOR(T) __has_trivial_constructor(T) | 
| 120 | #   endif | 
| 121 | #   if __has_feature(has_trivial_copy) | 
| 122 | #     define BOOST_MOVE_HAS_TRIVIAL_COPY(T) __has_trivial_copy(T) | 
| 123 | #   endif | 
| 124 | #   if __has_feature(has_trivial_assign) | 
| 125 | #     define BOOST_MOVE_HAS_TRIVIAL_ASSIGN(T) (__has_trivial_assign(T) ) | 
| 126 | #   endif | 
| 127 | #   if __has_feature(has_trivial_destructor) | 
| 128 | #     define BOOST_MOVE_HAS_TRIVIAL_DESTRUCTOR(T) __has_trivial_destructor(T) | 
| 129 | #   endif | 
| 130 | #   if __has_feature(has_nothrow_constructor) | 
| 131 | #     define BOOST_MOVE_HAS_NOTHROW_CONSTRUCTOR(T) __has_nothrow_constructor(T) | 
| 132 | #   endif | 
| 133 | #   if __has_feature(has_nothrow_copy) | 
| 134 | #     define BOOST_MOVE_HAS_NOTHROW_COPY(T) (__has_nothrow_copy(T)) | 
| 135 | #   endif | 
| 136 | #   if __has_feature(is_nothrow_copy_assignable) | 
| 137 | #     define BOOST_MOVE_HAS_NOTHROW_ASSIGN(T) (__has_nothrow_assign(T)) | 
| 138 | #   endif | 
| 139 | #   if __has_feature(is_enum) | 
| 140 | #     define BOOST_MOVE_IS_ENUM(T) __is_enum(T) | 
| 141 | #   endif | 
| 142 | #   if __has_feature(has_trivial_move_constructor) | 
| 143 | #     define BOOST_MOVE_HAS_TRIVIAL_MOVE_CONSTRUCTOR(T) __has_trivial_move_constructor(T) | 
| 144 | #   endif | 
| 145 | #   if __has_feature(has_trivial_move_assign) | 
| 146 | #     define BOOST_MOVE_HAS_TRIVIAL_MOVE_ASSIGN(T) __has_trivial_move_assign(T) | 
| 147 | #   endif | 
| 148 | #   define BOOST_MOVE_ALIGNMENT_OF(T) __alignof(T) | 
| 149 | #endif | 
| 150 |  | 
| 151 | #if defined(__GNUC__) && ((__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 3) && !defined(__GCCXML__))) && !defined(BOOST_CLANG) | 
| 152 |  | 
| 153 | #ifdef BOOST_INTEL | 
| 154 | #  define BOOST_MOVE_INTEL_TT_OPTS || ::boost::move_detail::is_pod<T>::value | 
| 155 | #else | 
| 156 | #  define BOOST_MOVE_INTEL_TT_OPTS | 
| 157 | #endif | 
| 158 |  | 
| 159 | #   define BOOST_MOVE_IS_UNION(T) __is_union(T) | 
| 160 | #   define BOOST_MOVE_IS_POD(T) __is_pod(T) | 
| 161 | #   define BOOST_MOVE_IS_EMPTY(T) __is_empty(T) | 
| 162 | #   define BOOST_MOVE_HAS_TRIVIAL_CONSTRUCTOR(T) ((__has_trivial_constructor(T) BOOST_MOVE_INTEL_TT_OPTS)) | 
| 163 | #   define BOOST_MOVE_HAS_TRIVIAL_COPY(T) ((__has_trivial_copy(T) BOOST_MOVE_INTEL_TT_OPTS)) | 
| 164 | #   define BOOST_MOVE_HAS_TRIVIAL_ASSIGN(T) ((__has_trivial_assign(T) BOOST_MOVE_INTEL_TT_OPTS) ) | 
| 165 | #   define BOOST_MOVE_HAS_TRIVIAL_DESTRUCTOR(T) (__has_trivial_destructor(T) BOOST_MOVE_INTEL_TT_OPTS) | 
| 166 | #   define BOOST_MOVE_HAS_NOTHROW_CONSTRUCTOR(T) (__has_nothrow_constructor(T) BOOST_MOVE_INTEL_TT_OPTS) | 
| 167 | #   define BOOST_MOVE_HAS_NOTHROW_COPY(T) ((__has_nothrow_copy(T) BOOST_MOVE_INTEL_TT_OPTS)) | 
| 168 | #   define BOOST_MOVE_HAS_NOTHROW_ASSIGN(T) ((__has_nothrow_assign(T) BOOST_MOVE_INTEL_TT_OPTS)) | 
| 169 |  | 
| 170 | #   define BOOST_MOVE_IS_ENUM(T) __is_enum(T) | 
| 171 | #   if (!defined(unix) && !defined(__unix__)) || defined(__LP64__) | 
| 172 |       // GCC sometimes lies about alignment requirements | 
| 173 |       // of type double on 32-bit unix platforms, use the | 
| 174 |       // old implementation instead in that case: | 
| 175 | #     define BOOST_MOVE_ALIGNMENT_OF(T) __alignof__(T) | 
| 176 | #   endif | 
| 177 | #endif | 
| 178 |  | 
| 179 | #if defined(__ghs__) && (__GHS_VERSION_NUMBER >= 600) | 
| 180 |  | 
| 181 | #   define BOOST_MOVE_IS_UNION(T) __is_union(T) | 
| 182 | #   define BOOST_MOVE_IS_POD(T) __is_pod(T) | 
| 183 | #   define BOOST_MOVE_IS_EMPTY(T) __is_empty(T) | 
| 184 | #   define BOOST_MOVE_HAS_TRIVIAL_CONSTRUCTOR(T) __has_trivial_constructor(T) | 
| 185 | #   define BOOST_MOVE_HAS_TRIVIAL_COPY(T) (__has_trivial_copy(T)) | 
| 186 | #   define BOOST_MOVE_HAS_TRIVIAL_ASSIGN(T) (__has_trivial_assign(T)) | 
| 187 | #   define BOOST_MOVE_HAS_TRIVIAL_DESTRUCTOR(T) __has_trivial_destructor(T) | 
| 188 | #   define BOOST_MOVE_HAS_NOTHROW_CONSTRUCTOR(T) __has_nothrow_constructor(T) | 
| 189 | #   define BOOST_MOVE_HAS_NOTHROW_COPY(T) (__has_nothrow_copy(T)) | 
| 190 | #   define BOOST_MOVE_HAS_NOTHROW_ASSIGN(T) (__has_nothrow_assign(T)) | 
| 191 |  | 
| 192 | #   define BOOST_MOVE_IS_ENUM(T) __is_enum(T) | 
| 193 | #   define BOOST_MOVE_ALIGNMENT_OF(T) __alignof__(T) | 
| 194 | #endif | 
| 195 |  | 
| 196 | # if defined(__CODEGEARC__) | 
| 197 | #   define BOOST_MOVE_IS_UNION(T) __is_union(T) | 
| 198 | #   define BOOST_MOVE_IS_POD(T) __is_pod(T) | 
| 199 | #   define BOOST_MOVE_IS_EMPTY(T) __is_empty(T) | 
| 200 | #   define BOOST_MOVE_HAS_TRIVIAL_CONSTRUCTOR(T) (__has_trivial_default_constructor(T)) | 
| 201 | #   define BOOST_MOVE_HAS_TRIVIAL_COPY(T) (__has_trivial_copy_constructor(T)) | 
| 202 | #   define BOOST_MOVE_HAS_TRIVIAL_ASSIGN(T) (__has_trivial_assign(T)) | 
| 203 | #   define BOOST_MOVE_HAS_TRIVIAL_DESTRUCTOR(T) (__has_trivial_destructor(T)) | 
| 204 | #   define BOOST_MOVE_HAS_NOTHROW_CONSTRUCTOR(T) (__has_nothrow_default_constructor(T)) | 
| 205 | #   define BOOST_MOVE_HAS_NOTHROW_COPY(T) (__has_nothrow_copy_constructor(T)) | 
| 206 | #   define BOOST_MOVE_HAS_NOTHROW_ASSIGN(T) (__has_nothrow_assign(T)) | 
| 207 |  | 
| 208 | #   define BOOST_MOVE_IS_ENUM(T) __is_enum(T) | 
| 209 | #   define BOOST_MOVE_ALIGNMENT_OF(T) alignof(T) | 
| 210 |  | 
| 211 | #endif | 
| 212 |  | 
| 213 | //Fallback definitions | 
| 214 |  | 
| 215 | #ifdef BOOST_MOVE_IS_UNION | 
| 216 |    #define BOOST_MOVE_IS_UNION_IMPL(T) BOOST_MOVE_IS_UNION(T) | 
| 217 | #else | 
| 218 |    #define BOOST_MOVE_IS_UNION_IMPL(T) false | 
| 219 | #endif | 
| 220 |  | 
| 221 | #ifdef BOOST_MOVE_IS_POD | 
| 222 |    //in some compilers the intrinsic is limited to class types so add scalar and void | 
| 223 |    #define BOOST_MOVE_IS_POD_IMPL(T) (::boost::move_detail::is_scalar<T>::value ||\ | 
| 224 |                                       ::boost::move_detail::is_void<T>::value   ||\ | 
| 225 |                                        BOOST_MOVE_IS_POD(T)) | 
| 226 | #else | 
| 227 |    #define BOOST_MOVE_IS_POD_IMPL(T) \ | 
| 228 |       (::boost::move_detail::is_scalar<T>::value || ::boost::move_detail::is_void<T>::value) | 
| 229 | #endif | 
| 230 |  | 
| 231 | #ifdef BOOST_MOVE_IS_EMPTY | 
| 232 |    #define BOOST_MOVE_IS_EMPTY_IMPL(T) BOOST_MOVE_IS_EMPTY(T) | 
| 233 | #else | 
| 234 |    #define BOOST_MOVE_IS_EMPTY_IMPL(T)    ::boost::move_detail::is_empty_nonintrinsic<T>::value | 
| 235 | #endif | 
| 236 |  | 
| 237 | #ifdef BOOST_MOVE_HAS_TRIVIAL_COPY | 
| 238 |    #define BOOST_MOVE_IS_TRIVIALLY_COPY_CONSTRUCTIBLE(T)   ::boost::move_detail::is_pod<T>::value ||\ | 
| 239 |                                                           (::boost::move_detail::is_copy_constructible<T>::value &&\ | 
| 240 |                                                            BOOST_MOVE_HAS_TRIVIAL_COPY(T)) | 
| 241 | #else | 
| 242 |    #define BOOST_MOVE_IS_TRIVIALLY_COPY_CONSTRUCTIBLE(T)   ::boost::move_detail::is_pod<T>::value | 
| 243 | #endif | 
| 244 |  | 
| 245 | #ifdef BOOST_MOVE_HAS_TRIVIAL_CONSTRUCTOR | 
| 246 |    #define BOOST_MOVE_IS_TRIVIALLY_DEFAULT_CONSTRUCTIBLE(T)  BOOST_MOVE_HAS_TRIVIAL_CONSTRUCTOR(T) | 
| 247 | #else | 
| 248 |    #define BOOST_MOVE_IS_TRIVIALLY_DEFAULT_CONSTRUCTIBLE(T)  ::boost::move_detail::is_pod<T>::value | 
| 249 | #endif | 
| 250 |  | 
| 251 | #ifdef BOOST_MOVE_HAS_TRIVIAL_MOVE_CONSTRUCTOR | 
| 252 |    #define BOOST_MOVE_IS_TRIVIALLY_MOVE_CONSTRUCTIBLE(T)   BOOST_MOVE_HAS_TRIVIAL_MOVE_CONSTRUCTOR(T) | 
| 253 | #else | 
| 254 |    #define BOOST_MOVE_IS_TRIVIALLY_MOVE_CONSTRUCTIBLE(T)   ::boost::move_detail::is_pod<T>::value | 
| 255 | #endif | 
| 256 |  | 
| 257 | #ifdef BOOST_MOVE_HAS_TRIVIAL_ASSIGN | 
| 258 |    #define BOOST_MOVE_IS_TRIVIALLY_COPY_ASSIGNABLE(T) ::boost::move_detail::is_pod<T>::value ||\ | 
| 259 |                                                       ( ::boost::move_detail::is_copy_assignable<T>::value &&\ | 
| 260 |                                                          BOOST_MOVE_HAS_TRIVIAL_ASSIGN(T)) | 
| 261 | #else | 
| 262 |    #define BOOST_MOVE_IS_TRIVIALLY_COPY_ASSIGNABLE(T) ::boost::move_detail::is_pod<T>::value | 
| 263 | #endif | 
| 264 |  | 
| 265 | #ifdef BOOST_MOVE_HAS_TRIVIAL_MOVE_ASSIGN | 
| 266 |    #define BOOST_MOVE_IS_TRIVIALLY_MOVE_ASSIGNABLE(T)  BOOST_MOVE_HAS_TRIVIAL_MOVE_ASSIGN(T) | 
| 267 | #else | 
| 268 |    #define BOOST_MOVE_IS_TRIVIALLY_MOVE_ASSIGNABLE(T)  ::boost::move_detail::is_pod<T>::value | 
| 269 | #endif | 
| 270 |  | 
| 271 | #ifdef BOOST_MOVE_HAS_TRIVIAL_DESTRUCTOR | 
| 272 |    #define BOOST_MOVE_IS_TRIVIALLY_DESTRUCTIBLE(T)   BOOST_MOVE_HAS_TRIVIAL_DESTRUCTOR(T) | 
| 273 | #else | 
| 274 |    #define BOOST_MOVE_IS_TRIVIALLY_DESTRUCTIBLE(T)   ::boost::move_detail::is_pod<T>::value | 
| 275 | #endif | 
| 276 |  | 
| 277 | #ifdef BOOST_MOVE_HAS_NOTHROW_CONSTRUCTOR | 
| 278 |    #define BOOST_MOVE_IS_NOTHROW_DEFAULT_CONSTRUCTIBLE(T)  BOOST_MOVE_HAS_NOTHROW_CONSTRUCTOR(T) | 
| 279 | #else | 
| 280 |    #define BOOST_MOVE_IS_NOTHROW_DEFAULT_CONSTRUCTIBLE(T)  ::boost::move_detail::is_pod<T>::value | 
| 281 | #endif | 
| 282 |  | 
| 283 | #ifdef BOOST_MOVE_HAS_NOTHROW_COPY | 
| 284 |    #define BOOST_MOVE_IS_NOTHROW_COPY_CONSTRUCTIBLE(T)   BOOST_MOVE_HAS_NOTHROW_COPY(T) | 
| 285 | #else | 
| 286 |    #define BOOST_MOVE_IS_NOTHROW_COPY_CONSTRUCTIBLE(T)   ::boost::move_detail::is_pod<T>::value | 
| 287 | #endif | 
| 288 |  | 
| 289 | #ifdef BOOST_MOVE_HAS_NOTHROW_MOVE | 
| 290 |    #define BOOST_MOVE_IS_NOTHROW_MOVE_CONSTRUCTIBLE(T)   BOOST_MOVE_HAS_NOTHROW_MOVE(T) | 
| 291 | #else | 
| 292 |    #define BOOST_MOVE_IS_NOTHROW_MOVE_CONSTRUCTIBLE(T)   ::boost::move_detail::is_pod<T>::value | 
| 293 | #endif | 
| 294 |  | 
| 295 | #ifdef BOOST_MOVE_HAS_NOTHROW_ASSIGN | 
| 296 |    #define BOOST_MOVE_IS_NOTHROW_COPY_ASSIGNABLE(T) BOOST_MOVE_HAS_NOTHROW_ASSIGN(T) | 
| 297 | #else | 
| 298 |    #define BOOST_MOVE_IS_NOTHROW_COPY_ASSIGNABLE(T) ::boost::move_detail::is_pod<T>::value | 
| 299 | #endif | 
| 300 |  | 
| 301 | #ifdef BOOST_MOVE_HAS_NOTHROW_MOVE_ASSIGN | 
| 302 |    #define BOOST_MOVE_IS_NOTHROW_MOVE_ASSIGNABLE(T) BOOST_MOVE_HAS_NOTHROW_MOVE_ASSIGN(T) | 
| 303 | #else | 
| 304 |    #define BOOST_MOVE_IS_NOTHROW_MOVE_ASSIGNABLE(T) ::boost::move_detail::is_pod<T>::value | 
| 305 | #endif | 
| 306 |  | 
| 307 | #ifdef BOOST_MOVE_IS_ENUM | 
| 308 |    #define BOOST_MOVE_IS_ENUM_IMPL(T)   BOOST_MOVE_IS_ENUM(T) | 
| 309 | #else | 
| 310 |    #define BOOST_MOVE_IS_ENUM_IMPL(T)   ::boost::move_detail::is_enum_nonintrinsic<T>::value | 
| 311 | #endif | 
| 312 |  | 
| 313 | namespace boost { | 
| 314 | namespace move_detail { | 
| 315 |  | 
| 316 | ////////////////////////// | 
| 317 | //    is_reference | 
| 318 | ////////////////////////// | 
| 319 | template<class T> | 
| 320 | struct is_reference | 
| 321 | {  static const bool value = false; }; | 
| 322 |  | 
| 323 | template<class T> | 
| 324 | struct is_reference<T&> | 
| 325 | {  static const bool value = true; }; | 
| 326 |  | 
| 327 | #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) | 
| 328 | template<class T> | 
| 329 | struct is_reference<T&&> | 
| 330 | {  static const bool value = true; }; | 
| 331 | #endif | 
| 332 |  | 
| 333 | ////////////////////////// | 
| 334 | //    is_pointer | 
| 335 | ////////////////////////// | 
| 336 | template<class T> | 
| 337 | struct is_pointer | 
| 338 | {  static const bool value = false; }; | 
| 339 |  | 
| 340 | template<class T> | 
| 341 | struct is_pointer<T*> | 
| 342 | {  static const bool value = true; }; | 
| 343 |  | 
| 344 | ////////////////////////// | 
| 345 | //       is_const | 
| 346 | ////////////////////////// | 
| 347 | template<class T> | 
| 348 | struct is_const | 
| 349 | {  static const bool value = false; }; | 
| 350 |  | 
| 351 | template<class T> | 
| 352 | struct is_const<const T> | 
| 353 | {  static const bool value = true; }; | 
| 354 |  | 
| 355 | ////////////////////////// | 
| 356 | //       unvoid_ref | 
| 357 | ////////////////////////// | 
| 358 | template <typename T> struct unvoid_ref : add_lvalue_reference<T>{}; | 
| 359 | template <> struct unvoid_ref<void>                { typedef unvoid_ref & type; }; | 
| 360 | template <> struct unvoid_ref<const void>          { typedef unvoid_ref & type; }; | 
| 361 | template <> struct unvoid_ref<volatile void>       { typedef unvoid_ref & type; }; | 
| 362 | template <> struct unvoid_ref<const volatile void> { typedef unvoid_ref & type; }; | 
| 363 |  | 
| 364 | template <typename T> | 
| 365 | struct add_reference : add_lvalue_reference<T> | 
| 366 | {}; | 
| 367 |  | 
| 368 | ////////////////////////// | 
| 369 | //    add_const_reference | 
| 370 | ////////////////////////// | 
| 371 | template <class T> | 
| 372 | struct add_const_reference | 
| 373 | {  typedef const T &type;   }; | 
| 374 |  | 
| 375 | template <class T> | 
| 376 | struct add_const_reference<T&> | 
| 377 | {  typedef T& type;   }; | 
| 378 |  | 
| 379 | ////////////////////////// | 
| 380 | //    add_const_if_c | 
| 381 | ////////////////////////// | 
| 382 | template<class T, bool Add> | 
| 383 | struct add_const_if_c | 
| 384 |    : if_c<Add, typename add_const<T>::type, T> | 
| 385 | {}; | 
| 386 |  | 
| 387 | ////////////////////////// | 
| 388 | //    remove_const | 
| 389 | ////////////////////////// | 
| 390 | template<class T> | 
| 391 | struct remove_const | 
| 392 | {  typedef T type;   }; | 
| 393 |  | 
| 394 | template<class T> | 
| 395 | struct remove_const< const T> | 
| 396 | {  typedef T type;   }; | 
| 397 |  | 
| 398 | ////////////////////////// | 
| 399 | //    remove_cv | 
| 400 | ////////////////////////// | 
| 401 | template<typename T> struct remove_cv                    {  typedef T type;   }; | 
| 402 | template<typename T> struct remove_cv<const T>           {  typedef T type;   }; | 
| 403 | template<typename T> struct remove_cv<const volatile T>  {  typedef T type;   }; | 
| 404 | template<typename T> struct remove_cv<volatile T>        {  typedef T type;   }; | 
| 405 |  | 
| 406 | ////////////////////////// | 
| 407 | //    make_unsigned | 
| 408 | ////////////////////////// | 
| 409 | template <class T> | 
| 410 | struct make_unsigned_impl                                         {  typedef T type;   }; | 
| 411 | template <> struct make_unsigned_impl<signed char>                {  typedef unsigned char  type; }; | 
| 412 | template <> struct make_unsigned_impl<signed short>               {  typedef unsigned short type; }; | 
| 413 | template <> struct make_unsigned_impl<signed int>                 {  typedef unsigned int   type; }; | 
| 414 | template <> struct make_unsigned_impl<signed long>                {  typedef unsigned long  type; }; | 
| 415 | #ifdef BOOST_HAS_LONG_LONG | 
| 416 | template <> struct make_unsigned_impl< ::boost::long_long_type >  {  typedef ::boost::ulong_long_type type; }; | 
| 417 | #endif | 
| 418 |  | 
| 419 | template <class T> | 
| 420 | struct make_unsigned | 
| 421 |    : make_unsigned_impl<typename remove_cv<T>::type> | 
| 422 | {}; | 
| 423 |  | 
| 424 | ////////////////////////// | 
| 425 | //    is_floating_point | 
| 426 | ////////////////////////// | 
| 427 | template<class T> struct is_floating_point_cv               {  static const bool value = false; }; | 
| 428 | template<>        struct is_floating_point_cv<float>        {  static const bool value = true; }; | 
| 429 | template<>        struct is_floating_point_cv<double>       {  static const bool value = true; }; | 
| 430 | template<>        struct is_floating_point_cv<long double>  {  static const bool value = true; }; | 
| 431 |  | 
| 432 | template<class T> | 
| 433 | struct is_floating_point | 
| 434 |    : is_floating_point_cv<typename remove_cv<T>::type> | 
| 435 | {}; | 
| 436 |  | 
| 437 | ////////////////////////// | 
| 438 | //    is_integral | 
| 439 | ////////////////////////// | 
| 440 | template<class T> struct is_integral_cv                    {  static const bool value = false; }; | 
| 441 | template<> struct is_integral_cv<                     bool>{  static const bool value = true; }; | 
| 442 | template<> struct is_integral_cv<                     char>{  static const bool value = true; }; | 
| 443 | template<> struct is_integral_cv<            unsigned char>{  static const bool value = true; }; | 
| 444 | template<> struct is_integral_cv<              signed char>{  static const bool value = true; }; | 
| 445 | #ifndef BOOST_NO_CXX11_CHAR16_T | 
| 446 | template<> struct is_integral_cv<                 char16_t>{  static const bool value = true; }; | 
| 447 | #endif | 
| 448 | #ifndef BOOST_NO_CXX11_CHAR32_T | 
| 449 | template<> struct is_integral_cv<                 char32_t>{  static const bool value = true; }; | 
| 450 | #endif | 
| 451 | #ifndef BOOST_NO_INTRINSIC_WCHAR_T | 
| 452 | template<> struct is_integral_cv<                  wchar_t>{  static const bool value = true; }; | 
| 453 | #endif | 
| 454 | template<> struct is_integral_cv<                    short>{  static const bool value = true; }; | 
| 455 | template<> struct is_integral_cv<           unsigned short>{  static const bool value = true; }; | 
| 456 | template<> struct is_integral_cv<                      int>{  static const bool value = true; }; | 
| 457 | template<> struct is_integral_cv<             unsigned int>{  static const bool value = true; }; | 
| 458 | template<> struct is_integral_cv<                     long>{  static const bool value = true; }; | 
| 459 | template<> struct is_integral_cv<            unsigned long>{  static const bool value = true; }; | 
| 460 | #ifdef BOOST_HAS_LONG_LONG | 
| 461 | template<> struct is_integral_cv< ::boost:: long_long_type>{  static const bool value = true; }; | 
| 462 | template<> struct is_integral_cv< ::boost::ulong_long_type>{  static const bool value = true; }; | 
| 463 | #endif | 
| 464 |  | 
| 465 | template<class T> | 
| 466 | struct is_integral | 
| 467 |    : public is_integral_cv<typename remove_cv<T>::type> | 
| 468 | {}; | 
| 469 |  | 
| 470 | ////////////////////////////////////// | 
| 471 | //          remove_all_extents | 
| 472 | ////////////////////////////////////// | 
| 473 | template <class T> | 
| 474 | struct remove_all_extents | 
| 475 | {  typedef T type;}; | 
| 476 |  | 
| 477 | template <class T> | 
| 478 | struct remove_all_extents<T[]> | 
| 479 | {  typedef typename remove_all_extents<T>::type type; }; | 
| 480 |  | 
| 481 | template <class T, std::size_t N> | 
| 482 | struct remove_all_extents<T[N]> | 
| 483 | {  typedef typename remove_all_extents<T>::type type;}; | 
| 484 |  | 
| 485 | ////////////////////////// | 
| 486 | //    is_scalar | 
| 487 | ////////////////////////// | 
| 488 | template<class T> | 
| 489 | struct is_scalar | 
| 490 | {  static const bool value = is_integral<T>::value || is_floating_point<T>::value; }; | 
| 491 |  | 
| 492 | ////////////////////////// | 
| 493 | //       is_void | 
| 494 | ////////////////////////// | 
| 495 | template<class T> | 
| 496 | struct is_void_cv | 
| 497 | {  static const bool value = false; }; | 
| 498 |  | 
| 499 | template<> | 
| 500 | struct is_void_cv<void> | 
| 501 | {  static const bool value = true; }; | 
| 502 |  | 
| 503 | template<class T> | 
| 504 | struct is_void | 
| 505 |    : is_void_cv<typename remove_cv<T>::type> | 
| 506 | {}; | 
| 507 |  | 
| 508 | ////////////////////////////////////// | 
| 509 | //          is_array | 
| 510 | ////////////////////////////////////// | 
| 511 | template<class T> | 
| 512 | struct is_array | 
| 513 | {  static const bool value = false; }; | 
| 514 |  | 
| 515 | template<class T> | 
| 516 | struct is_array<T[]> | 
| 517 | {  static const bool value = true;  }; | 
| 518 |  | 
| 519 | template<class T, std::size_t N> | 
| 520 | struct is_array<T[N]> | 
| 521 | {  static const bool value = true;  }; | 
| 522 |  | 
| 523 | ////////////////////////////////////// | 
| 524 | //           is_member_pointer | 
| 525 | ////////////////////////////////////// | 
| 526 | template <class T>         struct is_member_pointer_cv         {  static const bool value = false; }; | 
| 527 | template <class T, class U>struct is_member_pointer_cv<T U::*> {  static const bool value = true; }; | 
| 528 |  | 
| 529 | template <class T> | 
| 530 | struct is_member_pointer | 
| 531 |     : is_member_pointer_cv<typename remove_cv<T>::type> | 
| 532 | {}; | 
| 533 |  | 
| 534 | ////////////////////////////////////// | 
| 535 | //          is_nullptr_t | 
| 536 | ////////////////////////////////////// | 
| 537 | template <class T> | 
| 538 | struct is_nullptr_t_cv | 
| 539 | {  static const bool value = false; }; | 
| 540 |  | 
| 541 | #if !defined(BOOST_NO_CXX11_NULLPTR) | 
| 542 | template <> | 
| 543 | struct is_nullptr_t_cv | 
| 544 |    #if !defined(BOOST_NO_CXX11_DECLTYPE) | 
| 545 |    <decltype(nullptr)> | 
| 546 |    #else | 
| 547 |    <std::nullptr_t> | 
| 548 |    #endif | 
| 549 | {  static const bool value = true; }; | 
| 550 | #endif | 
| 551 |  | 
| 552 | template <class T> | 
| 553 | struct is_nullptr_t | 
| 554 |    : is_nullptr_t_cv<typename remove_cv<T>::type> | 
| 555 | {}; | 
| 556 |  | 
| 557 | ////////////////////////////////////// | 
| 558 | //          is_function | 
| 559 | ////////////////////////////////////// | 
| 560 | //Inspired by libc++, thanks to Howard Hinnant | 
| 561 | //For a function to pointer an lvalue of function type T can be implicitly converted to a prvalue | 
| 562 | //pointer to that function. This does not apply to non-static member functions because lvalues | 
| 563 | //that refer to non-static member functions do not exist. | 
| 564 | template <class T> | 
| 565 | struct is_reference_convertible_to_pointer | 
| 566 | { | 
| 567 |    struct twochar { char dummy[2]; }; | 
| 568 |    template <class U> static char    test(U*); | 
| 569 |    template <class U> static twochar test(...); | 
| 570 |    static T& source(); | 
| 571 |    static const bool value = sizeof(char) == sizeof(test<T>(source())); | 
| 572 | }; | 
| 573 | //Filter out: | 
| 574 | // - class types that might have implicit conversions | 
| 575 | // - void (to avoid forming a reference to void later) | 
| 576 | // - references (e.g.: filtering reference to functions) | 
| 577 | // - nullptr_t (convertible to pointer) | 
| 578 | template < class T | 
| 579 |          , bool Filter = is_class_or_union<T>::value  || | 
| 580 |                          is_void<T>::value            || | 
| 581 |                          is_reference<T>::value       || | 
| 582 |                          is_nullptr_t<T>::value       > | 
| 583 | struct is_function_impl | 
| 584 | {  static const bool value = is_reference_convertible_to_pointer<T>::value; }; | 
| 585 |  | 
| 586 | template <class T> | 
| 587 | struct is_function_impl<T, true> | 
| 588 | {  static const bool value = false; }; | 
| 589 |  | 
| 590 | template <class T> | 
| 591 | struct is_function | 
| 592 |    : is_function_impl<T> | 
| 593 | {}; | 
| 594 |  | 
| 595 | ////////////////////////////////////// | 
| 596 | //       is_union | 
| 597 | ////////////////////////////////////// | 
| 598 | template<class T> | 
| 599 | struct is_union_noextents_cv | 
| 600 | {  static const bool value = BOOST_MOVE_IS_UNION_IMPL(T); }; | 
| 601 |  | 
| 602 | template<class T> | 
| 603 | struct is_union | 
| 604 |    : is_union_noextents_cv<typename remove_cv<typename remove_all_extents<T>::type>::type> | 
| 605 | {}; | 
| 606 |  | 
| 607 | ////////////////////////////////////// | 
| 608 | //             is_class | 
| 609 | ////////////////////////////////////// | 
| 610 | template <class T> | 
| 611 | struct is_class | 
| 612 | { | 
| 613 |    static const bool value = is_class_or_union<T>::value && ! is_union<T>::value; | 
| 614 | }; | 
| 615 |  | 
| 616 |  | 
| 617 | ////////////////////////////////////// | 
| 618 | //             is_arithmetic | 
| 619 | ////////////////////////////////////// | 
| 620 | template <class T> | 
| 621 | struct is_arithmetic | 
| 622 | { | 
| 623 |    static const bool value = is_floating_point<T>::value || | 
| 624 |                              is_integral<T>::value; | 
| 625 | }; | 
| 626 |  | 
| 627 | ////////////////////////////////////// | 
| 628 | //    is_member_function_pointer | 
| 629 | ////////////////////////////////////// | 
| 630 | template <class T> | 
| 631 | struct is_member_function_pointer_cv | 
| 632 | { | 
| 633 |    static const bool value = false; | 
| 634 | }; | 
| 635 |  | 
| 636 | template <class T, class C> | 
| 637 | struct is_member_function_pointer_cv<T C::*> | 
| 638 |    : is_function<T> | 
| 639 | {}; | 
| 640 |  | 
| 641 | template <class T> | 
| 642 | struct is_member_function_pointer | 
| 643 |     : is_member_function_pointer_cv<typename remove_cv<T>::type> | 
| 644 | {}; | 
| 645 |  | 
| 646 | ////////////////////////////////////// | 
| 647 | //             is_enum | 
| 648 | ////////////////////////////////////// | 
| 649 | #if !defined(BOOST_MOVE_IS_ENUM) | 
| 650 | //Based on (http://howardhinnant.github.io/TypeHiearchy.pdf) | 
| 651 | template <class T> | 
| 652 | struct is_enum_nonintrinsic | 
| 653 | { | 
| 654 |    static const bool value =  !is_arithmetic<T>::value     && | 
| 655 |                               !is_reference<T>::value      && | 
| 656 |                               !is_class_or_union<T>::value && | 
| 657 |                               !is_array<T>::value          && | 
| 658 |                               !is_void<T>::value           && | 
| 659 |                               !is_nullptr_t<T>::value      && | 
| 660 |                               !is_member_pointer<T>::value && | 
| 661 |                               !is_pointer<T>::value        && | 
| 662 |                               !is_function<T>::value; | 
| 663 | }; | 
| 664 | #endif | 
| 665 |  | 
| 666 | template <class T> | 
| 667 | struct is_enum | 
| 668 | {  static const bool value = BOOST_MOVE_IS_ENUM_IMPL(T);  }; | 
| 669 |  | 
| 670 | ////////////////////////////////////// | 
| 671 | //       is_pod | 
| 672 | ////////////////////////////////////// | 
| 673 | template<class T> | 
| 674 | struct is_pod_noextents_cv  //for non-c++11 compilers, a safe fallback | 
| 675 | {  static const bool value = BOOST_MOVE_IS_POD_IMPL(T); }; | 
| 676 |  | 
| 677 | template<class T> | 
| 678 | struct is_pod | 
| 679 |    : is_pod_noextents_cv<typename remove_cv<typename remove_all_extents<T>::type>::type> | 
| 680 | {}; | 
| 681 |  | 
| 682 | ////////////////////////////////////// | 
| 683 | //             is_empty | 
| 684 | ////////////////////////////////////// | 
| 685 | #if !defined(BOOST_MOVE_IS_EMPTY) | 
| 686 |  | 
| 687 | template <typename T> | 
| 688 | struct empty_helper_t1 : public T | 
| 689 | { | 
| 690 |    empty_helper_t1();  // hh compiler bug workaround | 
| 691 |    int i[256]; | 
| 692 |    private: | 
| 693 |  | 
| 694 |    empty_helper_t1(const empty_helper_t1&); | 
| 695 |    empty_helper_t1& operator=(const empty_helper_t1&); | 
| 696 | }; | 
| 697 |  | 
| 698 | struct empty_helper_t2 { int i[256]; }; | 
| 699 |  | 
| 700 | template <typename T, bool IsClass = is_class<T>::value > | 
| 701 | struct is_empty_nonintrinsic | 
| 702 | { | 
| 703 |    static const bool value = false; | 
| 704 | }; | 
| 705 |  | 
| 706 | template <typename T> | 
| 707 | struct is_empty_nonintrinsic<T, true> | 
| 708 | { | 
| 709 |    static const bool value = sizeof(empty_helper_t1<T>) == sizeof(empty_helper_t2); | 
| 710 | }; | 
| 711 | #endif | 
| 712 |  | 
| 713 | template <class T> | 
| 714 | struct is_empty | 
| 715 | {  static const bool value = BOOST_MOVE_IS_EMPTY_IMPL(T);  }; | 
| 716 |  | 
| 717 |  | 
| 718 | template<class T> | 
| 719 | struct has_boost_move_no_copy_constructor_or_assign_type | 
| 720 | { | 
| 721 |    template <class U> | 
| 722 |    static yes_type test(typename U::boost_move_no_copy_constructor_or_assign*); | 
| 723 |  | 
| 724 |    template <class U> | 
| 725 |    static no_type test(...); | 
| 726 |  | 
| 727 |    static const bool value = sizeof(test<T>(0)) == sizeof(yes_type); | 
| 728 | }; | 
| 729 |  | 
| 730 | ////////////////////////////////////// | 
| 731 | //       is_copy_constructible | 
| 732 | ////////////////////////////////////// | 
| 733 | #if !defined(BOOST_NO_CXX11_DELETED_FUNCTIONS) && !defined(BOOST_NO_CXX11_DECLTYPE) \ | 
| 734 |    && !defined(BOOST_INTEL_CXX_VERSION) && \ | 
| 735 |       !(defined(BOOST_MSVC) && _MSC_VER == 1800) | 
| 736 | #define BOOST_MOVE_TT_CXX11_IS_COPY_CONSTRUCTIBLE | 
| 737 | #endif | 
| 738 |  | 
| 739 | template<class T> | 
| 740 | struct is_copy_constructible | 
| 741 | { | 
| 742 |    // Intel compiler has problems with SFINAE for copy constructors and deleted functions: | 
| 743 |    // | 
| 744 |    // error: function *function_name* cannot be referenced -- it is a deleted function | 
| 745 |    // static yes_type test(U&, decltype(U(boost::declval<U&>()))* = 0); | 
| 746 |    //                                                        ^  | 
| 747 |    // MSVC 12.0 (Visual 2013) has problems when the copy constructor has been deleted. See: | 
| 748 |    // https://connect.microsoft.com/VisualStudio/feedback/details/800328/std-is-copy-constructible-is-broken | 
| 749 |    #if defined(BOOST_MOVE_TT_CXX11_IS_COPY_CONSTRUCTIBLE) | 
| 750 |       template<class U> static typename add_reference<U>::type source(); | 
| 751 |       static no_type test(...); | 
| 752 |       #ifdef BOOST_NO_CXX11_DECLTYPE | 
| 753 |          template <class U> | 
| 754 |          static yes_type test(U&, bool_<sizeof(U(source<U>()))>* = 0); | 
| 755 |       #else | 
| 756 |          template <class U> | 
| 757 |          static yes_type test(U&, decltype(U(source<U>()))* = 0); | 
| 758 |       #endif | 
| 759 |       static const bool value = sizeof(test(source<T>())) == sizeof(yes_type); | 
| 760 |    #else | 
| 761 |    static const bool value = !has_boost_move_no_copy_constructor_or_assign_type<T>::value; | 
| 762 |    #endif | 
| 763 | }; | 
| 764 |  | 
| 765 |  | 
| 766 | ////////////////////////////////////// | 
| 767 | //       is_copy_assignable | 
| 768 | ////////////////////////////////////// | 
| 769 | #if !defined(BOOST_NO_CXX11_DELETED_FUNCTIONS) && !defined(BOOST_NO_CXX11_DECLTYPE) \ | 
| 770 |    && !defined(BOOST_INTEL_CXX_VERSION) && \ | 
| 771 |       !(defined(BOOST_MSVC) && _MSC_VER == 1800) | 
| 772 | #define BOOST_MOVE_TT_CXX11_IS_COPY_ASSIGNABLE | 
| 773 | #endif | 
| 774 |  | 
| 775 | template <class T> | 
| 776 | struct is_copy_assignable | 
| 777 | { | 
| 778 | // Intel compiler has problems with SFINAE for copy constructors and deleted functions: | 
| 779 | // | 
| 780 | // error: function *function_name* cannot be referenced -- it is a deleted function | 
| 781 | // static boost::type_traits::yes_type test(T1&, decltype(T1(boost::declval<T1&>()))* = 0); | 
| 782 | //                                                        ^  | 
| 783 | // | 
| 784 | // MSVC 12.0 (Visual 2013) has problems when the copy constructor has been deleted. See: | 
| 785 | // https://connect.microsoft.com/VisualStudio/feedback/details/800328/std-is-copy-constructible-is-broken | 
| 786 | #if defined(BOOST_MOVE_TT_CXX11_IS_COPY_ASSIGNABLE) | 
| 787 |    typedef char yes_type; | 
| 788 |    struct no_type { char dummy[2]; }; | 
| 789 |     | 
| 790 |    template <class U>   static typename add_reference<U>::type source(); | 
| 791 |    template <class U>   static decltype(source<U&>() = source<const U&>(), yes_type() ) test(int); | 
| 792 |    template <class>     static no_type test(...); | 
| 793 |  | 
| 794 |    static const bool value = sizeof(test<T>(0)) == sizeof(yes_type); | 
| 795 | #else | 
| 796 |    static const bool value = !has_boost_move_no_copy_constructor_or_assign_type<T>::value; | 
| 797 | #endif | 
| 798 | }; | 
| 799 |  | 
| 800 | ////////////////////////////////////// | 
| 801 | //       is_trivially_destructible | 
| 802 | ////////////////////////////////////// | 
| 803 | template<class T> | 
| 804 | struct is_trivially_destructible | 
| 805 | {  static const bool value = BOOST_MOVE_IS_TRIVIALLY_DESTRUCTIBLE(T); }; | 
| 806 |  | 
| 807 | ////////////////////////////////////// | 
| 808 | //       is_trivially_default_constructible | 
| 809 | ////////////////////////////////////// | 
| 810 | template<class T> | 
| 811 | struct is_trivially_default_constructible | 
| 812 | {  static const bool value = BOOST_MOVE_IS_TRIVIALLY_DEFAULT_CONSTRUCTIBLE(T); }; | 
| 813 |  | 
| 814 | ////////////////////////////////////// | 
| 815 | //       is_trivially_copy_constructible | 
| 816 | ////////////////////////////////////// | 
| 817 | template<class T> | 
| 818 | struct is_trivially_copy_constructible | 
| 819 | { | 
| 820 |    //In several compilers BOOST_MOVE_IS_TRIVIALLY_COPY_CONSTRUCTIBLE return true even with | 
| 821 |    //deleted copy constructors so make sure the type is copy constructible. | 
| 822 |    static const bool value = BOOST_MOVE_IS_TRIVIALLY_COPY_CONSTRUCTIBLE(T); | 
| 823 | }; | 
| 824 |  | 
| 825 | ////////////////////////////////////// | 
| 826 | //       is_trivially_move_constructible | 
| 827 | ////////////////////////////////////// | 
| 828 | template<class T> | 
| 829 | struct is_trivially_move_constructible | 
| 830 | { static const bool value = BOOST_MOVE_IS_TRIVIALLY_MOVE_CONSTRUCTIBLE(T); }; | 
| 831 |  | 
| 832 | ////////////////////////////////////// | 
| 833 | //       is_trivially_copy_assignable | 
| 834 | ////////////////////////////////////// | 
| 835 | template<class T> | 
| 836 | struct is_trivially_copy_assignable | 
| 837 | { | 
| 838 |    //In several compilers BOOST_MOVE_IS_TRIVIALLY_COPY_CONSTRUCTIBLE return true even with | 
| 839 |    //deleted copy constructors so make sure the type is copy constructible. | 
| 840 |    static const bool value = BOOST_MOVE_IS_TRIVIALLY_COPY_ASSIGNABLE(T); | 
| 841 | };                              | 
| 842 |  | 
| 843 | ////////////////////////////////////// | 
| 844 | //       is_trivially_move_assignable | 
| 845 | ////////////////////////////////////// | 
| 846 | template<class T> | 
| 847 | struct is_trivially_move_assignable | 
| 848 | {  static const bool value = BOOST_MOVE_IS_TRIVIALLY_MOVE_ASSIGNABLE(T);  }; | 
| 849 |  | 
| 850 | ////////////////////////////////////// | 
| 851 | //       is_nothrow_default_constructible | 
| 852 | ////////////////////////////////////// | 
| 853 | template<class T> | 
| 854 | struct is_nothrow_default_constructible | 
| 855 |    : is_pod<T> | 
| 856 | {  static const bool value = BOOST_MOVE_IS_NOTHROW_DEFAULT_CONSTRUCTIBLE(T);  }; | 
| 857 |  | 
| 858 | ////////////////////////////////////// | 
| 859 | //    is_nothrow_copy_constructible | 
| 860 | ////////////////////////////////////// | 
| 861 | template<class T> | 
| 862 | struct is_nothrow_copy_constructible | 
| 863 | {  static const bool value = BOOST_MOVE_IS_NOTHROW_COPY_CONSTRUCTIBLE(T);  }; | 
| 864 |  | 
| 865 | ////////////////////////////////////// | 
| 866 | //    is_nothrow_move_constructible | 
| 867 | ////////////////////////////////////// | 
| 868 | template<class T> | 
| 869 | struct is_nothrow_move_constructible | 
| 870 | {  static const bool value = BOOST_MOVE_IS_NOTHROW_MOVE_CONSTRUCTIBLE(T);  }; | 
| 871 |  | 
| 872 | ////////////////////////////////////// | 
| 873 | //       is_nothrow_copy_assignable | 
| 874 | ////////////////////////////////////// | 
| 875 | template<class T> | 
| 876 | struct is_nothrow_copy_assignable | 
| 877 | {  static const bool value = BOOST_MOVE_IS_NOTHROW_COPY_ASSIGNABLE(T);  }; | 
| 878 |  | 
| 879 | ////////////////////////////////////// | 
| 880 | //    is_nothrow_move_assignable | 
| 881 | ////////////////////////////////////// | 
| 882 | template<class T> | 
| 883 | struct is_nothrow_move_assignable | 
| 884 | {  static const bool value = BOOST_MOVE_IS_NOTHROW_MOVE_ASSIGNABLE(T);  }; | 
| 885 |  | 
| 886 | ////////////////////////////////////// | 
| 887 | //    is_nothrow_swappable | 
| 888 | ////////////////////////////////////// | 
| 889 | template<class T> | 
| 890 | struct is_nothrow_swappable | 
| 891 | { | 
| 892 |    static const bool value = is_empty<T>::value || is_pod<T>::value; | 
| 893 | }; | 
| 894 |  | 
| 895 | ////////////////////////////////////// | 
| 896 | //       alignment_of | 
| 897 | ////////////////////////////////////// | 
| 898 | template <typename T> | 
| 899 | struct alignment_of_hack | 
| 900 | { | 
| 901 |    T t1; | 
| 902 |    char c; | 
| 903 |    T t2; | 
| 904 |    alignment_of_hack(); | 
| 905 | }; | 
| 906 |  | 
| 907 | template <unsigned A, unsigned S> | 
| 908 | struct alignment_logic | 
| 909 | {  static const std::size_t value = A < S ? A : S; }; | 
| 910 |  | 
| 911 | template< typename T > | 
| 912 | struct alignment_of_impl | 
| 913 | #if defined(BOOST_MSVC) && (BOOST_MSVC >= 1400) | 
| 914 |     // With MSVC both the native __alignof operator | 
| 915 |     // and our own logic gets things wrong from time to time :-( | 
| 916 |     // Using a combination of the two seems to make the most of a bad job: | 
| 917 |    : alignment_logic< sizeof(alignment_of_hack<T>) - 2*sizeof(T), __alignof(T)> | 
| 918 | {}; | 
| 919 | #elif !defined(BOOST_MOVE_ALIGNMENT_OF) | 
| 920 |    : alignment_logic< sizeof(alignment_of_hack<T>) - 2*sizeof(T), sizeof(T)> | 
| 921 | {}; | 
| 922 | #else | 
| 923 | {  static const std::size_t value = BOOST_MOVE_ALIGNMENT_OF(T);  }; | 
| 924 | #endif | 
| 925 |  | 
| 926 | template< typename T > | 
| 927 | struct alignment_of | 
| 928 |    : alignment_of_impl<T> | 
| 929 | {}; | 
| 930 |  | 
| 931 | class alignment_dummy; | 
| 932 | typedef void (*function_ptr)(); | 
| 933 | typedef int (alignment_dummy::*member_ptr); | 
| 934 | typedef int (alignment_dummy::*member_function_ptr)(); | 
| 935 | struct alignment_struct | 
| 936 | {  long double dummy[4];  }; | 
| 937 |  | 
| 938 | ///////////////////////////// | 
| 939 | //    max_align_t | 
| 940 | ///////////////////////////// | 
| 941 | //This is not standard, but should work with all compilers | 
| 942 | union max_align | 
| 943 | { | 
| 944 |    char        char_; | 
| 945 |    short       short_; | 
| 946 |    int         int_; | 
| 947 |    long        long_; | 
| 948 |    #ifdef BOOST_HAS_LONG_LONG | 
| 949 |    ::boost::long_long_type   long_long_; | 
| 950 |    #endif | 
| 951 |    float       float_; | 
| 952 |    double      double_; | 
| 953 |    void *      void_ptr_; | 
| 954 |    long double long_double_[4]; | 
| 955 |    alignment_dummy *unknown_class_ptr_; | 
| 956 |    function_ptr function_ptr_; | 
| 957 |    member_function_ptr member_function_ptr_; | 
| 958 |    alignment_struct alignment_struct_; | 
| 959 | }; | 
| 960 |  | 
| 961 | typedef union max_align max_align_t; | 
| 962 |  | 
| 963 | ///////////////////////////// | 
| 964 | //    aligned_storage | 
| 965 | ///////////////////////////// | 
| 966 |  | 
| 967 | #if !defined(BOOST_NO_ALIGNMENT) | 
| 968 |  | 
| 969 | template<std::size_t Len, std::size_t Align> | 
| 970 | struct aligned_storage_impl; | 
| 971 |  | 
| 972 | #define BOOST_MOVE_ALIGNED_STORAGE_WITH_BOOST_ALIGNMENT(A)\ | 
| 973 | template<std::size_t Len>\ | 
| 974 | struct BOOST_ALIGNMENT(A) aligned_storage_impl<Len, A>\ | 
| 975 | {\ | 
| 976 |    char dummy[Len];\ | 
| 977 |    typedef aligned_storage_impl<Len, A> type;\ | 
| 978 | };\ | 
| 979 | // | 
| 980 |  | 
| 981 | //Up to 4K alignment (typical page size) | 
| 982 | BOOST_MOVE_ALIGNED_STORAGE_WITH_BOOST_ALIGNMENT(0x1) | 
| 983 | BOOST_MOVE_ALIGNED_STORAGE_WITH_BOOST_ALIGNMENT(0x2) | 
| 984 | BOOST_MOVE_ALIGNED_STORAGE_WITH_BOOST_ALIGNMENT(0x4) | 
| 985 | BOOST_MOVE_ALIGNED_STORAGE_WITH_BOOST_ALIGNMENT(0x8) | 
| 986 | BOOST_MOVE_ALIGNED_STORAGE_WITH_BOOST_ALIGNMENT(0x10) | 
| 987 | BOOST_MOVE_ALIGNED_STORAGE_WITH_BOOST_ALIGNMENT(0x20) | 
| 988 | BOOST_MOVE_ALIGNED_STORAGE_WITH_BOOST_ALIGNMENT(0x40) | 
| 989 | BOOST_MOVE_ALIGNED_STORAGE_WITH_BOOST_ALIGNMENT(0x80) | 
| 990 | BOOST_MOVE_ALIGNED_STORAGE_WITH_BOOST_ALIGNMENT(0x100) | 
| 991 | BOOST_MOVE_ALIGNED_STORAGE_WITH_BOOST_ALIGNMENT(0x200) | 
| 992 | BOOST_MOVE_ALIGNED_STORAGE_WITH_BOOST_ALIGNMENT(0x400) | 
| 993 | BOOST_MOVE_ALIGNED_STORAGE_WITH_BOOST_ALIGNMENT(0x800) | 
| 994 | BOOST_MOVE_ALIGNED_STORAGE_WITH_BOOST_ALIGNMENT(0x1000) | 
| 995 |  | 
| 996 | #undef BOOST_MOVE_ALIGNED_STORAGE_WITH_BOOST_ALIGNMENT | 
| 997 |  | 
| 998 | #else //BOOST_NO_ALIGNMENT | 
| 999 |  | 
| 1000 | template<class T, std::size_t Len> | 
| 1001 | union aligned_union | 
| 1002 | {    | 
| 1003 |    T aligner; | 
| 1004 |    char dummy[Len]; | 
| 1005 | }; | 
| 1006 |  | 
| 1007 | template<std::size_t Len, std::size_t Align, class T, bool Ok> | 
| 1008 | struct aligned_next; | 
| 1009 |  | 
| 1010 | template<std::size_t Len, std::size_t Align, class T> | 
| 1011 | struct aligned_next<Len, Align, T, true> | 
| 1012 | { | 
| 1013 |    BOOST_STATIC_ASSERT((alignment_of<T>::value == Align)); | 
| 1014 |    typedef aligned_union<T, Len> type; | 
| 1015 | }; | 
| 1016 |  | 
| 1017 | //End of search defaults to max_align_t | 
| 1018 | template<std::size_t Len, std::size_t Align> | 
| 1019 | struct aligned_next<Len, Align, max_align_t, false> | 
| 1020 | {   typedef aligned_union<max_align_t, Len> type;   }; | 
| 1021 |  | 
| 1022 | //Now define a search list through types | 
| 1023 | #define BOOST_MOVE_ALIGNED_NEXT_STEP(TYPE, NEXT_TYPE)\ | 
| 1024 |    template<std::size_t Len, std::size_t Align>\ | 
| 1025 |    struct aligned_next<Len, Align, TYPE, false>\ | 
| 1026 |       : aligned_next<Len, Align, NEXT_TYPE, Align == alignment_of<NEXT_TYPE>::value>\ | 
| 1027 |    {};\ | 
| 1028 |    // | 
| 1029 |    BOOST_MOVE_ALIGNED_NEXT_STEP(long double, max_align_t) | 
| 1030 |    BOOST_MOVE_ALIGNED_NEXT_STEP(double, long double) | 
| 1031 |    #ifdef BOOST_HAS_LONG_LONG | 
| 1032 |       BOOST_MOVE_ALIGNED_NEXT_STEP(::boost::long_long_type, double) | 
| 1033 |       BOOST_MOVE_ALIGNED_NEXT_STEP(long, ::boost::long_long_type) | 
| 1034 |    #else | 
| 1035 |       BOOST_MOVE_ALIGNED_NEXT_STEP(long, double) | 
| 1036 |    #endif | 
| 1037 |    BOOST_MOVE_ALIGNED_NEXT_STEP(int, long) | 
| 1038 |    BOOST_MOVE_ALIGNED_NEXT_STEP(short, int) | 
| 1039 |    BOOST_MOVE_ALIGNED_NEXT_STEP(char, short) | 
| 1040 | #undef BOOST_MOVE_ALIGNED_NEXT_STEP | 
| 1041 |  | 
| 1042 | template<std::size_t Len, std::size_t Align> | 
| 1043 | struct aligned_storage_impl | 
| 1044 |    : aligned_next<Len, Align, char, Align == alignment_of<char>::value> | 
| 1045 | {}; | 
| 1046 |  | 
| 1047 | #endif | 
| 1048 |  | 
| 1049 | template<std::size_t Len, std::size_t Align = alignment_of<max_align_t>::value> | 
| 1050 | struct aligned_storage | 
| 1051 | { | 
| 1052 |    //Sanity checks for input parameters | 
| 1053 |    BOOST_STATIC_ASSERT(Align > 0); | 
| 1054 |  | 
| 1055 |    //Sanity checks for output type | 
| 1056 |    typedef typename aligned_storage_impl<Len ? Len : 1, Align>::type type; | 
| 1057 |    static const std::size_t value = alignment_of<type>::value; | 
| 1058 |    BOOST_STATIC_ASSERT(value >= Align); | 
| 1059 |    BOOST_STATIC_ASSERT((value % Align) == 0); | 
| 1060 |  | 
| 1061 |    //Just in case someone instantiates aligned_storage | 
| 1062 |    //instead of aligned_storage::type (typical error). | 
| 1063 |    private: | 
| 1064 |    aligned_storage(); | 
| 1065 | }; | 
| 1066 |  | 
| 1067 | }  //namespace move_detail { | 
| 1068 | }  //namespace boost { | 
| 1069 |  | 
| 1070 | #include <boost/move/detail/config_end.hpp> | 
| 1071 |  | 
| 1072 | #endif   //#ifndef BOOST_MOVE_DETAIL_TYPE_TRAITS_HPP | 
| 1073 |  |