diff --git a/include/boost/move/detail/type_traits.hpp b/include/boost/move/detail/type_traits.hpp index cef0f20..11b0478 100644 --- a/include/boost/move/detail/type_traits.hpp +++ b/include/boost/move/detail/type_traits.hpp @@ -70,6 +70,7 @@ // user defined specializations as well as compiler intrinsics as // and when they become available: # include +# define BOOST_MOVE_IS_UNION(T) BOOST_STD_EXTENSION_NAMESPACE::is_union::value # define BOOST_MOVE_IS_POD(T) BOOST_STD_EXTENSION_NAMESPACE::is_POD::value # define BOOST_MOVE_HAS_TRIVIAL_CONSTRUCTOR(T) BOOST_STD_EXTENSION_NAMESPACE::has_trivial_default_ctor::value # define BOOST_MOVE_HAS_TRIVIAL_COPY(T) BOOST_STD_EXTENSION_NAMESPACE::has_trivial_copy_ctor::value @@ -79,7 +80,9 @@ #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_MOVE_IS_UNION(T) __is_union(T) # define BOOST_MOVE_IS_POD(T) (__is_pod(T) && __has_trivial_constructor(T)) +# define BOOST_MOVE_IS_EMPTY(T) __is_empty(T) # define BOOST_MOVE_HAS_TRIVIAL_CONSTRUCTOR(T) __has_trivial_constructor(T) # define BOOST_MOVE_HAS_TRIVIAL_COPY(T) (__has_trivial_copy(T)|| ::boost::move_detail::is_pod::value) # define BOOST_MOVE_HAS_TRIVIAL_ASSIGN(T) (__has_trivial_assign(T) || ::boost::move_detail::is_pod::value) @@ -97,9 +100,15 @@ #if defined(BOOST_CLANG) && defined(__has_feature) +# if __has_feature(is_union) +# define BOOST_MOVE_IS_UNION(T) __is_union(T) +# endif # if (!defined(__GLIBCXX__) || (__GLIBCXX__ >= 20080306 && __GLIBCXX__ != 20080519)) && __has_feature(is_pod) # define BOOST_MOVE_IS_POD(T) __is_pod(T) # endif +# if (!defined(__GLIBCXX__) || (__GLIBCXX__ >= 20080306 && __GLIBCXX__ != 20080519)) && __has_feature(is_empty) +# define BOOST_MOVE_IS_EMPTY(T) __is_empty(T) +# endif # if __has_feature(has_trivial_constructor) # define BOOST_MOVE_HAS_TRIVIAL_CONSTRUCTOR(T) __has_trivial_constructor(T) # endif @@ -143,7 +152,9 @@ # define BOOST_MOVE_INTEL_TT_OPTS #endif +# define BOOST_MOVE_IS_UNION(T) __is_union(T) # define BOOST_MOVE_IS_POD(T) __is_pod(T) +# define BOOST_MOVE_IS_EMPTY(T) __is_empty(T) # define BOOST_MOVE_HAS_TRIVIAL_CONSTRUCTOR(T) ((__has_trivial_constructor(T) BOOST_MOVE_INTEL_TT_OPTS)) # define BOOST_MOVE_HAS_TRIVIAL_COPY(T) ((__has_trivial_copy(T) BOOST_MOVE_INTEL_TT_OPTS)) # define BOOST_MOVE_HAS_TRIVIAL_ASSIGN(T) ((__has_trivial_assign(T) BOOST_MOVE_INTEL_TT_OPTS) ) @@ -163,7 +174,9 @@ #if defined(__ghs__) && (__GHS_VERSION_NUMBER >= 600) +# define BOOST_MOVE_IS_UNION(T) __is_union(T) # define BOOST_MOVE_IS_POD(T) __is_pod(T) +# define BOOST_MOVE_IS_EMPTY(T) __is_empty(T) # define BOOST_MOVE_HAS_TRIVIAL_CONSTRUCTOR(T) __has_trivial_constructor(T) # define BOOST_MOVE_HAS_TRIVIAL_COPY(T) (__has_trivial_copy(T)) # define BOOST_MOVE_HAS_TRIVIAL_ASSIGN(T) (__has_trivial_assign(T)) @@ -177,7 +190,9 @@ #endif # if defined(__CODEGEARC__) +# define BOOST_MOVE_IS_UNION(T) __is_union(T) # define BOOST_MOVE_IS_POD(T) __is_pod(T) +# define BOOST_MOVE_IS_EMPTY(T) __is_empty(T) # define BOOST_MOVE_HAS_TRIVIAL_CONSTRUCTOR(T) (__has_trivial_default_constructor(T)) # define BOOST_MOVE_HAS_TRIVIAL_COPY(T) (__has_trivial_copy_constructor(T)) # define BOOST_MOVE_HAS_TRIVIAL_ASSIGN(T) (__has_trivial_assign(T)) @@ -192,6 +207,13 @@ #endif //Fallback definitions + +#ifdef BOOST_MOVE_IS_UNION + #define BOOST_MOVE_IS_UNION_IMPL(T) BOOST_MOVE_IS_UNION(T) +#else + #define BOOST_MOVE_IS_UNION_IMPL(T) false +#endif + #ifdef BOOST_MOVE_IS_POD #define BOOST_MOVE_IS_POD_IMPL(T) BOOST_MOVE_IS_POD(T) #else @@ -199,6 +221,12 @@ (::boost::move_detail::is_scalar::value || ::boost::move_detail::is_void::value) #endif +#ifdef BOOST_MOVE_IS_EMPTY + #define BOOST_MOVE_IS_EMPTY_IMPL(T) BOOST_MOVE_IS_EMPTY(T) +#else + #define BOOST_MOVE_IS_EMPTY_IMPL(T) ::boost::move_detail::is_empty_nonintrinsic::value +#endif + #ifdef BOOST_MOVE_HAS_TRIVIAL_COPY #define BOOST_MOVE_IS_TRIVIALLY_COPY_CONSTRUCTIBLE(T) BOOST_MOVE_HAS_TRIVIAL_COPY(T) #else @@ -421,6 +449,21 @@ struct is_integral : public is_integral_cv::type> {}; +////////////////////////////////////// +// remove_all_extents +////////////////////////////////////// +template +struct remove_all_extents +{ typedef T type;}; + +template +struct remove_all_extents +{ typedef typename remove_all_extents::type type; }; + +template +struct remove_all_extents +{ typedef typename remove_all_extents::type type;}; + ////////////////////////// // is_scalar ////////////////////////// @@ -531,6 +574,28 @@ struct is_function : is_function_impl {}; +////////////////////////////////////// +// is_union +////////////////////////////////////// +template +struct is_union_noextents_cv +{ static const bool value = BOOST_MOVE_IS_UNION_IMPL(T); }; + +template +struct is_union + : is_union_noextents_cv::type>::type> +{}; + +////////////////////////////////////// +// is_class +////////////////////////////////////// +template +struct is_class +{ + static const bool value = is_class_or_union::value && ! is_union::value; +}; + + ////////////////////////////////////// // is_arithmetic ////////////////////////////////////// @@ -584,21 +649,6 @@ template struct is_enum { static const bool value = BOOST_MOVE_IS_ENUM_IMPL(T); }; -////////////////////////////////////// -// remove_all_extents -////////////////////////////////////// -template -struct remove_all_extents -{ typedef T type;}; - -template -struct remove_all_extents -{ typedef typename remove_all_extents::type type; }; - -template -struct remove_all_extents -{ typedef typename remove_all_extents::type type;}; - ////////////////////////////////////// // is_pod ////////////////////////////////////// @@ -611,6 +661,41 @@ struct is_pod : is_pod_noextents_cv::type>::type> {}; +////////////////////////////////////// +// is_empty +////////////////////////////////////// +#if !defined(BOOST_MOVE_IS_EMPTY) + +template +struct empty_helper_t1 : public T +{ + empty_helper_t1(); // hh compiler bug workaround + int i[256]; + private: + + empty_helper_t1(const empty_helper_t1&); + empty_helper_t1& operator=(const empty_helper_t1&); +}; + +struct empty_helper_t2 { int i[256]; }; + +template +struct is_empty_nonintrinsic +{ + static const bool value = false; +}; + +template +struct is_empty_nonintrinsic +{ + static const bool value = sizeof(empty_helper_t1) == sizeof(empty_helper_t2); +}; +#endif + +template +struct is_empty +{ static const bool value = BOOST_MOVE_IS_EMPTY_IMPL(T); }; + ////////////////////////////////////// // is_copy_constructible //////////////////////////////////////