From 7bba2acbcc4c250d77714f728a5f28255adb269c Mon Sep 17 00:00:00 2001 From: jzmaddock Date: Fri, 11 May 2018 17:19:44 +0100 Subject: [PATCH] is_virtual_base_of.hpp: simplify and use clang version for all compilers. --- .../boost/type_traits/is_virtual_base_of.hpp | 56 ++++--------------- 1 file changed, 12 insertions(+), 44 deletions(-) diff --git a/include/boost/type_traits/is_virtual_base_of.hpp b/include/boost/type_traits/is_virtual_base_of.hpp index f9e1331..c3d7684 100644 --- a/include/boost/type_traits/is_virtual_base_of.hpp +++ b/include/boost/type_traits/is_virtual_base_of.hpp @@ -27,11 +27,22 @@ namespace boost { #if !defined(BOOST_NO_SFINAE_EXPR) && !defined(BOOST_NO_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGS) && !defined(BOOST_NO_CXX11_NULLPTR) && !BOOST_WORKAROUND(BOOST_GCC, < 40800) -#ifdef __clang__ + // Implementation based on the standard's rules of explicit type conversions. + // A pointer to an object of *derived* class type may be explicitly converted to a pointer to an *unambiguous* *base* class type. + // A pointer to an object of an *unambiguous* *non-virtual* *base* class type may be explicitly converted to a pointer of a *derived* class type. + // Therefore Derived has a virtual base Base if and only if + // (1) a Derived* can be converted to Base* (so the base class is unambiguous, which comes necessarily from virtual inheritance) + // (2) a Base* cannot be converted to Derived* (so the base class is either ambiguous or virtual) + // With both conditions true, Base must be a virtual base of Derived. + // The "is_base_of" is only needed so the compiler can (but is not required to) error out if the types are incomplete. + // This is in league with the the expected behaviour. template constexpr bool is_virtual_base_impl(...) { return true; } + // C-style casts have the power to ignore inheritance visibility while still act as a static_cast. + // They can also fall back to the behaviour of reinterpret_cast, which allows is_virtual_base_of to work on non-class types too. + // Note that because we are casting pointers there can be no user-defined operators to interfere. template()))>* = nullptr> @@ -48,49 +59,6 @@ namespace boost { !detail::is_virtual_base_impl(0) > {}; - -#else - -template -struct is_virtual_base_of_impl -{ - template - struct can_cast - { - typedef char YES; - typedef struct { char x[2]; } NO; - - // C-style casts have the power to ignore inheritance visibility while still act as a static_cast. - // They can also fall back to the behaviour of reinterpret_cast, which allows is_virtual_base_of to work on non-class types too. - // Note that because we are casting pointers there can be no user-defined operators to interfere. - template static YES test(int*); - static NO test(...); - - BOOST_STATIC_CONSTANT(bool, value = (sizeof(test(nullptr)) == sizeof(YES))); - }; - - // Implementation based on the standard's rules of explicit type conversions. - // A pointer to an object of *derived* class type may be explicitly converted to a pointer to an *unambiguous* *base* class type. - // A pointer to an object of an *unambiguous* *non-virtual* *base* class type may be explicitly converted to a pointer of a *derived* class type. - // Therefore Derived has a virtual base Base if and only if - // (1) a Derived* can be converted to Base* (so the base class is unambiguous, which comes necessarily from virtual inheritance) - // (2) a Base* cannot be converted to Derived* (so the base class is either ambiguous or virtual) - // With both conditions true, Base must be a virtual base of Derived. - // The "is_base_of" is only needed so the compiler can (but is not required to) error out if the types are incomplete. - // This is in league with the the expected behaviour. - BOOST_STATIC_CONSTANT(bool, value = (boost::is_base_of::value && can_cast::value && !can_cast::value)); -}; - -#ifdef BOOST_MSVC -#pragma warning( pop ) -#endif - -} // namespace detail - -template struct is_virtual_base_of : public integral_constant::value)>{}; - -#endif // __clang__ - #else template