|
| 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 |
0 commit comments