From 63d45d2fddcab8c633bc457f51da261a3ff1815f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ion=20Gazta=C3=B1aga?= Date: Sat, 17 Jan 2015 19:59:33 +0100 Subject: [PATCH 1/4] Updated type traits workaround deleted copy constructors --- include/boost/move/detail/meta_utils.hpp | 38 ++++---------------- include/boost/move/detail/type_traits.hpp | 44 +++++++++++++++++++---- 2 files changed, 43 insertions(+), 39 deletions(-) diff --git a/include/boost/move/detail/meta_utils.hpp b/include/boost/move/detail/meta_utils.hpp index 1104a28..70fbc05 100644 --- a/include/boost/move/detail/meta_utils.hpp +++ b/include/boost/move/detail/meta_utils.hpp @@ -116,39 +116,13 @@ struct add_const ////////////////////////////////////// template struct add_lvalue_reference -{ - typedef T& type; -}; +{ 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_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 diff --git a/include/boost/move/detail/type_traits.hpp b/include/boost/move/detail/type_traits.hpp index 0ee31aa..cef0f20 100644 --- a/include/boost/move/detail/type_traits.hpp +++ b/include/boost/move/detail/type_traits.hpp @@ -104,7 +104,9 @@ # define BOOST_MOVE_HAS_TRIVIAL_CONSTRUCTOR(T) __has_trivial_constructor(T) # endif # if __has_feature(has_trivial_copy) -# define BOOST_MOVE_HAS_TRIVIAL_COPY(T) (__has_trivial_copy(T)) +# //There are problems with deleted copy constructors detected as trivially copyable. +# //http://stackoverflow.com/questions/12754886/has-trivial-copy-behaves-differently-in-clang-and-gcc-whos-right +# define BOOST_MOVE_HAS_TRIVIAL_COPY(T) (__has_trivial_copy(T) && ::boost::move_detail::is_copy_constructible::value) # endif # if __has_feature(has_trivial_assign) # define BOOST_MOVE_HAS_TRIVIAL_ASSIGN(T) (__has_trivial_assign(T) ) @@ -529,6 +531,35 @@ struct is_function : is_function_impl {}; +////////////////////////////////////// +// is_arithmetic +////////////////////////////////////// +template +struct is_arithmetic +{ + static const bool value = is_floating_point::value || + is_integral::value; +}; + +////////////////////////////////////// +// is_member_function_pointer +////////////////////////////////////// +template +struct is_member_function_pointer_cv +{ + static const bool value = false; +}; + +template +struct is_member_function_pointer_cv + : is_function +{}; + +template +struct is_member_function_pointer + : is_member_function_pointer_cv::type> +{}; + ////////////////////////////////////// // is_enum ////////////////////////////////////// @@ -537,15 +568,14 @@ struct is_function template struct is_enum_nonintrinsic { - static const bool value = !is_void::value && - !is_floating_point::value && - !is_integral::value && + static const bool value = !is_arithmetic::value && + !is_reference::value && + !is_class_or_union::value && + !is_array::value && + !is_void::value && !is_nullptr_t::value && !is_member_pointer::value && !is_pointer::value && - !is_array::value && - !is_class_or_union::value && - !is_reference::value && !is_function::value; }; #endif From 4ef98d900b94bb6c50ff525a4eca1c8269620c4e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ion=20Gazta=C3=B1aga?= Date: Sun, 18 Jan 2015 11:18:12 +0100 Subject: [PATCH 2/4] Added is_enum, is_empty --- include/boost/move/detail/type_traits.hpp | 115 +++++++++++++++++++--- 1 file changed, 100 insertions(+), 15 deletions(-) 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 ////////////////////////////////////// From f21d8f51e7ce132692f64270390ffe0219b994b6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ion=20Gazta=C3=B1aga?= Date: Sun, 18 Jan 2015 20:22:22 +0100 Subject: [PATCH 3/4] Use is_class in is_empty_nonintrinsic. --- include/boost/move/detail/type_traits.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/boost/move/detail/type_traits.hpp b/include/boost/move/detail/type_traits.hpp index 11b0478..ffae853 100644 --- a/include/boost/move/detail/type_traits.hpp +++ b/include/boost/move/detail/type_traits.hpp @@ -679,7 +679,7 @@ struct empty_helper_t1 : public T struct empty_helper_t2 { int i[256]; }; -template +template ::value > struct is_empty_nonintrinsic { static const bool value = false; From db6448f7ea7eaa502e64b46de534dd8542d09f78 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ion=20Gazta=C3=B1aga?= Date: Mon, 19 Jan 2015 00:05:05 +0100 Subject: [PATCH 4/4] Added is_nothrow_swappable --- include/boost/move/detail/type_traits.hpp | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/include/boost/move/detail/type_traits.hpp b/include/boost/move/detail/type_traits.hpp index ffae853..cf91acb 100644 --- a/include/boost/move/detail/type_traits.hpp +++ b/include/boost/move/detail/type_traits.hpp @@ -810,6 +810,15 @@ template struct is_nothrow_move_assignable { static const bool value = BOOST_MOVE_IS_NOTHROW_MOVE_ASSIGNABLE(T); }; +////////////////////////////////////// +// is_nothrow_swappable +////////////////////////////////////// +template +struct is_nothrow_swappable +{ + static const bool value = is_empty::value || is_pod::value; +}; + ////////////////////////////////////// // alignment_of //////////////////////////////////////