Merge pull request #180 from Lastique/feature/better_fallback_is_complete

Make fallback `is_complete` implementation more robust
This commit is contained in:
jzmaddock
2025-04-21 12:16:06 +01:00
committed by GitHub
2 changed files with 45 additions and 12 deletions

View File

@@ -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 <std::size_t N>
struct ok_tag { double d; char c[N]; };
@@ -48,15 +47,15 @@ namespace boost {
ok_tag<sizeof(T)> check_is_complete(int);
template <class T>
char check_is_complete(...);
}
} // namespace detail
template <class T> struct is_complete
: public integral_constant<bool, ::boost::is_function<typename boost::remove_reference<T>::type>::value || (sizeof(boost::detail::check_is_complete<T>(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 <class T>
struct is_complete_imp
@@ -70,7 +69,7 @@ namespace boost {
static const bool value = sizeof(check<T>(0)) == sizeof(type_traits::yes_type);
};
} // namespace detail
} // namespace detail
template <class T>
@@ -78,11 +77,33 @@ namespace boost {
{};
template <class T>
struct is_complete<T&> : boost::is_complete<T> {};
#else
template <class T> struct is_complete
: public boost::integral_constant<bool, true> {};
namespace detail {
template <class T>
struct is_complete_impl : public boost::true_type {};
template < >
struct is_complete_impl<void> : public boost::false_type {};
template <class T>
struct is_complete_impl<T[]> : public boost::false_type {};
template <class T>
struct is_complete_impl<T&> : public is_complete_impl<T>::type {};
} // namespace detail
template <class T>
struct is_complete : public detail::is_complete_impl<T>::type {};
template <class T>
struct is_complete<const T> : public detail::is_complete_impl<T>::type {};
template <class T>
struct is_complete<volatile T> : public detail::is_complete_impl<T>::type {};
template <class T>
struct is_complete<const volatile T> : public detail::is_complete_impl<T>::type {};
#undef BOOST_TT_HAS_WORKING_IS_COMPLETE

View File

@@ -14,6 +14,15 @@
TT_TEST_BEGIN(is_complete)
BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_complete<void>::value, false);
BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_complete<void const>::value, false);
BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_complete<void volatile>::value, false);
BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_complete<void const volatile>::value, false);
BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_complete<void*>::value, true);
BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_complete<void const*>::value, true);
BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_complete<void volatile*>::value, true);
BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_complete<void const volatile*>::value, true);
BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_complete<int>::value, true);
BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_complete<int const>::value, true);
BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_complete<int volatile>::value, true);
@@ -31,9 +40,11 @@ BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_complete<int[2]>::value, true);
BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_complete<int const[3]>::value, true);
BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_complete<int volatile[2][3]>::value, true);
BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_complete<int const volatile[4][5][6]>::value, true);
#ifdef BOOST_TT_HAS_WORKING_IS_COMPLETE
BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_complete<int[]>::value, false);
#endif
BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_complete<int const[]>::value, false);
BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_complete<int volatile[]>::value, false);
BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_complete<int const volatile[]>::value, false);
BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_complete<enum_UDT>::value, true);
BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_complete<UDT>::value, true);
@@ -46,6 +57,7 @@ BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_complete<test_abc1>::value, true);
#ifdef BOOST_TT_HAS_WORKING_IS_COMPLETE
BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_complete<incomplete_type>::value, false);
#endif
BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_complete<incomplete_type*>::value, true);
BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_complete<polymorphic_base>::value, true);
BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_complete<virtual_inherit6>::value, true);
BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_complete<foo0_t>::value, true);