#include "Test/Test.h" #include "Support/Enum.h" namespace clice::testing { namespace { struct Color : refl::Enum { enum Kind : uint8_t { Red, Green, Blue, Yellow, Invalid, }; using Enum::Enum; constexpr inline static auto InvalidEnum = Invalid; }; struct StringEnum : refl::Enum { using Enum::Enum; constexpr inline static std::string_view A = "A"; constexpr inline static std::string_view B = "B"; constexpr inline static std::string_view C = "C"; constexpr inline static std::string_view D = "D"; constexpr inline static std::array All = {A, B, C, D}; }; suite<"Enum"> enum_tests = [] { test("EnumName") = [&] { enum class E { A, B, C, }; static_assert(refl::enum_name(E::A) == "A"); static_assert(refl::enum_name(E::B) == "B"); static_assert(refl::enum_name(E::C) == "C"); enum F { A, B, C, }; static_assert(refl::enum_name(F::A) == "A"); static_assert(refl::enum_name(F::B) == "B"); static_assert(refl::enum_name(F::C) == "C"); }; test("NormalEnum") = [&] { constexpr Color invalid = {}; static_assert(!invalid); static_assert(invalid.value() == Color::Invalid); constexpr Color red = Color::Red; constexpr Color green = Color::Green; constexpr Color blue = Color::Blue; constexpr Color yellow = Color::Yellow; static_assert(red.name() == "Red" && red.kind() == Color::Red && red.value() == 0); static_assert(green.name() == "Green" && green.kind() == Color::Green && green.value() == 1); static_assert(blue.name() == "Blue" && blue.kind() == Color::Blue && blue.value() == 2); static_assert(yellow.name() == "Yellow" && yellow.kind() == Color::Yellow && yellow.value() == 3); static_assert(red != green && red != blue && red != yellow); constexpr Color red2 = Color(0); static_assert(red == red2); static_assert(red.is_one_of(Color::Red)); static_assert(!red.is_one_of(Color::Blue)); }; test("MaskEnum") = [&] { struct Mask : refl::Enum { enum Kind { A = 0, B, C, D, }; using Enum::Enum; }; constexpr Mask invalid = {}; static_assert(!invalid); static_assert(invalid.value() == 0); constexpr Mask mask = Mask::A; constexpr Mask mask2 = Mask::B; constexpr Mask mask3 = Mask::C; constexpr Mask mask4 = Mask::D; static_assert(mask.name() == "A" && mask.value() == 1); static_assert(mask2.name() == "B" && mask2.value() == 2); static_assert(mask3.name() == "C" && mask3.value() == 4); static_assert(mask4.name() == "D" && mask4.value() == 8); static_assert(mask != mask2 && mask != mask3 && mask != mask4); constexpr Mask mask5 = Mask(Mask::A, Mask::B, Mask::C, Mask::D); static_assert(mask5.name() == "A | B | C | D" && mask5.value() == 15); Mask mask6 = Mask::A; mask6 |= Mask::B; expect(mask6.name() == "A | B"); expect(bool(mask6 & Mask::A)); expect(bool(mask6 & Mask::B)); mask6 |= Mask::C; expect(mask6.name() == "A | B | C"); expect(bool(mask6 & Mask::A)); expect(bool(mask6 & Mask::B)); expect(bool(mask6 & Mask::C)); constexpr Mask mask7 = Mask(Mask::A, Mask::B, Mask::C); static_assert(mask7 & Mask::A); static_assert(mask7 & Mask::B); static_assert(mask7 & Mask::C); }; test("StringEnum") = [&] { constexpr StringEnum a = StringEnum::A; constexpr StringEnum b = StringEnum::B; constexpr StringEnum c = StringEnum::C; constexpr StringEnum d = StringEnum::D; static_assert(a.value() == "A"); static_assert(b.value() == "B"); static_assert(c.value() == "C"); static_assert(d.value() == "D"); static_assert(a != b && a != c && a != d); }; }; } // namespace } // namespace clice::testing