Serenity Operating System
at master 264 lines 8.3 kB view raw
1/* 2 * Copyright (c) 2020-2021, the SerenityOS developers. 3 * 4 * SPDX-License-Identifier: BSD-2-Clause 5 */ 6 7#include <LibTest/TestCase.h> 8 9#include <AK/TypeList.h> 10 11#define STATIC_EXPECT_EQ(lhs, rhs) \ 12 static_assert(IsSame<lhs, rhs>, ""); 13 14#define STATIC_EXPECT_FALSE(Expression) \ 15 static_assert(!Expression, ""); 16 17#define STATIC_EXPECT_TRUE(Expression) \ 18 static_assert(Expression, ""); 19 20#define EXPECT_TRAIT_TRUE(trait, ...) \ 21 for_each_type<TypeList<__VA_ARGS__>>([]<typename T>(TypeWrapper<T>) { \ 22 STATIC_EXPECT_TRUE(trait<T>); \ 23 }) 24 25#define EXPECT_TRAIT_FALSE(trait, ...) \ 26 for_each_type<TypeList<__VA_ARGS__>>([]<typename T>(TypeWrapper<T>) { \ 27 STATIC_EXPECT_FALSE(trait<T>); \ 28 }) 29 30#define EXPECT_EQ_WITH_TRAIT(trait, ListA, ListB) \ 31 for_each_type_zipped<ListA, ListB>([]<typename A, typename B>(TypeWrapper<A>, TypeWrapper<B>) { \ 32 STATIC_EXPECT_EQ(trait<A>, B); \ 33 }) 34 35#define EXPECT_VARIADIC_TRAIT_TRUE(trait, ...) \ 36 static_assert(trait<__VA_ARGS__>) 37 38#define EXPECT_VARIADIC_TRAIT_FALSE(trait, ...) \ 39 static_assert(!trait<__VA_ARGS__>) 40 41enum class Enummer : u8 { 42 Dummy 43}; 44 45TEST_CASE(FundamentalTypeClassification) 46{ 47 EXPECT_TRAIT_TRUE(IsVoid, void); 48 EXPECT_TRAIT_FALSE(IsVoid, int, Empty, nullptr_t); 49 50 EXPECT_TRAIT_TRUE(IsNullPointer, nullptr_t); 51 EXPECT_TRAIT_FALSE(IsNullPointer, void, int, Empty, decltype(0)); 52 53 EXPECT_TRAIT_TRUE(IsFloatingPoint, float, double, long double); 54 EXPECT_TRAIT_FALSE(IsFloatingPoint, int, Empty, nullptr_t, void); 55 56 EXPECT_TRAIT_TRUE(IsArithmetic, float, double, long double, bool, size_t); 57 EXPECT_TRAIT_TRUE(IsArithmetic, char, signed char, unsigned char, char8_t, char16_t, char32_t); 58 EXPECT_TRAIT_TRUE(IsArithmetic, short, int, long, long long); 59 EXPECT_TRAIT_TRUE(IsArithmetic, unsigned short, unsigned int, unsigned long, unsigned long long); 60 61 EXPECT_TRAIT_FALSE(IsArithmetic, void, nullptr_t, Empty); 62 63 EXPECT_TRAIT_TRUE(IsFundamental, void, nullptr_t); 64 EXPECT_TRAIT_TRUE(IsFundamental, float, double, long double, bool, size_t); 65 EXPECT_TRAIT_TRUE(IsFundamental, char, signed char, unsigned char, char8_t, char16_t, char32_t); 66 EXPECT_TRAIT_TRUE(IsFundamental, short, int, long, long long); 67 EXPECT_TRAIT_TRUE(IsFundamental, unsigned short, unsigned int, unsigned long, unsigned long long); 68 69 EXPECT_TRAIT_FALSE(IsFundamental, Empty, int*, int&); 70 71 EXPECT_TRAIT_FALSE(IsSigned, unsigned); 72 EXPECT_TRAIT_FALSE(IsSigned, unsigned short); 73 EXPECT_TRAIT_FALSE(IsSigned, unsigned char); 74 EXPECT_TRAIT_FALSE(IsSigned, unsigned long); 75 EXPECT_TRAIT_TRUE(IsSigned, int); 76 EXPECT_TRAIT_TRUE(IsSigned, short); 77 EXPECT_TRAIT_TRUE(IsSigned, long); 78 79 EXPECT_TRAIT_TRUE(IsUnsigned, unsigned); 80 EXPECT_TRAIT_TRUE(IsUnsigned, unsigned short); 81 EXPECT_TRAIT_TRUE(IsUnsigned, unsigned char); 82 EXPECT_TRAIT_TRUE(IsUnsigned, unsigned long); 83 EXPECT_TRAIT_FALSE(IsUnsigned, int); 84 EXPECT_TRAIT_FALSE(IsUnsigned, short); 85 EXPECT_TRAIT_FALSE(IsUnsigned, long); 86 87 EXPECT_TRAIT_TRUE(IsEnum, Enummer); 88 EXPECT_TRAIT_FALSE(IsEnum, Empty); 89 EXPECT_TRAIT_FALSE(IsEnum, int); 90 EXPECT_TRAIT_FALSE(IsEnum, void); 91 EXPECT_TRAIT_FALSE(IsEnum, nullptr_t); 92} 93 94TEST_CASE(AddConst) 95{ 96 // clang-format off 97 using NoConstList = TypeList<int, const int, Empty, const Empty>; 98 using YesConstList = TypeList<const int, const int, const Empty, const Empty>; 99 // clang-format on 100 101 EXPECT_EQ_WITH_TRAIT(AddConst, NoConstList, YesConstList); 102} 103 104TEST_CASE(UnderlyingType) 105{ 106 using Type = UnderlyingType<Enummer>; 107 108 STATIC_EXPECT_EQ(Type, u8); 109} 110 111TEST_CASE(RemoveCVReference) 112{ 113 using TestTypeList = TypeList<int, int&, int const&, int volatile&, int const volatile&, int&&, int const&&, int volatile&&, int const volatile&&>; 114 using ResultTypeList = TypeList<int, int, int, int, int, int, int, int, int>; 115 116 EXPECT_EQ_WITH_TRAIT(RemoveCVReference, TestTypeList, ResultTypeList); 117} 118 119TEST_CASE(AddReference) 120{ 121 STATIC_EXPECT_EQ(AddLvalueReference<int>, int&); 122 STATIC_EXPECT_EQ(AddLvalueReference<int&>, int&); 123 STATIC_EXPECT_EQ(AddLvalueReference<int&&>, int&); 124 125 STATIC_EXPECT_EQ(AddRvalueReference<int>, int&&); 126 STATIC_EXPECT_EQ(AddRvalueReference<int&>, int&); 127 STATIC_EXPECT_EQ(AddRvalueReference<int&&>, int&&); 128 129 STATIC_EXPECT_EQ(AddLvalueReference<void>, void); 130} 131 132TEST_CASE(IsConvertible) 133{ 134 struct A { 135 }; 136 struct B { 137 B(A); 138 }; 139 struct C { 140 A a; 141 operator A() { return a; }; 142 }; 143 struct D { 144 }; 145 146 EXPECT_VARIADIC_TRAIT_TRUE(IsConvertible, A, B); 147 EXPECT_VARIADIC_TRAIT_FALSE(IsConvertible, B, A); 148 EXPECT_VARIADIC_TRAIT_TRUE(IsConvertible, C, A); 149 EXPECT_VARIADIC_TRAIT_FALSE(IsConvertible, A, C); 150 EXPECT_VARIADIC_TRAIT_FALSE(IsConvertible, D, A); 151 EXPECT_VARIADIC_TRAIT_FALSE(IsConvertible, A, D); 152} 153 154TEST_CASE(IsAssignable) 155{ 156 EXPECT_VARIADIC_TRAIT_FALSE(IsAssignable, int, int); 157 EXPECT_VARIADIC_TRAIT_TRUE(IsAssignable, int&, int); 158 EXPECT_VARIADIC_TRAIT_FALSE(IsAssignable, int, void); 159 160 struct A { 161 }; 162 EXPECT_TRAIT_TRUE(IsCopyAssignable, A); 163 EXPECT_TRAIT_TRUE(IsTriviallyCopyAssignable, A); 164 EXPECT_TRAIT_TRUE(IsMoveAssignable, A); 165 EXPECT_TRAIT_TRUE(IsTriviallyMoveAssignable, A); 166 167 struct B { 168 B& operator=(B const&) { return *this; } 169 B& operator=(B&&) { return *this; } 170 }; 171 EXPECT_TRAIT_TRUE(IsCopyAssignable, B); 172 EXPECT_TRAIT_FALSE(IsTriviallyCopyAssignable, B); 173 EXPECT_TRAIT_TRUE(IsMoveAssignable, B); 174 EXPECT_TRAIT_FALSE(IsTriviallyMoveAssignable, B); 175 176 struct C { 177 C& operator=(C const&) = delete; 178 C& operator=(C&&) = delete; 179 }; 180 EXPECT_TRAIT_FALSE(IsCopyAssignable, C); 181 EXPECT_TRAIT_FALSE(IsTriviallyCopyAssignable, C); 182 EXPECT_TRAIT_FALSE(IsMoveAssignable, C); 183 EXPECT_TRAIT_FALSE(IsTriviallyMoveAssignable, C); 184} 185 186TEST_CASE(IsConstructible) 187{ 188 struct A { 189 }; 190 EXPECT_TRAIT_TRUE(IsCopyConstructible, A); 191 EXPECT_TRAIT_TRUE(IsTriviallyCopyConstructible, A); 192 EXPECT_TRAIT_TRUE(IsMoveConstructible, A); 193 EXPECT_TRAIT_TRUE(IsTriviallyMoveConstructible, A); 194 195 struct B { 196 B(B const&) 197 { 198 } 199 B(B&&) 200 { 201 } 202 }; 203 EXPECT_TRAIT_TRUE(IsCopyConstructible, B); 204 EXPECT_TRAIT_FALSE(IsTriviallyCopyConstructible, B); 205 EXPECT_TRAIT_TRUE(IsMoveConstructible, B); 206 EXPECT_TRAIT_FALSE(IsTriviallyMoveConstructible, B); 207 208 struct C { 209 C(C const&) = delete; 210 C(C&&) = delete; 211 }; 212 EXPECT_TRAIT_FALSE(IsCopyConstructible, C); 213 EXPECT_TRAIT_FALSE(IsTriviallyCopyConstructible, C); 214 EXPECT_TRAIT_FALSE(IsMoveConstructible, C); 215 EXPECT_TRAIT_FALSE(IsTriviallyMoveConstructible, C); 216 217 struct D { 218 D(int); 219 }; 220 EXPECT_VARIADIC_TRAIT_TRUE(IsConstructible, D, int); 221 EXPECT_VARIADIC_TRAIT_TRUE(IsConstructible, D, char); 222 EXPECT_VARIADIC_TRAIT_FALSE(IsConstructible, D, char const*); 223 EXPECT_VARIADIC_TRAIT_FALSE(IsConstructible, D, void); 224} 225 226TEST_CASE(IsDestructible) 227{ 228 struct A { 229 }; 230 EXPECT_TRAIT_TRUE(IsDestructible, A); 231 EXPECT_TRAIT_TRUE(IsTriviallyDestructible, A); 232 struct B { 233 ~B() 234 { 235 } 236 }; 237 EXPECT_TRAIT_TRUE(IsDestructible, B); 238 EXPECT_TRAIT_FALSE(IsTriviallyDestructible, B); 239 struct C { 240 ~C() = delete; 241 }; 242 EXPECT_TRAIT_FALSE(IsDestructible, C); 243 EXPECT_TRAIT_FALSE(IsTriviallyDestructible, C); 244} 245 246TEST_CASE(CommonType) 247{ 248 using TCommon0 = CommonType<int, float, char>; 249 EXPECT_VARIADIC_TRAIT_TRUE(IsSame, TCommon0, float); 250 251 using TCommon1 = CommonType<int, int, int, char>; 252 EXPECT_VARIADIC_TRAIT_TRUE(IsSame, TCommon1, int); 253 254 struct Foo { 255 }; 256 using TCommon2 = CommonType<Foo, Foo, Foo>; 257 EXPECT_VARIADIC_TRAIT_TRUE(IsSame, TCommon2, Foo); 258 259 struct Bar { 260 operator Foo(); 261 }; 262 using TCommon3 = CommonType<Bar, Foo, Bar>; 263 EXPECT_VARIADIC_TRAIT_TRUE(IsSame, TCommon3, Foo); 264}