Inspect and validate flag enums
To inspect and validate flag enums in magic_enum, you must first enable flag support by specializing magic_enum::customize::enum_range for your enum type. Once enabled, you can use enum_flags_name to generate string representations of bitmasks and enum_flags_contains to verify if a value or string represents a valid combination of flags.
Enable flag support
Flag-specific functionality is disabled by default. You must specialize the magic_enum::customize::enum_range template and set is_flags to true.
#include <iostream>
#include <cstdint>
#include <magic_enum/magic_enum_flags.hpp>
enum class Settings : std::uint32_t {
None = 0,
Audio = 1 << 0,
Video = 1 << 1,
Network = 1 << 2
};
// Enable flag support for the Settings enum
template <>
struct magic_enum::customize::enum_range<Settings> {
static constexpr bool is_flags = true;
};
int main() {
using namespace magic_enum::bitwise_operators;
Settings s = Settings::Audio | Settings::Video;
// enum_flags_name returns a string of flag names separated by '|'
std::cout << magic_enum::enum_flags_name(s) << std::endl; // "Audio|Video"
return 0;
}
Validate flag combinations
Use enum_flags_contains to check if a value, integer, or string is a valid combination of the defined flags. When passing an integer or a string, you must explicitly provide the enum type as a template argument.
#include <iostream>
#include <magic_enum/magic_enum_flags.hpp>
enum class Color : int { Red = 1, Green = 2, Blue = 4 };
template <>
struct magic_enum::customize::enum_range<Color> {
static constexpr bool is_flags = true;
};
int main() {
using namespace magic_enum::bitwise_operators;
// Validate using enum values
bool v1 = magic_enum::enum_flags_contains(Color::Red | Color::Green); // true
// Validate using underlying integers (requires explicit template argument)
bool v2 = magic_enum::enum_flags_contains<Color>(5); // true (Red | Blue)
bool v3 = magic_enum::enum_flags_contains<Color>(8); // false (no flag for 8)
// Validate using strings (requires explicit template argument)
bool v4 = magic_enum::enum_flags_contains<Color>("Red|Blue"); // true
bool v5 = magic_enum::enum_flags_contains<Color>("Yellow"); // false
return 0;
}
Perform case-insensitive validation
By default, enum_flags_contains is case-sensitive when validating strings. You can perform case-insensitive validation by passing a custom predicate.
#include <iostream>
#include <string_view>
#include <magic_enum/magic_enum_flags.hpp>
enum class Permission { Read = 1, Write = 2, Execute = 4 };
template <>
struct magic_enum::customize::enum_range<Permission> {
static constexpr bool is_flags = true;
};
// Case-insensitive string comparison predicate
struct case_insensitive_less {
using is_transparent = void;
bool operator()(char lhs, char rhs) const noexcept {
return to_lower(lhs) == to_lower(rhs);
}
private:
static char to_lower(char c) {
return (c >= 'A' && c <= 'Z') ? static_cast<char>(c + ('a' - 'A')) : c;
}
bool operator()(std::string_view lhs, std::string_view rhs) const noexcept {
if (lhs.size() != rhs.size()) return false;
for (std::size_t i = 0; i < lhs.size(); ++i) {
if (to_lower(lhs[i]) != to_lower(rhs[i])) return false;
}
return true;
}
friend magic_enum::enum_flags_contains<Permission, case_insensitive_less>;
};
int main() {
// Case-insensitive check for "READ|write"
bool valid = magic_enum::enum_flags_contains<Permission>("READ|write", [](char lhs, char rhs) {
auto to_low = [](char c) { return (c >= 'A' && c <= 'Z') ? static_cast<char>(c + 32) : c; };
return to_low(lhs) == to_low(rhs);
});
std::cout << std::boolalpha << valid << std::endl; // true
return 0;
}
Usage notes
- Zero values:
enum_flags_containsreturnsfalsefor a value of0(or a string representing a zero-value flag like"None"if it maps to 0), as0is not considered a set flag in magic_enum. - Bitwise operators: To use
|,&,~, and^directly with scoped enums, you must bring them into scope withusing namespace magic_enum::bitwise_operators;. - Header requirement: All flag-related APIs require the inclusion of
magic_enum/magic_enum_flags.hpp.