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// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
10
11// These compilers don't support __builtin_is_implicit_lifetime yet.
12// UNSUPPORTED: clang-18, clang-19, gcc-14, gcc-15, apple-clang-15, apple-clang-16, apple-clang-17
13
14// <type_traits>
15
16// template<class T> struct is_implicit_lifetime;
17
18#include <cassert>
19#include <cstddef>
20#include <tuple>
21#include <type_traits>
22#include <utility>
23
24#include "test_macros.h"
25#include "type_algorithms.h"
26
27enum Enum { EV };
28enum SignedEnum : signed int {};
29enum UnsignedEnum : unsigned int {};
30
31enum class EnumClass { EV };
32enum class SignedEnumClass : signed int {};
33enum class UnsignedEnumClass : unsigned int {};
34
35struct EmptyStruct {};
36struct IncompleteStruct;
37
38struct NoEligibleTrivialContructor {
39 NoEligibleTrivialContructor() {};
40 NoEligibleTrivialContructor(const NoEligibleTrivialContructor&) {}
41 NoEligibleTrivialContructor(NoEligibleTrivialContructor&&) {}
42};
43
44struct OnlyDefaultConstructorIsTrivial {
45 OnlyDefaultConstructorIsTrivial() = default;
46 OnlyDefaultConstructorIsTrivial(const OnlyDefaultConstructorIsTrivial&) {}
47 OnlyDefaultConstructorIsTrivial(OnlyDefaultConstructorIsTrivial&&) {}
48};
49
50struct AllContstructorsAreTrivial {
51 AllContstructorsAreTrivial() = default;
52 AllContstructorsAreTrivial(const AllContstructorsAreTrivial&) = default;
53 AllContstructorsAreTrivial(AllContstructorsAreTrivial&&) = default;
54};
55
56struct InheritedNoEligibleTrivialConstructor : NoEligibleTrivialContructor {
57 using NoEligibleTrivialContructor::NoEligibleTrivialContructor;
58};
59
60struct InheritedOnlyDefaultConstructorIsTrivial : OnlyDefaultConstructorIsTrivial {
61 using OnlyDefaultConstructorIsTrivial::OnlyDefaultConstructorIsTrivial;
62};
63
64struct InheritedAllContstructorsAreTrivial : AllContstructorsAreTrivial {
65 using AllContstructorsAreTrivial::AllContstructorsAreTrivial;
66};
67
68struct UserDeclaredDestructor {
69 ~UserDeclaredDestructor() = default;
70};
71
72struct UserProvidedDestructor {
73 ~UserProvidedDestructor() {}
74};
75
76struct UserDeletedDestructorInAggregate {
77 ~UserDeletedDestructorInAggregate() = delete;
78};
79
80struct UserDeletedDestructorInNonAggregate {
81 virtual void NonAggregate();
82 ~UserDeletedDestructorInNonAggregate() = delete;
83};
84
85struct DeletedDestructorViaBaseInAggregate : UserDeletedDestructorInAggregate {};
86struct DeletedDestructorViaBaseInNonAggregate : UserDeletedDestructorInNonAggregate {};
87
88template <bool B>
89struct ConstrainedUserDeclaredDefaultConstructor {
90 ConstrainedUserDeclaredDefaultConstructor()
91 requires B
92 = default;
93 ConstrainedUserDeclaredDefaultConstructor(const ConstrainedUserDeclaredDefaultConstructor&) {}
94};
95
96template <bool B>
97struct ConstrainedUserProvidedDestructor {
98 ~ConstrainedUserProvidedDestructor() = default;
99 ~ConstrainedUserProvidedDestructor()
100 requires B
101 {}
102};
103
104struct StructWithFlexibleArrayMember {
105 int arr[];
106};
107
108struct StructWithZeroSizedArray {
109 int arr[0];
110};
111
112// Test implicit-lifetime type
113template <typename T, bool Expected>
114constexpr void test_is_implicit_lifetime() {
115 assert(std::is_implicit_lifetime<T>::value == Expected);
116 assert(std::is_implicit_lifetime_v<T> == Expected);
117}
118
119// Test pointer, reference, array, etc. types
120template <typename T>
121constexpr void test_is_implicit_lifetime() {
122 test_is_implicit_lifetime<T, true>();
123
124 // cv-qualified
125 test_is_implicit_lifetime<const T, true>();
126 test_is_implicit_lifetime<volatile T, true>();
127
128 test_is_implicit_lifetime<T&, false>();
129 test_is_implicit_lifetime<T&&, false>();
130
131 // Pointer types
132 test_is_implicit_lifetime<T*, true>();
133
134 // Arrays
135 test_is_implicit_lifetime<T[], true>();
136 test_is_implicit_lifetime<T[94], true>();
137}
138
139struct AritmeticTypesTest {
140 template <class T>
141 constexpr void operator()() {
142 test_is_implicit_lifetime<T>();
143 }
144};
145
146constexpr bool test() {
147 // Standard fundamental C++ types
148
149 test_is_implicit_lifetime<std::nullptr_t, true>();
150
151 test_is_implicit_lifetime<void, false>();
152 test_is_implicit_lifetime<const void, false>();
153 test_is_implicit_lifetime<volatile void, false>();
154
155 types::for_each(types::arithmetic_types(), AritmeticTypesTest{});
156
157 test_is_implicit_lifetime<Enum>();
158 test_is_implicit_lifetime<SignedEnum>();
159 test_is_implicit_lifetime<UnsignedEnum>();
160
161 test_is_implicit_lifetime<EnumClass>();
162 test_is_implicit_lifetime<SignedEnumClass>();
163 test_is_implicit_lifetime<UnsignedEnumClass>();
164
165 test_is_implicit_lifetime<void(), false>();
166 test_is_implicit_lifetime<void()&, false>();
167 test_is_implicit_lifetime<void() const, false>();
168 test_is_implicit_lifetime<void (&)(), false>();
169 test_is_implicit_lifetime<void (*)(), true>();
170
171 // Implicit-lifetime class types
172
173 test_is_implicit_lifetime<EmptyStruct>();
174 test_is_implicit_lifetime<int EmptyStruct::*, true>(); // Pointer-to-member
175 test_is_implicit_lifetime<int (EmptyStruct::*)(), true>();
176 test_is_implicit_lifetime<int (EmptyStruct::*)() const, true>();
177 test_is_implicit_lifetime<int (EmptyStruct::*)()&, true>();
178 test_is_implicit_lifetime<int (EmptyStruct::*)()&&, true>();
179
180 test_is_implicit_lifetime<IncompleteStruct[], true>();
181 test_is_implicit_lifetime<IncompleteStruct[82], true>();
182
183 test_is_implicit_lifetime<UserDeclaredDestructor>();
184
185 test_is_implicit_lifetime<UserProvidedDestructor, false>();
186
187 test_is_implicit_lifetime<NoEligibleTrivialContructor, false>();
188
189 test_is_implicit_lifetime<OnlyDefaultConstructorIsTrivial, true>();
190
191 test_is_implicit_lifetime<AllContstructorsAreTrivial, true>();
192
193 test_is_implicit_lifetime<InheritedNoEligibleTrivialConstructor, false>();
194
195 test_is_implicit_lifetime<InheritedOnlyDefaultConstructorIsTrivial, true>();
196
197 test_is_implicit_lifetime<InheritedAllContstructorsAreTrivial, true>();
198
199 test_is_implicit_lifetime<UserDeletedDestructorInAggregate, true>();
200
201 test_is_implicit_lifetime<UserDeletedDestructorInNonAggregate, false>();
202
203 test_is_implicit_lifetime<DeletedDestructorViaBaseInAggregate, true>();
204
205 test_is_implicit_lifetime<DeletedDestructorViaBaseInNonAggregate, false>();
206
207 test_is_implicit_lifetime<ConstrainedUserDeclaredDefaultConstructor<true>, true>();
208 test_is_implicit_lifetime<ConstrainedUserDeclaredDefaultConstructor<false>, false>();
209
210 test_is_implicit_lifetime<ConstrainedUserProvidedDestructor<true>, false>();
211 test_is_implicit_lifetime<ConstrainedUserProvidedDestructor<false>, true>();
212
213 test_is_implicit_lifetime<StructWithFlexibleArrayMember, true>();
214
215 test_is_implicit_lifetime<StructWithZeroSizedArray, true>();
216
217 // C++ standard library types
218
219 test_is_implicit_lifetime<std::pair<int, float>>();
220 test_is_implicit_lifetime<std::tuple<int, float>>();
221
222 // Standard C23 types
223
224#ifdef TEST_COMPILER_CLANG
225 test_is_implicit_lifetime<_BitInt(8)>();
226 test_is_implicit_lifetime<_BitInt(128)>();
227#endif
228
229 return true;
230}
231
232int main(int, char**) {
233 test();
234 static_assert(test());
235
236 return 0;
237}
238

source code of libcxx/test/std/utilities/meta/meta.unary/meta.unary.prop/is_implicit_lifetime.pass.cpp