mirror of
https://github.com/boostorg/type_traits.git
synced 2025-07-31 13:07:22 +02:00
is_virtual_base_of.hpp: simplify and use clang version for all compilers.
This commit is contained in:
@ -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<class T, class U>
|
||||
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<class T, class U,
|
||||
boost::void_t<decltype((U*)(std::declval<T*>()))>* =
|
||||
nullptr>
|
||||
@ -48,49 +59,6 @@ namespace boost {
|
||||
!detail::is_virtual_base_impl<U, T>(0)
|
||||
> {};
|
||||
|
||||
|
||||
#else
|
||||
|
||||
template<class Base, class Derived>
|
||||
struct is_virtual_base_of_impl
|
||||
{
|
||||
template<class From, class To>
|
||||
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<unsigned = sizeof((To*)((From*)(0)))> 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<Base, Derived>::value && can_cast<Derived, Base>::value && !can_cast<Base, Derived>::value));
|
||||
};
|
||||
|
||||
#ifdef BOOST_MSVC
|
||||
#pragma warning( pop )
|
||||
#endif
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template <class Base, class Derived> struct is_virtual_base_of : public integral_constant<bool, (::boost::detail::is_virtual_base_of_impl<Base, Derived>::value)>{};
|
||||
|
||||
#endif // __clang__
|
||||
|
||||
#else
|
||||
|
||||
template<typename Base, typename Derived, typename tag>
|
||||
|
Reference in New Issue
Block a user