Inspect and validate flag enums
To inspect and validate flag enums in magic_enum, you must first enable flag support by specializing the magic_enum::customize::enum_range trait. Once enabled, you can use enum_flags_name to generate string representations of combined flags and enum_flags_contains to verify if a value represents a valid set of flags.
Enable Flag Support
By default, magic_enum treats enums as a sequence of distinct values. To enable bitwise logic and multi-flag string formatting, specialize magic_enum::customize::enum_range for your enum type and set is_flags to true.
#include <iostream>
#include <magic_enum/magic_enum_flags.hpp>
enum class AnimalFlags : std::uint64_t {
HasClaws = 1 << 10,
CanFly = 1 << 20,
EatsFish = 1 << 30,
Endangered = std::uint64_t{1} << 40
};
// Required: Define the enum as a flag set
template <>
struct magic_enum::customize::enum_range<AnimalFlags> {
static constexpr bool is_flags = true;
};
Combine Flags with Bitwise Operators
To use standard bitwise operators (|, &, ^, ~) with scoped enums, bring the magic_enum::bitwise_operators namespace into scope. This allows you to combine flags before passing them to inspection functions.
using namespace magic_enum::bitwise_operators;
// Combine flags using operator|
AnimalFlags flags = AnimalFlags::HasClaws | AnimalFlags::CanFly;
Format Flag Names
The magic_enum::enum_flags_name function returns a string containing the names of all set flags, joined by a separator (default is '|'). If the value contains bits that do not correspond to any named flag, the function returns an empty string.
// Default separator '|'
// Output: "HasClaws|CanFly"
std::cout << magic_enum::enum_flags_name(flags) << std::endl;
// Custom separator ','
// Output: "HasClaws,CanFly"
std::cout << magic_enum::enum_flags_name(flags, ',') << std::endl;
Validate Flag Values
Use magic_enum::enum_flags_contains to check if a value (enum, integer, or string) is a valid combination of the defined flags. A value is considered valid if it is non-zero and composed entirely of bits defined in the enum.
// Check enum values
bool valid = magic_enum::enum_flags_contains(AnimalFlags::HasClaws | AnimalFlags::CanFly); // true
bool invalid = magic_enum::enum_flags_contains(static_cast<AnimalFlags>(0)); // false (0 is not a flag)
// Check underlying integer values
bool is_valid_int = magic_enum::enum_flags_contains<AnimalFlags>(1024); // true (HasClaws)
bool is_invalid_int = magic_enum::enum_flags_contains<AnimalFlags>(1); // false (Undefined bit)
// Check string representations
bool is_valid_str = magic_enum::enum_flags_contains<AnimalFlags>("HasClaws|CanFly"); // true
bool is_invalid_str = magic_enum::enum_flags_contains<AnimalFlags>("HasClaws,CanFly"); // false (wrong separator)
Test for Specific Flags
While enum_flags_contains validates the entire set, magic_enum::enum_flags_test and magic_enum::enum_flags_test_any allow you to check for specific bits within a flag set.
AnimalFlags my_animal = AnimalFlags::HasClaws | AnimalFlags::EatsFish;
// Check if ALL specified flags are set
bool has_both = magic_enum::enum_flags_test(my_animal, AnimalFlags::HasClaws | AnimalFlags::EatsFish); // true
// Check if ANY specified flags are set
bool flies_or_swims = magic_enum::enum_flags_test_any(my_animal, AnimalFlags::CanFly | AnimalFlags::EatsFish); // true
Troubleshooting
- Empty String Output: If
enum_flags_namereturns an empty string, ensure that the value you passed does not contain "garbage" bits (bits not defined in the enum) and that the value is not0. - Compilation Errors on
|: If you cannot use bitwise operators, ensure you have includedusing namespace magic_enum::bitwise_operators;in the local scope. - Validation Fails for
0:enum_flags_containsandenum_flags_testreturnfalsefor a value of0because0is technically the absence of all flags.