https://gcc.gnu.org/g:acdf675933d549f2fe2c89e4feabcf36e382b4f5

commit r16-4725-gacdf675933d549f2fe2c89e4feabcf36e382b4f5
Author: Jakub Jelinek <[email protected]>
Date:   Thu Oct 30 08:43:18 2025 +0100

    libstd++: Implement C++23 P2674R1 - A trait for implicit lifetime types
    
    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  <[email protected]>
    
            * 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.

Diff:
---
 libstdc++-v3/include/bits/version.def              |   9 ++
 libstdc++-v3/include/bits/version.h                |  10 ++
 libstdc++-v3/include/std/type_traits               |  17 +++
 libstdc++-v3/src/c++23/std.cc.in                   |   4 +
 .../20_util/is_implicit_lifetime/value.cc          | 129 +++++++++++++++++++++
 .../20_util/is_implicit_lifetime/version.cc        |  27 +++++
 6 files changed, 196 insertions(+)

diff --git a/libstdc++-v3/include/bits/version.def 
b/libstdc++-v3/include/bits/version.def
index 1bf98f74d459..29ecf15c7e39 100644
--- a/libstdc++-v3/include/bits/version.def
+++ b/libstdc++-v3/include/bits/version.def
@@ -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";
diff --git a/libstdc++-v3/include/bits/version.h 
b/libstdc++-v3/include/bits/version.h
index 66de8b487e35..5901d27113d7 100644
--- a/libstdc++-v3/include/bits/version.h
+++ b/libstdc++-v3/include/bits/version.h
@@ -2455,4 +2455,14 @@
 #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
diff --git a/libstdc++-v3/include/std/type_traits 
b/libstdc++-v3/include/std/type_traits
index 77ebb7e2c2f9..d28b077398be 100644
--- a/libstdc++-v3/include/std/type_traits
+++ b/libstdc++-v3/include/std/type_traits
@@ -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
diff --git a/libstdc++-v3/src/c++23/std.cc.in b/libstdc++-v3/src/c++23/std.cc.in
index 4c11b1bf7114..28f0e8cb1fb6 100644
--- a/libstdc++-v3/src/c++23/std.cc.in
+++ b/libstdc++-v3/src/c++23/std.cc.in
@@ -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
index 000000000000..d8cb181e9af4
--- /dev/null
+++ b/libstdc++-v3/testsuite/20_util/is_implicit_lifetime/value.cc
@@ -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
index 000000000000..ed90b47c8662
--- /dev/null
+++ b/libstdc++-v3/testsuite/20_util/is_implicit_lifetime/version.cc
@@ -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

Reply via email to