Skip to main content

Inspect and validate flag enums

To inspect and validate bitmask-style enums in magic_enum, you must explicitly mark the enum as a flag type and use the specialized flag APIs. This allows you to format combinations of flags into strings and verify if a specific bitmask represents a valid set of defined enumerators.

Enable Flag Support

Before using flag-specific functions, you must specialize magic_enum::customize::enum_range for your enum type and set is_flags to true. This tells magic_enum to treat the enum as a bitmask rather than a simple list of values.

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

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

// Mandatory specialization to enable flag support
template <>
struct magic_enum::customize::enum_range<Color> {
static constexpr bool is_flags = true;
};

int main() {
// Use bitwise operators by bringing them into scope
using namespace magic_enum::bitwise_operators;

Color c = Color::RED | Color::BLUE;

// magic_enum::enum_flags_name returns "RED|BLUE"
std::cout << magic_enum::enum_flags_name(c) << std::endl;

return 0;
}

Format Flag Combinations to Strings

The magic_enum::enum_flags_name function converts a bitmask value into a string containing the names of all set flags, separated by a pipe (|) by default.

  • Order of Names: The resulting string lists flag names according to their declaration order in the enum, not the order in which they were combined.
  • Invalid Values: If the input contains bits that do not correspond to any defined enumerator, or if the value is 0, the function returns an empty string.
#include <magic_enum/magic_enum_flags.hpp>
#include <cassert>
#include <string>

enum class Directions { Left = 1, Down = 2, Up = 4, Right = 8 };

template <>
struct magic_enum::customize::enum_range<Directions> {
static constexpr bool is_flags = true;
};

void example() {
using namespace magic_enum::bitwise_operators;

// Normal combination
auto d1 = Directions::Right | Directions::Left;
assert(magic_enum::enum_flags_name(d1) == "Left|Right");

// Custom separator
auto d2 = Directions::Up | Directions::Down;
assert(magic_enum::enum_flags_name(d2, '+') == "Down+Up");

// Invalid value (bit 16 is not defined)
auto invalid = static_cast<Directions>(16);
assert(magic_enum::enum_flags_name(invalid).empty());

// Zero value (not considered a valid flag combination)
assert(magic_enum::enum_flags_name(static_cast<Directions>(0)).empty());
}

Validate Flag Values

The magic_enum::enum_flags_contains function checks if a value represents a valid combination of defined flags. It supports validation from enum types, underlying integers, and strings.

Validate by Enum Value or Integer

This is useful for checking if a bitmask contains only bits that are explicitly defined in the enum.

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

enum class Permission { Read = 1, Write = 2, Execute = 4 };

template <>
struct magic_enum::customize::enum_range<Permission> {
static constexpr bool is_flags = true;
};

void validate_bits() {
using namespace magic_enum::bitwise_operators;

// Valid combination
assert(magic_enum::enum_flags_contains(Permission::Read | Permission::Write));

// Valid integer representation (1 | 4 = 5)
assert(magic_enum::enum_flags_contains<Permission>(5));

// Invalid: contains bit 8 which is not defined
assert(!magic_enum::enum_flags_contains<Permission>(Permission::Read | static_cast<Permission>(8)));

// Invalid: 0 is not a valid flag combination
assert(!magic_enum::enum_flags_contains(static_cast<Permission>(0)));
}

Validate by String

You can verify if a string correctly names one or more flags separated by |.

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

void validate_string() {
// Valid string (order does not matter for validation)
assert(magic_enum::enum_flags_contains<Permission>("Write|Read"));

// Invalid: contains an unknown name
assert(!magic_enum::enum_flags_contains<Permission>("Read|Delete"));

// Invalid: empty string
assert(!magic_enum::enum_flags_contains<Permission>(""));
}

Troubleshooting

  • Bitwise Operators: If you get compilation errors when using | or & with scoped enums, ensure you have added using namespace magic_enum::bitwise_operators; in the local scope.
  • Empty Strings: If enum_flags_name returns an empty string for a value you expect to be valid, verify that the enum_range specialization is present and that the value does not include any undefined bits.
  • Zero Values: magic_enum treats 0 as an invalid flag value. enum_flags_contains will return false for 0, and enum_flags_name will return an empty string. If your enum uses 0 for a "None" state, you must handle it separately from the magic_enum flag APIs.