]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
libstd++: Implement C++23 P2674R1 - A trait for implicit lifetime types
authorJakub Jelinek <jakub@redhat.com>
Thu, 30 Oct 2025 07:43:18 +0000 (08:43 +0100)
committerJakub Jelinek <jakub@gcc.gnu.org>
Thu, 30 Oct 2025 07:46:26 +0000 (08:46 +0100)
The following patch attempts to implement the library side of the
C++23 P2674R1 paper.  As mentioned in the paper, since CWG2605
the trait isn't really implementable purely on the library side.

The compiler side has been committed earlier, so this just uses
the new builtin trait on the library side.

2025-10-30  Jakub Jelinek  <jakub@redhat.com>

* include/bits/version.def (is_implicit_lifetime): New.
* include/bits/version.h: Regenerate.
* include/std/type_traits (std::is_implicit_lifetime,
std::is_implicit_lifetime_v): New trait.
* src/c++23/std.cc.in (std::is_implicit_lifetime,
std::is_implicit_lifetime_v): Export.
* testsuite/20_util/is_implicit_lifetime/version.cc: New test.
* testsuite/20_util/is_implicit_lifetime/value.cc: New test.

libstdc++-v3/include/bits/version.def
libstdc++-v3/include/bits/version.h
libstdc++-v3/include/std/type_traits
libstdc++-v3/src/c++23/std.cc.in
libstdc++-v3/testsuite/20_util/is_implicit_lifetime/value.cc [new file with mode: 0644]
libstdc++-v3/testsuite/20_util/is_implicit_lifetime/version.cc [new file with mode: 0644]

index 1bf98f74d4592882445e60bafdcdb5635222e22e..29ecf15c7e397d8c4340216b6c759fce547bdac5 100644 (file)
@@ -2191,6 +2191,15 @@ ftms = {
   };
 };
 
+ftms = {
+  name = is_implicit_lifetime;
+  values = {
+    v =  202302;
+    cxxmin = 23;
+    extra_cond = "__has_builtin(__builtin_is_implicit_lifetime)";
+  };
+};
+
 // Standard test specifications.
 stds[97] = ">= 199711L";
 stds[03] = ">= 199711L";
index 66de8b487e35e16cb22aff4cead55da9ccbc7a8b..5901d27113d7b03513766de1ffdc99c5b89803a5 100644 (file)
 #endif /* !defined(__cpp_lib_philox_engine) */
 #undef __glibcxx_want_philox_engine
 
+#if !defined(__cpp_lib_is_implicit_lifetime)
+# if (__cplusplus >= 202100L) && (__has_builtin(__builtin_is_implicit_lifetime))
+#  define __glibcxx_is_implicit_lifetime 202302L
+#  if defined(__glibcxx_want_all) || defined(__glibcxx_want_is_implicit_lifetime)
+#   define __cpp_lib_is_implicit_lifetime 202302L
+#  endif
+# endif
+#endif /* !defined(__cpp_lib_is_implicit_lifetime) */
+#undef __glibcxx_want_is_implicit_lifetime
+
 #undef __glibcxx_want_all
index 77ebb7e2c2f95d15dfad7fcd16d5724d1a1ffc08..d28b077398bef31bbd5d29491797f948bf274932 100644 (file)
@@ -47,6 +47,7 @@
 #define __glibcxx_want_is_aggregate
 #define __glibcxx_want_is_constant_evaluated
 #define __glibcxx_want_is_final
+#define __glibcxx_want_is_implicit_lifetime
 #define __glibcxx_want_is_invocable
 #define __glibcxx_want_is_layout_compatible
 #define __glibcxx_want_is_nothrow_convertible
@@ -4053,6 +4054,22 @@ template<typename _Ret, typename _Fn, typename... _Args>
 # endif
 #endif
 
+#ifdef __cpp_lib_is_implicit_lifetime // C++ >= 23
+  /// True if the type is an implicit-lifetime type.
+  /// @since C++23
+
+  template<typename _Tp>
+    struct is_implicit_lifetime
+    : bool_constant<__builtin_is_implicit_lifetime(_Tp)>
+    { };
+
+  /// @ingroup variable_templates
+  /// @since C++23
+  template<typename _Tp>
+    inline constexpr bool is_implicit_lifetime_v
+      = __builtin_is_implicit_lifetime(_Tp);
+#endif
+
 #ifdef __cpp_lib_reference_from_temporary // C++ >= 23 && ref_{converts,constructs}_from_temp
   /// True if _Tp is a reference type, a _Up value can be bound to _Tp in
   /// direct-initialization, and a temporary object would be bound to
index 4c11b1bf7114b0d412f785b355c5ad356c07bd06..28f0e8cb1fb653e2f68dad5647b6a5a7cd1f9a5a 100644 (file)
@@ -3230,6 +3230,10 @@ export namespace std
   using std::is_scoped_enum;
   using std::is_scoped_enum_v;
 #endif
+#if __cpp_lib_is_implicit_lifetime
+  using std::is_implicit_lifetime;
+  using std::is_implicit_lifetime_v;
+#endif
 }
 
 // <typeindex>
diff --git a/libstdc++-v3/testsuite/20_util/is_implicit_lifetime/value.cc b/libstdc++-v3/testsuite/20_util/is_implicit_lifetime/value.cc
new file mode 100644 (file)
index 0000000..d8cb181
--- /dev/null
@@ -0,0 +1,129 @@
+// Copyright (C) 2025 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/>.
+
+// { dg-do compile { target c++23 } }
+// { dg-add-options no_pch }
+
+#include <type_traits>
+
+#ifndef __cpp_lib_is_implicit_lifetime
+# error "Feature test macro for is_implicit_lifetime is missing in <type_traits>"
+#elif __cpp_lib_is_implicit_lifetime < 202302L
+# error "Feature test macro for is_implicit_lifetime has wrong value in <type_traits>"
+#endif
+
+#include <testsuite_tr1.h>
+
+template<typename T>
+  concept Is_implicit_lifetime
+    = __gnu_test::test_category<std::is_implicit_lifetime, T>(true);
+
+static_assert( ! Is_implicit_lifetime<void> );
+static_assert( ! Is_implicit_lifetime<const void> );
+static_assert( ! Is_implicit_lifetime<volatile void> );
+static_assert( Is_implicit_lifetime<char> );
+static_assert( Is_implicit_lifetime<signed char> );
+static_assert( Is_implicit_lifetime<const unsigned char> );
+static_assert( Is_implicit_lifetime<short> );
+static_assert( Is_implicit_lifetime<volatile unsigned short> );
+static_assert( Is_implicit_lifetime<int> );
+static_assert( Is_implicit_lifetime<unsigned int> );
+static_assert( Is_implicit_lifetime<const volatile long> );
+static_assert( Is_implicit_lifetime<unsigned long> );
+static_assert( Is_implicit_lifetime<long long> );
+static_assert( Is_implicit_lifetime<unsigned long long> );
+static_assert( Is_implicit_lifetime<float> );
+static_assert( Is_implicit_lifetime<double> );
+static_assert( Is_implicit_lifetime<long double volatile> );
+enum W { W1 };
+static_assert( Is_implicit_lifetime<W> );
+enum class X : int { X1 };
+static_assert( Is_implicit_lifetime<const volatile X> );
+static_assert( Is_implicit_lifetime<int *> );
+static_assert( Is_implicit_lifetime<int (*) (int)> );
+struct Y { int g; int foo (int); };
+static_assert( Is_implicit_lifetime<int (Y::*)> );
+static_assert( Is_implicit_lifetime<int (Y::*) (int)> );
+static_assert( ! Is_implicit_lifetime<int &> );
+static_assert( ! Is_implicit_lifetime<char &&> );
+static_assert( Is_implicit_lifetime<int []> );
+static_assert( Is_implicit_lifetime<int [1]> );
+static_assert( Is_implicit_lifetime<const Y [42]> );
+static_assert( ! Is_implicit_lifetime<int ()> );
+static_assert( ! Is_implicit_lifetime<int () &> );
+static_assert( ! Is_implicit_lifetime<int () const> );
+static_assert( ! Is_implicit_lifetime<int (&) ()> );
+struct Z;
+static_assert( Is_implicit_lifetime<Z []> );
+static_assert( Is_implicit_lifetime<Z [5]> );
+struct A { int a, b, c; };
+static_assert( Is_implicit_lifetime<A> );
+class B { static int a; private: static int b; public: int c; };
+static_assert( Is_implicit_lifetime<B> );
+struct C { C () {} int a, b, c; };
+static_assert( Is_implicit_lifetime<C> );
+struct D { explicit D (int) {} int a, b, c; };
+static_assert( Is_implicit_lifetime<D> );
+struct E : public A { int d, e, f; };
+static_assert( Is_implicit_lifetime<E> );
+struct F : public C { using C::C; int d, e, f; };
+static_assert( Is_implicit_lifetime<F> );
+class G { int a, b; };
+static_assert( Is_implicit_lifetime<G> );
+struct H { private: int a, b; };
+static_assert( Is_implicit_lifetime<H> );
+struct I { protected: int a, b; };
+static_assert( Is_implicit_lifetime<I> );
+struct J { int a, b; void foo (); };
+static_assert( Is_implicit_lifetime<J> );
+struct K { int a, b; virtual void foo (); };
+static_assert( ! Is_implicit_lifetime<K> );
+struct L : virtual public A { int d, e; };
+static_assert( ! Is_implicit_lifetime<L> );
+struct M : protected A { int d, e; };
+static_assert( Is_implicit_lifetime<M> );
+struct N : private A { int d, e; };
+static_assert( Is_implicit_lifetime<N> );
+struct O { O () = delete; int a, b, c; };
+static_assert( Is_implicit_lifetime<O> );
+struct P { P () = default; int a, b, c; };
+static_assert( Is_implicit_lifetime<P> );
+struct Q { Q (); Q (const Q &); int a, b, c; };
+static_assert( ! Is_implicit_lifetime<Q> );
+struct R { R (); R (const R &); R (R &&) = default; int a, b, c; };
+static_assert( Is_implicit_lifetime<R> );
+struct S { S (); ~S (); int a, b, c; };
+static_assert( ! Is_implicit_lifetime<S> );
+static_assert( Is_implicit_lifetime<S [3]> );
+struct T { T (); ~T () = default; int a, b, c; };
+static_assert( Is_implicit_lifetime<T> );
+struct U { U (); U (const U &) = default; int a, b, c; };
+static_assert( Is_implicit_lifetime<U> );
+struct V { V () = default; V (const V &); int a, b, c; };
+static_assert( Is_implicit_lifetime<V> );
+struct AA { Q a; Q b; };
+static_assert( Is_implicit_lifetime<AA> );
+struct AB { Q a; Q b; ~AB () = default; };
+static_assert( Is_implicit_lifetime<AB> );
+struct AC { Q a; Q b; ~AC () {} };
+static_assert( ! Is_implicit_lifetime<AC> );
+struct AD : public Q {};
+static_assert( Is_implicit_lifetime<AD> );
+struct AE : public Q { ~AE () = default; };
+static_assert( Is_implicit_lifetime<AE> );
+struct AF : public Q { ~AF () {} };
+static_assert( ! Is_implicit_lifetime<AF> );
diff --git a/libstdc++-v3/testsuite/20_util/is_implicit_lifetime/version.cc b/libstdc++-v3/testsuite/20_util/is_implicit_lifetime/version.cc
new file mode 100644 (file)
index 0000000..ed90b47
--- /dev/null
@@ -0,0 +1,27 @@
+// Copyright (C) 2025 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/>.
+
+// { dg-do compile { target c++23 } }
+// { dg-add-options no_pch }
+
+#include <version>
+
+#ifndef __cpp_lib_is_implicit_lifetime
+# error "Feature test macro for is_implicit_lifetime is missing in <version>"
+#elif __cpp_lib_is_implicit_lifetime < 202302L
+# error "Feature test macro for is_implicit_lifetime has wrong value in <version>"
+#endif