From c81392a11834b9ccbe476c280915c9a4fbf64d6d Mon Sep 17 00:00:00 2001
From: Giuseppe D'Angelo <giuseppe.dangelo@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.
---
libstdc++-v3/include/bits/version.def | 8 +++
libstdc++-v3/include/bits/version.h | 10 ++++
libstdc++-v3/include/std/type_traits | 14 +++++
.../20_util/is_virtual_base_of/value.cc | 52 +++++++++++++++++++
4 files changed, 84 insertions(+)
create mode 100644 libstdc++-v3/testsuite/20_util/is_virtual_base_of/value.cc
@@ -1814,6 +1814,14 @@ ftms = {
};
};
+ftms = {
+ name = is_virtual_base_of;
+ values = {
+ v = 202406;
+ cxxmin = 26;
+ };
+};
+
// Standard test specifications.
stds[97] = ">= 199711L";
stds[03] = ">= 199711L";
@@ -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)
+# 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
@@ -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);
new file mode 100644
@@ -0,0 +1,52 @@
+// { dg-do compile { target c++26 } }
+
+// Copyright (C) 2013-2024 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+#include <type_traits>
+#include <testsuite_tr1.h>
+
+#if !defined(__cpp_lib_is_virtual_base_of) || __cpp_lib_is_virtual_base_of < 202406L
+#error
+#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