Skip to content

Commit a06591b

Browse files
H-G-HristovZingam
andauthored
[libc++][type_traits] P2674R1: A trait for implicit lifetime types (#106870)
Implements P2674R1: https://wg21.link/P2674R1 - https://eel.is/c++draft/type.traits - https://eel.is/c++draft/meta.type.synop - https://eel.is/c++draft/meta.unary.prop - https://eel.is/c++draft/support.limits - https://eel.is/c++draft/version.syn Implementation details: - Uses compiler intrinsic `__builtin_is_implicit_lifetime`: - #101807 - Tests based on: - https://github.com/llvm/llvm-project/blob/d213981c80626698a07b11ce872acba098a863d4/clang/test/SemaCXX/type-traits.cpp#L1989 References: - Implicit-lifetime - Implicit-lifetime types [basic.types.general]/9: https://eel.is/c++draft/basic.types.general - Implicit-lifetime class [class.prop]/9: https://eel.is/c++draft/class.prop - P0593R6 Implicit creation of objects for low-level object manipulation: https://wg21.link/P0593R6 - P1010R1 Container support for implicit lifetime types: https://wg21.link/P1010R1 - P0593R6 Implicit creation of objects for low-level object manipulation: https://wg21.link/P0593R6 Closes: #105259 --------- Co-authored-by: Hristo Hristov <[email protected]>
1 parent b26aac5 commit a06591b

File tree

14 files changed

+418
-3
lines changed

14 files changed

+418
-3
lines changed

libcxx/docs/FeatureTestMacroTable.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -336,6 +336,8 @@ Status
336336
---------------------------------------------------------- -----------------
337337
``__cpp_lib_ios_noreplace`` ``202207L``
338338
---------------------------------------------------------- -----------------
339+
``__cpp_lib_is_implicit_lifetime`` ``202302L``
340+
---------------------------------------------------------- -----------------
339341
``__cpp_lib_is_scoped_enum`` ``202011L``
340342
---------------------------------------------------------- -----------------
341343
``__cpp_lib_mdspan`` ``202207L``

libcxx/docs/ReleaseNotes/20.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ Implemented Papers
4242
- P2609R3: Relaxing Ranges Just A Smidge (`Github <https://github.com/llvm/llvm-project/issues/105253>`__)
4343
- P2985R0: A type trait for detecting virtual base classes (`Github <https://github.com/llvm/llvm-project/issues/105432>`__)
4444
- ``std::jthread`` and ``<stop_token>`` are not guarded behind ``-fexperimental-library`` anymore
45+
- P2674R1: A trait for implicit lifetime types (`Github <https://github.com/llvm/llvm-project/issues/105259>`__)
4546

4647
Improvements and New Features
4748
-----------------------------

libcxx/docs/Status/Cxx23Papers.csv

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@
113113
"`P2572R1 <https://wg21.link/P2572R1>`__","``std::format`` fill character allowances","2023-02 (Issaquah)","|Complete|","17.0",""
114114
"`P2693R1 <https://wg21.link/P2693R1>`__","Formatting ``thread::id`` and ``stacktrace``","2023-02 (Issaquah)","|Partial|","","The formatter for ``stacktrace`` is not implemented, since ``stacktrace`` is not implemented yet"
115115
"`P2679R2 <https://wg21.link/P2679R2>`__","Fixing ``std::start_lifetime_as`` for arrays","2023-02 (Issaquah)","","",""
116-
"`P2674R1 <https://wg21.link/P2674R1>`__","A trait for implicit lifetime types","2023-02 (Issaquah)","","",""
116+
"`P2674R1 <https://wg21.link/P2674R1>`__","A trait for implicit lifetime types","2023-02 (Issaquah)","|Complete|","20.0",""
117117
"`P2655R3 <https://wg21.link/P2655R3>`__","``common_reference_t`` of ``reference_wrapper`` Should Be a Reference Type","2023-02 (Issaquah)","","",""
118118
"`P2652R2 <https://wg21.link/P2652R2>`__","Disallow User Specialization of ``allocator_traits``","2023-02 (Issaquah)","|Complete|","19.0",""
119119
"`P2787R1 <https://wg21.link/P2787R1>`__","``pmr::generator`` - Promise Types are not Values","2023-02 (Issaquah)","","",""

libcxx/include/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -787,6 +787,7 @@ set(files
787787
__type_traits/is_floating_point.h
788788
__type_traits/is_function.h
789789
__type_traits/is_fundamental.h
790+
__type_traits/is_implicit_lifetime.h
790791
__type_traits/is_implicitly_default_constructible.h
791792
__type_traits/is_integral.h
792793
__type_traits/is_literal_type.h
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#ifndef _LIBCPP___TYPE_TRAITS_IS_IMPLICIT_LIFETIME_H
10+
#define _LIBCPP___TYPE_TRAITS_IS_IMPLICIT_LIFETIME_H
11+
12+
#include <__config>
13+
#include <__type_traits/integral_constant.h>
14+
15+
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
16+
# pragma GCC system_header
17+
#endif
18+
19+
_LIBCPP_BEGIN_NAMESPACE_STD
20+
21+
#if _LIBCPP_STD_VER >= 23
22+
# if __has_builtin(__builtin_is_implicit_lifetime)
23+
24+
template <class _Tp>
25+
struct _LIBCPP_TEMPLATE_VIS is_implicit_lifetime : public bool_constant<__builtin_is_implicit_lifetime(_Tp)> {};
26+
27+
template <class _Tp>
28+
inline constexpr bool is_implicit_lifetime_v = __builtin_is_implicit_lifetime(_Tp);
29+
30+
# endif
31+
#endif
32+
33+
_LIBCPP_END_NAMESPACE_STD
34+
35+
#endif // _LIBCPP___TYPE_TRAITS_IS_IMPLICIT_LIFETIME_H

libcxx/include/module.modulemap

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,10 @@ module std_core [system] {
200200
header "__type_traits/is_fundamental.h"
201201
export std_core.type_traits.integral_constant
202202
}
203+
module is_implicit_lifetime {
204+
header "__type_traits/is_implicit_lifetime.h"
205+
export std_core.type_traits.integral_constant
206+
}
203207
module is_implicitly_default_constructible {
204208
header "__type_traits/is_implicitly_default_constructible.h"
205209
export std_core.type_traits.integral_constant

libcxx/include/type_traits

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,8 @@ namespace std
137137
template <class T> struct is_nothrow_swappable; // C++17
138138
template <class T> struct is_nothrow_destructible;
139139
140+
template<class T> struct is_implicit_lifetime; // Since C++23
141+
140142
template <class T> struct has_virtual_destructor;
141143
142144
template<class T> struct has_unique_object_representations; // C++17
@@ -374,6 +376,8 @@ namespace std
374376
= is_nothrow_swappable<T>::value; // C++17
375377
template <class T> inline constexpr bool is_nothrow_destructible_v
376378
= is_nothrow_destructible<T>::value; // C++17
379+
template<class T>
380+
constexpr bool is_implicit_lifetime_v = is_implicit_lifetime<T>::value; // Since C++23
377381
template <class T> inline constexpr bool has_virtual_destructor_v
378382
= has_virtual_destructor<T>::value; // C++17
379383
template<class T> inline constexpr bool has_unique_object_representations_v // C++17
@@ -516,6 +520,10 @@ namespace std
516520
# include <__type_traits/unwrap_ref.h>
517521
#endif
518522

523+
#if _LIBCPP_STD_VER >= 23
524+
# include <__type_traits/is_implicit_lifetime.h>
525+
#endif
526+
519527
#include <version>
520528

521529
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)

libcxx/include/version

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,7 @@ __cpp_lib_ios_noreplace 202207L <ios>
138138
__cpp_lib_is_aggregate 201703L <type_traits>
139139
__cpp_lib_is_constant_evaluated 201811L <type_traits>
140140
__cpp_lib_is_final 201402L <type_traits>
141+
__cpp_lib_is_implicit_lifetime 202302L <type_traits>
141142
__cpp_lib_is_invocable 201703L <type_traits>
142143
__cpp_lib_is_layout_compatible 201907L <type_traits>
143144
__cpp_lib_is_nothrow_convertible 201806L <type_traits>
@@ -473,6 +474,9 @@ __cpp_lib_void_t 201411L <type_traits>
473474
# define __cpp_lib_forward_like 202207L
474475
# define __cpp_lib_invoke_r 202106L
475476
# define __cpp_lib_ios_noreplace 202207L
477+
# if __has_builtin(__builtin_is_implicit_lifetime)
478+
# define __cpp_lib_is_implicit_lifetime 202302L
479+
# endif
476480
# define __cpp_lib_is_scoped_enum 202011L
477481
# define __cpp_lib_mdspan 202207L
478482
# define __cpp_lib_modules 202207L

libcxx/modules/std/type_traits.inc

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,9 @@ export namespace std {
9898

9999
using std::is_nothrow_destructible;
100100

101-
// using std::is_implicit_lifetime;
101+
#if _LIBCPP_STD_VER >= 23 && __has_builtin(__builtin_is_implicit_lifetime)
102+
using std::is_implicit_lifetime;
103+
#endif
102104

103105
using std::has_virtual_destructor;
104106

@@ -246,7 +248,9 @@ export namespace std {
246248
using std::is_destructible_v;
247249
using std::is_empty_v;
248250
using std::is_final_v;
249-
// using std::is_implicit_lifetime_v;
251+
#if _LIBCPP_STD_VER >= 23 && __has_builtin(__builtin_is_implicit_lifetime)
252+
using std::is_implicit_lifetime_v;
253+
#endif
250254
using std::is_move_assignable_v;
251255
using std::is_move_constructible_v;
252256
using std::is_nothrow_assignable_v;

libcxx/test/std/language.support/support.limits/support.limits.general/type_traits.version.compile.pass.cpp

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
__cpp_lib_is_aggregate 201703L [C++17]
2424
__cpp_lib_is_constant_evaluated 201811L [C++20]
2525
__cpp_lib_is_final 201402L [C++14]
26+
__cpp_lib_is_implicit_lifetime 202302L [C++23]
2627
__cpp_lib_is_invocable 201703L [C++17]
2728
__cpp_lib_is_layout_compatible 201907L [C++20]
2829
__cpp_lib_is_nothrow_convertible 201806L [C++20]
@@ -75,6 +76,10 @@
7576
# error "__cpp_lib_is_final should not be defined before c++14"
7677
# endif
7778

79+
# ifdef __cpp_lib_is_implicit_lifetime
80+
# error "__cpp_lib_is_implicit_lifetime should not be defined before c++23"
81+
# endif
82+
7883
# ifdef __cpp_lib_is_invocable
7984
# error "__cpp_lib_is_invocable should not be defined before c++17"
8085
# endif
@@ -179,6 +184,10 @@
179184
# error "__cpp_lib_is_final should have the value 201402L in c++14"
180185
# endif
181186

187+
# ifdef __cpp_lib_is_implicit_lifetime
188+
# error "__cpp_lib_is_implicit_lifetime should not be defined before c++23"
189+
# endif
190+
182191
# ifdef __cpp_lib_is_invocable
183192
# error "__cpp_lib_is_invocable should not be defined before c++17"
184193
# endif
@@ -301,6 +310,10 @@
301310
# error "__cpp_lib_is_final should have the value 201402L in c++17"
302311
# endif
303312

313+
# ifdef __cpp_lib_is_implicit_lifetime
314+
# error "__cpp_lib_is_implicit_lifetime should not be defined before c++23"
315+
# endif
316+
304317
# ifndef __cpp_lib_is_invocable
305318
# error "__cpp_lib_is_invocable should be defined in c++17"
306319
# endif
@@ -444,6 +457,10 @@
444457
# error "__cpp_lib_is_final should have the value 201402L in c++20"
445458
# endif
446459

460+
# ifdef __cpp_lib_is_implicit_lifetime
461+
# error "__cpp_lib_is_implicit_lifetime should not be defined before c++23"
462+
# endif
463+
447464
# ifndef __cpp_lib_is_invocable
448465
# error "__cpp_lib_is_invocable should be defined in c++20"
449466
# endif
@@ -614,6 +631,19 @@
614631
# error "__cpp_lib_is_final should have the value 201402L in c++23"
615632
# endif
616633

634+
# if __has_builtin(__builtin_is_implicit_lifetime)
635+
# ifndef __cpp_lib_is_implicit_lifetime
636+
# error "__cpp_lib_is_implicit_lifetime should be defined in c++23"
637+
# endif
638+
# if __cpp_lib_is_implicit_lifetime != 202302L
639+
# error "__cpp_lib_is_implicit_lifetime should have the value 202302L in c++23"
640+
# endif
641+
# else
642+
# ifdef __cpp_lib_is_implicit_lifetime
643+
# error "__cpp_lib_is_implicit_lifetime should not be defined when the requirement '__has_builtin(__builtin_is_implicit_lifetime)' is not met!"
644+
# endif
645+
# endif
646+
617647
# ifndef __cpp_lib_is_invocable
618648
# error "__cpp_lib_is_invocable should be defined in c++23"
619649
# endif
@@ -796,6 +826,19 @@
796826
# error "__cpp_lib_is_final should have the value 201402L in c++26"
797827
# endif
798828

829+
# if __has_builtin(__builtin_is_implicit_lifetime)
830+
# ifndef __cpp_lib_is_implicit_lifetime
831+
# error "__cpp_lib_is_implicit_lifetime should be defined in c++26"
832+
# endif
833+
# if __cpp_lib_is_implicit_lifetime != 202302L
834+
# error "__cpp_lib_is_implicit_lifetime should have the value 202302L in c++26"
835+
# endif
836+
# else
837+
# ifdef __cpp_lib_is_implicit_lifetime
838+
# error "__cpp_lib_is_implicit_lifetime should not be defined when the requirement '__has_builtin(__builtin_is_implicit_lifetime)' is not met!"
839+
# endif
840+
# endif
841+
799842
# ifndef __cpp_lib_is_invocable
800843
# error "__cpp_lib_is_invocable should be defined in c++26"
801844
# endif

libcxx/test/std/language.support/support.limits/support.limits.general/version.version.compile.pass.cpp

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,7 @@
125125
__cpp_lib_is_aggregate 201703L [C++17]
126126
__cpp_lib_is_constant_evaluated 201811L [C++20]
127127
__cpp_lib_is_final 201402L [C++14]
128+
__cpp_lib_is_implicit_lifetime 202302L [C++23]
128129
__cpp_lib_is_invocable 201703L [C++17]
129130
__cpp_lib_is_layout_compatible 201907L [C++20]
130131
__cpp_lib_is_nothrow_convertible 201806L [C++20]
@@ -671,6 +672,10 @@
671672
# error "__cpp_lib_is_final should not be defined before c++14"
672673
# endif
673674

675+
# ifdef __cpp_lib_is_implicit_lifetime
676+
# error "__cpp_lib_is_implicit_lifetime should not be defined before c++23"
677+
# endif
678+
674679
# ifdef __cpp_lib_is_invocable
675680
# error "__cpp_lib_is_invocable should not be defined before c++17"
676681
# endif
@@ -1550,6 +1555,10 @@
15501555
# error "__cpp_lib_is_final should have the value 201402L in c++14"
15511556
# endif
15521557

1558+
# ifdef __cpp_lib_is_implicit_lifetime
1559+
# error "__cpp_lib_is_implicit_lifetime should not be defined before c++23"
1560+
# endif
1561+
15531562
# ifdef __cpp_lib_is_invocable
15541563
# error "__cpp_lib_is_invocable should not be defined before c++17"
15551564
# endif
@@ -2564,6 +2573,10 @@
25642573
# error "__cpp_lib_is_final should have the value 201402L in c++17"
25652574
# endif
25662575

2576+
# ifdef __cpp_lib_is_implicit_lifetime
2577+
# error "__cpp_lib_is_implicit_lifetime should not be defined before c++23"
2578+
# endif
2579+
25672580
# ifndef __cpp_lib_is_invocable
25682581
# error "__cpp_lib_is_invocable should be defined in c++17"
25692582
# endif
@@ -3842,6 +3855,10 @@
38423855
# error "__cpp_lib_is_final should have the value 201402L in c++20"
38433856
# endif
38443857

3858+
# ifdef __cpp_lib_is_implicit_lifetime
3859+
# error "__cpp_lib_is_implicit_lifetime should not be defined before c++23"
3860+
# endif
3861+
38453862
# ifndef __cpp_lib_is_invocable
38463863
# error "__cpp_lib_is_invocable should be defined in c++20"
38473864
# endif
@@ -5306,6 +5323,19 @@
53065323
# error "__cpp_lib_is_final should have the value 201402L in c++23"
53075324
# endif
53085325

5326+
# if __has_builtin(__builtin_is_implicit_lifetime)
5327+
# ifndef __cpp_lib_is_implicit_lifetime
5328+
# error "__cpp_lib_is_implicit_lifetime should be defined in c++23"
5329+
# endif
5330+
# if __cpp_lib_is_implicit_lifetime != 202302L
5331+
# error "__cpp_lib_is_implicit_lifetime should have the value 202302L in c++23"
5332+
# endif
5333+
# else
5334+
# ifdef __cpp_lib_is_implicit_lifetime
5335+
# error "__cpp_lib_is_implicit_lifetime should not be defined when the requirement '__has_builtin(__builtin_is_implicit_lifetime)' is not met!"
5336+
# endif
5337+
# endif
5338+
53095339
# ifndef __cpp_lib_is_invocable
53105340
# error "__cpp_lib_is_invocable should be defined in c++23"
53115341
# endif
@@ -7112,6 +7142,19 @@
71127142
# error "__cpp_lib_is_final should have the value 201402L in c++26"
71137143
# endif
71147144

7145+
# if __has_builtin(__builtin_is_implicit_lifetime)
7146+
# ifndef __cpp_lib_is_implicit_lifetime
7147+
# error "__cpp_lib_is_implicit_lifetime should be defined in c++26"
7148+
# endif
7149+
# if __cpp_lib_is_implicit_lifetime != 202302L
7150+
# error "__cpp_lib_is_implicit_lifetime should have the value 202302L in c++26"
7151+
# endif
7152+
# else
7153+
# ifdef __cpp_lib_is_implicit_lifetime
7154+
# error "__cpp_lib_is_implicit_lifetime should not be defined when the requirement '__has_builtin(__builtin_is_implicit_lifetime)' is not met!"
7155+
# endif
7156+
# endif
7157+
71157158
# ifndef __cpp_lib_is_invocable
71167159
# error "__cpp_lib_is_invocable should be defined in c++26"
71177160
# endif

0 commit comments

Comments
 (0)