Introduction
magic_enum provides static reflection capabilities for C++ enumerations using compiler intrinsics. Without macros or code generation, it turns any enum into something you can convert to/from strings, iterate over, and inspect at compile time.
What magic_enum Does
- Converts enum values to their string names and vice versa at compile time
- Iterates over all values of an enum without maintaining a separate list
- Provides compile-time enum count, min, max, and contains checks
- Supports scoped enums, unscoped enums, and flag/bitmask enums
- Works with enum values in custom ranges via template specialization
Architecture Overview
magic_enum leverages compiler-specific intrinsics (PRETTY_FUNCTION on GCC/Clang, FUNCSIG on MSVC) to extract enum value names at compile time. It generates a lookup table of valid enum values and their string representations during compilation, incurring zero runtime overhead for name lookups.
Self-Hosting & Configuration
- Single header file: download magic_enum.hpp or install via vcpkg/Conan
- Include the header and use directly; no linking or build configuration needed
- Customize the default enum range with MAGIC_ENUM_RANGE_MIN and MAGIC_ENUM_RANGE_MAX
- For flag enums, use magic_enum::flags functions instead of the default enum functions
- Requires C++17; works with GCC 9+, Clang 5+, and MSVC 2019+
Key Features
- Zero runtime overhead: all reflection data is computed at compile time
- No macros required; works with existing enum definitions unmodified
- Supports bidirectional enum-string conversion with optional case-insensitive matching
- Flag enum support for bitmask types with automatic combination name generation
- Compile-time enum validation and static_assert integration
Comparison with Similar Tools
- Manual switch/case — Hand-written mappings are error-prone and must be updated with every enum change; magic_enum stays in sync automatically
- X-macro pattern — X-macros work but require defining enums in a non-standard way; magic_enum works with standard enum declarations
- Boost.Describe — Boost.Describe requires annotating types; magic_enum needs no annotations
- nameof — nameof provides general name reflection; magic_enum is specialized for enums with richer features like iteration and casting
FAQ
Q: Does magic_enum work with all enum values? A: By default it covers enum values in the range [-128, 127]. Customize with MAGIC_ENUM_RANGE_MIN/MAX for larger ranges.
Q: Is there a runtime cost? A: No. String tables are built at compile time. Lookups are simple array accesses.
Q: Does it work with enum classes (scoped enums)? A: Yes. Both scoped (enum class) and unscoped (enum) types are fully supported.
Q: Can I use magic_enum with flags/bitmask enums? A: Yes. Use magic_enum::flags_name and related functions for bitmask enums that combine multiple values.