////////////////////////////////////////////////////////////////////////////// // // (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 #endif # #if defined(BOOST_HAS_PRAGMA_ONCE) # pragma once #endif #include //for std::size_t //Small meta-typetraits to support move namespace boost { namespace movelib { template struct default_delete; } //namespace movelib { #ifdef BOOST_NO_CXX11_RVALUE_REFERENCES //Forward declare boost::rv template class rv; #endif namespace move_upmu { ////////////////////////////////////// // nat ////////////////////////////////////// struct nat{}; ////////////////////////////////////// // natify ////////////////////////////////////// template struct natify{}; ////////////////////////////////////// // if_c ////////////////////////////////////// template struct if_c { typedef T1 type; }; template struct if_c { typedef T2 type; }; ////////////////////////////////////// // if_ ////////////////////////////////////// template struct if_ : if_c<0 != T1::value, T2, T3> {}; //enable_if_ template struct enable_if_c { typedef T type; }; ////////////////////////////////////// // enable_if_c ////////////////////////////////////// template struct enable_if_c {}; ////////////////////////////////////// // enable_if ////////////////////////////////////// template struct enable_if : public enable_if_c {}; ////////////////////////////////////// // remove_reference ////////////////////////////////////// template struct remove_reference { typedef T type; }; template struct remove_reference { typedef T type; }; #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES template struct remove_reference { typedef T type; }; #else template struct remove_reference< rv > { typedef T type; }; template struct remove_reference< rv &> { typedef T type; }; template struct remove_reference< const rv &> { typedef T type; }; #endif ////////////////////////////////////// // remove_const ////////////////////////////////////// template< class T > struct remove_const { typedef T type; }; template< class T > struct remove_const { typedef T type; }; ////////////////////////////////////// // remove_volatile ////////////////////////////////////// template< class T > struct remove_volatile { typedef T type; }; template< class T > struct remove_volatile { typedef T type; }; ////////////////////////////////////// // remove_cv ////////////////////////////////////// template< class T > struct remove_cv { typedef typename remove_volatile ::type>::type type; }; ////////////////////////////////////// // remove_extent ////////////////////////////////////// template struct remove_extent { typedef T type; }; template struct remove_extent { typedef T type; }; template struct remove_extent { typedef T type; }; ////////////////////////////////////// // extent ////////////////////////////////////// template struct extent { static const std::size_t value = 0; }; template struct extent { static const std::size_t value = 0; }; template struct extent { static const std::size_t value = extent::value; }; template struct extent { static const std::size_t value = N; }; template struct extent { static const std::size_t value = extent::value; }; ////////////////////////////////////// // add_lvalue_reference ////////////////////////////////////// template struct add_lvalue_reference { typedef T& type; }; template struct add_lvalue_reference { typedef T& type; }; template<> struct add_lvalue_reference { typedef void type; }; template<> struct add_lvalue_reference { typedef const void type; }; template<> struct add_lvalue_reference { typedef volatile void type; }; template<> struct add_lvalue_reference { typedef const volatile void type; }; template struct add_const_lvalue_reference { typedef typename remove_reference::type t_unreferenced; typedef const t_unreferenced t_unreferenced_const; typedef typename add_lvalue_reference ::type type; }; ////////////////////////////////////// // is_same ////////////////////////////////////// template struct is_same { static const bool value = false; }; template struct is_same { static const bool value = true; }; ////////////////////////////////////// // is_pointer ////////////////////////////////////// template< class T > struct is_pointer { static const bool value = false; }; template< class T > struct is_pointer { static const bool value = true; }; ////////////////////////////////////// // is_reference ////////////////////////////////////// template< class T > struct is_reference { static const bool value = false; }; template< class T > struct is_reference { static const bool value = true; }; #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES template< class T > struct is_reference { static const bool value = true; }; #endif ////////////////////////////////////// // is_lvalue_reference ////////////////////////////////////// template struct is_lvalue_reference { static const bool value = false; }; template struct is_lvalue_reference { static const bool value = true; }; ////////////////////////////////////// // is_array ////////////////////////////////////// template struct is_array { static const bool value = false; }; template struct is_array { static const bool value = true; }; template struct is_array { static const bool value = true; }; ////////////////////////////////////// // has_pointer_type ////////////////////////////////////// template struct has_pointer_type { struct two { char c[2]; }; template static two test(...); template static char test(typename U::pointer* = 0); static const bool value = sizeof(test(0)) == 1; }; ////////////////////////////////////// // pointer_type ////////////////////////////////////// template ::value> struct pointer_type_imp { typedef typename D::pointer type; }; template struct pointer_type_imp { typedef T* type; }; template struct pointer_type { typedef typename pointer_type_imp ::type, typename remove_reference::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 struct is_convertible { static const bool value = __is_convertible_to(T, U); }; #else template class is_convertible { typedef typename add_lvalue_reference::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(UNDER_CE) #define BOOST_MOVE_TT_TEST_MSC_FUNC_SIGS #endif template 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 struct is_unary_function_impl { static const bool value = true; }; template struct is_unary_function_impl { static const bool value = true; }; #else // BOOST_MOVE_TT_TEST_MSC_FUNC_SIGS template struct is_unary_function_impl { static const bool value = true; }; #ifndef _MANAGED template struct is_unary_function_impl { static const bool value = true; }; #endif template struct is_unary_function_impl { static const bool value = true; }; template struct is_unary_function_impl { static const bool value = true; }; #endif // avoid duplicate definitions of is_unary_function_impl #ifndef BOOST_MOVE_TT_TEST_MSC_FUNC_SIGS template struct is_unary_function_impl { static const bool value = true; }; template struct is_unary_function_impl { static const bool value = true; }; #else // BOOST_MOVE_TT_TEST_MSC_FUNC_SIGS template struct is_unary_function_impl { static const bool value = true; }; #ifndef _MANAGED template struct is_unary_function_impl { static const bool value = true; }; #endif template struct is_unary_function_impl { static const bool value = true; }; template struct is_unary_function_impl { static const bool value = true; }; #endif template struct is_unary_function_impl { static const bool value = false; }; template struct is_unary_function { static const bool value = is_unary_function_impl::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 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 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::value && !is_same::type, void>::value && !is_same::type, typename remove_cv::type>::value > struct missing_virtual_destructor_default_delete { static const bool value = !has_virtual_destructor::value; }; template struct missing_virtual_destructor_default_delete { static const bool value = false; }; template struct missing_virtual_destructor { static const bool value = false; }; template struct missing_virtual_destructor< ::boost::movelib::default_delete, U > : missing_virtual_destructor_default_delete {}; } //namespace move_upmu { } //namespace boost { #endif //#ifndef BOOST_MOVE_UNIQUE_PTR_DETAIL_META_UTILS_HPP