Skip to main content

Inspect and validate flag enums

When you work with bitwise flag enums in C++, standard string conversion and validation functions often fail to handle combined values (e.g., Color::Red | Color::Blue). magic_enum provides specialized APIs in magic_enum/magic_enum_flags.hpp to format these combinations into delimited strings and validate whether a bitset represents a valid set of flags.

Enable Flag Support

To use flag-specific functions, you must explicitly mark your enum as a flag type by specializing magic_enum::customize::enum_range. This tells magic_enum to treat the enum as a bitmask rather than a sequential list of values.

#include <magic_enum/magic_enum_flags.hpp>

enum class Color { RED = 1, GREEN = 2, BLUE = 4 };

// Enable flag support for Color
template <>
struct magic_enum::customize::enum_range<Color> {
static constexpr bool is_flags = true;
};

Format Flag Combinations to Strings

The magic_enum::enum_flags_name function converts an enum value (or a bitwise combination of values) into a string. If multiple flags are set, it concatenates their names using a separator (defaulting to |).

To combine scoped enum values using the | operator, you must make magic_enum::bitwise_operators visible.

#include <iostream>
#include <magic_enum/magic_enum_flags.hpp>

using namespace magic_enum::bitwise_operators; // Enables operator| for enums

void print_color(Color c) {
// Returns a string like "RED|BLUE"
std::cout << magic_enum::enum_flags_name(c) << std::endl;
}

int main() {
print_color(Color::RED | Color::BLUE); // Output: RED|BLUE
return 0;
}

Validate Flag Values

The magic_enum::enum_flags_contains function checks if a value represents a valid flag or a valid combination of flags defined in the enum. It supports checking raw enum values, underlying integers, or string representations.

Validate Enum and Integer Values

A value is considered valid if every bit set in the value corresponds to a named flag in the enum.

#include <magic_enum/magic_enum_flags.hpp>
#include <cassert>

using namespace magic_enum::bitwise_operators;

void validate_flags() {
// Valid combinations
assert(magic_enum::enum_flags_contains(Color::RED | Color::GREEN));
assert(magic_enum::enum_flags_contains<Color>(1 | 4)); // RED | BLUE

// Invalid values (bits that don't exist in the enum)
assert(!magic_enum::enum_flags_contains<Color>(8));
assert(!magic_enum::enum_flags_contains<Color>(1 | 8));
}

Validate String Representations

You can also validate if a string correctly names a set of flags. This is useful for parsing configuration or user input.

#include <magic_enum/magic_enum_flags.hpp>
#include <cctype>
#include <cassert>

void validate_strings() {
// Basic validation
assert(magic_enum::magic_enum::enum_flags_contains<Color>("RED|GREEN"));

// Case-insensitive validation using a custom predicate
auto case_insensitive = [](char lhs, char rhs) {
return std::tolower(static_cast<unsigned char>(lhs)) == std::tolower(static_cast<unsigned char>(rhs));
};

assert(magic_enum::enum_flags_contains<Color>("red|BLUE", case_insensitive));
}

Test for Specific Flags

While enum_flags_contains validates the entire bitset, magic_enum::enum_flags_test checks if a specific flag is set within a bitset.

#include <magic_enum/magic_enum_flags.hpp>
#include <cassert>

using namespace magic_enum::bitwise_operators;

void test_bits() {
Color c = Color::RED | Color::BLUE;

assert(magic_enum::enum_flags_test(c, Color::RED));
assert(!magic_enum::enum_flags_test(c, Color::GREEN));
}

Troubleshooting and Constraints

  • Zero Values: In magic_enum, 0 is not considered a valid flag. magic_enum::enum_flags_name returns an empty string for 0, and magic_enum::enum_flags_contains returns false.
  • Missing Specialization: If you forget to set is_flags = true in magic_enum::customize::enum_range, the enum_flags_* functions will not correctly identify combined bitmasks and may return empty results or fail to compile.
  • Operator Overloading: Scoped enums (enum class) do not support bitwise operators by default. You must include using namespace magic_enum::bitwise_operators; in the scope where you perform the OR operation.