Hello,

On 31/07/2024 00:55, Jonathan Wakely wrote:
If __cpp_lib_is_virtual_base_of depends on __has_builtin, then that
will do the right thing for #ifdef __cpp_lib_is_virtual_base_of in
<type_traits>.

Third time's the charm, I hope; clang trunk seems to like this.

Thank you,
--
Giuseppe D'Angelo
From 7e81a94810692b1db3835227f3bc84464aef5df9 Mon Sep 17 00:00:00 2001
From: Giuseppe D'Angelo <giuseppe.dang...@kdab.com>
Date: Mon, 29 Jul 2024 19:23:54 +0200
Subject: [PATCH 2/2] 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.dang...@kdab.com>
---
 libstdc++-v3/include/bits/version.def         |  9 +++++
 libstdc++-v3/include/bits/version.h           | 10 ++++++
 libstdc++-v3/include/std/type_traits          | 14 ++++++++
 .../20_util/is_virtual_base_of/value.cc       | 34 +++++++++++++++++++
 4 files changed, 67 insertions(+)
 create mode 100644 libstdc++-v3/testsuite/20_util/is_virtual_base_of/value.cc

diff --git a/libstdc++-v3/include/bits/version.def b/libstdc++-v3/include/bits/version.def
index 42cdef2f526..6b8a5b89f29 100644
--- a/libstdc++-v3/include/bits/version.def
+++ b/libstdc++-v3/include/bits/version.def
@@ -1814,6 +1814,15 @@ ftms = {
   };
 };
 
+ftms = {
+  name = is_virtual_base_of;
+  values = {
+    v = 202406;
+    cxxmin = 26;
+    extra_cond = "__has_builtin(__builtin_is_virtual_base_of)";
+  };
+};
+
 // Standard test specifications.
 stds[97] = ">= 199711L";
 stds[03] = ">= 199711L";
diff --git a/libstdc++-v3/include/bits/version.h b/libstdc++-v3/include/bits/version.h
index 1eaf3733bc2..d884b019601 100644
--- a/libstdc++-v3/include/bits/version.h
+++ b/libstdc++-v3/include/bits/version.h
@@ -2023,4 +2023,14 @@
 #endif /* !defined(__cpp_lib_ranges_concat) && defined(__glibcxx_want_ranges_concat) */
 #undef __glibcxx_want_ranges_concat
 
+#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
+
 #undef __glibcxx_want_all
diff --git a/libstdc++-v3/include/std/type_traits b/libstdc++-v3/include/std/type_traits
index c39a3792537..99656d863fa 100644
--- a/libstdc++-v3/include/std/type_traits
+++ b/libstdc++-v3/include/std/type_traits
@@ -51,6 +51,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
@@ -1539,6 +1540,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
@@ -3619,6 +3629,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);
diff --git a/libstdc++-v3/testsuite/20_util/is_virtual_base_of/value.cc b/libstdc++-v3/testsuite/20_util/is_virtual_base_of/value.cc
new file mode 100644
index 00000000000..5d83de0683e
--- /dev/null
+++ b/libstdc++-v3/testsuite/20_util/is_virtual_base_of/value.cc
@@ -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>());
+}
-- 
2.34.1

Attachment: smime.p7s
Description: S/MIME Cryptographic Signature

Reply via email to