AK: Add a CommonType<Ts...> type trait

Also adds a simple-ish test for CommonType.
This commit is contained in:
Ali Mohammad Pur 2021-07-22 19:01:05 +04:30 committed by Andreas Kling
parent ccd19d464e
commit 6c9ef20010
2 changed files with 45 additions and 3 deletions

View file

@ -319,6 +319,30 @@ struct __MakeSigned<char> {
template<typename T>
using MakeSigned = typename __MakeSigned<T>::Type;
template<typename T>
auto declval() -> T;
template<typename...>
struct __CommonType;
template<typename T>
struct __CommonType<T> {
using Type = T;
};
template<typename T1, typename T2>
struct __CommonType<T1, T2> {
using Type = decltype(true ? declval<T1>() : declval<T2>());
};
template<typename T1, typename T2, typename... Ts>
struct __CommonType<T1, T2, Ts...> {
using Type = typename __CommonType<typename __CommonType<T1, T2>::Type, Ts...>::Type;
};
template<typename... Ts>
using CommonType = typename __CommonType<Ts...>::Type;
template<class T>
inline constexpr bool IsVoid = IsSame<void, RemoveCV<T>>;
@ -457,9 +481,6 @@ inline constexpr bool IsTrivial = __is_trivial(T);
template<typename T>
inline constexpr bool IsTriviallyCopyable = __is_trivially_copyable(T);
template<typename T>
auto declval() -> T;
template<typename T, typename... Args>
inline constexpr bool IsCallableWithArguments = requires(T t) { t(declval<Args>()...); };
@ -515,6 +536,7 @@ inline constexpr bool IsTriviallyMoveAssignable = IsTriviallyAssignable<AddLvalu
using AK::Detail::AddConst;
using AK::Detail::AddLvalueReference;
using AK::Detail::AddRvalueReference;
using AK::Detail::CommonType;
using AK::Detail::Conditional;
using AK::Detail::CopyConst;
using AK::Detail::declval;

View file

@ -246,3 +246,23 @@ TEST_CASE(IsDestructible)
EXPECT_TRAIT_FALSE(IsDestructible, C);
EXPECT_TRAIT_FALSE(IsTriviallyDestructible, C);
}
TEST_CASE(CommonType)
{
using TCommon0 = CommonType<int, float, char>;
EXPECT_VARIADIC_TRAIT_TRUE(IsSame, TCommon0, float);
using TCommon1 = CommonType<int, int, int, char>;
EXPECT_VARIADIC_TRAIT_TRUE(IsSame, TCommon1, int);
struct Foo {
};
using TCommon2 = CommonType<Foo, Foo, Foo>;
EXPECT_VARIADIC_TRAIT_TRUE(IsSame, TCommon2, Foo);
struct Bar {
operator Foo();
};
using TCommon3 = CommonType<Bar, Foo, Bar>;
EXPECT_VARIADIC_TRAIT_TRUE(IsSame, TCommon3, Foo);
}