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 // BOOST_MOVE_HAS_NOTHROW_MOVE_CONSTRUCTOR(T) should evaluate to true if T has a non-throwing move constructor.
69 // BOOST_MOVE_HAS_NOTHROW_MOVE_ASSIGN(T) should evaluate to true if T has a non-throwing move assignment operator.
70 //
71 // The following can also be defined: when detected our implementation is greatly simplified.
72 //
73 // BOOST_ALIGNMENT_OF(T) should evaluate to the alignment requirements of type T.
74 
75 #if defined(__MSL_CPP__) && (__MSL_CPP__ >= 0x8000)
76     // Metrowerks compiler is acquiring intrinsic type traits support
77     // post version 8.  We hook into the published interface to pick up
78     // user defined specializations as well as compiler intrinsics as
79     // and when they become available:
80 #   include <msl_utility>
81 #   define BOOST_MOVE_IS_UNION(T) BOOST_STD_EXTENSION_NAMESPACE::is_union<T>::value
82 #   define BOOST_MOVE_IS_POD(T) BOOST_STD_EXTENSION_NAMESPACE::is_POD<T>::value
83 #   define BOOST_MOVE_HAS_TRIVIAL_CONSTRUCTOR(T) BOOST_STD_EXTENSION_NAMESPACE::has_trivial_default_ctor<T>::value
84 #   define BOOST_MOVE_HAS_TRIVIAL_COPY(T) BOOST_STD_EXTENSION_NAMESPACE::has_trivial_copy_ctor<T>::value
85 #   define BOOST_MOVE_HAS_TRIVIAL_ASSIGN(T) BOOST_STD_EXTENSION_NAMESPACE::has_trivial_assignment<T>::value
86 #   define BOOST_MOVE_HAS_TRIVIAL_DESTRUCTOR(T) BOOST_STD_EXTENSION_NAMESPACE::has_trivial_dtor<T>::value
87 #endif
88 
89 #if (defined(BOOST_MSVC) && defined(BOOST_MSVC_FULL_VER) && (BOOST_MSVC_FULL_VER >=140050215))\
90          || (defined(BOOST_INTEL) && defined(_MSC_VER) && (_MSC_VER >= 1500))
91 #   define BOOST_MOVE_IS_UNION(T) __is_union(T)
92 #   define BOOST_MOVE_IS_POD(T)                    (__is_pod(T) && __has_trivial_constructor(T))
93 #   define BOOST_MOVE_IS_EMPTY(T)                  __is_empty(T)
94 #   define BOOST_MOVE_HAS_TRIVIAL_CONSTRUCTOR(T)   __has_trivial_constructor(T)
95 #   define BOOST_MOVE_HAS_TRIVIAL_COPY(T)          (__has_trivial_copy(T)|| ::boost::move_detail::is_pod<T>::value)
96 #   define BOOST_MOVE_HAS_TRIVIAL_ASSIGN(T)        (__has_trivial_assign(T) || ::boost::move_detail::is_pod<T>::value)
97 #   define BOOST_MOVE_HAS_TRIVIAL_DESTRUCTOR(T)    (__has_trivial_destructor(T) || ::boost::move_detail::is_pod<T>::value)
98 #   define BOOST_MOVE_HAS_NOTHROW_CONSTRUCTOR(T)   (__has_nothrow_constructor(T) || ::boost::move_detail::is_trivially_default_constructible<T>::value)
99 #   define BOOST_MOVE_HAS_NOTHROW_COPY(T)          (__has_nothrow_copy(T) || ::boost::move_detail::is_trivially_copy_constructible<T>::value)
100 #   define BOOST_MOVE_HAS_NOTHROW_ASSIGN(T)        (__has_nothrow_assign(T) || ::boost::move_detail::is_trivially_copy_assignable<T>::value)
101 
102 #   define BOOST_MOVE_IS_ENUM(T) __is_enum(T)
103 #   if defined(_MSC_VER) && (_MSC_VER >= 1700)
104 #       define BOOST_MOVE_HAS_TRIVIAL_MOVE_CONSTRUCTOR(T)   (__has_trivial_move_constructor(T) || ::boost::move_detail::is_pod<T>::value)
105 #       define BOOST_MOVE_HAS_TRIVIAL_MOVE_ASSIGN(T)        (__has_trivial_move_assign(T) || ::boost::move_detail::is_pod<T>::value)
106 #   endif
107 #  if _MSC_FULL_VER >= 180020827
108 #     define BOOST_MOVE_HAS_NOTHROW_MOVE_ASSIGN(T) (__is_nothrow_assignable(T&, T&&))
109 #     define BOOST_MOVE_HAS_NOTHROW_MOVE_CONSTRUCTOR(T) (__is_nothrow_constructible(T, T&&))
110 #  endif
111 #endif
112 
113 #if defined(BOOST_CLANG)
114 //    BOOST_MOVE_HAS_TRAIT
115 #   if defined __is_identifier
116 #       define BOOST_MOVE_HAS_TRAIT(T) (__has_extension(T) || !__is_identifier(__##T))
117 #   elif defined(__has_extension)
118 #     define BOOST_MOVE_HAS_TRAIT(T) __has_extension(T)
119 #   else
120 #     define BOOST_MOVE_HAS_TRAIT(T) 0
121 #   endif
122 
123 //    BOOST_MOVE_IS_UNION
124 #   if BOOST_MOVE_HAS_TRAIT(is_union)
125 #     define BOOST_MOVE_IS_UNION(T) __is_union(T)
126 #   endif
127 
128 //    BOOST_MOVE_IS_ENUM
129 #   if BOOST_MOVE_HAS_TRAIT(is_enum)
130 #     define BOOST_MOVE_IS_ENUM(T) __is_enum(T)
131 #   endif
132 
133 //    BOOST_MOVE_IS_POD
134 #   if (!defined(__GLIBCXX__) || (__GLIBCXX__ >= 20080306 && __GLIBCXX__ != 20080519)) && BOOST_MOVE_HAS_TRAIT(is_pod)
135 #     define BOOST_MOVE_IS_POD(T) __is_pod(T)
136 #   endif
137 
138 //    BOOST_MOVE_IS_EMPTY
139 #   if (!defined(__GLIBCXX__) || (__GLIBCXX__ >= 20080306 && __GLIBCXX__ != 20080519)) && BOOST_MOVE_HAS_TRAIT(is_empty)
140 #     define BOOST_MOVE_IS_EMPTY(T) __is_empty(T)
141 #   endif
142 
143 //    BOOST_MOVE_HAS_TRIVIAL_CONSTRUCTOR
144 #   if BOOST_MOVE_HAS_TRAIT(is_constructible) && BOOST_MOVE_HAS_TRAIT(is_trivially_constructible)
145 #     define BOOST_MOVE_HAS_TRIVIAL_CONSTRUCTOR(T) __is_trivially_constructible(T)
146 #   elif BOOST_MOVE_HAS_TRAIT(has_trivial_constructor)
147 #     define BOOST_MOVE_HAS_TRIVIAL_CONSTRUCTOR(T) __has_trivial_constructor(T)
148 #   endif
149 
150 //    BOOST_MOVE_HAS_TRIVIAL_COPY
151 #   if BOOST_MOVE_HAS_TRAIT(is_constructible) && BOOST_MOVE_HAS_TRAIT(is_trivially_constructible)
152 #     define BOOST_MOVE_HAS_TRIVIAL_COPY(T) (__is_constructible(T, const T &) && __is_trivially_constructible(T, const T &))
153 #   elif BOOST_MOVE_HAS_TRAIT(has_trivial_copy)
154 #     define BOOST_MOVE_HAS_TRIVIAL_COPY(T) __has_trivial_copy(T)
155 #   endif
156 
157 //    BOOST_MOVE_HAS_TRIVIAL_ASSIGN
158 #   if BOOST_MOVE_HAS_TRAIT(is_assignable) && BOOST_MOVE_HAS_TRAIT(is_trivially_assignable)
159 #     define BOOST_MOVE_HAS_TRIVIAL_ASSIGN(T) (__is_assignable(T, const T &) && __is_trivially_assignable(T, const T &))
160 #   elif BOOST_MOVE_HAS_TRAIT(has_trivial_copy)
161 #     define BOOST_MOVE_HAS_TRIVIAL_ASSIGN(T) __has_trivial_assign(T)
162 #   endif
163 
164 //    BOOST_MOVE_HAS_TRIVIAL_DESTRUCTOR
165 #   if BOOST_MOVE_HAS_TRAIT(is_trivially_destructible)
166 #     define BOOST_MOVE_HAS_TRIVIAL_DESTRUCTOR(T) __is_trivially_destructible(T)
167 #   elif BOOST_MOVE_HAS_TRAIT(has_trivial_destructor)
168 #     define BOOST_MOVE_HAS_TRIVIAL_DESTRUCTOR(T) __has_trivial_destructor(T)
169 #   endif
170 
171 //    BOOST_MOVE_HAS_NOTHROW_CONSTRUCTOR
172 #   if BOOST_MOVE_HAS_TRAIT(is_nothrow_constructible)
173 #     define BOOST_MOVE_HAS_NOTHROW_CONSTRUCTOR(T) __is_nothrow_constructible(T)
174 #   elif BOOST_MOVE_HAS_TRAIT(has_nothrow_constructor)
175 #     define BOOST_MOVE_HAS_NOTHROW_CONSTRUCTOR(T) __has_nothrow_constructor(T)
176 #   endif
177 
178 //    BOOST_MOVE_HAS_NOTHROW_COPY
179 #   if BOOST_MOVE_HAS_TRAIT(is_constructible) && BOOST_MOVE_HAS_TRAIT(is_nothrow_constructible)
180 #     define BOOST_MOVE_HAS_NOTHROW_COPY(T) (__is_constructible(T, const T &) && __is_nothrow_constructible(T, const T &))
181 #   elif BOOST_MOVE_HAS_TRAIT(has_nothrow_copy)
182 #     define BOOST_MOVE_HAS_NOTHROW_COPY(T) (__has_nothrow_copy(T))
183 #   endif
184 
185 //    BOOST_MOVE_HAS_NOTHROW_ASSIGN
186 #   if BOOST_MOVE_HAS_TRAIT(is_assignable) && BOOST_MOVE_HAS_TRAIT(is_nothrow_assignable)
187 #     define BOOST_MOVE_HAS_NOTHROW_ASSIGN(T) (__is_assignable(T, const T &) && __is_nothrow_assignable(T, const T &))
188 #   elif BOOST_MOVE_HAS_TRAIT(has_nothrow_assign)
189 #     define BOOST_MOVE_HAS_NOTHROW_ASSIGN(T) (__has_nothrow_assign(T))
190 #   endif
191 
192 //    BOOST_MOVE_HAS_TRIVIAL_MOVE_CONSTRUCTOR
193 #   if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && BOOST_MOVE_HAS_TRAIT(is_constructible) && BOOST_MOVE_HAS_TRAIT(is_trivially_constructible)
194 #     define BOOST_MOVE_HAS_TRIVIAL_MOVE_CONSTRUCTOR(T) (__is_constructible(T, T&&) && __is_trivially_constructible(T, T&&))
195 #   elif BOOST_MOVE_HAS_TRAIT(has_trivial_move_constructor)
196 #     define BOOST_MOVE_HAS_TRIVIAL_MOVE_CONSTRUCTOR(T) __has_trivial_move_constructor(T)
197 #   endif
198 
199 //    BOOST_MOVE_HAS_TRIVIAL_MOVE_ASSIGN
200 #   if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && BOOST_MOVE_HAS_TRAIT(is_assignable) && BOOST_MOVE_HAS_TRAIT(is_trivially_assignable)
201 #     define BOOST_MOVE_HAS_TRIVIAL_MOVE_ASSIGN(T) (__is_assignable(T, T&&) && __is_trivially_assignable(T, T&&))
202 #   elif BOOST_MOVE_HAS_TRAIT(has_trivial_move_assign)
203 #     define BOOST_MOVE_HAS_TRIVIAL_MOVE_ASSIGN(T) __has_trivial_move_assign(T)
204 #   endif
205 
206 //    BOOST_MOVE_HAS_NOTHROW_MOVE_CONSTRUCTOR
207 #   if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && BOOST_MOVE_HAS_TRAIT(is_constructible) && BOOST_MOVE_HAS_TRAIT(is_nothrow_constructible)
208 #     define BOOST_MOVE_HAS_NOTHROW_MOVE_CONSTRUCTOR(T) (__is_constructible(T, T&&) && __is_nothrow_constructible(T, T&&))
209 #   elif BOOST_MOVE_HAS_TRAIT(has_nothrow_move_constructor)
210 #     define BOOST_MOVE_HAS_NOTHROW_MOVE_CONSTRUCTOR(T) __has_nothrow_move_constructor(T)
211 #   endif
212 
213 //    BOOST_MOVE_HAS_NOTHROW_MOVE_ASSIGN
214 #   if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && BOOST_MOVE_HAS_TRAIT(is_assignable) && BOOST_MOVE_HAS_TRAIT(is_nothrow_assignable)
215 #     define BOOST_MOVE_HAS_NOTHROW_MOVE_ASSIGN(T) (__is_assignable(T, T&&) && __is_nothrow_assignable(T, T&&))
216 #   elif BOOST_MOVE_HAS_TRAIT(has_nothrow_move_assign)
217 #     define BOOST_MOVE_HAS_NOTHROW_MOVE_ASSIGN(T) __has_nothrow_move_assign(T)
218 #   endif
219 
220 //    BOOST_MOVE_ALIGNMENT_OF
221 #   define BOOST_MOVE_ALIGNMENT_OF(T) __alignof(T)
222 
223 #endif   //#if defined(BOOST_CLANG)
224 
225 #if defined(__GNUC__) && ((__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 3) && !defined(__GCCXML__))) && !defined(BOOST_CLANG)
226 
227 #ifdef BOOST_INTEL
228 #  define BOOST_MOVE_INTEL_TT_OPTS || ::boost::move_detail::is_pod<T>::value
229 #else
230 #  define BOOST_MOVE_INTEL_TT_OPTS
231 #endif
232 
233 #   define BOOST_MOVE_IS_UNION(T) __is_union(T)
234 #   define BOOST_MOVE_IS_POD(T) __is_pod(T)
235 #   define BOOST_MOVE_IS_EMPTY(T) __is_empty(T)
236 #   define BOOST_MOVE_HAS_TRIVIAL_CONSTRUCTOR(T) ((__has_trivial_constructor(T) BOOST_MOVE_INTEL_TT_OPTS))
237 
238 #   if defined(BOOST_GCC) && (BOOST_GCC > 50000)
239 #     define BOOST_MOVE_HAS_TRIVIAL_COPY(T) (__is_trivially_constructible(T, const T &))
240 #     define BOOST_MOVE_HAS_TRIVIAL_ASSIGN(T) (__is_trivially_assignable(T, const T &))
241 #   else
242 #     define BOOST_MOVE_HAS_TRIVIAL_COPY(T) ((__has_trivial_copy(T) BOOST_MOVE_INTEL_TT_OPTS))
243 #     define BOOST_MOVE_HAS_TRIVIAL_ASSIGN(T) ((__has_trivial_assign(T) BOOST_MOVE_INTEL_TT_OPTS) )
244 #   endif
245 
246 #   define BOOST_MOVE_HAS_TRIVIAL_DESTRUCTOR(T) (__has_trivial_destructor(T) BOOST_MOVE_INTEL_TT_OPTS)
247 #   define BOOST_MOVE_HAS_NOTHROW_CONSTRUCTOR(T) (__has_nothrow_constructor(T) BOOST_MOVE_INTEL_TT_OPTS)
248 #   define BOOST_MOVE_HAS_NOTHROW_COPY(T) ((__has_nothrow_copy(T) BOOST_MOVE_INTEL_TT_OPTS))
249 #   define BOOST_MOVE_HAS_NOTHROW_ASSIGN(T) ((__has_nothrow_assign(T) BOOST_MOVE_INTEL_TT_OPTS))
250 
251 #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && !defined(BOOST_NO_CXX11_SFINAE_EXPR)
252 
253    template <typename T>
254    T && boost_move_tt_declval() BOOST_NOEXCEPT;
255 
256 #  if defined(BOOST_GCC) && (BOOST_GCC >= 80000)
257 // __is_assignable / __is_constructible implemented
258 #     define BOOST_MOVE_IS_ASSIGNABLE(T, U)     __is_assignable(T, U)
259 #     define BOOST_MOVE_IS_CONSTRUCTIBLE(T, U)  __is_constructible(T, U)
260 #  else
261 
262    template<typename Tt, typename Ut>
263    class boost_move_tt_is_assignable
264    {
265       struct twochar {  char dummy[2]; };
266       template < class T
267                , class U
268                , class = decltype(boost_move_tt_declval<T>() = boost_move_tt_declval<U>())
269                > static char test(int);
270 
271       template<class, class> static twochar test(...);
272 
273       public:
274       static const bool value = sizeof(test<Tt, Ut>(0)) == sizeof(char);
275    };
276 
277    template<typename Tt, typename Ut>
278    class boost_move_tt_is_constructible
279    {
280       struct twochar {  char dummy[2]; };
281       template < class T
282                , class U
283                , class = decltype(T(boost_move_tt_declval<U>()))
284                > static char test(int);
285 
286       template<class, class> static twochar test(...);
287 
288       public:
289       static const bool value = sizeof(test<Tt, Ut>(0)) == sizeof(char);
290    };
291 
292 #     define BOOST_MOVE_IS_ASSIGNABLE(T, U)     boost_move_tt_is_assignable<T,U>::value
293 #     define BOOST_MOVE_IS_CONSTRUCTIBLE(T, U)  boost_move_tt_is_constructible<T, U>::value
294 
295 #  endif
296 
297    template <typename T, typename U, bool = BOOST_MOVE_IS_ASSIGNABLE(T, U)>
298    struct boost_move_tt_is_nothrow_assignable
299    {
300       static const bool value = false;
301    };
302 
303    template <typename T, typename U>
304    struct boost_move_tt_is_nothrow_assignable<T, U, true>
305    {
306       #if !defined(BOOST_NO_CXX11_NOEXCEPT)
307       static const bool value = noexcept(boost_move_tt_declval<T>() = boost_move_tt_declval<U>());
308       #else
309       static const bool value = false;
310       #endif
311    };
312 
313    template <typename T, typename U, bool = BOOST_MOVE_IS_CONSTRUCTIBLE(T, U)>
314    struct boost_move_tt_is_nothrow_constructible
315    {
316       static const bool value = false;
317    };
318 
319    template <typename T, typename U>
320    struct boost_move_tt_is_nothrow_constructible<T, U, true>
321    {
322       #if !defined(BOOST_NO_CXX11_NOEXCEPT)
323       static const bool value = noexcept(T(boost_move_tt_declval<U>()));
324       #else
325       static const bool value = false;
326       #endif
327    };
328 
329 #     define BOOST_MOVE_HAS_NOTHROW_MOVE_ASSIGN(T)       boost_move_tt_is_nothrow_assignable<T, T&&>::value
330 #     define BOOST_MOVE_HAS_NOTHROW_MOVE_CONSTRUCTOR(T)  boost_move_tt_is_nothrow_constructible<T, T&&>::value
331 
332 #  endif
333 
334 #   define BOOST_MOVE_IS_ENUM(T) __is_enum(T)
335 
336 // BOOST_MOVE_ALIGNMENT_OF
337 #   if (!defined(unix) && !defined(__unix__)) || defined(__LP64__)
338       // GCC sometimes lies about alignment requirements
339       // of type double on 32-bit unix platforms, use the
340       // old implementation instead in that case:
341 #     define BOOST_MOVE_ALIGNMENT_OF(T) __alignof__(T)
342 #   endif
343 #endif
344 
345 #if defined(__ghs__) && (__GHS_VERSION_NUMBER >= 600)
346 
347 #   define BOOST_MOVE_IS_UNION(T) __is_union(T)
348 #   define BOOST_MOVE_IS_POD(T) __is_pod(T)
349 #   define BOOST_MOVE_IS_EMPTY(T) __is_empty(T)
350 #   define BOOST_MOVE_HAS_TRIVIAL_CONSTRUCTOR(T) __has_trivial_constructor(T)
351 #   define BOOST_MOVE_HAS_TRIVIAL_COPY(T) (__has_trivial_copy(T))
352 #   define BOOST_MOVE_HAS_TRIVIAL_ASSIGN(T) (__has_trivial_assign(T))
353 #   define BOOST_MOVE_HAS_TRIVIAL_DESTRUCTOR(T) __has_trivial_destructor(T)
354 #   define BOOST_MOVE_HAS_NOTHROW_CONSTRUCTOR(T) __has_nothrow_constructor(T)
355 #   define BOOST_MOVE_HAS_NOTHROW_COPY(T) (__has_nothrow_copy(T))
356 #   define BOOST_MOVE_HAS_NOTHROW_ASSIGN(T) (__has_nothrow_assign(T))
357 
358 #   define BOOST_MOVE_IS_ENUM(T) __is_enum(T)
359 #   define BOOST_MOVE_ALIGNMENT_OF(T) __alignof__(T)
360 #endif
361 
362 # if defined(BOOST_CODEGEARC)
363 #   define BOOST_MOVE_IS_UNION(T) __is_union(T)
364 #   define BOOST_MOVE_IS_POD(T) __is_pod(T)
365 #   define BOOST_MOVE_IS_EMPTY(T) __is_empty(T)
366 #   define BOOST_MOVE_HAS_TRIVIAL_CONSTRUCTOR(T) (__has_trivial_default_constructor(T))
367 #   define BOOST_MOVE_HAS_TRIVIAL_COPY(T) (__has_trivial_copy_constructor(T))
368 #   define BOOST_MOVE_HAS_TRIVIAL_ASSIGN(T) (__has_trivial_assign(T))
369 #   define BOOST_MOVE_HAS_TRIVIAL_DESTRUCTOR(T) (__has_trivial_destructor(T))
370 #   define BOOST_MOVE_HAS_NOTHROW_CONSTRUCTOR(T) (__has_nothrow_default_constructor(T))
371 #   define BOOST_MOVE_HAS_NOTHROW_COPY(T) (__has_nothrow_copy_constructor(T))
372 #   define BOOST_MOVE_HAS_NOTHROW_ASSIGN(T) (__has_nothrow_assign(T))
373 
374 #   define BOOST_MOVE_IS_ENUM(T) __is_enum(T)
375 #   define BOOST_MOVE_ALIGNMENT_OF(T) alignof(T)
376 
377 #endif
378 
379 //Fallback definitions
380 
381 #ifdef BOOST_MOVE_IS_UNION
382    #define BOOST_MOVE_IS_UNION_IMPL(T) BOOST_MOVE_IS_UNION(T)
383 #else
384    #define BOOST_MOVE_IS_UNION_IMPL(T) false
385 #endif
386 
387 #ifdef BOOST_MOVE_IS_POD
388    //in some compilers the intrinsic is limited to class types so add scalar and void
389    #define BOOST_MOVE_IS_POD_IMPL(T) (::boost::move_detail::is_scalar<T>::value ||\
390                                       ::boost::move_detail::is_void<T>::value   ||\
391                                        BOOST_MOVE_IS_POD(T))
392 #else
393    #define BOOST_MOVE_IS_POD_IMPL(T) \
394       (::boost::move_detail::is_scalar<T>::value || ::boost::move_detail::is_void<T>::value)
395 #endif
396 
397 #ifdef BOOST_MOVE_IS_EMPTY
398    #define BOOST_MOVE_IS_EMPTY_IMPL(T) BOOST_MOVE_IS_EMPTY(T)
399 #else
400    #define BOOST_MOVE_IS_EMPTY_IMPL(T)    ::boost::move_detail::is_empty_nonintrinsic<T>::value
401 #endif
402 
403 #ifdef BOOST_MOVE_HAS_TRIVIAL_COPY
404    #define BOOST_MOVE_IS_TRIVIALLY_COPY_CONSTRUCTIBLE(T)   ::boost::move_detail::is_pod<T>::value ||\
405                                                           (::boost::move_detail::is_copy_constructible<T>::value &&\
406                                                            BOOST_MOVE_HAS_TRIVIAL_COPY(T))
407 #else
408    #define BOOST_MOVE_IS_TRIVIALLY_COPY_CONSTRUCTIBLE(T)   ::boost::move_detail::is_pod<T>::value
409 #endif
410 
411 #ifdef BOOST_MOVE_HAS_TRIVIAL_CONSTRUCTOR
412    #define BOOST_MOVE_IS_TRIVIALLY_DEFAULT_CONSTRUCTIBLE(T)  BOOST_MOVE_HAS_TRIVIAL_CONSTRUCTOR(T) || ::boost::move_detail::is_pod<T>::value
413 #else
414    #define BOOST_MOVE_IS_TRIVIALLY_DEFAULT_CONSTRUCTIBLE(T)  ::boost::move_detail::is_pod<T>::value
415 #endif
416 
417 #ifdef BOOST_MOVE_HAS_TRIVIAL_MOVE_CONSTRUCTOR
418    #define BOOST_MOVE_IS_TRIVIALLY_MOVE_CONSTRUCTIBLE(T)   BOOST_MOVE_HAS_TRIVIAL_MOVE_CONSTRUCTOR(T) || ::boost::move_detail::is_pod<T>::value
419 #else
420    #define BOOST_MOVE_IS_TRIVIALLY_MOVE_CONSTRUCTIBLE(T)   ::boost::move_detail::is_pod<T>::value
421 #endif
422 
423 #ifdef BOOST_MOVE_HAS_TRIVIAL_ASSIGN
424    #define BOOST_MOVE_IS_TRIVIALLY_COPY_ASSIGNABLE(T) ::boost::move_detail::is_pod<T>::value ||\
425                                                       ( ::boost::move_detail::is_copy_assignable<T>::value &&\
426                                                          BOOST_MOVE_HAS_TRIVIAL_ASSIGN(T))
427 #else
428    #define BOOST_MOVE_IS_TRIVIALLY_COPY_ASSIGNABLE(T) ::boost::move_detail::is_pod<T>::value
429 #endif
430 
431 #ifdef BOOST_MOVE_HAS_TRIVIAL_MOVE_ASSIGN
432    #define BOOST_MOVE_IS_TRIVIALLY_MOVE_ASSIGNABLE(T)  BOOST_MOVE_HAS_TRIVIAL_MOVE_ASSIGN(T) || ::boost::move_detail::is_pod<T>::value
433 #else
434    #define BOOST_MOVE_IS_TRIVIALLY_MOVE_ASSIGNABLE(T)  ::boost::move_detail::is_pod<T>::value
435 #endif
436 
437 #ifdef BOOST_MOVE_HAS_TRIVIAL_DESTRUCTOR
438    #define BOOST_MOVE_IS_TRIVIALLY_DESTRUCTIBLE(T)   BOOST_MOVE_HAS_TRIVIAL_DESTRUCTOR(T) || ::boost::move_detail::is_pod<T>::value
439 #else
440    #define BOOST_MOVE_IS_TRIVIALLY_DESTRUCTIBLE(T)   ::boost::move_detail::is_pod<T>::value
441 #endif
442 
443 #ifdef BOOST_MOVE_HAS_NOTHROW_CONSTRUCTOR
444    #define BOOST_MOVE_IS_NOTHROW_DEFAULT_CONSTRUCTIBLE(T)  BOOST_MOVE_HAS_NOTHROW_CONSTRUCTOR(T) || ::boost::move_detail::is_pod<T>::value
445 #else
446    #define BOOST_MOVE_IS_NOTHROW_DEFAULT_CONSTRUCTIBLE(T)  ::boost::move_detail::is_pod<T>::value
447 #endif
448 
449 #ifdef BOOST_MOVE_HAS_NOTHROW_COPY
450    #define BOOST_MOVE_IS_NOTHROW_COPY_CONSTRUCTIBLE(T)   BOOST_MOVE_HAS_NOTHROW_COPY(T) || ::boost::move_detail::is_pod<T>::value
451 #else
452    #define BOOST_MOVE_IS_NOTHROW_COPY_CONSTRUCTIBLE(T)   BOOST_MOVE_IS_TRIVIALLY_COPY_ASSIGNABLE(T)
453 #endif
454 
455 #ifdef BOOST_MOVE_HAS_NOTHROW_ASSIGN
456    #define BOOST_MOVE_IS_NOTHROW_COPY_ASSIGNABLE(T) BOOST_MOVE_HAS_NOTHROW_ASSIGN(T) || ::boost::move_detail::is_pod<T>::value
457 #else
458    #define BOOST_MOVE_IS_NOTHROW_COPY_ASSIGNABLE(T) BOOST_MOVE_IS_TRIVIALLY_COPY_ASSIGNABLE(T)
459 #endif
460 
461 #ifdef BOOST_MOVE_HAS_NOTHROW_MOVE_CONSTRUCTOR
462    #define BOOST_MOVE_IS_NOTHROW_MOVE_CONSTRUCTIBLE(T)   BOOST_MOVE_HAS_NOTHROW_MOVE_CONSTRUCTOR(T) || ::boost::move_detail::is_pod<T>::value
463 #else
464    #define BOOST_MOVE_IS_NOTHROW_MOVE_CONSTRUCTIBLE(T)   BOOST_MOVE_IS_TRIVIALLY_MOVE_ASSIGNABLE(T)
465 #endif
466 
467 #ifdef BOOST_MOVE_HAS_NOTHROW_MOVE_ASSIGN
468    #define BOOST_MOVE_IS_NOTHROW_MOVE_ASSIGNABLE(T) BOOST_MOVE_HAS_NOTHROW_MOVE_ASSIGN(T) || ::boost::move_detail::is_pod<T>::value
469 #else
470    #define BOOST_MOVE_IS_NOTHROW_MOVE_ASSIGNABLE(T) BOOST_MOVE_IS_TRIVIALLY_MOVE_ASSIGNABLE(T)
471 #endif
472 
473 #ifdef BOOST_MOVE_IS_ENUM
474    #define BOOST_MOVE_IS_ENUM_IMPL(T)   BOOST_MOVE_IS_ENUM(T)
475 #else
476    #define BOOST_MOVE_IS_ENUM_IMPL(T)   ::boost::move_detail::is_enum_nonintrinsic<T>::value
477 #endif
478 
479 namespace boost {
480 namespace move_detail {
481 
482 //////////////////////////
483 //    is_reference
484 //////////////////////////
485 template<class T>
486 struct is_reference
487 {  static const bool value = false; };
488 
489 template<class T>
490 struct is_reference<T&>
491 {  static const bool value = true; };
492 
493 #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
494 template<class T>
495 struct is_reference<T&&>
496 {  static const bool value = true; };
497 #endif
498 
499 //////////////////////////
500 //    is_pointer
501 //////////////////////////
502 template<class T>
503 struct is_pointer
504 {  static const bool value = false; };
505 
506 template<class T>
507 struct is_pointer<T*>
508 {  static const bool value = true; };
509 
510 //////////////////////////
511 //       is_const
512 //////////////////////////
513 template<class T>
514 struct is_const
515 {  static const bool value = false; };
516 
517 template<class T>
518 struct is_const<const T>
519 {  static const bool value = true; };
520 
521 //////////////////////////
522 //       unvoid_ref
523 //////////////////////////
524 template <typename T> struct unvoid_ref : add_lvalue_reference<T>{};
525 template <> struct unvoid_ref<void>                { typedef unvoid_ref & type; };
526 template <> struct unvoid_ref<const void>          { typedef unvoid_ref & type; };
527 template <> struct unvoid_ref<volatile void>       { typedef unvoid_ref & type; };
528 template <> struct unvoid_ref<const volatile void> { typedef unvoid_ref & type; };
529 
530 template <typename T>
531 struct add_reference : add_lvalue_reference<T>
532 {};
533 
534 //////////////////////////
535 //    add_const_reference
536 //////////////////////////
537 template <class T>
538 struct add_const_reference
539 {  typedef const T &type;   };
540 
541 template <class T>
542 struct add_const_reference<T&>
543 {  typedef T& type;   };
544 
545 //////////////////////////
546 //    add_const_if_c
547 //////////////////////////
548 template<class T, bool Add>
549 struct add_const_if_c
550    : if_c<Add, typename add_const<T>::type, T>
551 {};
552 
553 //////////////////////////
554 //    remove_const
555 //////////////////////////
556 template<class T>
557 struct remove_const
558 {  typedef T type;   };
559 
560 template<class T>
561 struct remove_const< const T>
562 {  typedef T type;   };
563 
564 //////////////////////////
565 //    remove_cv
566 //////////////////////////
567 template<typename T> struct remove_cv                    {  typedef T type;   };
568 template<typename T> struct remove_cv<const T>           {  typedef T type;   };
569 template<typename T> struct remove_cv<const volatile T>  {  typedef T type;   };
570 template<typename T> struct remove_cv<volatile T>        {  typedef T type;   };
571 
572 //////////////////////////
573 //    remove_cvref
574 //////////////////////////
575 template<class T>
576 struct remove_cvref
577    : remove_cv<typename remove_reference<T>::type>
578 {
579 };
580 
581 //////////////////////////
582 //    make_unsigned
583 //////////////////////////
584 template <class T>
585 struct make_unsigned_impl                                         {  typedef T type;   };
586 template <> struct make_unsigned_impl<signed char>                {  typedef unsigned char  type; };
587 template <> struct make_unsigned_impl<signed short>               {  typedef unsigned short type; };
588 template <> struct make_unsigned_impl<signed int>                 {  typedef unsigned int   type; };
589 template <> struct make_unsigned_impl<signed long>                {  typedef unsigned long  type; };
590 #ifdef BOOST_HAS_LONG_LONG
591 template <> struct make_unsigned_impl< ::boost::long_long_type >  {  typedef ::boost::ulong_long_type type; };
592 #endif
593 
594 template <class T>
595 struct make_unsigned
596    : make_unsigned_impl<typename remove_cv<T>::type>
597 {};
598 
599 //////////////////////////
600 //    is_floating_point
601 //////////////////////////
602 template<class T> struct is_floating_point_cv               {  static const bool value = false; };
603 template<>        struct is_floating_point_cv<float>        {  static const bool value = true; };
604 template<>        struct is_floating_point_cv<double>       {  static const bool value = true; };
605 template<>        struct is_floating_point_cv<long double>  {  static const bool value = true; };
606 
607 template<class T>
608 struct is_floating_point
609    : is_floating_point_cv<typename remove_cv<T>::type>
610 {};
611 
612 //////////////////////////
613 //    is_integral
614 //////////////////////////
615 template<class T> struct is_integral_cv                    {  static const bool value = false; };
616 template<> struct is_integral_cv<                     bool>{  static const bool value = true; };
617 template<> struct is_integral_cv<                     char>{  static const bool value = true; };
618 template<> struct is_integral_cv<            unsigned char>{  static const bool value = true; };
619 template<> struct is_integral_cv<              signed char>{  static const bool value = true; };
620 #ifndef BOOST_NO_CXX11_CHAR16_T
621 template<> struct is_integral_cv<                 char16_t>{  static const bool value = true; };
622 #endif
623 #ifndef BOOST_NO_CXX11_CHAR32_T
624 template<> struct is_integral_cv<                 char32_t>{  static const bool value = true; };
625 #endif
626 #ifndef BOOST_NO_INTRINSIC_WCHAR_T
627 template<> struct is_integral_cv<                  wchar_t>{  static const bool value = true; };
628 #endif
629 template<> struct is_integral_cv<                    short>{  static const bool value = true; };
630 template<> struct is_integral_cv<           unsigned short>{  static const bool value = true; };
631 template<> struct is_integral_cv<                      int>{  static const bool value = true; };
632 template<> struct is_integral_cv<             unsigned int>{  static const bool value = true; };
633 template<> struct is_integral_cv<                     long>{  static const bool value = true; };
634 template<> struct is_integral_cv<            unsigned long>{  static const bool value = true; };
635 #ifdef BOOST_HAS_LONG_LONG
636 template<> struct is_integral_cv< ::boost:: long_long_type>{  static const bool value = true; };
637 template<> struct is_integral_cv< ::boost::ulong_long_type>{  static const bool value = true; };
638 #endif
639 
640 template<class T>
641 struct is_integral
642    : public is_integral_cv<typename remove_cv<T>::type>
643 {};
644 
645 //////////////////////////////////////
646 //          remove_all_extents
647 //////////////////////////////////////
648 template <class T>
649 struct remove_all_extents
650 {  typedef T type;};
651 
652 template <class T>
653 struct remove_all_extents<T[]>
654 {  typedef typename remove_all_extents<T>::type type; };
655 
656 template <class T, std::size_t N>
657 struct remove_all_extents<T[N]>
658 {  typedef typename remove_all_extents<T>::type type;};
659 
660 //////////////////////////
661 //    is_scalar
662 //////////////////////////
663 template<class T>
664 struct is_scalar
665 {  static const bool value = is_integral<T>::value || is_floating_point<T>::value; };
666 
667 //////////////////////////
668 //       is_void
669 //////////////////////////
670 template<class T>
671 struct is_void_cv
672 {  static const bool value = false; };
673 
674 template<>
675 struct is_void_cv<void>
676 {  static const bool value = true; };
677 
678 template<class T>
679 struct is_void
680    : is_void_cv<typename remove_cv<T>::type>
681 {};
682 
683 //////////////////////////////////////
684 //          is_array
685 //////////////////////////////////////
686 template<class T>
687 struct is_array
688 {  static const bool value = false; };
689 
690 template<class T>
691 struct is_array<T[]>
692 {  static const bool value = true;  };
693 
694 template<class T, std::size_t N>
695 struct is_array<T[N]>
696 {  static const bool value = true;  };
697 
698 //////////////////////////////////////
699 //           is_member_pointer
700 //////////////////////////////////////
701 template <class T>         struct is_member_pointer_cv         {  static const bool value = false; };
702 template <class T, class U>struct is_member_pointer_cv<T U::*> {  static const bool value = true; };
703 
704 template <class T>
705 struct is_member_pointer
706     : is_member_pointer_cv<typename remove_cv<T>::type>
707 {};
708 
709 //////////////////////////////////////
710 //          is_nullptr_t
711 //////////////////////////////////////
712 template <class T>
713 struct is_nullptr_t_cv
714 {  static const bool value = false; };
715 
716 #if !defined(BOOST_NO_CXX11_NULLPTR)
717 template <>
718 struct is_nullptr_t_cv
719    #if !defined(BOOST_NO_CXX11_DECLTYPE)
720    <decltype(nullptr)>
721    #else
722    <std::nullptr_t>
723    #endif
724 {  static const bool value = true; };
725 #endif
726 
727 template <class T>
728 struct is_nullptr_t
729    : is_nullptr_t_cv<typename remove_cv<T>::type>
730 {};
731 
732 //////////////////////////////////////
733 //          is_function
734 //////////////////////////////////////
735 //Inspired by libc++, thanks to Howard Hinnant
736 //For a function to pointer an lvalue of function type T can be implicitly converted to a prvalue
737 //pointer to that function. This does not apply to non-static member functions because lvalues
738 //that refer to non-static member functions do not exist.
739 template <class T>
740 struct is_reference_convertible_to_pointer
741 {
742    struct twochar { char dummy[2]; };
743    template <class U> static char    test(U*);
744    template <class U> static twochar test(...);
745    static T& source();
746    static const bool value = sizeof(char) == sizeof(test<T>(source()));
747 };
748 //Filter out:
749 // - class types that might have implicit conversions
750 // - void (to avoid forming a reference to void later)
751 // - references (e.g.: filtering reference to functions)
752 // - nullptr_t (convertible to pointer)
753 template < class T
754          , bool Filter = is_class_or_union<T>::value  ||
755                          is_void<T>::value            ||
756                          is_reference<T>::value       ||
757                          is_nullptr_t<T>::value       >
758 struct is_function_impl
759 {  static const bool value = is_reference_convertible_to_pointer<T>::value; };
760 
761 template <class T>
762 struct is_function_impl<T, true>
763 {  static const bool value = false; };
764 
765 template <class T>
766 struct is_function
767    : is_function_impl<T>
768 {};
769 
770 //////////////////////////////////////
771 //       is_union
772 //////////////////////////////////////
773 template<class T>
774 struct is_union_noextents_cv
775 {  static const bool value = BOOST_MOVE_IS_UNION_IMPL(T); };
776 
777 template<class T>
778 struct is_union
779    : is_union_noextents_cv<typename remove_cv<typename remove_all_extents<T>::type>::type>
780 {};
781 
782 //////////////////////////////////////
783 //             is_class
784 //////////////////////////////////////
785 template <class T>
786 struct is_class
787 {
788    static const bool value = is_class_or_union<T>::value && ! is_union<T>::value;
789 };
790 
791 
792 //////////////////////////////////////
793 //             is_arithmetic
794 //////////////////////////////////////
795 template <class T>
796 struct is_arithmetic
797 {
798    static const bool value = is_floating_point<T>::value ||
799                              is_integral<T>::value;
800 };
801 
802 //////////////////////////////////////
803 //    is_member_function_pointer
804 //////////////////////////////////////
805 template <class T>
806 struct is_member_function_pointer_cv
807 {
808    static const bool value = false;
809 };
810 
811 template <class T, class C>
812 struct is_member_function_pointer_cv<T C::*>
813    : is_function<T>
814 {};
815 
816 template <class T>
817 struct is_member_function_pointer
818     : is_member_function_pointer_cv<typename remove_cv<T>::type>
819 {};
820 
821 //////////////////////////////////////
822 //             is_enum
823 //////////////////////////////////////
824 #if !defined(BOOST_MOVE_IS_ENUM)
825 //Based on (http://howardhinnant.github.io/TypeHiearchy.pdf)
826 template <class T>
827 struct is_enum_nonintrinsic
828 {
829    static const bool value =  !is_arithmetic<T>::value     &&
830                               !is_reference<T>::value      &&
831                               !is_class_or_union<T>::value &&
832                               !is_array<T>::value          &&
833                               !is_void<T>::value           &&
834                               !is_nullptr_t<T>::value      &&
835                               !is_member_pointer<T>::value &&
836                               !is_pointer<T>::value        &&
837                               !is_function<T>::value;
838 };
839 #endif
840 
841 template <class T>
842 struct is_enum
843 {  static const bool value = BOOST_MOVE_IS_ENUM_IMPL(T);  };
844 
845 //////////////////////////////////////
846 //       is_pod
847 //////////////////////////////////////
848 template<class T>
849 struct is_pod_noextents_cv  //for non-c++11 compilers, a safe fallback
850 {  static const bool value = BOOST_MOVE_IS_POD_IMPL(T); };
851 
852 template<class T>
853 struct is_pod
854    : is_pod_noextents_cv<typename remove_cv<typename remove_all_extents<T>::type>::type>
855 {};
856 
857 //////////////////////////////////////
858 //             is_empty
859 //////////////////////////////////////
860 #if !defined(BOOST_MOVE_IS_EMPTY)
861 
862 template <typename T>
863 struct empty_helper_t1 : public T
864 {
865    empty_helper_t1();  // hh compiler bug workaround
866    int i[256];
867    private:
868 
869    empty_helper_t1(const empty_helper_t1&);
870    empty_helper_t1& operator=(const empty_helper_t1&);
871 };
872 
873 struct empty_helper_t2 { int i[256]; };
874 
875 template <typename T, bool IsClass = is_class<T>::value >
876 struct is_empty_nonintrinsic
877 {
878    static const bool value = false;
879 };
880 
881 template <typename T>
882 struct is_empty_nonintrinsic<T, true>
883 {
884    static const bool value = sizeof(empty_helper_t1<T>) == sizeof(empty_helper_t2);
885 };
886 #endif
887 
888 template <class T>
889 struct is_empty
890 {  static const bool value = BOOST_MOVE_IS_EMPTY_IMPL(T);  };
891 
892 
893 template<class T>
894 struct has_boost_move_no_copy_constructor_or_assign_type
895 {
896    template <class U>
897    static yes_type test(typename U::boost_move_no_copy_constructor_or_assign*);
898 
899    template <class U>
900    static no_type test(...);
901 
902    static const bool value = sizeof(test<T>(0)) == sizeof(yes_type);
903 };
904 
905 //////////////////////////////////////
906 //       is_copy_constructible
907 //////////////////////////////////////
908 #if !defined(BOOST_NO_CXX11_DELETED_FUNCTIONS) && !defined(BOOST_NO_CXX11_DECLTYPE) \
909    && !defined(BOOST_INTEL_CXX_VERSION) && \
910       !(defined(BOOST_MSVC) && _MSC_VER == 1800)
911 #define BOOST_MOVE_TT_CXX11_IS_COPY_CONSTRUCTIBLE
912 #endif
913 
914 template<class T>
915 struct is_copy_constructible
916 {
917    // Intel compiler has problems with SFINAE for copy constructors and deleted functions:
918    //
919    // error: function *function_name* cannot be referenced -- it is a deleted function
920    // static yes_type test(U&, decltype(U(boost::declval<U&>()))* = 0);
921    //                                                        ^
922    // MSVC 12.0 (Visual 2013) has problems when the copy constructor has been deleted. See:
923    // https://connect.microsoft.com/VisualStudio/feedback/details/800328/std-is-copy-constructible-is-broken
924    #if defined(BOOST_MOVE_TT_CXX11_IS_COPY_CONSTRUCTIBLE)
925       template<class U> static typename add_reference<U>::type source();
926       static no_type test(...);
927       #ifdef BOOST_NO_CXX11_DECLTYPE
928          template <class U>
929          static yes_type test(U&, bool_<sizeof(U(source<U>()))>* = 0);
930       #else
931          template <class U>
932          static yes_type test(U&, decltype(U(source<U>()))* = 0);
933       #endif
934       static const bool value = sizeof(test(source<T>())) == sizeof(yes_type);
935    #else
936    static const bool value = !has_boost_move_no_copy_constructor_or_assign_type<T>::value;
937    #endif
938 };
939 
940 
941 //////////////////////////////////////
942 //       is_copy_assignable
943 //////////////////////////////////////
944 #if !defined(BOOST_NO_CXX11_DELETED_FUNCTIONS) && !defined(BOOST_NO_CXX11_DECLTYPE) \
945    && !defined(BOOST_INTEL_CXX_VERSION) && \
946       !(defined(BOOST_MSVC) && _MSC_VER == 1800)
947 #define BOOST_MOVE_TT_CXX11_IS_COPY_ASSIGNABLE
948 #endif
949 
950 template <class T>
951 struct is_copy_assignable
952 {
953 // Intel compiler has problems with SFINAE for copy constructors and deleted functions:
954 //
955 // error: function *function_name* cannot be referenced -- it is a deleted function
956 // static boost::type_traits::yes_type test(T1&, decltype(T1(boost::declval<T1&>()))* = 0);
957 //                                                        ^
958 //
959 // MSVC 12.0 (Visual 2013) has problems when the copy constructor has been deleted. See:
960 // https://connect.microsoft.com/VisualStudio/feedback/details/800328/std-is-copy-constructible-is-broken
961 #if defined(BOOST_MOVE_TT_CXX11_IS_COPY_ASSIGNABLE)
962    typedef char yes_type;
963    struct no_type { char dummy[2]; };
964 
965    template <class U>   static typename add_reference<U>::type source();
966    template <class U>   static decltype(source<U&>() = source<const U&>(), yes_type() ) test(int);
967    template <class>     static no_type test(...);
968 
969    static const bool value = sizeof(test<T>(0)) == sizeof(yes_type);
970 #else
971    static const bool value = !has_boost_move_no_copy_constructor_or_assign_type<T>::value;
972 #endif
973 };
974 
975 //////////////////////////////////////
976 //       is_trivially_destructible
977 //////////////////////////////////////
978 template<class T>
979 struct is_trivially_destructible
980 {  static const bool value = BOOST_MOVE_IS_TRIVIALLY_DESTRUCTIBLE(T); };
981 
982 //////////////////////////////////////
983 //       is_trivially_default_constructible
984 //////////////////////////////////////
985 template<class T>
986 struct is_trivially_default_constructible
987 {  static const bool value = BOOST_MOVE_IS_TRIVIALLY_DEFAULT_CONSTRUCTIBLE(T); };
988 
989 //////////////////////////////////////
990 //       is_trivially_copy_constructible
991 //////////////////////////////////////
992 template<class T>
993 struct is_trivially_copy_constructible
994 {
995    static const bool value = BOOST_MOVE_IS_TRIVIALLY_COPY_CONSTRUCTIBLE(T);
996 };
997 
998 //////////////////////////////////////
999 //       is_trivially_move_constructible
1000 //////////////////////////////////////
1001 template<class T>
1002 struct is_trivially_move_constructible
1003 { static const bool value = BOOST_MOVE_IS_TRIVIALLY_MOVE_CONSTRUCTIBLE(T); };
1004 
1005 //////////////////////////////////////
1006 //       is_trivially_copy_assignable
1007 //////////////////////////////////////
1008 template<class T>
1009 struct is_trivially_copy_assignable
1010 {
1011    static const bool value = BOOST_MOVE_IS_TRIVIALLY_COPY_ASSIGNABLE(T);
1012 };
1013 
1014 //////////////////////////////////////
1015 //       is_trivially_move_assignable
1016 //////////////////////////////////////
1017 template<class T>
1018 struct is_trivially_move_assignable
1019 {  static const bool value = BOOST_MOVE_IS_TRIVIALLY_MOVE_ASSIGNABLE(T);  };
1020 
1021 //////////////////////////////////////
1022 //       is_nothrow_default_constructible
1023 //////////////////////////////////////
1024 template<class T>
1025 struct is_nothrow_default_constructible
1026 {  static const bool value = BOOST_MOVE_IS_NOTHROW_DEFAULT_CONSTRUCTIBLE(T);  };
1027 
1028 //////////////////////////////////////
1029 //    is_nothrow_copy_constructible
1030 //////////////////////////////////////
1031 template<class T>
1032 struct is_nothrow_copy_constructible
1033 {  static const bool value = BOOST_MOVE_IS_NOTHROW_COPY_CONSTRUCTIBLE(T);  };
1034 
1035 //////////////////////////////////////
1036 //    is_nothrow_move_constructible
1037 //////////////////////////////////////
1038 template<class T>
1039 struct is_nothrow_move_constructible
1040 {  static const bool value = BOOST_MOVE_IS_NOTHROW_MOVE_CONSTRUCTIBLE(T);  };
1041 
1042 //////////////////////////////////////
1043 //       is_nothrow_copy_assignable
1044 //////////////////////////////////////
1045 template<class T>
1046 struct is_nothrow_copy_assignable
1047 {  static const bool value = BOOST_MOVE_IS_NOTHROW_COPY_ASSIGNABLE(T);  };
1048 
1049 //////////////////////////////////////
1050 //    is_nothrow_move_assignable
1051 //////////////////////////////////////
1052 template<class T>
1053 struct is_nothrow_move_assignable
1054 {  static const bool value = BOOST_MOVE_IS_NOTHROW_MOVE_ASSIGNABLE(T);  };
1055 
1056 //////////////////////////////////////
1057 //    is_nothrow_swappable
1058 //////////////////////////////////////
1059 template<class T>
1060 struct is_nothrow_swappable
1061 {
1062    static const bool value = is_empty<T>::value || is_pod<T>::value;
1063 };
1064 
1065 //////////////////////////////////////
1066 //       alignment_of
1067 //////////////////////////////////////
1068 template <typename T>
1069 struct alignment_of_hack
1070 {
1071    T t1;
1072    char c;
1073    T t2;
1074    alignment_of_hack();
1075    ~alignment_of_hack();
1076 };
1077 
1078 template <unsigned A, unsigned S>
1079 struct alignment_logic
1080 {  static const std::size_t value = A < S ? A : S; };
1081 
1082 template< typename T >
1083 struct alignment_of_impl
1084 #if defined(BOOST_MSVC) && (BOOST_MSVC >= 1400)
1085     // With MSVC both the native __alignof operator
1086     // and our own logic gets things wrong from time to time :-(
1087     // Using a combination of the two seems to make the most of a bad job:
1088    : alignment_logic< sizeof(alignment_of_hack<T>) - 2*sizeof(T), __alignof(T)>
1089 {};
1090 #elif !defined(BOOST_MOVE_ALIGNMENT_OF)
1091    : alignment_logic< sizeof(alignment_of_hack<T>) - 2*sizeof(T), sizeof(T)>
1092 {};
1093 #else
1094 {  static const std::size_t value = BOOST_MOVE_ALIGNMENT_OF(T);  };
1095 #endif
1096 
1097 template< typename T >
1098 struct alignment_of
1099    : alignment_of_impl<T>
1100 {};
1101 
1102 class alignment_dummy;
1103 typedef void (*function_ptr)();
1104 typedef int (alignment_dummy::*member_ptr);
1105 typedef int (alignment_dummy::*member_function_ptr)();
1106 struct alignment_struct
1107 {  long double dummy[4];  };
1108 
1109 /////////////////////////////
1110 //    max_align_t
1111 /////////////////////////////
1112 //This is not standard, but should work with all compilers
1113 union max_align
1114 {
1115    char        char_;
1116    short       short_;
1117    int         int_;
1118    long        long_;
1119    #ifdef BOOST_HAS_LONG_LONG
1120    ::boost::long_long_type   long_long_;
1121    #endif
1122    float       float_;
1123    double      double_;
1124    void *      void_ptr_;
1125    long double long_double_[4];
1126    alignment_dummy *unknown_class_ptr_;
1127    function_ptr function_ptr_;
1128    member_function_ptr member_function_ptr_;
1129    alignment_struct alignment_struct_;
1130 };
1131 
1132 typedef union max_align max_align_t;
1133 
1134 /////////////////////////////
1135 //    aligned_storage
1136 /////////////////////////////
1137 
1138 #if defined(_MSC_VER) && defined(_M_IX86)
1139 
1140 // Special version for usual alignments on x86 MSVC because it might crash
1141 // when passsing aligned types by value even for 8 byte alignment.
1142 template<std::size_t Align>
1143 struct aligned_struct;
1144 
1145 template <> struct aligned_struct<1> { char data; };
1146 template <> struct aligned_struct<2> { short data; };
1147 template <> struct aligned_struct<4> { int data; };
1148 template <> struct aligned_struct<8> { double data; };
1149 
1150 #define BOOST_MOVE_ALIGNED_STRUCT(x) \
1151   template <> struct aligned_struct<x> { \
1152     __declspec(align(x)) char data; \
1153   }
1154 BOOST_MOVE_ALIGNED_STRUCT(16);
1155 BOOST_MOVE_ALIGNED_STRUCT(32);
1156 BOOST_MOVE_ALIGNED_STRUCT(64);
1157 BOOST_MOVE_ALIGNED_STRUCT(128);
1158 BOOST_MOVE_ALIGNED_STRUCT(512);
1159 BOOST_MOVE_ALIGNED_STRUCT(1024);
1160 BOOST_MOVE_ALIGNED_STRUCT(2048);
1161 BOOST_MOVE_ALIGNED_STRUCT(4096);
1162 
1163 template<std::size_t Len, std::size_t Align>
1164 union aligned_union
1165 {
1166    typedef aligned_struct<Align> aligner_t;
1167    aligner_t aligner;
1168    unsigned char data[Len > sizeof(aligner_t) ? Len : sizeof(aligner_t)];
1169 };
1170 
1171 template<std::size_t Len, std::size_t Align>
1172 struct aligned_storage_impl
1173 {
1174    typedef aligned_union<Len, Align> type;
1175 };
1176 
1177 #elif !defined(BOOST_NO_ALIGNMENT)
1178 
1179 template<std::size_t Len, std::size_t Align>
1180 struct aligned_struct;
1181 
1182 #define BOOST_MOVE_ALIGNED_STORAGE_WITH_BOOST_ALIGNMENT(A)\
1183 template<std::size_t Len>\
1184 struct BOOST_ALIGNMENT(A) aligned_struct<Len, A>\
1185 {\
1186    unsigned char data[Len];\
1187 };\
1188 //
1189 
1190 //Up to 4K alignment (typical page size)
1191 BOOST_MOVE_ALIGNED_STORAGE_WITH_BOOST_ALIGNMENT(0x1)
1192 BOOST_MOVE_ALIGNED_STORAGE_WITH_BOOST_ALIGNMENT(0x2)
1193 BOOST_MOVE_ALIGNED_STORAGE_WITH_BOOST_ALIGNMENT(0x4)
1194 BOOST_MOVE_ALIGNED_STORAGE_WITH_BOOST_ALIGNMENT(0x8)
1195 BOOST_MOVE_ALIGNED_STORAGE_WITH_BOOST_ALIGNMENT(0x10)
1196 BOOST_MOVE_ALIGNED_STORAGE_WITH_BOOST_ALIGNMENT(0x20)
1197 BOOST_MOVE_ALIGNED_STORAGE_WITH_BOOST_ALIGNMENT(0x40)
1198 BOOST_MOVE_ALIGNED_STORAGE_WITH_BOOST_ALIGNMENT(0x80)
1199 BOOST_MOVE_ALIGNED_STORAGE_WITH_BOOST_ALIGNMENT(0x100)
1200 BOOST_MOVE_ALIGNED_STORAGE_WITH_BOOST_ALIGNMENT(0x200)
1201 BOOST_MOVE_ALIGNED_STORAGE_WITH_BOOST_ALIGNMENT(0x400)
1202 BOOST_MOVE_ALIGNED_STORAGE_WITH_BOOST_ALIGNMENT(0x800)
1203 BOOST_MOVE_ALIGNED_STORAGE_WITH_BOOST_ALIGNMENT(0x1000)
1204 
1205 #undef BOOST_MOVE_ALIGNED_STORAGE_WITH_BOOST_ALIGNMENT
1206 
1207 // Workaround for bogus [-Wignored-attributes] warning on GCC 6.x/7.x: don't use a type that "directly" carries the alignment attribute.
1208 // See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82270
1209 template<std::size_t Len, std::size_t Align>
1210 union aligned_struct_wrapper
1211 {
1212    typedef aligned_struct<Len, Align> aligner_t;
1213    aligned_struct<Len, Align> aligner;
1214    unsigned char data[Len > sizeof(aligner_t) ? Len : sizeof(aligner_t)];
1215 };
1216 
1217 template<std::size_t Len, std::size_t Align>
1218 struct aligned_storage_impl
1219 {
1220    typedef aligned_struct_wrapper<Len, Align> type;
1221 };
1222 
1223 #else //BOOST_NO_ALIGNMENT
1224 
1225 template<class T, std::size_t Len>
1226 union aligned_union
1227 {
1228    T aligner;
1229    unsigned char data[Len > sizeof(T) ? Len : sizeof(T)];
1230 };
1231 
1232 template<std::size_t Len, std::size_t Align, class T, bool Ok>
1233 struct aligned_next;
1234 
1235 template<std::size_t Len, std::size_t Align, class T>
1236 struct aligned_next<Len, Align, T, true>
1237 {
1238    BOOST_STATIC_ASSERT((alignment_of<T>::value == Align));
1239    typedef aligned_union<T, Len> type;
1240 };
1241 
1242 //End of search defaults to max_align_t
1243 template<std::size_t Len, std::size_t Align>
1244 struct aligned_next<Len, Align, max_align_t, false>
1245 {   typedef aligned_union<max_align_t, Len> type;   };
1246 
1247 //Now define a search list through types
1248 #define BOOST_MOVE_ALIGNED_NEXT_STEP(TYPE, NEXT_TYPE)\
1249    template<std::size_t Len, std::size_t Align>\
1250    struct aligned_next<Len, Align, TYPE, false>\
1251       : aligned_next<Len, Align, NEXT_TYPE, Align == alignment_of<NEXT_TYPE>::value>\
1252    {};\
1253    //
1254    BOOST_MOVE_ALIGNED_NEXT_STEP(long double, max_align_t)
1255    BOOST_MOVE_ALIGNED_NEXT_STEP(double, long double)
1256    #ifdef BOOST_HAS_LONG_LONG
1257       BOOST_MOVE_ALIGNED_NEXT_STEP(::boost::long_long_type, double)
1258       BOOST_MOVE_ALIGNED_NEXT_STEP(long, ::boost::long_long_type)
1259    #else
1260       BOOST_MOVE_ALIGNED_NEXT_STEP(long, double)
1261    #endif
1262    BOOST_MOVE_ALIGNED_NEXT_STEP(int, long)
1263    BOOST_MOVE_ALIGNED_NEXT_STEP(short, int)
1264    BOOST_MOVE_ALIGNED_NEXT_STEP(char, short)
1265 #undef BOOST_MOVE_ALIGNED_NEXT_STEP
1266 
1267 template<std::size_t Len, std::size_t Align>
1268 struct aligned_storage_impl
1269    : aligned_next<Len, Align, char, Align == alignment_of<char>::value>
1270 {};
1271 
1272 #endif
1273 
1274 template<std::size_t Len, std::size_t Align = alignment_of<max_align_t>::value>
1275 struct aligned_storage
1276 {
1277    //Sanity checks for input parameters
1278    BOOST_STATIC_ASSERT(Align > 0);
1279 
1280    //Sanity checks for output type
1281    typedef typename aligned_storage_impl<Len ? Len : 1, Align>::type type;
1282    static const std::size_t value = alignment_of<type>::value;
1283    BOOST_STATIC_ASSERT(value >= Align);
1284    BOOST_STATIC_ASSERT((value % Align) == 0);
1285 
1286    //Just in case someone instantiates aligned_storage
1287    //instead of aligned_storage::type (typical error).
1288    private:
1289    aligned_storage();
1290 };
1291 
1292 }  //namespace move_detail {
1293 }  //namespace boost {
1294 
1295 #include <boost/move/detail/config_end.hpp>
1296 
1297 #endif   //#ifndef BOOST_MOVE_DETAIL_TYPE_TRAITS_HPP
1298