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