type_traits.hpp 39 KB

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