Static reflection for enums (to string, from string, iteration) for modern C++, work with any enum type without any macro or boilerplate code
__ __ _ ______ _____
| \/ | (_) | ____| / ____|_ _
| \ / | __ _ __ _ _ ___ | |__ _ __ _ _ _ __ ___ | | _| |_ _| |_
| |\/| |/ _` |/ _` | |/ __| | __| | '_ \| | | | '_ ` _ \ | | |_ _|_ _|
| | | | (_| | (_| | | (__ | |____| | | | |_| | | | | | | | |____|_| |_|
|_| |_|\__,_|\__, |_|\___| |______|_| |_|\__,_|_| |_| |_| \_____|
__/ |
|___/
Magic Enum C++
Header-only C++17 library provides static reflection for enums, work with any enum type without any macro or boilerplate code.
enum_cast
obtains enum value from string or integer.enum_value
returns enum value at specified index.enum_values
obtains enum value sequence.enum_count
returns number of enum values.enum_integer
obtains integer value from enum value.enum_name
returns name from enum value.enum_names
obtains string enum name sequence.enum_entries
obtains pair (value enum, string enum name) sequence.enum_index
obtains index in enum value sequence from enum value.enum_contains
checks whether enum contains enumerator with such value.enum_type_name
returns name of enum type.enum_fuse
allows multidimensional switch/cases.enum_switch
allows runtime enum value transformation to constexpr context.enum_for_each
calls a function with all enum constexpr value.is_unscoped_enum
checks whether type is an Unscoped enumeration.is_scoped_enum
checks whether type is an Scoped enumeration.underlying_type
improved UB-free "SFINAE-friendly" underlying_type.ostream_operators
ostream operators for enums.bitwise_operators
bitwise operators for enums.
Documentation
Features
- C++17
- Header-only
- Dependency-free
- Compile-time
- Enum to string
- String to enum
- Iterating over enum
Examples
// For example color enum.
enum class Color { RED = 2, BLUE = 4, GREEN = 8 };
-
Enum value to string
Color color = Color::RED; auto color_name = magic_enum::enum_name(color); // color_name -> "RED"
-
String to enum value
std::string color_name{"GREEN"}; auto color = magic_enum::enum_cast<Color>(color_name); if (color.has_value()) { // color.value() -> Color::GREEN }
-
Integer to enum value
int color_integer = 2; auto color = magic_enum::enum_cast<Color>(color_integer); if (color.has_value()) { // color.value() -> Color::RED }
-
Indexed access to enum value
std::size_t i = 1; Color color = magic_enum::enum_value<Color>(i); // color -> Color::BLUE
-
Enum value sequence
constexpr auto colors = magic_enum::enum_values<Color>(); // colors -> {Color::RED, Color::BLUE, Color::GREEN} // colors[0] -> Color::RED
-
Number of enum elements
constexpr std::size_t color_count = magic_enum::enum_count<Color>(); // color_count -> 3
-
Enum value to integer
Color color = Color::RED; auto color_integer = magic_enum::enum_integer(color); // color -> 2
-
Enum names sequence
constexpr auto color_names = magic_enum::enum_names<Color>(); // color_names -> {"RED", "BLUE", "GREEN"} // color_names[0] -> "RED"
-
Enum entries sequence
constexpr auto color_entries = magic_enum::enum_entries<Color>(); // color_entries -> {{Color::RED, "RED"}, {Color::BLUE, "BLUE"}, {Color::GREEN, "GREEN"}} // color_entries[0].first -> Color::RED // color_entries[0].second -> "RED"
-
Enum fusion for multi-level switch/case statements
switch (magic_enum::enum_fuse(color, direction).value()) { case magic_enum::enum_fuse(Color::RED, Directions::Up).value(): // ... case magic_enum::enum_fuse(Color::BLUE, Directions::Down).value(): // ... // ... }
-
Enum switch runtime value as constexpr constant
Color color = Color::RED; magic_enum::enum_switch([] (auto val) { constexpr Color c_color = val; // ... }, color);
-
Enum iterate for each enum as constexpr constant
magic_enum::enum_for_each<Color>([] (auto val) { constexpr Color c_color = val; // ... });
-
Ostream operator for enum
using namespace magic_enum::ostream_operators; // out-of-the-box ostream operators for enums. Color color = Color::BLUE; std::cout << color << std::endl; // "BLUE"
-
Bitwise operator for enum
enum class Flags { A = 1 << 0, B = 1 << 1, C = 1 << 2, D = 1 << 3 }; using namespace magic_enum::bitwise_operators; // out-of-the-box bitwise operators for enums. // Support operators: ~, |, &, ^, |=, &=, ^=. Flags flags = Flags::A | Flags::B & ~Flags::C;
-
Checks whether type is an Unscoped enumeration.
enum color { red, green, blue }; enum class direction { left, right }; magic_enum::is_unscoped_enum<color>::value -> true magic_enum::is_unscoped_enum<direction>::value -> false magic_enum::is_unscoped_enum<int>::value -> false // Helper variable template. magic_enum::is_unscoped_enum_v<color> -> true
-
Checks whether type is an Scoped enumeration.
enum color { red, green, blue }; enum class direction { left, right }; magic_enum::is_scoped_enum<color>::value -> false magic_enum::is_scoped_enum<direction>::value -> true magic_enum::is_scoped_enum<int>::value -> false // Helper variable template. magic_enum::is_scoped_enum_v<direction> -> true
-
Static storage enum variable to string This version is much lighter on the compile times and is not restricted to the enum_range limitation.
constexpr Color color = Color::BLUE; constexpr auto color_name = magic_enum::enum_name<color>(); // color_name -> "BLUE"
Remarks
-
magic_enum
does not pretend to be a silver bullet for reflection for enums, it was originally designed for small enum. -
Before use, read the limitations of functionality.
Integration
-
You should add the required file magic_enum.hpp.
-
If you are using vcpkg on your project for external dependencies, then you can use the magic-enum package.
-
If you are using Conan to manage your dependencies, merely add
magic_enum/x.y.z
to your conan's requires, wherex.y.z
is the release version you want to use. -
If you are using Build2 to build and manage your dependencies, add
depends: magic_enum ^x.y.z
to the manifest file wherex.y.z
is the release version you want to use. You can then import the target usingmagic_enum%lib{magic_enum}
. -
Alternatively, you can use something like CPM which is based on CMake's
Fetch_Content
module.CPMAddPackage( NAME magic_enum GITHUB_REPOSITORY Neargye/magic_enum GIT_TAG x.y.z # Where `x.y.z` is the release version you want to use. )
-
Bazel is also supported, simply add to your WORKSPACE file:
http_archive( name = "magic_enum", strip_prefix = "magic_enum-<commit>", urls = ["https://github.com/Neargye/magic_enum/archive/<commit>.zip"], )
To use bazel inside the repository it's possible to do:
bazel build //... bazel test //... bazel run //:example
(Note that you must use a supported compiler or specify it with
export CC= <compiler>
.) -
If you are using Ros, you can include this package by adding
<depend>magic_enum</depend>
to your package.xml and include this package in your workspace. In your CMakeLists.txt add the following:find_package(magic_enum CONFIG REQUIRED) ... target_link_libraries(your_executable magic_enum::magic_enum)
Compiler compatibility
- Clang/LLVM >= 6
- MSVC++ >= 14.11 / Visual Studio >= 2017
- Xcode >= 10
- GCC >= 9
- MinGW >= 9
Licensed under the MIT License
version | 0.8.1 |
---|---|
license | MIT License |
repository | https://pkg.cppget.org/1/alpha |
download | magic_enum-0.8.1.tar.gz |
sha256 | 57a28c1bcfa5224902b61f3c644b3a32f63c59f72d0d95348e0548bdba05c1ff |
project | magic_enum |
---|---|
doc-url | github.com/Neargye/magic_enum/blob/master/doc/reference.md |
src-url | github.com/Neargye/magic_enum |
package-email | wmbat-dev@protonmail.com |
topics | Enumreflection |
Requires (1)
c++ >= 17 |
Tests
magic_enum-tests == 0.8.1 |
Reviews
fail | 0 |
---|---|
pass | 1 |
Builds
toolchain | public-0.17.0 |
---|---|
target | x86_64-microsoft-win32-msvc14.3 |
tgt config | windows_10-clang_18_llvm_msvc_17.10-static_O2 |
timestamp | 2025-09-13 21:44:56 UTC (01:46:05 hours ago) |
result | success | log | rebuild |
toolchain | public-0.17.0 |
---|---|
target | x86_64-microsoft-win32-msvc14.3 |
tgt config | windows_10-clang_18_llvm_msvc_17.10-O2 |
timestamp | 2025-09-13 21:40:30 UTC (01:50:31 hours ago) |
result | success | log | rebuild |
toolchain | public-0.17.0 |
---|---|
target | x86_64-microsoft-win32-msvc14.3 |
tgt config | windows_10-clang_18_llvm_msvc_17.10 |
timestamp | 2025-09-13 21:39:03 UTC (01:51:58 hours ago) |
result | success | log | rebuild |
toolchain | public-0.17.0 |
---|---|
target | x86_64-linux-gnu |
tgt config | linux_ubuntu_24.04-gcc_13-bindist |
timestamp | 2025-09-13 21:16:15 UTC (02:14:46 hours ago) |
result | success | log | rebuild |
toolchain | public-0.17.0 |
---|---|
target | x86_64-w64-mingw32 |
tgt config | windows_10-gcc_13.2_mingw_w64-static_O2 |
timestamp | 2025-09-13 21:08:43 UTC (02:22:18 hours ago) |
result | success | log | rebuild |
toolchain | public-0.17.0 |
---|---|
target | x86_64-w64-mingw32 |
tgt config | windows_10-gcc_13.2_mingw_w64-O2 |
timestamp | 2025-09-13 21:07:02 UTC (02:23:59 hours ago) |
result | success | log | rebuild |
toolchain | public-0.17.0 |
---|---|
target | x86_64-microsoft-win32-msvc14.3 |
tgt config | windows_10-msvc_17.10-O2 |
timestamp | 2025-09-13 21:06:05 UTC (02:24:55 hours ago) |
result | success | log | rebuild |
toolchain | public-0.17.0 |
---|---|
target | x86_64-microsoft-win32-msvc14.3 |
tgt config | windows_10-msvc_17.10 |
timestamp | 2025-09-13 21:05:06 UTC (02:25:54 hours ago) |
result | success | log | rebuild |
toolchain | public-0.17.0 |
---|---|
target | x86_64-w64-mingw32 |
tgt config | windows_10-gcc_13.2_mingw_w64 |
timestamp | 2025-09-13 21:04:49 UTC (02:26:12 hours ago) |
result | success | log | rebuild |
toolchain | public-0.17.0 |
---|---|
target | x86_64-microsoft-win32-msvc14.3 |
tgt config | windows_10-msvc_17.10-static_O2 |
timestamp | 2025-09-13 21:03:05 UTC (02:27:56 hours ago) |
result | success | log | rebuild |
toolchain | public-0.17.0 |
---|---|
target | x86_64-microsoft-win32-msvc14.3 |
tgt config | windows_10-msvc_17.8-static_O2 |
timestamp | 2025-09-13 21:02:14 UTC (02:28:47 hours ago) |
result | success | log | rebuild |
toolchain | public-0.17.0 |
---|---|
target | x86_64-microsoft-win32-msvc14.3 |
tgt config | windows_10-msvc_17.8-O2 |
timestamp | 2025-09-13 21:01:06 UTC (02:29:55 hours ago) |
result | success | log | rebuild |
toolchain | public-0.17.0 |
---|---|
target | x86_64-microsoft-win32-msvc14.3 |
tgt config | windows_10-msvc_17.8 |
timestamp | 2025-09-13 20:58:44 UTC (02:32:17 hours ago) |
result | success | log | rebuild |
toolchain | public-0.17.0 |
---|---|
target | x86_64-microsoft-win32-msvc14.3 |
tgt config | windows_10-clang_17_msvc_msvc_17.10 |
timestamp | 2025-09-13 20:58:24 UTC (02:32:37 hours ago) |
result | success | log | rebuild |
toolchain | public-0.17.0 |
---|---|
target | x86_64-linux-gnu |
tgt config | linux_debian_12-gcc_12-bindist |
timestamp | 2025-09-13 20:52:36 UTC (02:38:25 hours ago) |
result | success | log | rebuild |
toolchain | public-0.17.0 |
---|---|
target | x86_64-freebsd13.3 |
tgt config | freebsd_13-clang_17 |
timestamp | 2025-09-13 20:41:22 UTC (02:49:39 hours ago) |
result | success | log | rebuild |
toolchain | public-0.17.0 |
---|---|
target | x86_64-linux-gnu |
tgt config | linux_debian_12-gcc_14-ndebug_O3 |
timestamp | 2025-09-13 20:40:43 UTC (02:50:18 hours ago) |
result | success | log | rebuild |
toolchain | public-0.17.0 |
---|---|
target | x86_64-linux-gnu |
tgt config | linux_debian_12-gcc_14-static_O3 |
timestamp | 2025-09-13 20:39:19 UTC (02:51:42 hours ago) |
result | success | log | rebuild |
toolchain | public-0.17.0 |
---|---|
target | x86_64-linux-gnu |
tgt config | linux_debian_12-gcc_14 |
timestamp | 2025-09-13 20:38:33 UTC (02:52:28 hours ago) |
result | success | log | rebuild |
toolchain | public-0.17.0 |
---|---|
target | x86_64-linux-gnu |
tgt config | linux_debian_12-gcc_14-O3 |
timestamp | 2025-09-13 20:37:18 UTC (02:53:43 hours ago) |
result | success | log | rebuild |
toolchain | public-0.17.0 |
---|---|
target | x86_64-freebsd14.1 |
tgt config | freebsd_14-clang_18-static_O3 |
timestamp | 2025-09-13 20:33:12 UTC (02:57:48 hours ago) |
result | success | log | rebuild |
toolchain | public-0.17.0 |
---|---|
target | x86_64-freebsd14.1 |
tgt config | freebsd_14-clang_18-O3 |
timestamp | 2025-09-13 20:32:03 UTC (02:58:58 hours ago) |
result | success | log | rebuild |
toolchain | public-0.17.0 |
---|---|
target | x86_64-freebsd14.1 |
tgt config | freebsd_14-clang_18 |
timestamp | 2025-09-13 20:31:28 UTC (02:59:33 hours ago) |
result | success | log | rebuild |
toolchain | public-0.17.0 |
---|---|
target | x86_64-linux-gnu |
tgt config | linux_debian_12-gcc_13.1 |
timestamp | 2025-09-13 20:28:15 UTC (03:02:46 hours ago) |
result | success | log | rebuild |
toolchain | public-0.17.0 |
---|---|
target | x86_64-linux-gnu |
tgt config | linux_debian_12-clang_17_libc++ |
timestamp | 2025-09-13 20:27:37 UTC (03:03:24 hours ago) |
result | success | log | rebuild |
toolchain | public-0.17.0 |
---|---|
target | x86_64-linux-gnu |
tgt config | linux_debian_12-clang_17 |
timestamp | 2025-09-13 20:27:32 UTC (03:03:28 hours ago) |
result | success | log | rebuild |
toolchain | public-0.17.0 |
---|---|
target | aarch64-linux-gnu |
tgt config | linux_debian_12-clang_18_libc++-O3 |
timestamp | 2025-09-13 05:36:42 UTC (17:54:19 hours ago) |
result | success | log | rebuild |
toolchain | public-0.17.0 |
---|---|
target | aarch64-linux-gnu |
tgt config | linux_debian_12-clang_18_libc++ |
timestamp | 2025-09-13 05:36:09 UTC (17:54:51 hours ago) |
result | success | log | rebuild |
toolchain | public-0.17.0 |
---|---|
target | aarch64-linux-gnu |
tgt config | linux_debian_12-clang_18-static_O3 |
timestamp | 2025-09-13 05:35:58 UTC (17:55:03 hours ago) |
result | success | log | rebuild |
toolchain | public-0.17.0 |
---|---|
target | aarch64-linux-gnu |
tgt config | linux_debian_12-clang_18-O3 |
timestamp | 2025-09-13 05:34:35 UTC (17:56:26 hours ago) |
result | success | log | rebuild |
toolchain | public-0.17.0 |
---|---|
target | aarch64-linux-gnu |
tgt config | linux_debian_12-clang_18 |
timestamp | 2025-09-13 05:33:51 UTC (17:57:10 hours ago) |
result | success | log | rebuild |
toolchain | public-0.17.0 |
---|---|
target | aarch64-linux-gnu |
tgt config | linux_debian_12-clang_18_libc++-static_O3 |
timestamp | 2025-09-12 18:05:54 UTC (01 05:25:07 days ago) |
result | success | log | rebuild |
toolchain | public-0.17.0 |
---|---|
target | x86_64-linux-gnu |
tgt config | linux_fedora_40-gcc_14-bindist |
timestamp | 2025-09-12 05:29:40 UTC (01 18:01:20 days ago) |
result | success | log | rebuild |
toolchain | public-0.17.0 |
---|---|
target | aarch64-linux-gnu |
tgt config | linux_debian_12-gcc_14-static_O3 |
timestamp | 2025-09-12 03:41:15 UTC (01 19:49:46 days ago) |
result | success | log | rebuild |
toolchain | public-0.17.0 |
---|---|
target | aarch64-linux-gnu |
tgt config | linux_debian_12-gcc_14 |
timestamp | 2025-09-12 03:33:05 UTC (01 19:57:55 days ago) |
result | success | log | rebuild |
toolchain | public-0.17.0 |
---|---|
target | aarch64-linux-gnu |
tgt config | linux_debian_12-gcc_14-O3 |
timestamp | 2025-09-12 03:32:27 UTC (01 19:58:34 days ago) |
result | success | log | rebuild |
toolchain | public-0.17.0 |
---|---|
target | aarch64-linux-gnu |
tgt config | linux_debian_12-gcc_14-ndebug_O3 |
timestamp | 2025-09-12 03:31:08 UTC (01 19:59:53 days ago) |
result | success | log | rebuild |
toolchain | public-0.17.0 |
---|---|
target | aarch64-linux-gnu |
tgt config | linux_debian_12-clang_17_libc++ |
timestamp | 2025-09-11 14:50:16 UTC (02 08:40:45 days ago) |
result | success | log | rebuild |
toolchain | public-0.17.0 |
---|---|
target | aarch64-linux-gnu |
tgt config | linux_debian_12-clang_17 |
timestamp | 2025-09-11 14:45:37 UTC (02 08:45:24 days ago) |
result | success | log | rebuild |
toolchain | public-0.17.0 |
---|---|
target | aarch64-linux-gnu |
tgt config | linux_debian_12-gcc_13 |
timestamp | 2025-09-11 14:23:03 UTC (02 09:07:58 days ago) |
result | success | log | rebuild |
toolchain | public-0.17.0 |
---|---|
target | x86_64-linux-gnu |
tgt config | linux_debian_12-clang_18 |
result | unbuilt |
toolchain | public-0.17.0 |
---|---|
target | x86_64-linux-gnu |
tgt config | linux_debian_12-clang_18-O3 |
result | unbuilt |
toolchain | public-0.17.0 |
---|---|
target | x86_64-linux-gnu |
tgt config | linux_debian_12-clang_18-static_O3 |
result | unbuilt |
toolchain | public-0.17.0 |
---|---|
target | x86_64-linux-gnu |
tgt config | linux_debian_12-clang_18_libc++ |
result | unbuilt |
toolchain | public-0.17.0 |
---|---|
target | x86_64-linux-gnu |
tgt config | linux_debian_12-clang_18_libc++-O3 |
result | unbuilt |
toolchain | public-0.17.0 |
---|---|
target | x86_64-linux-gnu |
tgt config | linux_debian_12-clang_18_libc++-static_O3 |
result | unbuilt |
toolchain | public-0.17.0 |
---|---|
target | x86_64-linux-gnu |
tgt config | linux_fedora_39-gcc_13-bindist |
result | unbuilt |
toolchain | public-0.17.0 |
---|---|
target | x86_64-apple-darwin22.5.0 |
tgt config | macos_13-clang_15.0 |
result | unbuilt |
toolchain | public-0.17.0 |
---|---|
target | x86_64-apple-darwin23.5.0 |
tgt config | macos_14-clang_15.0 |
result | unbuilt |
toolchain | public-0.17.0 |
---|---|
target | x86_64-apple-darwin23.5.0 |
tgt config | macos_14-clang_15.0-O3 |
result | unbuilt |
toolchain | public-0.17.0 |
---|---|
target | x86_64-apple-darwin23.5.0 |
tgt config | macos_14-clang_15.0-static_O3 |
result | unbuilt |
toolchain | public-0.17.0 |
---|---|
target | x86_64-apple-darwin23.5.0 |
tgt config | macos_14-gcc_14_homebrew |
result | unbuilt |
toolchain | public-0.17.0 |
---|---|
target | x86_64-apple-darwin23.5.0 |
tgt config | macos_14-gcc_14_homebrew-O3 |
result | unbuilt |
toolchain | public-0.17.0 |
---|---|
target | x86_64-apple-darwin23.5.0 |
tgt config | macos_14-gcc_14_homebrew-static_O3 |
result | unbuilt |