1 //////////////////////////////////////////////////////////////////////////////
3 // (C) Copyright Ion Gaztanaga 2012-2012.
4 // Distributed under the Boost Software License, Version 1.0.
5 // (See accompanying file LICENSE_1_0.txt or copy at
6 // http://www.boost.org/LICENSE_1_0.txt)
8 // See http://www.boost.org/libs/move for documentation.
10 //////////////////////////////////////////////////////////////////////////////
14 #ifndef BOOST_MOVE_UNIQUE_PTR_DETAIL_META_UTILS_HPP
15 #define BOOST_MOVE_UNIQUE_PTR_DETAIL_META_UTILS_HPP
17 #ifndef BOOST_CONFIG_HPP
18 # include <boost/config.hpp>
21 #if defined(BOOST_HAS_PRAGMA_ONCE)
25 #include <cstddef> //for std::size_t
27 //Small meta-typetraits to support move
34 struct default_delete;
36 } //namespace movelib {
38 #ifdef BOOST_NO_CXX11_RVALUE_REFERENCES
39 //Forward declare boost::rv
40 template <class T> class rv;
45 //////////////////////////////////////
47 //////////////////////////////////////
50 //////////////////////////////////////
52 //////////////////////////////////////
53 template <class T> struct natify{};
55 //////////////////////////////////////
57 //////////////////////////////////////
58 template<bool C, typename T1, typename T2>
64 template<typename T1, typename T2>
65 struct if_c<false,T1,T2>
70 //////////////////////////////////////
72 //////////////////////////////////////
73 template<typename T1, typename T2, typename T3>
74 struct if_ : if_c<0 != T1::value, T2, T3>
78 template <bool B, class T = nat>
84 //////////////////////////////////////
86 //////////////////////////////////////
88 struct enable_if_c<false, T> {};
90 //////////////////////////////////////
92 //////////////////////////////////////
93 template <class Cond, class T = nat>
94 struct enable_if : public enable_if_c<Cond::value, T> {};
96 //////////////////////////////////////
98 //////////////////////////////////////
100 struct remove_reference
106 struct remove_reference<T&>
111 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
114 struct remove_reference<T&&>
122 struct remove_reference< rv<T> >
128 struct remove_reference< rv<T> &>
134 struct remove_reference< const rv<T> &>
142 //////////////////////////////////////
144 //////////////////////////////////////
152 struct remove_const<const T>
157 //////////////////////////////////////
159 //////////////////////////////////////
161 struct remove_volatile
167 struct remove_volatile<volatile T>
172 //////////////////////////////////////
174 //////////////////////////////////////
178 typedef typename remove_volatile
179 <typename remove_const<T>::type>::type type;
182 //////////////////////////////////////
184 //////////////////////////////////////
192 struct remove_extent<T[]>
197 template<class T, std::size_t N>
198 struct remove_extent<T[N]>
203 //////////////////////////////////////
205 //////////////////////////////////////
207 template<class T, unsigned N = 0>
210 static const std::size_t value = 0;
214 struct extent<T[], 0>
216 static const std::size_t value = 0;
219 template<class T, unsigned N>
220 struct extent<T[], N>
222 static const std::size_t value = extent<T, N-1>::value;
225 template<class T, std::size_t N>
226 struct extent<T[N], 0>
228 static const std::size_t value = N;
231 template<class T, std::size_t I, unsigned N>
232 struct extent<T[I], N>
234 static const std::size_t value = extent<T, N-1>::value;
237 //////////////////////////////////////
238 // add_lvalue_reference
239 //////////////////////////////////////
241 struct add_lvalue_reference
247 struct add_lvalue_reference<T&>
253 struct add_lvalue_reference<void>
259 struct add_lvalue_reference<const void>
261 typedef const void type;
265 struct add_lvalue_reference<volatile void>
267 typedef volatile void type;
271 struct add_lvalue_reference<const volatile void>
273 typedef const volatile void type;
277 struct add_const_lvalue_reference
279 typedef typename remove_reference<T>::type t_unreferenced;
280 typedef const t_unreferenced t_unreferenced_const;
281 typedef typename add_lvalue_reference
282 <t_unreferenced_const>::type type;
285 //////////////////////////////////////
287 //////////////////////////////////////
288 template<class T, class U>
291 static const bool value = false;
297 static const bool value = true;
300 //////////////////////////////////////
302 //////////////////////////////////////
306 static const bool value = false;
310 struct is_pointer<T*>
312 static const bool value = true;
315 //////////////////////////////////////
317 //////////////////////////////////////
321 static const bool value = false;
325 struct is_reference<T&>
327 static const bool value = true;
330 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
333 struct is_reference<T&&>
335 static const bool value = true;
340 //////////////////////////////////////
341 // is_lvalue_reference
342 //////////////////////////////////////
344 struct is_lvalue_reference
346 static const bool value = false;
350 struct is_lvalue_reference<T&>
352 static const bool value = true;
355 //////////////////////////////////////
357 //////////////////////////////////////
361 static const bool value = false;
367 static const bool value = true;
370 template<class T, std::size_t N>
371 struct is_array<T[N]>
373 static const bool value = true;
376 //////////////////////////////////////
378 //////////////////////////////////////
380 struct has_pointer_type
382 struct two { char c[2]; };
383 template <class U> static two test(...);
384 template <class U> static char test(typename U::pointer* = 0);
385 static const bool value = sizeof(test<T>(0)) == 1;
388 //////////////////////////////////////
390 //////////////////////////////////////
391 template <class T, class D, bool = has_pointer_type<D>::value>
392 struct pointer_type_imp
394 typedef typename D::pointer type;
397 template <class T, class D>
398 struct pointer_type_imp<T, D, false>
400 typedef typename remove_extent<T>::type* type;
403 template <class T, class D>
406 typedef typename pointer_type_imp
407 <typename remove_extent<T>::type, typename remove_reference<D>::type>::type type;
410 //////////////////////////////////////
412 //////////////////////////////////////
413 #if defined(_MSC_VER) && (_MSC_VER >= 1400)
415 //use intrinsic since in MSVC
416 //overaligned types can't go through ellipsis
417 template <class T, class U>
418 struct is_convertible
420 static const bool value = __is_convertible_to(T, U);
425 template <class T, class U>
428 typedef typename add_lvalue_reference<T>::type t_reference;
430 class false_t { char dummy[2]; };
431 static false_t dispatch(...);
432 static true_t dispatch(U);
433 static t_reference trigger();
435 static const bool value = sizeof(dispatch(trigger())) == sizeof(true_t);
440 //////////////////////////////////////
442 //////////////////////////////////////
443 #if defined(BOOST_MSVC) || defined(__BORLANDC_)
444 #define BOOST_MOVE_TT_DECL __cdecl
446 #define BOOST_MOVE_TT_DECL
449 #if defined(_MSC_EXTENSIONS) && !defined(__BORLAND__) && !defined(_WIN64) && !defined(_M_ARM) && !defined(UNDER_CE)
450 #define BOOST_MOVE_TT_TEST_MSC_FUNC_SIGS
453 template <typename T>
454 struct is_unary_function_impl
455 { static const bool value = false; };
457 // avoid duplicate definitions of is_unary_function_impl
458 #ifndef BOOST_MOVE_TT_TEST_MSC_FUNC_SIGS
460 template <typename R>
461 struct is_unary_function_impl<R (*)()>
462 { static const bool value = true; };
464 template <typename R>
465 struct is_unary_function_impl<R (*)(...)>
466 { static const bool value = true; };
468 #else // BOOST_MOVE_TT_TEST_MSC_FUNC_SIGS
470 template <typename R>
471 struct is_unary_function_impl<R (__stdcall*)()>
472 { static const bool value = true; };
476 template <typename R>
477 struct is_unary_function_impl<R (__fastcall*)()>
478 { static const bool value = true; };
482 template <typename R>
483 struct is_unary_function_impl<R (__cdecl*)()>
484 { static const bool value = true; };
486 template <typename R>
487 struct is_unary_function_impl<R (__cdecl*)(...)>
488 { static const bool value = true; };
492 // avoid duplicate definitions of is_unary_function_impl
493 #ifndef BOOST_MOVE_TT_TEST_MSC_FUNC_SIGS
495 template <typename R, class T0>
496 struct is_unary_function_impl<R (*)(T0)>
497 { static const bool value = true; };
499 template <typename R, class T0>
500 struct is_unary_function_impl<R (*)(T0...)>
501 { static const bool value = true; };
503 #else // BOOST_MOVE_TT_TEST_MSC_FUNC_SIGS
505 template <typename R, class T0>
506 struct is_unary_function_impl<R (__stdcall*)(T0)>
507 { static const bool value = true; };
511 template <typename R, class T0>
512 struct is_unary_function_impl<R (__fastcall*)(T0)>
513 { static const bool value = true; };
517 template <typename R, class T0>
518 struct is_unary_function_impl<R (__cdecl*)(T0)>
519 { static const bool value = true; };
521 template <typename R, class T0>
522 struct is_unary_function_impl<R (__cdecl*)(T0...)>
523 { static const bool value = true; };
527 template <typename T>
528 struct is_unary_function_impl<T&>
529 { static const bool value = false; };
532 struct is_unary_function
533 { static const bool value = is_unary_function_impl<T>::value; };
535 //////////////////////////////////////
536 // has_virtual_destructor
537 //////////////////////////////////////
538 #if (defined(BOOST_MSVC) && defined(BOOST_MSVC_FULL_VER) && (BOOST_MSVC_FULL_VER >=140050215))\
539 || (defined(BOOST_INTEL) && defined(_MSC_VER) && (_MSC_VER >= 1500))
540 # define BOOST_MOVEUP_HAS_VIRTUAL_DESTRUCTOR(T) __has_virtual_destructor(T)
541 #elif defined(BOOST_CLANG) && defined(__has_feature)
542 # if __has_feature(has_virtual_destructor)
543 # define BOOST_MOVEUP_HAS_VIRTUAL_DESTRUCTOR(T) __has_virtual_destructor(T)
545 #elif defined(__GNUC__) && ((__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 3) && !defined(__GCCXML__))) && !defined(BOOST_CLANG)
546 # define BOOST_MOVEUP_HAS_VIRTUAL_DESTRUCTOR(T) __has_virtual_destructor(T)
547 #elif defined(__ghs__) && (__GHS_VERSION_NUMBER >= 600)
548 # define BOOST_MOVEUP_HAS_VIRTUAL_DESTRUCTOR(T) __has_virtual_destructor(T)
549 #elif defined(__CODEGEARC__)
550 # define BOOST_MOVEUP_HAS_VIRTUAL_DESTRUCTOR(T) __has_virtual_destructor(T)
553 #ifdef BOOST_MOVEUP_HAS_VIRTUAL_DESTRUCTOR
555 struct has_virtual_destructor{ static const bool value = BOOST_MOVEUP_HAS_VIRTUAL_DESTRUCTOR(T); };
557 //If no intrinsic is available you trust the programmer knows what is doing
559 struct has_virtual_destructor{ static const bool value = true; };
562 //////////////////////////////////////
563 // missing_virtual_destructor
564 //////////////////////////////////////
566 template< class T, class U
567 , bool enable = is_convertible< U*, T*>::value &&
568 !is_array<T>::value &&
569 !is_same<typename remove_cv<T>::type, void>::value &&
570 !is_same<typename remove_cv<U>::type, typename remove_cv<T>::type>::value
572 struct missing_virtual_destructor_default_delete
573 { static const bool value = !has_virtual_destructor<T>::value; };
575 template<class T, class U>
576 struct missing_virtual_destructor_default_delete<T, U, false>
577 { static const bool value = false; };
579 template<class Deleter, class U>
580 struct missing_virtual_destructor
581 { static const bool value = false; };
583 template<class T, class U>
584 struct missing_virtual_destructor< ::boost::movelib::default_delete<T>, U >
585 : missing_virtual_destructor_default_delete<T, U>
588 } //namespace move_upmu {
589 } //namespace boost {
591 #endif //#ifndef BOOST_MOVE_UNIQUE_PTR_DETAIL_META_UTILS_HPP