Skip to content

Commit a1f5a49

Browse files
authored
[libc] Add type_traits tests (#65956)
This is not exhaustive for now but it provides a placeholder for `invoke_result` test mentioned in #65750.
1 parent d557e2b commit a1f5a49

File tree

3 files changed

+320
-0
lines changed

3 files changed

+320
-0
lines changed

libc/test/src/__support/CPP/CMakeLists.txt

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,3 +106,13 @@ add_libc_test(
106106
libc.src.__support.CPP.string
107107
libc.src.__support.CPP.string_view
108108
)
109+
110+
add_libc_test(
111+
type_traits_test
112+
SUITE
113+
libc-cpp-utils-tests
114+
SRCS
115+
type_traits_test.cpp
116+
DEPENDS
117+
libc.src.__support.CPP.type_traits
118+
)
Lines changed: 300 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,300 @@
1+
//===-- Unittests for type_traits -----------------------------------------===//
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+
#include "src/__support/CPP/type_traits.h"
10+
#include "test/UnitTest/Test.h"
11+
12+
// TODO: Split this file if it becomes too big.
13+
14+
namespace __llvm_libc::cpp {
15+
16+
class Class {};
17+
union Union {};
18+
struct Struct {};
19+
enum Enum {};
20+
enum class EnumClass {};
21+
22+
using UnqualObjectTypes = testing::TypeList<int, float, Class, Union, Struct>;
23+
24+
TYPED_TEST(LlvmLibcTypeTraitsTest, add_lvalue_reference, UnqualObjectTypes) {
25+
// non-ref cv, adds ref
26+
EXPECT_TRUE((is_same_v<add_lvalue_reference_t<T>, T &>));
27+
EXPECT_TRUE((is_same_v<add_lvalue_reference_t<const T>, const T &>));
28+
EXPECT_TRUE((is_same_v<add_lvalue_reference_t<volatile T>, volatile T &>));
29+
EXPECT_TRUE((
30+
is_same_v<add_lvalue_reference_t<const volatile T>, const volatile T &>));
31+
32+
// pointer cv, adds ref
33+
EXPECT_TRUE((is_same_v<add_lvalue_reference_t<T *>, T *&>));
34+
EXPECT_TRUE((is_same_v<add_lvalue_reference_t<const T *>, const T *&>));
35+
EXPECT_TRUE((is_same_v<add_lvalue_reference_t<volatile T *>, volatile T *&>));
36+
EXPECT_TRUE((is_same_v<add_lvalue_reference_t<const volatile T *>,
37+
const volatile T *&>));
38+
39+
// ref cv, returns same type
40+
EXPECT_TRUE((is_same_v<add_lvalue_reference_t<T &>, T &>));
41+
EXPECT_TRUE((is_same_v<add_lvalue_reference_t<const T &>, const T &>));
42+
EXPECT_TRUE((is_same_v<add_lvalue_reference_t<volatile T &>, volatile T &>));
43+
EXPECT_TRUE((is_same_v<add_lvalue_reference_t<const volatile T &>,
44+
const volatile T &>));
45+
}
46+
47+
TEST(LlvmLibcTypeTraitsTest, add_lvalue_reference_void) {
48+
// void cannot be referenced
49+
EXPECT_TRUE((is_same_v<add_lvalue_reference_t<void>, void>));
50+
EXPECT_TRUE((is_same_v<add_lvalue_reference_t<const void>, const void>));
51+
EXPECT_TRUE(
52+
(is_same_v<add_lvalue_reference_t<volatile void>, volatile void>));
53+
EXPECT_TRUE((is_same_v<add_lvalue_reference_t<const volatile void>,
54+
const volatile void>));
55+
}
56+
57+
TYPED_TEST(LlvmLibcTypeTraitsTest, add_pointer, UnqualObjectTypes) {
58+
// object types -> pointer type
59+
EXPECT_TRUE((is_same_v<add_pointer_t<T>, T *>));
60+
EXPECT_TRUE((is_same_v<add_pointer_t<const T>, const T *>));
61+
EXPECT_TRUE((is_same_v<add_pointer_t<volatile T>, volatile T *>));
62+
EXPECT_TRUE((is_same_v<add_pointer_t<const volatile T>, const volatile T *>));
63+
64+
// pointer types -> pointer type
65+
EXPECT_TRUE((is_same_v<add_pointer_t<T *>, T **>));
66+
EXPECT_TRUE((is_same_v<add_pointer_t<const T *>, const T **>));
67+
EXPECT_TRUE((is_same_v<add_pointer_t<volatile T *>, volatile T **>));
68+
EXPECT_TRUE(
69+
(is_same_v<add_pointer_t<const volatile T *>, const volatile T **>));
70+
71+
// reference type -> pointer type
72+
EXPECT_TRUE((is_same_v<add_pointer_t<T &>, T *>));
73+
EXPECT_TRUE((is_same_v<add_pointer_t<const T &>, const T *>));
74+
EXPECT_TRUE((is_same_v<add_pointer_t<volatile T &>, volatile T *>));
75+
EXPECT_TRUE(
76+
(is_same_v<add_pointer_t<const volatile T &>, const volatile T *>));
77+
}
78+
79+
TEST(LlvmLibcTypeTraitsTest, add_pointer_void) {
80+
// void -> pointer type
81+
EXPECT_TRUE((is_same_v<add_pointer_t<void>, void *>));
82+
EXPECT_TRUE((is_same_v<add_pointer_t<const void>, const void *>));
83+
EXPECT_TRUE((is_same_v<add_pointer_t<volatile void>, volatile void *>));
84+
EXPECT_TRUE(
85+
(is_same_v<add_pointer_t<const volatile void>, const volatile void *>));
86+
}
87+
88+
TYPED_TEST(LlvmLibcTypeTraitsTest, add_rvalue_reference, UnqualObjectTypes) {
89+
90+
// non-ref cv, adds ref
91+
EXPECT_TRUE((is_same_v<add_rvalue_reference_t<T>, T &&>));
92+
EXPECT_TRUE((is_same_v<add_rvalue_reference_t<const T>, const T &&>));
93+
EXPECT_TRUE((is_same_v<add_rvalue_reference_t<volatile T>, volatile T &&>));
94+
EXPECT_TRUE((is_same_v<add_rvalue_reference_t<const volatile T>,
95+
const volatile T &&>));
96+
97+
// ref cv, returns same type
98+
EXPECT_TRUE((is_same_v<add_rvalue_reference_t<T &>, T &>));
99+
EXPECT_TRUE((is_same_v<add_rvalue_reference_t<const T &>, const T &>));
100+
EXPECT_TRUE((is_same_v<add_rvalue_reference_t<volatile T &>, volatile T &>));
101+
EXPECT_TRUE((is_same_v<add_rvalue_reference_t<const volatile T &>,
102+
const volatile T &>));
103+
}
104+
105+
TEST(LlvmLibcTypeTraitsTest, add_rvalue_reference_void) {
106+
// void cannot be referenced
107+
EXPECT_TRUE((is_same_v<add_rvalue_reference_t<void>, void>));
108+
EXPECT_TRUE((is_same_v<add_rvalue_reference_t<const void>, const void>));
109+
EXPECT_TRUE(
110+
(is_same_v<add_rvalue_reference_t<volatile void>, volatile void>));
111+
EXPECT_TRUE((is_same_v<add_rvalue_reference_t<const volatile void>,
112+
const volatile void>));
113+
}
114+
115+
TEST(LlvmLibcTypeTraitsTest, bool_constant) {
116+
EXPECT_TRUE((bool_constant<true>::value));
117+
EXPECT_FALSE((bool_constant<false>::value));
118+
}
119+
120+
TEST(LlvmLibcTypeTraitsTest, conditional_t) {
121+
EXPECT_TRUE((is_same_v<conditional_t<true, int, float>, int>));
122+
EXPECT_TRUE((is_same_v<conditional_t<false, int, float>, float>));
123+
}
124+
125+
TEST(LlvmLibcTypeTraitsTest, decay) {
126+
EXPECT_TRUE((is_same_v<decay_t<int>, int>));
127+
128+
// array decay
129+
EXPECT_TRUE((is_same_v<decay_t<int[2]>, int *>));
130+
EXPECT_TRUE((is_same_v<decay_t<int[2]>, int *>));
131+
EXPECT_TRUE((is_same_v<decay_t<int[2][4]>, int(*)[4]>));
132+
133+
// cv ref decay
134+
EXPECT_TRUE((is_same_v<decay_t<int &>, int>));
135+
EXPECT_TRUE((is_same_v<decay_t<const int &>, int>));
136+
EXPECT_TRUE((is_same_v<decay_t<volatile int &>, int>));
137+
EXPECT_TRUE((is_same_v<decay_t<const volatile int &>, int>));
138+
}
139+
140+
// TODO enable_if
141+
142+
TEST(LlvmLibcTypeTraitsTest, false_type) { EXPECT_FALSE((false_type::value)); }
143+
144+
TEST(LlvmLibcTypeTraitsTest, integral_constant) {
145+
EXPECT_EQ((integral_constant<int, 4>::value), 4);
146+
}
147+
148+
using IntegralAndFloatingTypes =
149+
testing::TypeList<bool, char, short, int, long, long long, unsigned char,
150+
unsigned short, unsigned int, unsigned long,
151+
unsigned long long, float, double, long double>;
152+
153+
TYPED_TEST(LlvmLibcTypeTraitsTest, is_arithmetic, IntegralAndFloatingTypes) {
154+
EXPECT_TRUE((is_arithmetic_v<T>));
155+
EXPECT_TRUE((is_arithmetic_v<const T>));
156+
EXPECT_TRUE((is_arithmetic_v<volatile T>));
157+
EXPECT_TRUE((is_arithmetic_v<const volatile T>));
158+
159+
EXPECT_FALSE((is_arithmetic_v<T *>));
160+
EXPECT_FALSE((is_arithmetic_v<T &>));
161+
}
162+
163+
TEST(LlvmLibcTypeTraitsTest, is_arithmetic_non_integral) {
164+
EXPECT_FALSE((is_arithmetic_v<Union>));
165+
EXPECT_FALSE((is_arithmetic_v<Class>));
166+
EXPECT_FALSE((is_arithmetic_v<Struct>));
167+
EXPECT_FALSE((is_arithmetic_v<Enum>));
168+
}
169+
170+
TEST(LlvmLibcTypeTraitsTest, is_array) {
171+
EXPECT_FALSE((is_array_v<int>));
172+
EXPECT_FALSE((is_array_v<float>));
173+
EXPECT_FALSE((is_array_v<Struct>));
174+
EXPECT_FALSE((is_array_v<int *>));
175+
176+
EXPECT_TRUE((is_array_v<Class[]>));
177+
EXPECT_TRUE((is_array_v<Union[4]>));
178+
}
179+
180+
TEST(LlvmLibcTypeTraitsTest, is_base_of) {
181+
struct A {};
182+
EXPECT_TRUE((is_base_of_v<A, A>));
183+
184+
// Test public, protected and private inheritance.
185+
struct B : public A {};
186+
EXPECT_TRUE((is_base_of_v<A, B>));
187+
EXPECT_FALSE((is_base_of_v<B, A>));
188+
189+
struct C : protected A {};
190+
EXPECT_TRUE((is_base_of_v<A, C>));
191+
EXPECT_FALSE((is_base_of_v<C, A>));
192+
193+
struct D : private A {};
194+
EXPECT_TRUE((is_base_of_v<A, D>));
195+
EXPECT_FALSE((is_base_of_v<D, A>));
196+
197+
// Test inheritance chain.
198+
struct E : private B {};
199+
EXPECT_TRUE((is_base_of_v<A, E>));
200+
}
201+
202+
TEST(LlvmLibcTypeTraitsTest, is_class) {
203+
EXPECT_TRUE((is_class_v<Struct>));
204+
EXPECT_TRUE((is_class_v<Class>));
205+
206+
// Pointer or ref do not qualify.
207+
EXPECT_FALSE((is_class_v<Class *>));
208+
EXPECT_FALSE((is_class_v<Class &>));
209+
210+
// Neither other types.
211+
EXPECT_FALSE((is_class_v<Union>));
212+
EXPECT_FALSE((is_class_v<int>));
213+
EXPECT_FALSE((is_class_v<EnumClass>));
214+
}
215+
216+
TYPED_TEST(LlvmLibcTypeTraitsTest, is_const, UnqualObjectTypes) {
217+
EXPECT_FALSE((is_const_v<T>));
218+
EXPECT_TRUE((is_const_v<const T>));
219+
220+
using Aliased = const T;
221+
EXPECT_TRUE((is_const_v<Aliased>));
222+
}
223+
224+
// TODO is_convertible
225+
226+
TYPED_TEST(LlvmLibcTypeTraitsTest, is_destructible, UnqualObjectTypes) {
227+
EXPECT_TRUE((is_destructible_v<T>));
228+
}
229+
TEST(LlvmLibcTypeTraitsTest, is_destructible_no_destructor) {
230+
struct S {
231+
~S() = delete;
232+
};
233+
EXPECT_FALSE((is_destructible_v<S>));
234+
}
235+
236+
TYPED_TEST(LlvmLibcTypeTraitsTest, is_enum, UnqualObjectTypes) {
237+
EXPECT_FALSE((is_enum_v<T>));
238+
}
239+
TEST(LlvmLibcTypeTraitsTest, is_enum_enum) {
240+
EXPECT_TRUE((is_enum_v<Enum>));
241+
EXPECT_TRUE((is_enum_v<EnumClass>));
242+
}
243+
244+
// TODO is_floating_point
245+
246+
// TODO is_function
247+
248+
// TODO is_integral
249+
250+
// TODO is_lvalue_reference
251+
252+
// TODO is_member_pointer
253+
254+
// TODO is_null_pointer
255+
256+
// TODO is_pointer
257+
258+
// TODO is_reference
259+
260+
// TODO is_rvalue_reference
261+
262+
// TODO is_same
263+
264+
// TODO is_scalar
265+
266+
// TODO is_signed
267+
268+
// TODO is_trivially_constructible
269+
270+
// TODO is_trivially_copyable
271+
272+
// TODO is_trivially_destructible
273+
274+
// TODO is_union
275+
276+
// TODO is_unsigned
277+
278+
// TODO is_void
279+
280+
// TODO make_signed
281+
282+
// TODO make_unsigned
283+
284+
// TODO remove_all_extents
285+
286+
// TODO remove_cv
287+
288+
// TODO remove_cvref
289+
290+
// TODO remove_extent
291+
292+
// TODO remove_reference
293+
294+
TEST(LlvmLibcTypeTraitsTest, true_type) { EXPECT_TRUE((true_type::value)); }
295+
296+
// TODO type_identity
297+
298+
// TODO void_t
299+
300+
} // namespace __llvm_libc::cpp

utils/bazel/llvm-project-overlay/libc/test/src/__support/CPP/BUILD.bazel

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,3 +110,13 @@ cc_test(
110110
"//libc/test/UnitTest:LibcUnitTest",
111111
],
112112
)
113+
114+
cc_test(
115+
name = "type_traits_test",
116+
srcs = ["type_traits_test.cpp"],
117+
deps = [
118+
"//libc:__support_cpp_type_traits",
119+
"//libc:libc_root",
120+
"//libc/test/UnitTest:LibcUnitTest",
121+
],
122+
)

0 commit comments

Comments
 (0)