23 #if defined(__clang__)
24 # pragma clang diagnostic push
25 #elif defined(__GNUC__)
26 # pragma GCC diagnostic push
27 #elif defined(_MSC_VER)
28 # pragma warning(push)
29 # pragma warning(disable : 4244) // warning C4244: 'argument': conversion from 'const T' to 'unsigned int', possible loss of data.
32 #define CATCH_CONFIG_MAIN
43 #include <string_view>
49 static constexpr
bool is_flags =
true;
61 static constexpr
bool is_flags =
true;
66 Left = std::uint64_t{1} << 10,
67 Down = std::uint64_t{1} << 20,
68 Up = std::uint64_t{1} << 31,
73 static constexpr
bool is_flags =
true;
82 #if defined(MAGIC_ENUM_SUPPORTED_ALIASES)
91 static constexpr
bool is_flags =
true;
102 constexpr
auto cr = enum_cast<Color>(
"RED");
105 REQUIRE(enum_cast<Color>(
"blue", [](
char lhs,
char rhs) {
return std::tolower(lhs) == std::tolower(rhs); }).
value() ==
Color::BLUE);
106 REQUIRE_FALSE(enum_cast<Color&>(
"blue|RED", [](
char lhs,
char rhs) {
return std::tolower(lhs) == std::tolower(rhs); }).has_value());
108 REQUIRE_FALSE(enum_cast<Color&>(
"GREEN|RED|RED").has_value());
109 REQUIRE_FALSE(enum_cast<Color&>(
"GREEN|RED|None").has_value());
113 REQUIRE(enum_flags_cast<Color>(
"blue", [](
char lhs,
char rhs) {
return std::tolower(lhs) == std::tolower(rhs); }).
value() ==
Color::BLUE);
117 REQUIRE_FALSE(enum_flags_cast<Color&>(
"GREEN|RED|None").has_value());
120 constexpr
auto no = enum_cast<Numbers>(
"one");
127 constexpr
auto dr = enum_cast<Directions>(
"Right");
134 constexpr
auto nto = enum_flags_cast<number>(
"three|one");
145 constexpr
auto cr = enum_cast<Color>(1);
158 REQUIRE_FALSE(enum_flags_cast<Color>(1 | 2 | 8).has_value());
161 constexpr
auto no = enum_cast<Numbers>(2);
169 constexpr
auto dr = enum_cast<Directions>(std::uint64_t{1} << 63);
176 constexpr
auto nto = enum_flags_cast<number>(2 | 8);
228 REQUIRE(enum_contains<Color&>(cg));
232 REQUIRE(enum_flags_contains<Color&>(cg));
248 REQUIRE(enum_contains<Directions&>(dl));
266 REQUIRE(enum_contains<Color>(1));
267 REQUIRE(enum_contains<Color&>(2));
268 REQUIRE(enum_contains<const Color>(4));
271 REQUIRE(enum_flags_contains<Color>(1));
272 REQUIRE(enum_flags_contains<Color&>(2));
273 REQUIRE(enum_flags_contains<Color>(4));
274 REQUIRE(enum_flags_contains<Color>(1 | 2));
275 REQUIRE(enum_flags_contains<Color>(1 | 2 | 1));
279 constexpr
auto no = enum_contains<Numbers>(1 << 1);
281 REQUIRE(enum_contains<Numbers>(1 << 2));
282 REQUIRE(enum_contains<Numbers>(1 << 3));
283 REQUIRE(enum_contains<Numbers>(1 << 30));
285 constexpr
auto dr = enum_contains<Directions&>(std::uint64_t{1} << 63);
287 REQUIRE(enum_contains<const Directions>(std::uint64_t{1} << 10));
288 REQUIRE(enum_contains<Directions>(std::uint64_t{1} << 20));
289 REQUIRE(enum_contains<Directions>(std::uint64_t{1} << 31));
292 constexpr
auto nto = enum_contains<number>(8 | 2);
293 REQUIRE(enum_contains<number>(1 << 1));
294 REQUIRE(enum_contains<number>(1 << 2));
295 REQUIRE(enum_contains<number>(1 << 3));
296 REQUIRE(enum_contains<number>(1 << 4));
305 constexpr
auto cr =
"RED";
306 REQUIRE(enum_contains<Color>(cr));
307 REQUIRE(enum_contains<Color&>(
"GREEN"));
308 REQUIRE(enum_contains<const Color>(
"blue", [](
char lhs,
char rhs) {
return std::tolower(lhs) == std::tolower(rhs); }));
309 REQUIRE_FALSE(enum_contains<Color&>(
"blue|RED", [](
char lhs,
char rhs) {
return std::tolower(lhs) == std::tolower(rhs); }));
315 REQUIRE(enum_flags_contains<Color&>(
"GREEN"));
316 REQUIRE(enum_flags_contains<Color>(
"blue", [](
char lhs,
char rhs) {
return std::tolower(lhs) == std::tolower(rhs); }));
317 REQUIRE(enum_flags_contains<Color>(
"blue|RED", [](
char lhs,
char rhs) {
return std::tolower(lhs) == std::tolower(rhs); }));
318 REQUIRE(enum_flags_contains<Color>(
"GREEN|RED"));
319 REQUIRE(enum_flags_contains<Color>(
"GREEN|RED|RED"));
323 constexpr
auto no = std::string_view{
"one"};
324 REQUIRE(enum_contains<Numbers>(no));
325 REQUIRE(enum_contains<Numbers>(
"two"));
326 REQUIRE(enum_contains<Numbers>(
"three"));
327 REQUIRE(enum_contains<Numbers>(
"many"));
330 auto dr = std::string{
"Right"};
331 REQUIRE(enum_contains<Directions&>(
"Up"));
332 REQUIRE(enum_contains<Directions>(
"Down"));
333 REQUIRE(enum_contains<const Directions>(dr));
334 REQUIRE(enum_contains<Directions>(
"Left"));
337 constexpr
auto nto = enum_contains<number>(
"three|one");
338 REQUIRE(enum_contains<number>(
"one"));
339 REQUIRE(enum_contains<number>(
"two"));
340 REQUIRE(enum_contains<number>(
"three"));
341 REQUIRE(enum_contains<number>(
"four"));
345 REQUIRE(enum_flags_contains<number>(
"three|one"));
350 constexpr
auto cr = enum_value<Color>(0);
359 constexpr
auto no = enum_value<Numbers>(0);
370 constexpr
auto dr = enum_value<Directions>(3);
381 constexpr
auto nt = enum_value<number>(2);
394 REQUIRE(std::is_same_v<decltype(enum_values<Color>()),
const std::array<Color, 3>&>);
396 constexpr
auto&
s1 = enum_values<Color&>();
399 constexpr
auto&
s2 = enum_values<Numbers>();
402 constexpr
auto&
s3 = enum_values<const Directions>();
405 constexpr
auto&
s4 = enum_values<number>();
410 constexpr
auto s1 = enum_count<Color&>();
413 constexpr
auto s2 = enum_count<Numbers>();
416 constexpr
auto s3 = enum_count<const Directions>();
419 constexpr
auto s4 = enum_count<number>();
430 REQUIRE(enum_name<Color&>(cb) ==
"BLUE");
449 REQUIRE(enum_name<Directions&>(du) ==
"Up");
457 constexpr
auto nto_name =
enum_name(nto);
473 REQUIRE(enum_flags_name<Color&>(cb) ==
"BLUE");
492 REQUIRE(enum_flags_name<Directions&>(du) ==
"Up");
505 REQUIRE(nto_name ==
"one|three");
510 REQUIRE(std::is_same_v<decltype(enum_names<Color>()),
const std::array<std::string_view, 3>&>);
512 constexpr
auto&
s1 = enum_names<Color&>();
513 REQUIRE(
s1 == std::array<std::string_view, 3>{{
"RED",
"GREEN",
"BLUE"}});
515 constexpr
auto&
s2 = enum_names<Numbers>();
516 REQUIRE(
s2 == std::array<std::string_view, 4>{{
"one",
"two",
"three",
"many"}});
518 constexpr
auto&
s3 = enum_names<const Directions>();
519 REQUIRE(
s3 == std::array<std::string_view, 4>{{
"Left",
"Down",
"Up",
"Right"}});
521 constexpr
auto&
s4 = enum_names<number>();
522 REQUIRE(
s4 == std::array<std::string_view, 4>{{
"one",
"two",
"three",
"four"}});
526 REQUIRE(std::is_same_v<decltype(enum_entries<Color>()),
const std::array<std::pair<Color, std::string_view>, 3>&>);
528 constexpr
auto&
s1 = enum_entries<Color&>();
531 constexpr
auto&
s2 = enum_entries<Numbers>();
534 constexpr
auto&
s3 = enum_entries<Directions&>();
537 constexpr
auto&
s4 = enum_entries<number>();
542 auto test_ostream = [](
auto e, std::string name) {
544 std::stringstream ss;
549 test_ostream(std::make_optional(
Color::RED),
"RED");
554 test_ostream(
static_cast<Color>(0),
"0");
555 test_ostream(std::make_optional(
static_cast<Color>(0)),
"0");
561 test_ostream(
static_cast<Numbers>(0),
"0");
562 test_ostream(std::make_optional(
static_cast<Numbers>(0)),
"0");
569 test_ostream(
static_cast<Directions>(0),
"0");
570 test_ostream(std::make_optional(
static_cast<Directions>(0)),
"0");
572 test_ostream(std::make_optional(
number::one),
"one");
577 test_ostream(
static_cast<number>(0),
"0");
578 test_ostream(std::make_optional(
static_cast<number>(0)),
"0");
582 auto test_istream = [](
const auto e, std::string name) {
584 std::istringstream ss(name);
585 std::decay_t<decltype(e)> v;
695 #if defined(__clang__) && __clang_major__ >= 5 || defined(__GNUC__) && __GNUC__ >= 9 || defined(_MSC_VER) && _MSC_VER >= 1920
696 # define MAGIC_ENUM_SUPPORTED_CONSTEXPR_FOR 1
699 #if defined(MAGIC_ENUM_SUPPORTED_CONSTEXPR_FOR)
702 template <auto Start, auto End, auto Inc,
class F>
703 constexpr
void constexpr_for(F&& f) {
704 if constexpr (Start < End) {
705 f(std::integral_constant<decltype(Start), Start>());
706 constexpr_for<Start + Inc, End, Inc>(f);
710 template <
typename E, E V>
714 constexpr_for<0, magic_enum::enum_count<Color>(), 1>([](
auto i) {
715 [[maybe_unused]] Foo<Color, magic_enum::enum_value<Color, i>()> bar{};
721 #if defined(__cpp_lib_format)