From 14560070cab41ef6c76e94a85b80abb3a6bfdb82 Mon Sep 17 00:00:00 2001 From: Andrey Semashev Date: Sun, 21 May 2023 15:05:13 +0300 Subject: [PATCH] Make fallback is_complete implementation more robust. When all else fails, at least indicate the types that we always know to be incomplete: cv void and boundless arrays. Also cleanup formatting a bit. --- include/boost/type_traits/is_complete.hpp | 41 +++++++++++++++++------ test/is_complete_test.cpp | 16 +++++++-- 2 files changed, 45 insertions(+), 12 deletions(-) diff --git a/include/boost/type_traits/is_complete.hpp b/include/boost/type_traits/is_complete.hpp index 08f0e62..428edf1 100644 --- a/include/boost/type_traits/is_complete.hpp +++ b/include/boost/type_traits/is_complete.hpp @@ -27,11 +27,10 @@ * 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 { - // // We will undef this if the trait isn't fully functional: // @@ -39,7 +38,7 @@ namespace boost { #if !defined(BOOST_NO_SFINAE_EXPR) && !BOOST_WORKAROUND(BOOST_MSVC, <= 1900) && !BOOST_WORKAROUND(BOOST_GCC_VERSION, < 40600) - namespace detail{ + namespace detail { template struct ok_tag { double d; char c[N]; }; @@ -48,15 +47,15 @@ namespace boost { ok_tag check_is_complete(int); template char check_is_complete(...); - } + + } // namespace detail template struct is_complete : public integral_constant::type>::value || (sizeof(boost::detail::check_is_complete(0)) != sizeof(char))> {}; #elif !defined(BOOST_NO_SFINAE) && !defined(BOOST_NO_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGS) && !BOOST_WORKAROUND(BOOST_GCC_VERSION, < 40500) - namespace detail - { + namespace detail { template struct is_complete_imp @@ -70,7 +69,7 @@ namespace boost { static const bool value = sizeof(check(0)) == sizeof(type_traits::yes_type); }; -} // namespace detail + } // namespace detail template @@ -78,11 +77,33 @@ namespace boost { {}; template struct is_complete : boost::is_complete {}; - + #else - template struct is_complete - : public boost::integral_constant {}; + namespace detail { + + template + struct is_complete_impl : public boost::true_type {}; + + template < > + struct is_complete_impl : public boost::false_type {}; + + template + struct is_complete_impl : public boost::false_type {}; + + template + struct is_complete_impl : public is_complete_impl::type {}; + + } // namespace detail + + template + struct is_complete : public detail::is_complete_impl::type {}; + template + struct is_complete : public detail::is_complete_impl::type {}; + template + struct is_complete : public detail::is_complete_impl::type {}; + template + struct is_complete : public detail::is_complete_impl::type {}; #undef BOOST_TT_HAS_WORKING_IS_COMPLETE diff --git a/test/is_complete_test.cpp b/test/is_complete_test.cpp index 075e70d..74d7a3d 100644 --- a/test/is_complete_test.cpp +++ b/test/is_complete_test.cpp @@ -14,6 +14,15 @@ TT_TEST_BEGIN(is_complete) +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_complete::value, false); +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_complete::value, false); +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_complete::value, false); +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_complete::value, false); +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); @@ -31,9 +40,11 @@ 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); -#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, false); +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_complete::value, false); +BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_complete::value, false); BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_complete::value, true); BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_complete::value, true); @@ -46,6 +57,7 @@ BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_complete::value, true); #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); 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);