diff mbox series

[2/2] libstdc++: add std::is_virtual_base_of

Message ID bcdaf182-44ec-4c67-a857-31a34d34c186@kdab.com
State New
Headers show
Series [1/2] Introduce __builtin_is_virtual_base_of | expand

Commit Message

Giuseppe D'Angelo July 29, 2024, 8:58 p.m. UTC
Hi,

And this is the corresponding change libstdc++.

Thank you,

Comments

Jonathan Wakely July 30, 2024, 1:04 p.m. UTC | #1
On Mon, 29 Jul 2024 at 21:58, Giuseppe D'Angelo wrote:
>
> Hi,
>
> And this is the corresponding change libstdc++.

Thanks for the patch. Do you have a copyright assignment for GCC in
place, or are you covered by a corporate assignment for KDAB?

If not, please complete that process, or contribute under the DCO
terms, see https://gcc.gnu.org/contribute.html#legal

This is a C++26 change, so it can use bool_constant instead of
__bool_constant. That's only needed for C++11 and C++14 code.

The new test says:

+// Copyright (C) 2013-2024 Free Software Foundation, Inc.

Unless you reused the code from an existing test that was written in
2013, then the date is wrong. And if you dont' have a copyright
assignment, then claiming it's copyright FSF is also wrong.

Please don't put copyright and license headers on new tests at all,
unless they really are copyright FSF, and really do contain something
original and copyrightable (which I don't think applies here).
This is documented at
https://gcc.gnu.org/onlinedocs/libstdc++/manual/test.html#test.new_tests

With those things fixed, this should definitely go in once the new
built-in is supported in the compiler, thanks again!
Giuseppe D'Angelo July 30, 2024, 10:49 p.m. UTC | #2
Hello,

On 30/07/2024 15:04, Jonathan Wakely wrote:
> On Mon, 29 Jul 2024 at 21:58, Giuseppe D'Angelo wrote:
>>
>> Hi,
>>
>> And this is the corresponding change libstdc++.
> 
> Thanks for the patch. 

Again, thanks for the guidance, should be all fixed.
Jonathan Wakely July 30, 2024, 10:55 p.m. UTC | #3
On Tue, 30 Jul 2024 at 23:49, Giuseppe D'Angelo
<giuseppe.dangelo@kdab.com> wrote:
>
> Hello,
>
> On 30/07/2024 15:04, Jonathan Wakely wrote:
> > On Mon, 29 Jul 2024 at 21:58, Giuseppe D'Angelo wrote:
> >>
> >> Hi,
> >>
> >> And this is the corresponding change libstdc++.
> >
> > Thanks for the patch.
>
> Again, thanks for the guidance, should be all fixed.


The new built-in won't be available when compiling with older versions
of Clang, so it needs to be used conditionally. I think the feature
test macro should only be defined if the built-in is available. See
the version.def entry for bit_cast, for example.

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>.
Giuseppe D'Angelo Aug. 2, 2024, 9:35 a.m. UTC | #4
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,
Jonathan Wakely Aug. 2, 2024, 10:09 a.m. UTC | #5
On Fri, 2 Aug 2024 at 10:35, Giuseppe D'Angelo wrote:
>
> 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.

Yup, this looks good now, thanks!

Once your patch to add the built-in is approved, we can add this.
diff mbox series

Patch

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

diff --git a/libstdc++-v3/include/bits/version.def b/libstdc++-v3/include/bits/version.def
index 42cdef2f526..ad4715048ab 100644
--- a/libstdc++-v3/include/bits/version.def
+++ b/libstdc++-v3/include/bits/version.def
@@ -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";
diff --git a/libstdc++-v3/include/bits/version.h b/libstdc++-v3/include/bits/version.h
index 1eaf3733bc2..e35254d8202 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)
+#  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..2ddeddb4b38 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..f7bb5f135b1
--- /dev/null
+++ b/libstdc++-v3/testsuite/20_util/is_virtual_base_of/value.cc
@@ -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