1
0
mirror of https://github.com/SerenityOS/serenity synced 2024-07-05 23:14:54 +00:00

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.
This commit is contained in:
Timothy Flynn 2022-12-23 09:18:15 -05:00 committed by Andreas Kling
parent 4fec9540ec
commit d2a304ae87
2 changed files with 17 additions and 1 deletions

View File

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

View File

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