Explorar el Código

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

Also adds a simple-ish test for CommonType.
Ali Mohammad Pur hace 4 años
padre
commit
6c9ef20010
Se han modificado 2 ficheros con 45 adiciones y 3 borrados
  1. 25 3
      AK/StdLibExtraDetails.h
  2. 20 0
      Tests/AK/TestTypeTraits.cpp

+ 25 - 3
AK/StdLibExtraDetails.h

@@ -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;

+ 20 - 0
Tests/AK/TestTypeTraits.cpp

@@ -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);
+}