123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592 |
- //////////////////////////////////////////////////////////////////////////////
- //
- // (C) Copyright Ion Gaztanaga 2012-2012.
- // Distributed under the Boost Software License, Version 1.0.
- // (See accompanying file LICENSE_1_0.txt or copy at
- // http://www.boost.org/LICENSE_1_0.txt)
- //
- // See http://www.boost.org/libs/move for documentation.
- //
- //////////////////////////////////////////////////////////////////////////////
- //! \file
- #ifndef BOOST_MOVE_UNIQUE_PTR_DETAIL_META_UTILS_HPP
- #define BOOST_MOVE_UNIQUE_PTR_DETAIL_META_UTILS_HPP
- #ifndef BOOST_CONFIG_HPP
- # include <boost/config.hpp>
- #endif
- #
- #if defined(BOOST_HAS_PRAGMA_ONCE)
- # pragma once
- #endif
- #include <cstddef> //for std::size_t
- //Small meta-typetraits to support move
- namespace boost {
- namespace movelib {
- template <class T>
- struct default_delete;
- } //namespace movelib {
- #ifdef BOOST_NO_CXX11_RVALUE_REFERENCES
- //Forward declare boost::rv
- template <class T> class rv;
- #endif
- namespace move_upmu {
- //////////////////////////////////////
- // nat
- //////////////////////////////////////
- struct nat{};
- //////////////////////////////////////
- // natify
- //////////////////////////////////////
- template <class T> struct natify{};
- //////////////////////////////////////
- // if_c
- //////////////////////////////////////
- template<bool C, typename T1, typename T2>
- struct if_c
- {
- typedef T1 type;
- };
- template<typename T1, typename T2>
- struct if_c<false,T1,T2>
- {
- typedef T2 type;
- };
- //////////////////////////////////////
- // if_
- //////////////////////////////////////
- template<typename T1, typename T2, typename T3>
- struct if_ : if_c<0 != T1::value, T2, T3>
- {};
- //enable_if_
- template <bool B, class T = nat>
- struct enable_if_c
- {
- typedef T type;
- };
- //////////////////////////////////////
- // enable_if_c
- //////////////////////////////////////
- template <class T>
- struct enable_if_c<false, T> {};
- //////////////////////////////////////
- // enable_if
- //////////////////////////////////////
- template <class Cond, class T = nat>
- struct enable_if : public enable_if_c<Cond::value, T> {};
- //////////////////////////////////////
- // remove_reference
- //////////////////////////////////////
- template<class T>
- struct remove_reference
- {
- typedef T type;
- };
- template<class T>
- struct remove_reference<T&>
- {
- typedef T type;
- };
- #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
- template<class T>
- struct remove_reference<T&&>
- {
- typedef T type;
- };
- #else
- template<class T>
- struct remove_reference< rv<T> >
- {
- typedef T type;
- };
- template<class T>
- struct remove_reference< rv<T> &>
- {
- typedef T type;
- };
- template<class T>
- struct remove_reference< const rv<T> &>
- {
- typedef T type;
- };
- #endif
- //////////////////////////////////////
- // remove_const
- //////////////////////////////////////
- template< class T >
- struct remove_const
- {
- typedef T type;
- };
- template< class T >
- struct remove_const<const T>
- {
- typedef T type;
- };
- //////////////////////////////////////
- // remove_volatile
- //////////////////////////////////////
- template< class T >
- struct remove_volatile
- {
- typedef T type;
- };
- template< class T >
- struct remove_volatile<volatile T>
- {
- typedef T type;
- };
- //////////////////////////////////////
- // remove_cv
- //////////////////////////////////////
- template< class T >
- struct remove_cv
- {
- typedef typename remove_volatile
- <typename remove_const<T>::type>::type type;
- };
- //////////////////////////////////////
- // remove_extent
- //////////////////////////////////////
- template<class T>
- struct remove_extent
- {
- typedef T type;
- };
-
- template<class T>
- struct remove_extent<T[]>
- {
- typedef T type;
- };
-
- template<class T, std::size_t N>
- struct remove_extent<T[N]>
- {
- typedef T type;
- };
- //////////////////////////////////////
- // extent
- //////////////////////////////////////
- template<class T, unsigned N = 0>
- struct extent
- {
- static const std::size_t value = 0;
- };
-
- template<class T>
- struct extent<T[], 0>
- {
- static const std::size_t value = 0;
- };
- template<class T, unsigned N>
- struct extent<T[], N>
- {
- static const std::size_t value = extent<T, N-1>::value;
- };
- template<class T, std::size_t N>
- struct extent<T[N], 0>
- {
- static const std::size_t value = N;
- };
-
- template<class T, std::size_t I, unsigned N>
- struct extent<T[I], N>
- {
- static const std::size_t value = extent<T, N-1>::value;
- };
- //////////////////////////////////////
- // add_lvalue_reference
- //////////////////////////////////////
- template<class T>
- struct add_lvalue_reference
- {
- typedef T& type;
- };
- template<class T>
- struct add_lvalue_reference<T&>
- {
- typedef T& type;
- };
- template<>
- struct add_lvalue_reference<void>
- {
- typedef void type;
- };
- template<>
- struct add_lvalue_reference<const void>
- {
- typedef const void type;
- };
- template<>
- struct add_lvalue_reference<volatile void>
- {
- typedef volatile void type;
- };
- template<>
- struct add_lvalue_reference<const volatile void>
- {
- typedef const volatile void type;
- };
- template<class T>
- struct add_const_lvalue_reference
- {
- typedef typename remove_reference<T>::type t_unreferenced;
- typedef const t_unreferenced t_unreferenced_const;
- typedef typename add_lvalue_reference
- <t_unreferenced_const>::type type;
- };
- //////////////////////////////////////
- // is_same
- //////////////////////////////////////
- template<class T, class U>
- struct is_same
- {
- static const bool value = false;
- };
-
- template<class T>
- struct is_same<T, T>
- {
- static const bool value = true;
- };
- //////////////////////////////////////
- // is_pointer
- //////////////////////////////////////
- template< class T >
- struct is_pointer
- {
- static const bool value = false;
- };
- template< class T >
- struct is_pointer<T*>
- {
- static const bool value = true;
- };
- //////////////////////////////////////
- // is_reference
- //////////////////////////////////////
- template< class T >
- struct is_reference
- {
- static const bool value = false;
- };
- template< class T >
- struct is_reference<T&>
- {
- static const bool value = true;
- };
- #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
- template< class T >
- struct is_reference<T&&>
- {
- static const bool value = true;
- };
- #endif
- //////////////////////////////////////
- // is_lvalue_reference
- //////////////////////////////////////
- template<class T>
- struct is_lvalue_reference
- {
- static const bool value = false;
- };
- template<class T>
- struct is_lvalue_reference<T&>
- {
- static const bool value = true;
- };
- //////////////////////////////////////
- // is_array
- //////////////////////////////////////
- template<class T>
- struct is_array
- {
- static const bool value = false;
- };
-
- template<class T>
- struct is_array<T[]>
- {
- static const bool value = true;
- };
-
- template<class T, std::size_t N>
- struct is_array<T[N]>
- {
- static const bool value = true;
- };
- //////////////////////////////////////
- // has_pointer_type
- //////////////////////////////////////
- template <class T>
- struct has_pointer_type
- {
- struct two { char c[2]; };
- template <class U> static two test(...);
- template <class U> static char test(typename U::pointer* = 0);
- static const bool value = sizeof(test<T>(0)) == 1;
- };
- //////////////////////////////////////
- // pointer_type
- //////////////////////////////////////
- template <class T, class D, bool = has_pointer_type<D>::value>
- struct pointer_type_imp
- {
- typedef typename D::pointer type;
- };
- template <class T, class D>
- struct pointer_type_imp<T, D, false>
- {
- typedef T* type;
- };
- template <class T, class D>
- struct pointer_type
- {
- typedef typename pointer_type_imp
- <typename remove_extent<T>::type, typename remove_reference<D>::type>::type type;
- };
- //////////////////////////////////////
- // is_convertible
- //////////////////////////////////////
- #if defined(_MSC_VER) && (_MSC_VER >= 1400)
- //use intrinsic since in MSVC
- //overaligned types can't go through ellipsis
- template <class T, class U>
- struct is_convertible
- {
- static const bool value = __is_convertible_to(T, U);
- };
- #else
- template <class T, class U>
- class is_convertible
- {
- typedef typename add_lvalue_reference<T>::type t_reference;
- typedef char true_t;
- class false_t { char dummy[2]; };
- static false_t dispatch(...);
- static true_t dispatch(U);
- static t_reference trigger();
- public:
- static const bool value = sizeof(dispatch(trigger())) == sizeof(true_t);
- };
- #endif
- //////////////////////////////////////
- // is_unary_function
- //////////////////////////////////////
- #if defined(BOOST_MSVC) || defined(__BORLANDC_)
- #define BOOST_MOVE_TT_DECL __cdecl
- #else
- #define BOOST_MOVE_TT_DECL
- #endif
- #if defined(_MSC_EXTENSIONS) && !defined(__BORLAND__) && !defined(_WIN64) && !defined(_M_ARM) && !defined(_M_ARM64) && !defined(UNDER_CE)
- #define BOOST_MOVE_TT_TEST_MSC_FUNC_SIGS
- #endif
- template <typename T>
- struct is_unary_function_impl
- { static const bool value = false; };
- // avoid duplicate definitions of is_unary_function_impl
- #ifndef BOOST_MOVE_TT_TEST_MSC_FUNC_SIGS
- template <typename R>
- struct is_unary_function_impl<R (*)()>
- { static const bool value = true; };
- template <typename R>
- struct is_unary_function_impl<R (*)(...)>
- { static const bool value = true; };
- #else // BOOST_MOVE_TT_TEST_MSC_FUNC_SIGS
- template <typename R>
- struct is_unary_function_impl<R (__stdcall*)()>
- { static const bool value = true; };
- #ifndef _MANAGED
- template <typename R>
- struct is_unary_function_impl<R (__fastcall*)()>
- { static const bool value = true; };
- #endif
- template <typename R>
- struct is_unary_function_impl<R (__cdecl*)()>
- { static const bool value = true; };
- template <typename R>
- struct is_unary_function_impl<R (__cdecl*)(...)>
- { static const bool value = true; };
- #endif
- // avoid duplicate definitions of is_unary_function_impl
- #ifndef BOOST_MOVE_TT_TEST_MSC_FUNC_SIGS
- template <typename R, class T0>
- struct is_unary_function_impl<R (*)(T0)>
- { static const bool value = true; };
- template <typename R, class T0>
- struct is_unary_function_impl<R (*)(T0...)>
- { static const bool value = true; };
- #else // BOOST_MOVE_TT_TEST_MSC_FUNC_SIGS
- template <typename R, class T0>
- struct is_unary_function_impl<R (__stdcall*)(T0)>
- { static const bool value = true; };
- #ifndef _MANAGED
- template <typename R, class T0>
- struct is_unary_function_impl<R (__fastcall*)(T0)>
- { static const bool value = true; };
- #endif
- template <typename R, class T0>
- struct is_unary_function_impl<R (__cdecl*)(T0)>
- { static const bool value = true; };
- template <typename R, class T0>
- struct is_unary_function_impl<R (__cdecl*)(T0...)>
- { static const bool value = true; };
- #endif
- template <typename T>
- struct is_unary_function_impl<T&>
- { static const bool value = false; };
- template<typename T>
- struct is_unary_function
- { static const bool value = is_unary_function_impl<T>::value; };
- //////////////////////////////////////
- // has_virtual_destructor
- //////////////////////////////////////
- #if (defined(BOOST_MSVC) && defined(BOOST_MSVC_FULL_VER) && (BOOST_MSVC_FULL_VER >=140050215))\
- || (defined(BOOST_INTEL) && defined(_MSC_VER) && (_MSC_VER >= 1500))
- # define BOOST_MOVEUP_HAS_VIRTUAL_DESTRUCTOR(T) __has_virtual_destructor(T)
- #elif defined(BOOST_CLANG) && defined(__has_feature)
- # if __has_feature(has_virtual_destructor)
- # define BOOST_MOVEUP_HAS_VIRTUAL_DESTRUCTOR(T) __has_virtual_destructor(T)
- # endif
- #elif defined(__GNUC__) && ((__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 3) && !defined(__GCCXML__))) && !defined(BOOST_CLANG)
- # define BOOST_MOVEUP_HAS_VIRTUAL_DESTRUCTOR(T) __has_virtual_destructor(T)
- #elif defined(__ghs__) && (__GHS_VERSION_NUMBER >= 600)
- # define BOOST_MOVEUP_HAS_VIRTUAL_DESTRUCTOR(T) __has_virtual_destructor(T)
- #elif defined(__CODEGEARC__)
- # define BOOST_MOVEUP_HAS_VIRTUAL_DESTRUCTOR(T) __has_virtual_destructor(T)
- #endif
- #ifdef BOOST_MOVEUP_HAS_VIRTUAL_DESTRUCTOR
- template<class T>
- struct has_virtual_destructor{ static const bool value = BOOST_MOVEUP_HAS_VIRTUAL_DESTRUCTOR(T); };
- #else
- //If no intrinsic is available you trust the programmer knows what is doing
- template<class T>
- struct has_virtual_destructor{ static const bool value = true; };
- #endif
- //////////////////////////////////////
- // missing_virtual_destructor
- //////////////////////////////////////
- template< class T, class U
- , bool enable = is_convertible< U*, T*>::value &&
- !is_array<T>::value &&
- !is_same<typename remove_cv<T>::type, void>::value &&
- !is_same<typename remove_cv<U>::type, typename remove_cv<T>::type>::value
- >
- struct missing_virtual_destructor_default_delete
- { static const bool value = !has_virtual_destructor<T>::value; };
- template<class T, class U>
- struct missing_virtual_destructor_default_delete<T, U, false>
- { static const bool value = false; };
- template<class Deleter, class U>
- struct missing_virtual_destructor
- { static const bool value = false; };
- template<class T, class U>
- struct missing_virtual_destructor< ::boost::movelib::default_delete<T>, U >
- : missing_virtual_destructor_default_delete<T, U>
- {};
- } //namespace move_upmu {
- } //namespace boost {
- #endif //#ifndef BOOST_MOVE_UNIQUE_PTR_DETAIL_META_UTILS_HPP
|