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