1
0
mirror of https://github.com/SerenityOS/serenity synced 2024-07-09 10:20:45 +00:00

AK: Implement IsEnum<T> and UnderlyingType<T> type traits

I needed these meta-programming type traits while working on something else.
Add basic support for these two type traits as well as some tests.
This commit is contained in:
Brian Gianforcaro 2021-03-04 23:16:59 -08:00 committed by Andreas Kling
parent 17e7cdc6cc
commit fc5b252010
2 changed files with 36 additions and 0 deletions

View File

@ -450,6 +450,10 @@ constexpr T exchange(T& slot, U&& value)
return old_value; return old_value;
} }
template<typename T>
struct IsEnum : public IntegralConstant<bool, __is_enum(T)> {
};
template<typename T> template<typename T>
struct IsUnion : public IntegralConstant<bool, __is_union(T)> { struct IsUnion : public IntegralConstant<bool, __is_union(T)> {
}; };
@ -570,6 +574,19 @@ struct IdentityType {
using Type = T; using Type = T;
}; };
template<class T, bool = IsEnum<T>::value>
struct __UnderlyingType {
using Type = __underlying_type(T);
};
template<class T>
struct __UnderlyingType<T, false> {
};
template<class T>
struct UnderlyingType : __UnderlyingType<T> {
};
} }
using AK::AddConst; using AK::AddConst;
@ -590,6 +607,7 @@ using AK::IsArithmetic;
using AK::IsBaseOf; using AK::IsBaseOf;
using AK::IsClass; using AK::IsClass;
using AK::IsConst; using AK::IsConst;
using AK::IsEnum;
using AK::IsFundamental; using AK::IsFundamental;
using AK::IsNullPointer; using AK::IsNullPointer;
using AK::IsSame; using AK::IsSame;
@ -605,4 +623,5 @@ using AK::min;
using AK::move; using AK::move;
using AK::RemoveConst; using AK::RemoveConst;
using AK::swap; using AK::swap;
using AK::UnderlyingType;
using AK::Void; using AK::Void;

View File

@ -55,6 +55,10 @@
struct Empty { struct Empty {
}; };
enum class Enummer : u8 {
Dummmy,
};
TEST_CASE(FundamentalTypeClassification) TEST_CASE(FundamentalTypeClassification)
{ {
EXPECT_TRAIT_TRUE(IsVoid, void); EXPECT_TRAIT_TRUE(IsVoid, void);
@ -89,6 +93,12 @@ TEST_CASE(FundamentalTypeClassification)
EXPECT_TRAIT_FALSE(IsUnsigned, short); EXPECT_TRAIT_FALSE(IsUnsigned, short);
EXPECT_TRAIT_FALSE(IsUnsigned, char); EXPECT_TRAIT_FALSE(IsUnsigned, char);
EXPECT_TRAIT_FALSE(IsUnsigned, long); EXPECT_TRAIT_FALSE(IsUnsigned, long);
EXPECT_TRAIT_TRUE(IsEnum, Enummer);
EXPECT_TRAIT_FALSE(IsEnum, Empty);
EXPECT_TRAIT_FALSE(IsEnum, int);
EXPECT_TRAIT_FALSE(IsEnum, void);
EXPECT_TRAIT_FALSE(IsEnum, std::nullptr_t);
} }
TEST_CASE(AddConst) TEST_CASE(AddConst)
@ -101,4 +111,11 @@ TEST_CASE(AddConst)
EXPECT_EQ_WITH_TRAIT(AddConst, NoConstList, YesConstList); EXPECT_EQ_WITH_TRAIT(AddConst, NoConstList, YesConstList);
} }
TEST_CASE(UnderlyingType)
{
using Type = UnderlyingType<Enummer>::Type;
STATIC_EXPECT_EQ(Type, u8);
}
TEST_MAIN(TypeTraits) TEST_MAIN(TypeTraits)