From 8898c6d1bbf0f0c265c0b12d06035b0346088602 Mon Sep 17 00:00:00 2001 From: jzmaddock Date: Thu, 17 May 2018 18:26:31 +0100 Subject: [PATCH 1/4] clang intrinsics: Use __is_trivially_constructible and __is_trivially_assignable to test for trivial move construct and assign. See https://github.com/boostorg/type_traits/issues/73. --- include/boost/type_traits/intrinsics.hpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/include/boost/type_traits/intrinsics.hpp b/include/boost/type_traits/intrinsics.hpp index f8c5639..41cd16b 100644 --- a/include/boost/type_traits/intrinsics.hpp +++ b/include/boost/type_traits/intrinsics.hpp @@ -222,11 +222,11 @@ # if __has_feature(is_polymorphic) # define BOOST_IS_POLYMORPHIC(T) __is_polymorphic(T) # endif -# if __has_feature(has_trivial_move_constructor) -# define BOOST_HAS_TRIVIAL_MOVE_CONSTRUCTOR(T) (__has_trivial_move_constructor(T) && is_constructible::value && !::boost::is_volatile::value) +# if __has_extension(is_trivially_constructible) +# define BOOST_HAS_TRIVIAL_MOVE_CONSTRUCTOR(T) (__is_trivially_constructible(T, T&&) && is_constructible::value && !::boost::is_volatile::value) # endif -# if __has_feature(has_trivial_move_assign) -# define BOOST_HAS_TRIVIAL_MOVE_ASSIGN(T) (__has_trivial_move_assign(T) && is_assignable::value && !::boost::is_volatile::value) +# if __has_extension(is_trivially_assignable) +# define BOOST_HAS_TRIVIAL_MOVE_ASSIGN(T) (__is_trivially_assignable(T&, T&&) && is_assignable::value && !::boost::is_volatile::value) # endif # if (!defined(unix) && !defined(__unix__)) || defined(__LP64__) || !defined(__GNUC__) // GCC sometimes lies about alignment requirements From 7eab81300ec1ede149a84c7d0b5a27abc4c12168 Mon Sep 17 00:00:00 2001 From: jzmaddock Date: Fri, 18 May 2018 08:00:28 +0100 Subject: [PATCH 2/4] clang intrinsics: disable trivial move construction testing for c++03. --- include/boost/type_traits/intrinsics.hpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/boost/type_traits/intrinsics.hpp b/include/boost/type_traits/intrinsics.hpp index 41cd16b..ddcd50f 100644 --- a/include/boost/type_traits/intrinsics.hpp +++ b/include/boost/type_traits/intrinsics.hpp @@ -222,12 +222,14 @@ # if __has_feature(is_polymorphic) # define BOOST_IS_POLYMORPHIC(T) __is_polymorphic(T) # endif +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES # if __has_extension(is_trivially_constructible) # define BOOST_HAS_TRIVIAL_MOVE_CONSTRUCTOR(T) (__is_trivially_constructible(T, T&&) && is_constructible::value && !::boost::is_volatile::value) # endif # if __has_extension(is_trivially_assignable) # define BOOST_HAS_TRIVIAL_MOVE_ASSIGN(T) (__is_trivially_assignable(T&, T&&) && is_assignable::value && !::boost::is_volatile::value) # endif +#endif # if (!defined(unix) && !defined(__unix__)) || defined(__LP64__) || !defined(__GNUC__) // GCC sometimes lies about alignment requirements // of type double on 32-bit unix platforms, use the From 4c9add90d05259a1da5320904b9f88b0b304b531 Mon Sep 17 00:00:00 2001 From: jzmaddock Date: Sat, 19 May 2018 09:29:13 +0100 Subject: [PATCH 3/4] Intrinsics: update msvc trivial move intrinsics. Tighten up the tests. --- include/boost/type_traits/intrinsics.hpp | 5 ++- test/has_trivial_move_assign_test.cpp | 38 ++++++++++++++++++++-- test/has_trivial_move_constructor_test.cpp | 36 +++++++++++++++++++- 3 files changed, 75 insertions(+), 4 deletions(-) diff --git a/include/boost/type_traits/intrinsics.hpp b/include/boost/type_traits/intrinsics.hpp index ddcd50f..d41a61e 100644 --- a/include/boost/type_traits/intrinsics.hpp +++ b/include/boost/type_traits/intrinsics.hpp @@ -122,7 +122,10 @@ // This one fails if the default alignment has been changed with /Zp: // # define BOOST_ALIGNMENT_OF(T) __alignof(T) -# if defined(_MSC_VER) && (_MSC_VER >= 1700) +# if defined(_MSC_VER) && (_MSC_VER >= 1800) +# define BOOST_HAS_TRIVIAL_MOVE_CONSTRUCTOR(T) ((__is_trivially_constructible(T, T&&) || boost::is_pod::value) && ! ::boost::is_volatile::value && ! ::boost::is_reference::value) +# define BOOST_HAS_TRIVIAL_MOVE_ASSIGN(T) ((__is_trivially_assignable(T, T&&) || boost::is_pod::value) && ! ::boost::is_const::value && !::boost::is_volatile::value && ! ::boost::is_reference::value) +# elif defined(_MSC_VER) && (_MSC_VER >= 1700) # define BOOST_HAS_TRIVIAL_MOVE_CONSTRUCTOR(T) ((__has_trivial_move_constructor(T) || boost::is_pod::value) && ! ::boost::is_volatile::value && ! ::boost::is_reference::value) # define BOOST_HAS_TRIVIAL_MOVE_ASSIGN(T) ((__has_trivial_move_assign(T) || boost::is_pod::value) && ! ::boost::is_const::value && !::boost::is_volatile::value && ! ::boost::is_reference::value) # endif diff --git a/test/has_trivial_move_assign_test.cpp b/test/has_trivial_move_assign_test.cpp index aa27bb4..32a415d 100644 --- a/test/has_trivial_move_assign_test.cpp +++ b/test/has_trivial_move_assign_test.cpp @@ -220,6 +220,37 @@ BOOST_CHECK_INTEGRAL_CONSTANT(::tt::has_trivial_move_assign: BOOST_CHECK_INTEGRAL_CONSTANT(::tt::has_trivial_move_assign::value, false); BOOST_CHECK_INTEGRAL_CONSTANT(::tt::has_trivial_move_assign::value, false); BOOST_CHECK_INTEGRAL_CONSTANT(::tt::has_trivial_move_assign::value, false); + +#ifdef BOOST_HAS_TRIVIAL_MOVE_ASSIGN + +// cases we would like to succeed but can't implement in the language: +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::has_trivial_move_assign::value, true); +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::has_trivial_move_assign::value, true); +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::has_trivial_move_assign::value, true); +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::has_trivial_move_assign::value, true); + +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::has_trivial_move_assign::value, false); +// Why does this fail on multiple compilers?? +//BOOST_CHECK_INTEGRAL_CONSTANT(::tt::has_trivial_move_assign::value, true); +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::has_trivial_move_assign::value, true); +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::has_trivial_move_assign::value, true); +/* +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::has_trivial_move_assign >::value, false); +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::has_trivial_move_assign >::value, true); +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::has_trivial_move_assign >::value, true); +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::has_trivial_move_assign >::value, true); +*/ +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::has_trivial_move_assign::value, false); + +#ifndef BOOST_NO_CXX11_DELETED_FUNCTIONS +#if !BOOST_WORKAROUND(BOOST_MSVC, < 1900) +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::has_trivial_move_assign::value, true); +#endif +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::has_trivial_move_assign::value, false); +#endif + +#else + // cases we would like to succeed but can't implement in the language: BOOST_CHECK_SOFT_INTEGRAL_CONSTANT(::tt::has_trivial_move_assign::value, true, false); BOOST_CHECK_SOFT_INTEGRAL_CONSTANT(::tt::has_trivial_move_assign::value, true, false); @@ -230,18 +261,21 @@ BOOST_CHECK_INTEGRAL_CONSTANT(::tt::has_trivial_move_assign::value, true, false); BOOST_CHECK_SOFT_INTEGRAL_CONSTANT(::tt::has_trivial_move_assign::value, true, false); BOOST_CHECK_SOFT_INTEGRAL_CONSTANT(::tt::has_trivial_move_assign::value, true, false); +/* BOOST_CHECK_INTEGRAL_CONSTANT(::tt::has_trivial_move_assign >::value, false); BOOST_CHECK_SOFT_INTEGRAL_CONSTANT(::tt::has_trivial_move_assign >::value, true, false); BOOST_CHECK_SOFT_INTEGRAL_CONSTANT(::tt::has_trivial_move_assign >::value, true, false); BOOST_CHECK_SOFT_INTEGRAL_CONSTANT(::tt::has_trivial_move_assign >::value, true, false); - +*/ BOOST_CHECK_INTEGRAL_CONSTANT(::tt::has_trivial_move_assign::value, false); #ifndef BOOST_NO_CXX11_DELETED_FUNCTIONS BOOST_CHECK_SOFT_INTEGRAL_CONSTANT(::tt::has_trivial_move_assign::value, true, false); BOOST_CHECK_INTEGRAL_CONSTANT(::tt::has_trivial_move_assign::value, false); #endif - + +#endif + TT_TEST_END diff --git a/test/has_trivial_move_constructor_test.cpp b/test/has_trivial_move_constructor_test.cpp index a2e71e2..b60d23f 100644 --- a/test/has_trivial_move_constructor_test.cpp +++ b/test/has_trivial_move_constructor_test.cpp @@ -220,6 +220,37 @@ BOOST_CHECK_INTEGRAL_CONSTANT(::tt::has_trivial_move_constructor::val BOOST_CHECK_INTEGRAL_CONSTANT(::tt::has_trivial_move_constructor::value, false); BOOST_CHECK_INTEGRAL_CONSTANT(::tt::has_trivial_move_constructor::value, false); BOOST_CHECK_INTEGRAL_CONSTANT(::tt::has_trivial_move_constructor::value, false); + +#ifdef BOOST_HAS_TRIVIAL_MOVE_CONSTRUCTOR + +// cases we would like to succeed but can't implement in the language: +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::has_trivial_move_constructor::value, true); +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::has_trivial_move_constructor::value, true); +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::has_trivial_move_constructor::value, true); +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::has_trivial_move_constructor::value, true); + +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::has_trivial_move_constructor::value, false); +// Why does this fail on multiple compilers?? +//BOOST_CHECK_INTEGRAL_CONSTANT(::tt::has_trivial_move_constructor::value, true); +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::has_trivial_move_constructor::value, true); +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::has_trivial_move_constructor::value, true); +/* +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::has_trivial_move_constructor >::value, false); +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::has_trivial_move_constructor >::value, true); +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::has_trivial_move_constructor >::value, true); +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::has_trivial_move_constructor >::value, true); +*/ +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::has_trivial_move_constructor::value, false); + +#ifndef BOOST_NO_CXX11_DELETED_FUNCTIONS +#if !BOOST_WORKAROUND(BOOST_MSVC, < 1900) +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::has_trivial_move_constructor::value, true); +#endif +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::has_trivial_move_constructor::value, false); +#endif + +#else + // cases we would like to succeed but can't implement in the language: BOOST_CHECK_SOFT_INTEGRAL_CONSTANT(::tt::has_trivial_move_constructor::value, true, false); BOOST_CHECK_SOFT_INTEGRAL_CONSTANT(::tt::has_trivial_move_constructor::value, true, false); @@ -230,11 +261,12 @@ BOOST_CHECK_INTEGRAL_CONSTANT(::tt::has_trivial_move_constructor::value, true, false); BOOST_CHECK_SOFT_INTEGRAL_CONSTANT(::tt::has_trivial_move_constructor::value, true, false); BOOST_CHECK_SOFT_INTEGRAL_CONSTANT(::tt::has_trivial_move_constructor::value, true, false); +/* BOOST_CHECK_INTEGRAL_CONSTANT(::tt::has_trivial_move_constructor >::value, false); BOOST_CHECK_SOFT_INTEGRAL_CONSTANT(::tt::has_trivial_move_constructor >::value, true, false); BOOST_CHECK_SOFT_INTEGRAL_CONSTANT(::tt::has_trivial_move_constructor >::value, true, false); BOOST_CHECK_SOFT_INTEGRAL_CONSTANT(::tt::has_trivial_move_constructor >::value, true, false); - +*/ BOOST_CHECK_INTEGRAL_CONSTANT(::tt::has_trivial_move_constructor::value, false); #ifndef BOOST_NO_CXX11_DELETED_FUNCTIONS @@ -242,6 +274,8 @@ BOOST_CHECK_SOFT_INTEGRAL_CONSTANT(::tt::has_trivial_move_constructor::value, false); #endif +#endif + TT_TEST_END From 7b115c8d0e4d590658e7d5d5cbcc8a52fb9650d5 Mon Sep 17 00:00:00 2001 From: jzmaddock Date: Sat, 19 May 2018 19:45:10 +0100 Subject: [PATCH 4/4] Tests: disable some failing tests for msvc-11.0. --- test/has_trivial_move_assign_test.cpp | 2 ++ test/has_trivial_move_constructor_test.cpp | 2 ++ 2 files changed, 4 insertions(+) diff --git a/test/has_trivial_move_assign_test.cpp b/test/has_trivial_move_assign_test.cpp index 32a415d..fd8b3c9 100644 --- a/test/has_trivial_move_assign_test.cpp +++ b/test/has_trivial_move_assign_test.cpp @@ -232,8 +232,10 @@ BOOST_CHECK_INTEGRAL_CONSTANT(::tt::has_trivial_move_assign BOOST_CHECK_INTEGRAL_CONSTANT(::tt::has_trivial_move_assign::value, false); // Why does this fail on multiple compilers?? //BOOST_CHECK_INTEGRAL_CONSTANT(::tt::has_trivial_move_assign::value, true); +#if !BOOST_WORKAROUND(BOOST_MSVC, < 1800) BOOST_CHECK_INTEGRAL_CONSTANT(::tt::has_trivial_move_assign::value, true); BOOST_CHECK_INTEGRAL_CONSTANT(::tt::has_trivial_move_assign::value, true); +#endif /* BOOST_CHECK_INTEGRAL_CONSTANT(::tt::has_trivial_move_assign >::value, false); BOOST_CHECK_INTEGRAL_CONSTANT(::tt::has_trivial_move_assign >::value, true); diff --git a/test/has_trivial_move_constructor_test.cpp b/test/has_trivial_move_constructor_test.cpp index b60d23f..26894c9 100644 --- a/test/has_trivial_move_constructor_test.cpp +++ b/test/has_trivial_move_constructor_test.cpp @@ -232,8 +232,10 @@ BOOST_CHECK_INTEGRAL_CONSTANT(::tt::has_trivial_move_constructor::value, false); // Why does this fail on multiple compilers?? //BOOST_CHECK_INTEGRAL_CONSTANT(::tt::has_trivial_move_constructor::value, true); +#if !BOOST_WORKAROUND(BOOST_MSVC, < 1800) BOOST_CHECK_INTEGRAL_CONSTANT(::tt::has_trivial_move_constructor::value, true); BOOST_CHECK_INTEGRAL_CONSTANT(::tt::has_trivial_move_constructor::value, true); +#endif /* BOOST_CHECK_INTEGRAL_CONSTANT(::tt::has_trivial_move_constructor >::value, false); BOOST_CHECK_INTEGRAL_CONSTANT(::tt::has_trivial_move_constructor >::value, true);