libstdc++: add std::is_virtual_base_of
Added by P2985R0 for C++26. This simply exposes the compiler builtin, and adds the feature-testing macro. libstdc++-v3/ChangeLog: * include/bits/version.def: Added the feature-testing macro. * include/bits/version.h: Regenerated. * include/std/type_traits: Add support for std::is_virtual_base_of and std::is_virtual_base_of_v, implemented in terms of the compiler builtin. * testsuite/20_util/is_virtual_base_of/value.cc: New test. Signed-off-by: Giuseppe D'Angelo <giuseppe.dangelo@kdab.com> Reviewed-by: Jonathan Wakely <jwakely@redhat.com>
This commit is contained in:
parent
7c0d1e9f2a
commit
9fc5b8f956
4 changed files with 67 additions and 0 deletions
|
@ -1807,6 +1807,15 @@ ftms = {
|
|||
};
|
||||
};
|
||||
|
||||
ftms = {
|
||||
name = is_virtual_base_of;
|
||||
values = {
|
||||
v = 202406;
|
||||
cxxmin = 26;
|
||||
extra_cond = "__has_builtin(__builtin_is_virtual_base_of)";
|
||||
};
|
||||
};
|
||||
|
||||
ftms = {
|
||||
name = ranges_concat;
|
||||
values = {
|
||||
|
|
|
@ -2000,6 +2000,16 @@
|
|||
#endif /* !defined(__cpp_lib_fstream_native_handle) && defined(__glibcxx_want_fstream_native_handle) */
|
||||
#undef __glibcxx_want_fstream_native_handle
|
||||
|
||||
#if !defined(__cpp_lib_is_virtual_base_of)
|
||||
# if (__cplusplus > 202302L) && (__has_builtin(__builtin_is_virtual_base_of))
|
||||
# define __glibcxx_is_virtual_base_of 202406L
|
||||
# if defined(__glibcxx_want_all) || defined(__glibcxx_want_is_virtual_base_of)
|
||||
# define __cpp_lib_is_virtual_base_of 202406L
|
||||
# endif
|
||||
# endif
|
||||
#endif /* !defined(__cpp_lib_is_virtual_base_of) && defined(__glibcxx_want_is_virtual_base_of) */
|
||||
#undef __glibcxx_want_is_virtual_base_of
|
||||
|
||||
#if !defined(__cpp_lib_ranges_concat)
|
||||
# if (__cplusplus > 202302L)
|
||||
# define __glibcxx_ranges_concat 202403L
|
||||
|
|
|
@ -53,6 +53,7 @@
|
|||
#define __glibcxx_want_is_pointer_interconvertible
|
||||
#define __glibcxx_want_is_scoped_enum
|
||||
#define __glibcxx_want_is_swappable
|
||||
#define __glibcxx_want_is_virtual_base_of
|
||||
#define __glibcxx_want_logical_traits
|
||||
#define __glibcxx_want_reference_from_temporary
|
||||
#define __glibcxx_want_remove_cvref
|
||||
|
@ -1541,6 +1542,15 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
|||
: public __bool_constant<__is_base_of(_Base, _Derived)>
|
||||
{ };
|
||||
|
||||
#ifdef __cpp_lib_is_virtual_base_of // C++ >= 26
|
||||
/// is_virtual_base_of
|
||||
/// @since C++26
|
||||
template<typename _Base, typename _Derived>
|
||||
struct is_virtual_base_of
|
||||
: public bool_constant<__builtin_is_virtual_base_of(_Base, _Derived)>
|
||||
{ };
|
||||
#endif
|
||||
|
||||
#if _GLIBCXX_USE_BUILTIN_TRAIT(__is_convertible)
|
||||
template<typename _From, typename _To>
|
||||
struct is_convertible
|
||||
|
@ -3636,6 +3646,10 @@ template <typename _Tp>
|
|||
#endif
|
||||
template <typename _Base, typename _Derived>
|
||||
inline constexpr bool is_base_of_v = __is_base_of(_Base, _Derived);
|
||||
#ifdef __cpp_lib_is_virtual_base_of // C++ >= 26
|
||||
template <typename _Base, typename _Derived>
|
||||
inline constexpr bool is_virtual_base_of_v = __builtin_is_virtual_base_of(_Base, _Derived);
|
||||
#endif
|
||||
#if _GLIBCXX_USE_BUILTIN_TRAIT(__is_convertible)
|
||||
template <typename _From, typename _To>
|
||||
inline constexpr bool is_convertible_v = __is_convertible(_From, _To);
|
||||
|
|
34
libstdc++-v3/testsuite/20_util/is_virtual_base_of/value.cc
Normal file
34
libstdc++-v3/testsuite/20_util/is_virtual_base_of/value.cc
Normal file
|
@ -0,0 +1,34 @@
|
|||
// { dg-do compile { target c++26 } }
|
||||
|
||||
#include <type_traits>
|
||||
|
||||
#if !defined(__cpp_lib_is_virtual_base_of) || __cpp_lib_is_virtual_base_of < 202406L
|
||||
#error "__cpp_lib_is_virtual_base_of should have been defined to 202406L or more"
|
||||
#endif
|
||||
|
||||
class B { };
|
||||
class X : virtual public B { };
|
||||
class Y : virtual public B { };
|
||||
class Z : public B { };
|
||||
class AA : public X, public Y, public Z { };
|
||||
|
||||
template<typename Base, typename Derived>
|
||||
constexpr bool test()
|
||||
{
|
||||
constexpr bool t1 = std::is_virtual_base_of<Base, Derived>::value;
|
||||
constexpr bool t2 = std::is_virtual_base_of_v<Base, Derived>;
|
||||
static_assert(t1 == t2);
|
||||
return t1;
|
||||
}
|
||||
|
||||
void test01()
|
||||
{
|
||||
static_assert(!test<B, B>());
|
||||
static_assert( test<B, X>());
|
||||
static_assert( test<B, Y>());
|
||||
static_assert(!test<B, Z>());
|
||||
static_assert( test<B, AA>());
|
||||
static_assert(!test<X, AA>());
|
||||
static_assert(!test<Y, AA>());
|
||||
static_assert(!test<Z, AA>());
|
||||
}
|
Loading…
Add table
Reference in a new issue