diff --git a/src/variant17.lib/variant17/Variant.h b/src/variant17.lib/variant17/Variant.h index db2db36..0d403c2 100644 --- a/src/variant17.lib/variant17/Variant.h +++ b/src/variant17.lib/variant17/Variant.h @@ -59,40 +59,53 @@ auto selectType() { template using SelectType = UnwrapType())>; -/// Variant != std::variant -/// * unchecked invalid state (only destruction is valid!) -/// * simple recursive vistor -/// * allows uncheck casts (you have to check before!) -/// * sizeof(index) limits +/// VariantWhich is an enum-like type used in Variant to determine which type is currently present in the Variant. template -struct Variant { +struct VariantWhich { static constexpr auto pack = to_type_pack; static constexpr auto indices = indexPackFor(pack); - using First = TypeHead; using WhichValue = UnwrapType>; // enough for npos! - enum { npos = sizeof...(Ts) }; // invalid state after exception - only destruction checks! - struct Which { - explicit constexpr Which(WhichValue v) - : value(v) {} + constexpr VariantWhich() = default; + explicit constexpr VariantWhich(WhichValue v) + : value(v) {} - constexpr operator WhichValue() const { return value; } + constexpr operator WhichValue() const { return value; } - constexpr bool operator==(Which w) const { return w.value == value; } - constexpr bool operator!=(Which w) const { return w.value != value; } + constexpr bool operator==(VariantWhich w) const { return w.value == value; } + constexpr bool operator!=(VariantWhich w) const { return w.value != value; } - template - constexpr bool operator==(Type) const { - return whichOf() == *this; - } - template - constexpr bool operator!=(Type) const { - return whichOf() != *this; - } + template + constexpr bool operator==(Type) const { + return of() == *this; + } + template + constexpr bool operator!=(Type) const { + return of() != *this; + } - private: - WhichValue value; - }; + template + constexpr static auto of(Type = {}) -> VariantWhich { + return VariantWhich{static_cast(indexedTypePackIndexOf(pack, indices))}; + } + +private: + WhichValue value{}; +}; + +/// Variant != std::variant +/// * unchecked invalid state (only destruction is valid!) +/// * simple recursive vistor +/// * allows uncheck casts (you have to check before!) +/// * sizeof(index) limits +template +struct Variant { + using Which = VariantWhich; + static constexpr auto pack = Which::pack; + static constexpr auto indices = Which::indices; + using First = TypeHead; + using WhichValue = typename Which::WhichValue; + enum { npos = sizeof...(Ts) }; // invalid state after exception - only destruction checks! private: std::aligned_union_t<0, Ts...> m{}; @@ -171,7 +184,7 @@ struct Variant { Variant(T&& t) { static_assert(containsOf(pack), "type not part of variant"); constructOf(type, std::forward(t)); - whichValue = whichOf(); + whichValue = whichOf(type); } /// inplace construct of type @@ -179,7 +192,7 @@ struct Variant { Variant(Type, Args&&... args) { static_assert(containsOf(pack), "type not part of variant"); constructOf(type, std::forward(args)...); - whichValue = whichOf(); + whichValue = whichOf(type); } template @@ -207,12 +220,12 @@ struct Variant { if (whichValue != npos) destruct(); whichValue = npos; constructOf(type, std::forward(args)...); - whichValue = whichOf(); + whichValue = whichOf(type); } template constexpr static auto whichOf(Type = {}) -> Which { - return Which{static_cast(indexedTypePackIndexOf(pack, indices))}; + return Which::of(type); } template diff --git a/src/variant17.lib/variant17/Variant.trait.h b/src/variant17.lib/variant17/Variant.trait.h index e62b708..164fad8 100644 --- a/src/variant17.lib/variant17/Variant.trait.h +++ b/src/variant17.lib/variant17/Variant.trait.h @@ -9,4 +9,10 @@ constexpr auto is_variant = false; template constexpr auto is_variant> = true; +template +constexpr auto is_variant_which = false; + +template +constexpr auto is_variant_which> = true; + } // namespace variant17 diff --git a/src/variant17.lib/variant17/Variant.trait.test.cpp b/src/variant17.lib/variant17/Variant.trait.test.cpp index de0d50a..0a6333e 100644 --- a/src/variant17.lib/variant17/Variant.trait.test.cpp +++ b/src/variant17.lib/variant17/Variant.trait.test.cpp @@ -8,14 +8,21 @@ using namespace variant17; TEST(Variant, trait) { using T = Variant; static_assert(is_variant); + static_assert(!is_variant_which); + + static_assert(!is_variant); + static_assert(is_variant_which); struct S { int i; }; static_assert(!is_variant); + static_assert(!is_variant_which); using P = std::pair; static_assert(!is_variant

); + static_assert(!is_variant_which

); static_assert(!is_variant); + static_assert(!is_variant_which); }