summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTimothy Flynn <trflynn89@pm.me>2022-12-23 09:18:15 -0500
committerAndreas Kling <kling@serenityos.org>2022-12-26 09:36:16 +0100
commitd2a304ae87bd89bb0d3c99d0d04dff976b7d7f98 (patch)
tree7a57f2e88e99266c854f1b60663b5404ecd726a0
parent4fec9540ec865a52070770a3a872e1fa7cc8ccc6 (diff)
downloadserenity-d2a304ae87bd89bb0d3c99d0d04dff976b7d7f98.zip
AK: Specialize TypeList for Variant types
This allows callers to use the following semantics: using MyVariant = Variant<Empty, int>; template<typename T> size_t size() { return TypeList<T>::size; } auto s = size<MyVariant>(); This will be needed for an upcoming IPC change, which will result in us knowing the Variant type, but not the underlying variadic types that the Variant holds.
-rw-r--r--AK/Variant.h5
-rw-r--r--Tests/AK/TestVariant.cpp13
2 files changed, 17 insertions, 1 deletions
diff --git a/AK/Variant.h b/AK/Variant.h
index ee423927a0..ed477b7bd4 100644
--- a/AK/Variant.h
+++ b/AK/Variant.h
@@ -226,7 +226,7 @@ template<NotLvalueReference... Ts>
struct Variant
: public Detail::MergeAndDeduplicatePacks<Detail::VariantConstructors<Ts, Variant<Ts...>>...> {
public:
- using IndexType = Conditional<sizeof...(Ts) < 255, u8, size_t>; // Note: size+1 reserved for internal value checks
+ using IndexType = Conditional<(sizeof...(Ts) < 255), u8, size_t>; // Note: size+1 reserved for internal value checks
private:
static constexpr IndexType invalid_index = sizeof...(Ts);
@@ -518,6 +518,9 @@ private:
IndexType m_index;
};
+template<typename... Ts>
+struct TypeList<Variant<Ts...>> : TypeList<Ts...> { };
+
}
#if USING_AK_GLOBALLY
diff --git a/Tests/AK/TestVariant.cpp b/Tests/AK/TestVariant.cpp
index 37bbf646cd..88a3e5fb7d 100644
--- a/Tests/AK/TestVariant.cpp
+++ b/Tests/AK/TestVariant.cpp
@@ -260,3 +260,16 @@ TEST_CASE(default_empty)
EXPECT(my_variant.has<Empty>());
EXPECT(!my_variant.has<int>());
}
+
+TEST_CASE(type_list_specialization)
+{
+ EXPECT_EQ((TypeList<Variant<Empty>>::size), 1u);
+ EXPECT_EQ((TypeList<Variant<Empty, int>>::size), 2u);
+ EXPECT_EQ((TypeList<Variant<Empty, int, String>>::size), 3u);
+
+ using MyVariant = Variant<Empty, int, String>;
+ using MyList = TypeList<MyVariant>;
+ EXPECT((IsSame<typename MyList::template Type<0>, Empty>));
+ EXPECT((IsSame<typename MyList::template Type<1>, int>));
+ EXPECT((IsSame<typename MyList::template Type<2>, String>));
+}