From ac351390b215b73d8a9e16d2ca37ba2d9d88a14f Mon Sep 17 00:00:00 2001 From: jzmaddock Date: Sun, 4 Feb 2018 10:03:30 +0000 Subject: [PATCH 1/4] Assert when we try to use an incomplete type on a trait which requires complete types as arguments. This prevents some traits from doing the wrong thing (ie compiling but giving the wrong answer when handed an incomplete type. See https://svn.boost.org/trac10/ticket/12285. A by-product of this is we add is_complete as a new trait. --- include/boost/type_traits/common_type.hpp | 7 ++ .../type_traits/has_nothrow_destructor.hpp | 13 ++- include/boost/type_traits/is_assignable.hpp | 12 ++- include/boost/type_traits/is_complete.hpp | 81 +++++++++++++++++++ .../boost/type_traits/is_constructible.hpp | 12 ++- include/boost/type_traits/is_convertible.hpp | 10 ++- .../type_traits/is_default_constructible.hpp | 12 ++- include/boost/type_traits/is_destructible.hpp | 12 ++- .../type_traits/is_list_constructible.hpp | 4 + .../is_nothrow_move_assignable.hpp | 17 +++- .../is_nothrow_move_constructible.hpp | 16 +++- test/Jamfile.v2 | 4 + test/compile_fail/common_type2_fail.cpp | 15 ++++ test/compile_fail/common_type_fail.cpp | 15 ++++ test/compile_fail/has_nothrow_assign_fail.cpp | 15 ++++ test/compile_fail/has_nothrow_cons_fail.cpp | 15 ++++ test/compile_fail/has_nothrow_copy_fail.cpp | 15 ++++ .../has_nothrow_destruct_fail.cpp | 15 ++++ test/compile_fail/is_assignable_fail.cpp | 15 ++++ test/compile_fail/is_base_of_fail.cpp | 15 ++++ test/compile_fail/is_constructible_fail.cpp | 15 ++++ test/compile_fail/is_convertible2_fail.cpp | 19 +++++ test/compile_fail/is_convertible_fail.cpp | 15 ++++ test/compile_fail/is_copy_assignable_fail.cpp | 15 ++++ .../is_copy_constructible_fail.cpp | 15 ++++ .../is_default_constructible_fail.cpp | 15 ++++ test/compile_fail/is_destructible_fail.cpp | 15 ++++ test/compile_fail/is_empty_fail.cpp | 15 ++++ .../is_list_constructible_fail.cpp | 15 ++++ .../is_nothrow_move_assignable_fail.cpp | 15 ++++ .../is_nothrow_move_constructible_fail.cpp | 15 ++++ test/compile_fail/is_polymorphic_fail.cpp | 15 ++++ test/compile_fail/is_stateless_fail.cpp | 15 ++++ test/compile_fail/is_virtual_base_of_fail.cpp | 15 ++++ test/is_complete_test.cpp | 55 +++++++++++++ 35 files changed, 572 insertions(+), 17 deletions(-) create mode 100644 include/boost/type_traits/is_complete.hpp create mode 100644 test/compile_fail/common_type2_fail.cpp create mode 100644 test/compile_fail/common_type_fail.cpp create mode 100644 test/compile_fail/has_nothrow_assign_fail.cpp create mode 100644 test/compile_fail/has_nothrow_cons_fail.cpp create mode 100644 test/compile_fail/has_nothrow_copy_fail.cpp create mode 100644 test/compile_fail/has_nothrow_destruct_fail.cpp create mode 100644 test/compile_fail/is_assignable_fail.cpp create mode 100644 test/compile_fail/is_base_of_fail.cpp create mode 100644 test/compile_fail/is_constructible_fail.cpp create mode 100644 test/compile_fail/is_convertible2_fail.cpp create mode 100644 test/compile_fail/is_convertible_fail.cpp create mode 100644 test/compile_fail/is_copy_assignable_fail.cpp create mode 100644 test/compile_fail/is_copy_constructible_fail.cpp create mode 100644 test/compile_fail/is_default_constructible_fail.cpp create mode 100644 test/compile_fail/is_destructible_fail.cpp create mode 100644 test/compile_fail/is_empty_fail.cpp create mode 100644 test/compile_fail/is_list_constructible_fail.cpp create mode 100644 test/compile_fail/is_nothrow_move_assignable_fail.cpp create mode 100644 test/compile_fail/is_nothrow_move_constructible_fail.cpp create mode 100644 test/compile_fail/is_polymorphic_fail.cpp create mode 100644 test/compile_fail/is_stateless_fail.cpp create mode 100644 test/compile_fail/is_virtual_base_of_fail.cpp create mode 100644 test/is_complete_test.cpp diff --git a/include/boost/type_traits/common_type.hpp b/include/boost/type_traits/common_type.hpp index c887a89..7136d3e 100644 --- a/include/boost/type_traits/common_type.hpp +++ b/include/boost/type_traits/common_type.hpp @@ -13,6 +13,10 @@ #include #include #include +#include +#include +#include +#include #if defined(BOOST_NO_CXX11_DECLTYPE) #include @@ -75,6 +79,7 @@ struct common_type: common_type::type, T3, T4, T5, template struct common_type: boost::decay { + BOOST_STATIC_ASSERT_MSG(::boost::is_complete::value || ::boost::is_void::value || ::boost::is_array::value, "Arguments to common_type must both be complete types"); }; // two arguments @@ -138,6 +143,8 @@ template struct common_type_decay_helper: co template struct common_type: type_traits_detail::common_type_decay_helper { + BOOST_STATIC_ASSERT_MSG(::boost::is_complete::value || ::boost::is_void::value || ::boost::is_array::value, "Arguments to common_type must both be complete types"); + BOOST_STATIC_ASSERT_MSG(::boost::is_complete::value || ::boost::is_void::value || ::boost::is_array::value, "Arguments to common_type must both be complete types"); }; } // namespace boost diff --git a/include/boost/type_traits/has_nothrow_destructor.hpp b/include/boost/type_traits/has_nothrow_destructor.hpp index ba70e89..74dd9e7 100644 --- a/include/boost/type_traits/has_nothrow_destructor.hpp +++ b/include/boost/type_traits/has_nothrow_destructor.hpp @@ -15,6 +15,8 @@ #include #include +#include +#include namespace boost{ @@ -27,12 +29,19 @@ namespace boost{ } - template struct has_nothrow_destructor : public detail::has_nothrow_destructor_imp::value>{}; - template struct has_nothrow_destructor : public has_nothrow_destructor{}; + template struct has_nothrow_destructor : public detail::has_nothrow_destructor_imp::value> + { + BOOST_STATIC_ASSERT_MSG(boost::is_complete::value, "Arguments to has_nothrow_destructor must be complete types"); + }; + template struct has_nothrow_destructor : public has_nothrow_destructor + { + BOOST_STATIC_ASSERT_MSG(boost::is_complete::value, "Arguments to has_nothrow_destructor must be complete types"); + }; template struct has_nothrow_destructor : public integral_constant{}; #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) template struct has_nothrow_destructor : public integral_constant{}; #endif + template <> struct has_nothrow_destructor : public false_type {}; } #else diff --git a/include/boost/type_traits/is_assignable.hpp b/include/boost/type_traits/is_assignable.hpp index 49d1716..6a9474b 100644 --- a/include/boost/type_traits/is_assignable.hpp +++ b/include/boost/type_traits/is_assignable.hpp @@ -12,6 +12,8 @@ #include // size_t #include #include +#include +#include namespace boost{ @@ -39,7 +41,10 @@ namespace boost{ } - template struct is_assignable : public integral_constant(0)) == sizeof(boost::type_traits::yes_type)>{}; + template struct is_assignable : public integral_constant(0)) == sizeof(boost::type_traits::yes_type)> + { + BOOST_STATIC_ASSERT_MSG(boost::is_complete::value, "Arguments to is_assignable must be complete types"); + }; template struct is_assignable : public is_assignable{}; template struct is_assignable : public is_assignable{}; template struct is_assignable : public is_assignable{}; @@ -57,7 +62,10 @@ namespace boost{ namespace boost{ // We don't know how to implement this: - template struct is_assignable : public integral_constant{}; + template struct is_assignable : public integral_constant + { + BOOST_STATIC_ASSERT_MSG(boost::is_complete::value, "Arguments to is_assignable must be complete types"); + }; template struct is_assignable : public integral_constant::value && is_pod::type>::value>{}; template struct is_assignable : public integral_constant{}; template struct is_assignable : public integral_constant{}; diff --git a/include/boost/type_traits/is_complete.hpp b/include/boost/type_traits/is_complete.hpp new file mode 100644 index 0000000..0de36a9 --- /dev/null +++ b/include/boost/type_traits/is_complete.hpp @@ -0,0 +1,81 @@ + +// (C) Copyright John Maddock 2017. +// Use, modification and distribution are subject to 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/type_traits for most recent version including documentation. + +#ifndef BOOST_TT_IS_COMPLETE_HPP_INCLUDED +#define BOOST_TT_IS_COMPLETE_HPP_INCLUDED + +#include +#include +#include + +/* + * CAUTION: + * ~~~~~~~~ + * + * THIS TRAIT EXISTS SOLELY TO GENERATE HARD ERRORS WHEN A ANOTHER TRAIT + * WHICH REQUIRES COMPLETE TYPES AS ARGUMENTS IS PASSED AN INCOMPLETE TYPE + * + * DO NOT MAKE GENERAL USE OF THIS TRAIT, AS THE COMPLETENESS OF A TYPE + * VARIES ACROSS TRANSLATION UNITS AS WELL AS WITHIN A SINGLE UNIT. + * +*/ + +namespace boost { + +#ifndef BOOST_NO_SFINAE_EXPR + + namespace detail{ + + template + struct ok_tag { double d; char c[N]; }; + + template + ok_tag check_is_complete(int); + template + char check_is_complete(...); + } + + template struct is_complete + : public integral_constant::type>::value || (sizeof(detail::check_is_complete(0)) != sizeof(char))> {}; + +#elif !defined(BOOST_NO_SFINAE) + + namespace detail + { + + template + struct is_complete_imp + { + template ())) > + static type_traits::yes_type check(U*); + + template + static type_traits::no_type check(...); + + static const bool value = sizeof(check(0)) == sizeof(type_traits::yes_type); + }; + +} // namespace detail + + + template + struct is_complete : std::integral_constant::type>::value || detail::is_complete_imp::value> + {}; + template + struct is_complete : is_complete {}; + +#else + + template struct is_complete + : public integral_constant {}; + +#endif + +} // namespace boost + +#endif // BOOST_TT_IS_COMPLETE_HPP_INCLUDED diff --git a/include/boost/type_traits/is_constructible.hpp b/include/boost/type_traits/is_constructible.hpp index 0c3b5c8..da62599 100644 --- a/include/boost/type_traits/is_constructible.hpp +++ b/include/boost/type_traits/is_constructible.hpp @@ -18,6 +18,8 @@ #include #include #include +#include +#include #define BOOST_TT_IS_CONSTRUCTIBLE_CONFORMING 1 @@ -45,8 +47,14 @@ namespace boost{ } - template struct is_constructible : public integral_constant(0)) == sizeof(boost::type_traits::yes_type)>{}; - template struct is_constructible : public integral_constant::value && sizeof(detail::is_constructible_imp::test1(0)) == sizeof(boost::type_traits::yes_type)>{}; + template struct is_constructible : public integral_constant(0)) == sizeof(boost::type_traits::yes_type)> + { + BOOST_STATIC_ASSERT_MSG(::boost::is_complete::value, "The target type must be complete in order to test for constructibility"); + }; + template struct is_constructible : public integral_constant::value && sizeof(detail::is_constructible_imp::test1(0)) == sizeof(boost::type_traits::yes_type)> + { + BOOST_STATIC_ASSERT_MSG(::boost::is_complete::value, "The target type must be complete in order to test for constructibility"); + }; template struct is_constructible : public integral_constant(boost::declval())) == sizeof(boost::type_traits::yes_type)>{}; template struct is_constructible : public integral_constant(boost::declval())) == sizeof(boost::type_traits::yes_type)>{}; diff --git a/include/boost/type_traits/is_convertible.hpp b/include/boost/type_traits/is_convertible.hpp index 417ece2..991cdfd 100644 --- a/include/boost/type_traits/is_convertible.hpp +++ b/include/boost/type_traits/is_convertible.hpp @@ -15,6 +15,10 @@ #include #include #ifndef BOOST_IS_CONVERTIBLE +#include +#include +#include +#include #include #include #include @@ -474,7 +478,11 @@ template struct is_convertible_impl_dispatch : } // namespace detail template -struct is_convertible : public integral_constant::value> {}; +struct is_convertible : public integral_constant::value> +{ + BOOST_STATIC_ASSERT_MSG(boost::is_complete::value || boost::is_void::value || boost::is_array::value, "Destination argument type to is_convertible must be a complete type"); + BOOST_STATIC_ASSERT_MSG(boost::is_complete::value || boost::is_void::value || boost::is_array::value, "From argument type to is_convertible must be a complete type"); +}; #else diff --git a/include/boost/type_traits/is_default_constructible.hpp b/include/boost/type_traits/is_default_constructible.hpp index dc8ea13..9a4a0a7 100644 --- a/include/boost/type_traits/is_default_constructible.hpp +++ b/include/boost/type_traits/is_default_constructible.hpp @@ -12,6 +12,8 @@ #include // size_t #include #include +#include +#include #if BOOST_WORKAROUND(BOOST_GCC_VERSION, < 40700) #include @@ -51,9 +53,15 @@ namespace boost{ } #if BOOST_WORKAROUND(BOOST_GCC_VERSION, < 40700) - template struct is_default_constructible : public integral_constant::value>::value>{}; + template struct is_default_constructible : public integral_constant::value>::value> + { + BOOST_STATIC_ASSERT_MSG(boost::is_complete::value, "Arguments to is_default_constructible must be complete types"); + }; #else - template struct is_default_constructible : public integral_constant(0)) == sizeof(boost::type_traits::yes_type)>{}; + template struct is_default_constructible : public integral_constant(0)) == sizeof(boost::type_traits::yes_type)> + { + BOOST_STATIC_ASSERT_MSG(boost::is_complete::value, "Arguments to is_default_constructible must be complete types"); + }; #endif template struct is_default_constructible : public is_default_constructible{}; template struct is_default_constructible : public is_default_constructible{}; diff --git a/include/boost/type_traits/is_destructible.hpp b/include/boost/type_traits/is_destructible.hpp index 742d990..cc72fb7 100644 --- a/include/boost/type_traits/is_destructible.hpp +++ b/include/boost/type_traits/is_destructible.hpp @@ -12,6 +12,8 @@ #include // size_t #include #include +#include +#include #if !defined(BOOST_NO_CXX11_DECLTYPE) && !BOOST_WORKAROUND(BOOST_MSVC, < 1800) @@ -32,7 +34,10 @@ namespace boost{ } - template struct is_destructible : public integral_constant(0)) == sizeof(boost::type_traits::yes_type)>{}; + template struct is_destructible : public integral_constant(0)) == sizeof(boost::type_traits::yes_type)> + { + BOOST_STATIC_ASSERT_MSG(boost::is_complete::value, "Arguments to is_destructible must be complete types"); + }; #else @@ -42,7 +47,10 @@ namespace boost{ namespace boost{ // We don't know how to implement this: - template struct is_destructible : public integral_constant::value || is_class::value>{}; + template struct is_destructible : public integral_constant::value || is_class::value> + { + BOOST_STATIC_ASSERT_MSG(boost::is_complete::value, "Arguments to is_destructible must be complete types"); + }; #endif template <> struct is_destructible : public false_type{}; diff --git a/include/boost/type_traits/is_list_constructible.hpp b/include/boost/type_traits/is_list_constructible.hpp index 518a75b..a47fac1 100644 --- a/include/boost/type_traits/is_list_constructible.hpp +++ b/include/boost/type_traits/is_list_constructible.hpp @@ -10,6 +10,8 @@ #include #include #include +#include +#include namespace boost { @@ -18,6 +20,7 @@ namespace boost template struct is_list_constructible: false_type { + BOOST_STATIC_ASSERT_MSG(boost::is_complete::value, "Arguments to is_list_constructible must be complete types"); }; #else @@ -32,6 +35,7 @@ template false_type is_list_constructible_impl( ... ); template struct is_list_constructible: decltype( type_traits_detail::is_list_constructible_impl(0) ) { + BOOST_STATIC_ASSERT_MSG(boost::is_complete::value, "Arguments to is_list_constructible must be complete types"); }; #endif diff --git a/include/boost/type_traits/is_nothrow_move_assignable.hpp b/include/boost/type_traits/is_nothrow_move_assignable.hpp index 4fb5bd8..5f63cb7 100644 --- a/include/boost/type_traits/is_nothrow_move_assignable.hpp +++ b/include/boost/type_traits/is_nothrow_move_assignable.hpp @@ -18,13 +18,18 @@ #include #include #include +#include +#include namespace boost { #ifdef BOOST_IS_NOTHROW_MOVE_ASSIGN template -struct is_nothrow_move_assignable : public integral_constant{}; +struct is_nothrow_move_assignable : public integral_constant +{ + BOOST_STATIC_ASSERT_MSG(boost::is_complete::value, "Arguments to is_nothrow_move_assignable must be complete types"); +}; template struct is_nothrow_move_assignable : public false_type{}; template struct is_nothrow_move_assignable : public false_type{}; template struct is_nothrow_move_assignable : public false_type{}; @@ -50,7 +55,10 @@ struct false_or_cpp11_noexcept_move_assignable < } template -struct is_nothrow_move_assignable : public integral_constant::value>{}; +struct is_nothrow_move_assignable : public integral_constant::value> +{ + BOOST_STATIC_ASSERT_MSG(boost::is_complete::value, "Arguments to is_nothrow_move_assignable must be complete types"); +}; template struct is_nothrow_move_assignable : public ::boost::false_type {}; template struct is_nothrow_move_assignable : public ::boost::false_type{}; @@ -64,7 +72,10 @@ template struct is_nothrow_move_assignable : public ::boost::fals template struct is_nothrow_move_assignable : public integral_constant::value || ::boost::has_nothrow_assign::value) && ! ::boost::is_array::value>{}; + (::boost::has_trivial_move_assign::value || ::boost::has_nothrow_assign::value) && ! ::boost::is_array::value> +{ + BOOST_STATIC_ASSERT_MSG(boost::is_complete::value, "Arguments to is_nothrow_move_assignable must be complete types"); +}; #endif diff --git a/include/boost/type_traits/is_nothrow_move_constructible.hpp b/include/boost/type_traits/is_nothrow_move_constructible.hpp index 0d5d57a..6aaef51 100644 --- a/include/boost/type_traits/is_nothrow_move_constructible.hpp +++ b/include/boost/type_traits/is_nothrow_move_constructible.hpp @@ -16,13 +16,18 @@ #include #include #include +#include +#include #ifdef BOOST_IS_NOTHROW_MOVE_CONSTRUCT namespace boost { template -struct is_nothrow_move_constructible : public integral_constant{}; +struct is_nothrow_move_constructible : public integral_constant +{ + BOOST_STATIC_ASSERT_MSG(boost::is_complete::value, "Arguments to is_nothrow_move_constructible must be complete types"); +}; template struct is_nothrow_move_constructible : public ::boost::false_type {}; template struct is_nothrow_move_constructible : public ::boost::false_type{}; @@ -47,7 +52,10 @@ struct false_or_cpp11_noexcept_move_constructible < } template struct is_nothrow_move_constructible - : public integral_constant::value>{}; + : public integral_constant::value> +{ + BOOST_STATIC_ASSERT_MSG(boost::is_complete::value, "Arguments to is_nothrow_move_constructible must be complete types"); +}; template struct is_nothrow_move_constructible : public ::boost::false_type {}; template struct is_nothrow_move_constructible : public ::boost::false_type{}; @@ -66,7 +74,9 @@ template struct is_nothrow_move_constructible : public integral_constant::value || ::boost::has_nothrow_copy::value) && !::boost::is_array::value> -{}; +{ + BOOST_STATIC_ASSERT_MSG(boost::is_complete::value, "Arguments to is_nothrow_move_constructible must be complete types"); +}; #endif diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index 2e35876..e58b1f1 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -39,6 +39,10 @@ rule all-tests { { result += [ run $(source) ] ; } + for local source in [ glob compile_fail/*.cpp ] + { + result += [ compile-fail $(source) ] ; + } # # These traits have both intrinsic support, and a std conforming version, test a version with intrinsics disabled for better code coverage: # diff --git a/test/compile_fail/common_type2_fail.cpp b/test/compile_fail/common_type2_fail.cpp new file mode 100644 index 0000000..a4b3db4 --- /dev/null +++ b/test/compile_fail/common_type2_fail.cpp @@ -0,0 +1,15 @@ + +// (C) Copyright John Maddock 2017. +// Use, modification and distribution are subject to 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) + +# include +#include "../test.hpp" + +int main() +{ + return sizeof(boost::common_type::type); +} + + diff --git a/test/compile_fail/common_type_fail.cpp b/test/compile_fail/common_type_fail.cpp new file mode 100644 index 0000000..7594811 --- /dev/null +++ b/test/compile_fail/common_type_fail.cpp @@ -0,0 +1,15 @@ + +// (C) Copyright John Maddock 2017. +// Use, modification and distribution are subject to 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) + +# include +#include "../test.hpp" + +int main() +{ + return sizeof(boost::common_type::type); +} + + diff --git a/test/compile_fail/has_nothrow_assign_fail.cpp b/test/compile_fail/has_nothrow_assign_fail.cpp new file mode 100644 index 0000000..3196d3a --- /dev/null +++ b/test/compile_fail/has_nothrow_assign_fail.cpp @@ -0,0 +1,15 @@ + +// (C) Copyright John Maddock 2017. +// Use, modification and distribution are subject to 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) + +# include +#include "../test.hpp" + +int main() +{ + return boost::has_nothrow_assign::value; +} + + diff --git a/test/compile_fail/has_nothrow_cons_fail.cpp b/test/compile_fail/has_nothrow_cons_fail.cpp new file mode 100644 index 0000000..8512e5d --- /dev/null +++ b/test/compile_fail/has_nothrow_cons_fail.cpp @@ -0,0 +1,15 @@ + +// (C) Copyright John Maddock 2017. +// Use, modification and distribution are subject to 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) + +# include +#include "../test.hpp" + +int main() +{ + return boost::has_nothrow_constructor::value; +} + + diff --git a/test/compile_fail/has_nothrow_copy_fail.cpp b/test/compile_fail/has_nothrow_copy_fail.cpp new file mode 100644 index 0000000..997a48a --- /dev/null +++ b/test/compile_fail/has_nothrow_copy_fail.cpp @@ -0,0 +1,15 @@ + +// (C) Copyright John Maddock 2017. +// Use, modification and distribution are subject to 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) + +# include +#include "../test.hpp" + +int main() +{ + return boost::has_nothrow_copy::value; +} + + diff --git a/test/compile_fail/has_nothrow_destruct_fail.cpp b/test/compile_fail/has_nothrow_destruct_fail.cpp new file mode 100644 index 0000000..1b0d5a0 --- /dev/null +++ b/test/compile_fail/has_nothrow_destruct_fail.cpp @@ -0,0 +1,15 @@ + +// (C) Copyright John Maddock 2017. +// Use, modification and distribution are subject to 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) + +# include +#include "../test.hpp" + +int main() +{ + return boost::has_nothrow_destructor::value; +} + + diff --git a/test/compile_fail/is_assignable_fail.cpp b/test/compile_fail/is_assignable_fail.cpp new file mode 100644 index 0000000..b745443 --- /dev/null +++ b/test/compile_fail/is_assignable_fail.cpp @@ -0,0 +1,15 @@ + +// (C) Copyright John Maddock 2017. +// Use, modification and distribution are subject to 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) + +# include +#include "../test.hpp" + +int main() +{ + return boost::is_assignable::value; +} + + diff --git a/test/compile_fail/is_base_of_fail.cpp b/test/compile_fail/is_base_of_fail.cpp new file mode 100644 index 0000000..cff40b2 --- /dev/null +++ b/test/compile_fail/is_base_of_fail.cpp @@ -0,0 +1,15 @@ + +// (C) Copyright John Maddock 2017. +// Use, modification and distribution are subject to 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) + +# include +#include "../test.hpp" + +int main() +{ + return boost::is_base_of::value; +} + + diff --git a/test/compile_fail/is_constructible_fail.cpp b/test/compile_fail/is_constructible_fail.cpp new file mode 100644 index 0000000..926b43c --- /dev/null +++ b/test/compile_fail/is_constructible_fail.cpp @@ -0,0 +1,15 @@ + +// (C) Copyright John Maddock 2017. +// Use, modification and distribution are subject to 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) + +# include +#include "../test.hpp" + +int main() +{ + return boost::is_constructible::value; +} + + diff --git a/test/compile_fail/is_convertible2_fail.cpp b/test/compile_fail/is_convertible2_fail.cpp new file mode 100644 index 0000000..0afd996 --- /dev/null +++ b/test/compile_fail/is_convertible2_fail.cpp @@ -0,0 +1,19 @@ + +// (C) Copyright John Maddock 2017. +// Use, modification and distribution are subject to 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) + +# include +#include "../test.hpp" + +#if defined(CI_SUPPRESS_KNOWN_ISSUES) && defined(BOOST_MSVC) && (BOOST_MSVC <= 1800) +#error "Sorry check doesn't work" +#endif + +int main() +{ + return boost::is_convertible::value; +} + + diff --git a/test/compile_fail/is_convertible_fail.cpp b/test/compile_fail/is_convertible_fail.cpp new file mode 100644 index 0000000..792c442 --- /dev/null +++ b/test/compile_fail/is_convertible_fail.cpp @@ -0,0 +1,15 @@ + +// (C) Copyright John Maddock 2017. +// Use, modification and distribution are subject to 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) + +# include +#include "../test.hpp" + +int main() +{ + return boost::is_convertible::value; +} + + diff --git a/test/compile_fail/is_copy_assignable_fail.cpp b/test/compile_fail/is_copy_assignable_fail.cpp new file mode 100644 index 0000000..f8c512e --- /dev/null +++ b/test/compile_fail/is_copy_assignable_fail.cpp @@ -0,0 +1,15 @@ + +// (C) Copyright John Maddock 2017. +// Use, modification and distribution are subject to 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) + +# include +#include "../test.hpp" + +int main() +{ + return boost::is_copy_assignable::value; +} + + diff --git a/test/compile_fail/is_copy_constructible_fail.cpp b/test/compile_fail/is_copy_constructible_fail.cpp new file mode 100644 index 0000000..8ab35da --- /dev/null +++ b/test/compile_fail/is_copy_constructible_fail.cpp @@ -0,0 +1,15 @@ + +// (C) Copyright John Maddock 2017. +// Use, modification and distribution are subject to 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) + +# include +#include "../test.hpp" + +int main() +{ + return boost::is_copy_constructible::value; +} + + diff --git a/test/compile_fail/is_default_constructible_fail.cpp b/test/compile_fail/is_default_constructible_fail.cpp new file mode 100644 index 0000000..78381b3 --- /dev/null +++ b/test/compile_fail/is_default_constructible_fail.cpp @@ -0,0 +1,15 @@ + +// (C) Copyright John Maddock 2017. +// Use, modification and distribution are subject to 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) + +# include +#include "../test.hpp" + +int main() +{ + return boost::is_default_constructible::value; +} + + diff --git a/test/compile_fail/is_destructible_fail.cpp b/test/compile_fail/is_destructible_fail.cpp new file mode 100644 index 0000000..33dea9b --- /dev/null +++ b/test/compile_fail/is_destructible_fail.cpp @@ -0,0 +1,15 @@ + +// (C) Copyright John Maddock 2017. +// Use, modification and distribution are subject to 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) + +# include +#include "../test.hpp" + +int main() +{ + return boost::is_destructible::value; +} + + diff --git a/test/compile_fail/is_empty_fail.cpp b/test/compile_fail/is_empty_fail.cpp new file mode 100644 index 0000000..ef3d171 --- /dev/null +++ b/test/compile_fail/is_empty_fail.cpp @@ -0,0 +1,15 @@ + +// (C) Copyright John Maddock 2017. +// Use, modification and distribution are subject to 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) + +# include +#include "../test.hpp" + +int main() +{ + return boost::is_empty::value; +} + + diff --git a/test/compile_fail/is_list_constructible_fail.cpp b/test/compile_fail/is_list_constructible_fail.cpp new file mode 100644 index 0000000..429f8de --- /dev/null +++ b/test/compile_fail/is_list_constructible_fail.cpp @@ -0,0 +1,15 @@ + +// (C) Copyright John Maddock 2017. +// Use, modification and distribution are subject to 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) + +# include +#include "../test.hpp" + +int main() +{ + return boost::is_list_constructible::value; +} + + diff --git a/test/compile_fail/is_nothrow_move_assignable_fail.cpp b/test/compile_fail/is_nothrow_move_assignable_fail.cpp new file mode 100644 index 0000000..5cb5f54 --- /dev/null +++ b/test/compile_fail/is_nothrow_move_assignable_fail.cpp @@ -0,0 +1,15 @@ + +// (C) Copyright John Maddock 2017. +// Use, modification and distribution are subject to 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) + +# include +#include "../test.hpp" + +int main() +{ + return boost::is_nothrow_move_assignable::value; +} + + diff --git a/test/compile_fail/is_nothrow_move_constructible_fail.cpp b/test/compile_fail/is_nothrow_move_constructible_fail.cpp new file mode 100644 index 0000000..54d1329 --- /dev/null +++ b/test/compile_fail/is_nothrow_move_constructible_fail.cpp @@ -0,0 +1,15 @@ + +// (C) Copyright John Maddock 2017. +// Use, modification and distribution are subject to 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) + +# include +#include "../test.hpp" + +int main() +{ + return boost::is_nothrow_move_constructible::value; +} + + diff --git a/test/compile_fail/is_polymorphic_fail.cpp b/test/compile_fail/is_polymorphic_fail.cpp new file mode 100644 index 0000000..d182519 --- /dev/null +++ b/test/compile_fail/is_polymorphic_fail.cpp @@ -0,0 +1,15 @@ + +// (C) Copyright John Maddock 2017. +// Use, modification and distribution are subject to 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) + +# include +#include "../test.hpp" + +int main() +{ + return boost::is_polymorphic::value; +} + + diff --git a/test/compile_fail/is_stateless_fail.cpp b/test/compile_fail/is_stateless_fail.cpp new file mode 100644 index 0000000..2a8b4aa --- /dev/null +++ b/test/compile_fail/is_stateless_fail.cpp @@ -0,0 +1,15 @@ + +// (C) Copyright John Maddock 2017. +// Use, modification and distribution are subject to 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) + +# include +#include "../test.hpp" + +int main() +{ + return boost::is_stateless::value; +} + + diff --git a/test/compile_fail/is_virtual_base_of_fail.cpp b/test/compile_fail/is_virtual_base_of_fail.cpp new file mode 100644 index 0000000..a8ca79e --- /dev/null +++ b/test/compile_fail/is_virtual_base_of_fail.cpp @@ -0,0 +1,15 @@ + +// (C) Copyright John Maddock 2017. +// Use, modification and distribution are subject to 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) + +# include +#include "../test.hpp" + +int main() +{ + return boost::is_virtual_base_of::value; +} + + diff --git a/test/is_complete_test.cpp b/test/is_complete_test.cpp new file mode 100644 index 0000000..b981f18 --- /dev/null +++ b/test/is_complete_test.cpp @@ -0,0 +1,55 @@ + +// (C) Copyright John Maddock 2000. +// Use, modification and distribution are subject to 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) + +#ifdef TEST_STD +# include +#else +# include +#endif +#include "test.hpp" +#include "check_integral_constant.hpp" + +TT_TEST_BEGIN(is_complete) + +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_complete::value, true); +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_complete::value, true); +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_complete::value, true); +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_complete::value, true); +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_complete::value, true); +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_complete::value, true); +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_complete::value, true); +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_complete::value, true); +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_complete::value, true); +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_complete::value, true); +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_complete::value, true); +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_complete::value, true); + +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_complete::value, true); +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_complete::value, true); +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_complete::value, true); +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_complete::value, true); +#ifndef BOOST_NO_SFINAE +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_complete::value, false); +#endif + +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_complete::value, true); +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_complete::value, true); +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_complete::value, true); +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_complete::value, true); +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_complete::value, true); +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_complete::value, true); +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_complete::value, true); +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_complete::value, true); +#ifndef BOOST_NO_SFINAE +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_complete::value, false); +#endif +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_complete::value, true); +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_complete::value, true); +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_complete::value, true); +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_complete::value, true); + +TT_TEST_END + From bfb6384a0ac3ca9383a085bf386367b64088510f Mon Sep 17 00:00:00 2001 From: jzmaddock Date: Sun, 4 Feb 2018 12:52:24 +0000 Subject: [PATCH 2/4] Assert on incomplete types: begin fixing test failures for msvc-12.0, 14.0, and clang. --- include/boost/type_traits/is_complete.hpp | 4 ++-- include/boost/type_traits/is_convertible.hpp | 11 +++++++++-- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/include/boost/type_traits/is_complete.hpp b/include/boost/type_traits/is_complete.hpp index 0de36a9..55dbbbf 100644 --- a/include/boost/type_traits/is_complete.hpp +++ b/include/boost/type_traits/is_complete.hpp @@ -27,7 +27,7 @@ namespace boost { -#ifndef BOOST_NO_SFINAE_EXPR +#if !defined(BOOST_NO_SFINAE_EXPR) && !BOOST_WORKAROUND(BOOST_MSVC, <= 1900) namespace detail{ @@ -43,7 +43,7 @@ namespace boost { template struct is_complete : public integral_constant::type>::value || (sizeof(detail::check_is_complete(0)) != sizeof(char))> {}; -#elif !defined(BOOST_NO_SFINAE) +#elif !defined(BOOST_NO_SFINAE) && !defined(BOOST_NO_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGS) namespace detail { diff --git a/include/boost/type_traits/is_convertible.hpp b/include/boost/type_traits/is_convertible.hpp index 991cdfd..058301f 100644 --- a/include/boost/type_traits/is_convertible.hpp +++ b/include/boost/type_traits/is_convertible.hpp @@ -14,11 +14,11 @@ #include #include -#ifndef BOOST_IS_CONVERTIBLE #include #include #include #include +#ifndef BOOST_IS_CONVERTIBLE #include #include #include @@ -487,7 +487,14 @@ struct is_convertible : public integral_constant -struct is_convertible : public integral_constant {}; +struct is_convertible : public integral_constant +{ +#ifdef __clang__ + // clang's intrinsic doesn't assert on incomplete types: + BOOST_STATIC_ASSERT_MSG(boost::is_complete::value || boost::is_void::value || boost::is_array::value, "Destination argument type to is_convertible must be a complete type"); + BOOST_STATIC_ASSERT_MSG(boost::is_complete::value || boost::is_void::value || boost::is_array::value, "From argument type to is_convertible must be a complete type"); +#endif +}; #endif From 0886e13a99f5e209be5b049501c14367255bd61f Mon Sep 17 00:00:00 2001 From: jzmaddock Date: Sun, 4 Feb 2018 18:15:34 +0000 Subject: [PATCH 3/4] Assert completeness fixes: fix up msvc failures. --- include/boost/type_traits/is_complete.hpp | 8 ++++++++ include/boost/type_traits/is_convertible.hpp | 5 ++++- test/compile_fail/is_assignable_fail.cpp | 4 ++++ test/compile_fail/is_convertible2_fail.cpp | 4 ++-- test/compile_fail/is_list_constructible_fail.cpp | 4 ++++ test/is_complete_test.cpp | 4 ++-- 6 files changed, 24 insertions(+), 5 deletions(-) diff --git a/include/boost/type_traits/is_complete.hpp b/include/boost/type_traits/is_complete.hpp index 55dbbbf..af9a1ef 100644 --- a/include/boost/type_traits/is_complete.hpp +++ b/include/boost/type_traits/is_complete.hpp @@ -27,6 +27,12 @@ namespace boost { + +// +// We will undef this if the trait isn't fully functional: +// +#define BOOST_TT_HAS_WORKING_IS_COMPLETE + #if !defined(BOOST_NO_SFINAE_EXPR) && !BOOST_WORKAROUND(BOOST_MSVC, <= 1900) namespace detail{ @@ -74,6 +80,8 @@ namespace boost { template struct is_complete : public integral_constant {}; +#undef BOOST_TT_HAS_WORKING_IS_COMPLETE + #endif } // namespace boost diff --git a/include/boost/type_traits/is_convertible.hpp b/include/boost/type_traits/is_convertible.hpp index 058301f..bf648fc 100644 --- a/include/boost/type_traits/is_convertible.hpp +++ b/include/boost/type_traits/is_convertible.hpp @@ -489,7 +489,10 @@ struct is_convertible : public integral_constant struct is_convertible : public integral_constant { -#ifdef __clang__ +#if BOOST_WORKAROUND(BOOST_MSVC, <= 1900) + BOOST_STATIC_ASSERT_MSG(boost::is_complete::value || boost::is_void::value || boost::is_array::value || boost::is_reference::value, "From argument type to is_convertible must be a complete type"); +#endif +#if defined(__clang__) // clang's intrinsic doesn't assert on incomplete types: BOOST_STATIC_ASSERT_MSG(boost::is_complete::value || boost::is_void::value || boost::is_array::value, "Destination argument type to is_convertible must be a complete type"); BOOST_STATIC_ASSERT_MSG(boost::is_complete::value || boost::is_void::value || boost::is_array::value, "From argument type to is_convertible must be a complete type"); diff --git a/test/compile_fail/is_assignable_fail.cpp b/test/compile_fail/is_assignable_fail.cpp index b745443..2ea6ac2 100644 --- a/test/compile_fail/is_assignable_fail.cpp +++ b/test/compile_fail/is_assignable_fail.cpp @@ -7,6 +7,10 @@ # include #include "../test.hpp" +#ifndef BOOST_TT_HAS_WORKING_IS_COMPLETE +#error "Sorry can't test this." +#endif + int main() { return boost::is_assignable::value; diff --git a/test/compile_fail/is_convertible2_fail.cpp b/test/compile_fail/is_convertible2_fail.cpp index 0afd996..8a4a051 100644 --- a/test/compile_fail/is_convertible2_fail.cpp +++ b/test/compile_fail/is_convertible2_fail.cpp @@ -7,8 +7,8 @@ # include #include "../test.hpp" -#if defined(CI_SUPPRESS_KNOWN_ISSUES) && defined(BOOST_MSVC) && (BOOST_MSVC <= 1800) -#error "Sorry check doesn't work" +#ifndef BOOST_TT_HAS_WORKING_IS_COMPLETE +#error "Sorry can't test this." #endif int main() diff --git a/test/compile_fail/is_list_constructible_fail.cpp b/test/compile_fail/is_list_constructible_fail.cpp index 429f8de..eb69bd1 100644 --- a/test/compile_fail/is_list_constructible_fail.cpp +++ b/test/compile_fail/is_list_constructible_fail.cpp @@ -7,6 +7,10 @@ # include #include "../test.hpp" +#ifndef BOOST_TT_HAS_WORKING_IS_COMPLETE +#error "Sorry can't test this." +#endif + int main() { return boost::is_list_constructible::value; diff --git a/test/is_complete_test.cpp b/test/is_complete_test.cpp index b981f18..075e70d 100644 --- a/test/is_complete_test.cpp +++ b/test/is_complete_test.cpp @@ -31,7 +31,7 @@ BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_complete::value, true); BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_complete::value, true); BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_complete::value, true); BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_complete::value, true); -#ifndef BOOST_NO_SFINAE +#ifdef BOOST_TT_HAS_WORKING_IS_COMPLETE BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_complete::value, false); #endif @@ -43,7 +43,7 @@ BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_complete::value, true); BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_complete::value, true); BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_complete::value, true); BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_complete::value, true); -#ifndef BOOST_NO_SFINAE +#ifdef BOOST_TT_HAS_WORKING_IS_COMPLETE BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_complete::value, false); #endif BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_complete::value, true); From df4eccb9111e6298e028363fff106988c0048ec6 Mon Sep 17 00:00:00 2001 From: jzmaddock Date: Sun, 4 Feb 2018 19:26:10 +0000 Subject: [PATCH 4/4] Document is_complete. [CI SKIP] --- doc/html/boost_typetraits/reference.html | 1 + .../boost_typetraits/reference/is_class.html | 6 +- .../reference/is_complete.html | 79 +++++++++++++++++++ .../reference/is_complex.html | 6 +- doc/html/index.html | 1 + doc/html/index/s11.html | 3 +- doc/html/index/s12.html | 2 +- doc/html/index/s13.html | 6 +- doc/html/index/s14.html | 18 ++++- doc/is_complete.qbk | 29 +++++++ doc/type_traits.qbk | 1 + 11 files changed, 142 insertions(+), 10 deletions(-) create mode 100644 doc/html/boost_typetraits/reference/is_complete.html create mode 100644 doc/is_complete.qbk diff --git a/doc/html/boost_typetraits/reference.html b/doc/html/boost_typetraits/reference.html index 668a724..83f7ba1 100644 --- a/doc/html/boost_typetraits/reference.html +++ b/doc/html/boost_typetraits/reference.html @@ -108,6 +108,7 @@
is_assignable
is_base_of
is_class
+
is_complete
is_complex
is_compound
is_const
diff --git a/doc/html/boost_typetraits/reference/is_class.html b/doc/html/boost_typetraits/reference/is_class.html index 480364a..ce40913 100644 --- a/doc/html/boost_typetraits/reference/is_class.html +++ b/doc/html/boost_typetraits/reference/is_class.html @@ -7,7 +7,7 @@ - + @@ -20,7 +20,7 @@

-PrevUpHomeNext +PrevUpHomeNext

@@ -93,7 +93,7 @@
-PrevUpHomeNext +PrevUpHomeNext
diff --git a/doc/html/boost_typetraits/reference/is_complete.html b/doc/html/boost_typetraits/reference/is_complete.html new file mode 100644 index 0000000..6a5fe82 --- /dev/null +++ b/doc/html/boost_typetraits/reference/is_complete.html @@ -0,0 +1,79 @@ + + + +is_complete + + + + + + + + + + + + + + + +
Boost C++ LibrariesHomeLibrariesPeopleFAQMore
+
+
+PrevUpHomeNext +
+
+ +
template <class T>
+struct is_complete : public true_type-or-false_type {};
+
+

+ Inherits: If T + is a complete type then inherits from true_type, + otherwise inherits from false_type. +

+
+ + + + + +
[Important]Important

+ This trait is designed for one use only: to trigger a hard error (via a + static_assert) when a template + is accidentally instantiated on an incomplete type. Any other use case + will cause ODR violations as the "completeness" of type T may vary at different points in the + current translation unit, as well as across translations units. In particular this trait should never ever be used to change + code paths depending on the completeness of a type. +

+

+ Header: #include + <boost/type_traits/is_complete.hpp> + or #include <boost/type_traits.hpp> +

+

+ Compiler Compatibility: Requires C++11 SFINAE-expressions + to function fully. The macro BOOST_TT_HAS_WORKING_IS_COMPLETE + is defined when the trait is fully functional. +

+
+ + + +
+
+
+PrevUpHomeNext +
+ + diff --git a/doc/html/boost_typetraits/reference/is_complex.html b/doc/html/boost_typetraits/reference/is_complex.html index 684b36c..5668e28 100644 --- a/doc/html/boost_typetraits/reference/is_complex.html +++ b/doc/html/boost_typetraits/reference/is_complex.html @@ -6,7 +6,7 @@ - + @@ -20,7 +20,7 @@
-PrevUpHomeNext +PrevUpHomeNext

@@ -62,7 +62,7 @@
-PrevUpHomeNext +PrevUpHomeNext
diff --git a/doc/html/index.html b/doc/html/index.html index 7e6d1f5..7785e78 100644 --- a/doc/html/index.html +++ b/doc/html/index.html @@ -164,6 +164,7 @@
is_assignable
is_base_of
is_class
+
is_complete
is_complex
is_compound
is_const
diff --git a/doc/html/index/s11.html b/doc/html/index/s11.html index 51c8a37..3007515 100644 --- a/doc/html/index/s11.html +++ b/doc/html/index/s11.html @@ -24,7 +24,7 @@

-Class Index

+Class Index

A C D E F H I M N O P R T

@@ -232,6 +232,7 @@
  • User Defined Specializations

  • +
  • is_complete

  • is_complex

  • is_compound

  • is_const

  • diff --git a/doc/html/index/s12.html b/doc/html/index/s12.html index df18fb5..aa6adbb 100644 --- a/doc/html/index/s12.html +++ b/doc/html/index/s12.html @@ -24,7 +24,7 @@

    -Typedef Index

    +Typedef Index

    F R T V

    diff --git a/doc/html/index/s13.html b/doc/html/index/s13.html index 6fca6f7..a8db2be 100644 --- a/doc/html/index/s13.html +++ b/doc/html/index/s13.html @@ -24,7 +24,7 @@

    -Macro Index

    +Macro Index

    B

    @@ -168,6 +168,10 @@
  • +

    BOOST_TT_HAS_WORKING_IS_COMPLETE

    + +
  • +
  • BOOST_TT_IS_CONSTRUCTIBLE_CONFORMING

  • diff --git a/doc/html/index/s14.html b/doc/html/index/s14.html index 2bf95cd..6727001 100644 --- a/doc/html/index/s14.html +++ b/doc/html/index/s14.html @@ -23,7 +23,7 @@

    -Index

    +Index

    A B C D E F H I M N O P R T U V

    @@ -199,6 +199,10 @@
  • +

    BOOST_TT_HAS_WORKING_IS_COMPLETE

    + +
  • +
  • BOOST_TT_IS_CONSTRUCTIBLE_CONFORMING

  • @@ -208,6 +212,10 @@
    • +

      check

      + +
    • +
    • common_type

    • +
    • +

      is_complete

      + +
    • is_complex

    • is_compound

    • is_const

    • @@ -871,6 +886,7 @@

      Operator Type Traits

      • any

      • +
      • check

      • dont_care

      • has_equal_to

      • has_operator

      • diff --git a/doc/is_complete.qbk b/doc/is_complete.qbk new file mode 100644 index 0000000..9624e16 --- /dev/null +++ b/doc/is_complete.qbk @@ -0,0 +1,29 @@ +[/ + Copyright 2018 John Maddock. + 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). +] + +[section:is_complete is_complete] + + template + struct is_complete : public __tof {}; + +__inherit If `T` is a complete type then inherits from __true_type, +otherwise inherits from __false_type. + +[important This trait is designed for one use only: to trigger a hard error (via a `static_assert`) when a template +is accidentally instantiated on an incomplete type. Any other use case will cause ODR violations as the "completeness" +of type `T` may vary at different points in the current translation unit, as well as across translations units. +['[*In particular this trait should never ever be used to change code paths depending on the completeness of a type]].] + +__header ` #include ` or ` #include ` + +__compat Requires C++11 SFINAE-expressions to function fully. The macro `BOOST_TT_HAS_WORKING_IS_COMPLETE` is defined +when the trait is fully functional. + +[endsect] + + + diff --git a/doc/type_traits.qbk b/doc/type_traits.qbk index b751f9f..757ca99 100644 --- a/doc/type_traits.qbk +++ b/doc/type_traits.qbk @@ -291,6 +291,7 @@ See __has_trivial_constructor. [include is_assignable.qbk] [include is_base_of.qbk] [include is_class.qbk] +[include is_complete.qbk] [include is_complex.qbk] [include is_compound.qbk] [include is_const.qbk]