📦Neargye / magic_enum
← 返回首页
Static reflection for enums (to string, from string, iteration) for modern C++, work with any enum type without any macro or boilerplate code
⚖️ MIT#cplusplus#cplusplus-17#c-plus-plus#c-plus-plus-17#cpp📅 创建于 2019-03-30🔄 更新于 2026-10-28

📄 仓库 README

在 GitHub 查看 ↗
来自 GitHub 仓库自述文件 · 版权归原作者所有

Github releases Conan package Vcpkg package Build2 package Meson wrap License Compiler explorer OpenSSF Scorecard

Magic Enum C++

Header-only C++17 library provides static reflection for enums, work with any enum type without any macro or boilerplate code.

Documentation

Features & Examples

  • Basic

```cpp #include #include

enum class Color { RED = -10, BLUE = 0, GREEN = 10 };

int main() { Color c1 = Color::RED; std::cout << magic_enum::enum_name(c1) << std::endl; // RED return 0; } ```

  • Enum value to string

cpp Color color = Color::RED; auto color_name = magic_enum::enum_name(color); // color_name -> "RED"

  • String to enum value

```cpp std::string color_name{"GREEN"}; auto color = magic_enum::enum_cast(color_name); if (color.has_value()) { // color.value() -> Color::GREEN }

// case insensitive enum_cast auto color_case_insensitive = magic_enum::enum_cast(color_name, magic_enum::case_insensitive);

// enum_cast with BinaryPredicate auto color_with_predicate = magic_enum::enum_cast(color_name, { return std::tolower(static_cast(lhs)) == std::tolower(static_cast(rhs)); });

// enum_cast with default auto color_or_default = magic_enum::enum_cast(color_name).value_or(Color::RED); ```

  • Integer to enum value

```cpp int color_integer = 0; auto color = magic_enum::enum_cast(color_integer); if (color.has_value()) { // color.value() -> Color::BLUE }

auto color_or_default = magic_enum::enum_cast(123).value_or(Color::RED); ```

  • Indexed access to enum value

cpp std::size_t i = 0; Color color = magic_enum::enum_value<Color>(i); // color -> Color::RED

  • Enum value sequence

cpp constexpr auto colors = magic_enum::enum_values<Color>(); // colors -> {Color::RED, Color::BLUE, Color::GREEN} // colors[0] -> Color::RED

  • Number of enum values

cpp constexpr std::size_t color_count = magic_enum::enum_count<Color>(); // color_count -> 3

  • Enum value to integer

cpp Color color = Color::RED; auto color_integer = magic_enum::enum_integer(color); // or magic_enum::enum_underlying(color); // color_integer -> -10

  • Enum name sequence

cpp constexpr auto color_names = magic_enum::enum_names<Color>(); // color_names -> {"RED", "BLUE", "GREEN"} // color_names[0] -> "RED"

  • Enum entry sequence

cpp 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

cpp 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(): // ... // ... }

  • Runtime enum value as constexpr constant

cpp Color color = Color::RED; magic_enum::enum_switch([](auto val) { constexpr Color c_color = val; // ... }, color);

  • Iterate over enum values as constexpr constants

cpp magic_enum::enum_for_each<Color>([](auto val) { constexpr Color c_color = val; // ... });

  • Move through enum values

cpp magic_enum::enum_next_value(Color::RED); // -> optional containing Color::BLUE magic_enum::enum_prev_value_circular(Color::RED); // -> Color::GREEN

  • Check whether enum contains value

cpp magic_enum::enum_contains(Color::GREEN); // -> true magic_enum::enum_contains<Color>(0); // -> true magic_enum::enum_contains<Color>(123); // -> false magic_enum::enum_contains<Color>("GREEN"); // -> true magic_enum::enum_contains<Color>("fda"); // -> false

  • Check whether value can be reflected

cpp magic_enum::enum_reflected(Color::GREEN); // -> true

  • Enum index in sequence

cpp constexpr auto color_index = magic_enum::enum_index(Color::BLUE); // color_index.value() -> 1 // color_index.has_value() -> true

  • Flag operations

```cpp enum Directions : std::uint64_t { Left = 1, Down = 2, Up = 4, Right = 8, }; template <> struct magic_enum::customize::enum_range { static constexpr bool is_flags = true; }; using namespace magic_enum::bitwise_operators; // Use with care; operators are enabled for all enums.

magic_enum::enum_flags_name(Directions::Up | Directions::Right); // -> "Up|Right" magic_enum::enum_flags_name(Directions::Up | Directions::Right, ','); // -> "Up,Right" magic_enum::enum_flags_contains(Directions::Up | Directions::Right); // -> true magic_enum::enum_flags_cast(3).value(); // -> Directions::Left|Directions::Down magic_enum::enum_flags_cast("Left,Down", ',').value(); // -> Directions::Left|Directions::Down magic_enum::enum_flags_test(Directions::Up | Directions::Right, Directions::Up); // -> true magic_enum::enum_flags_test_any(Directions::Left | Directions::Down, Directions::Down | Directions::Right); // -> true magic_enum::is_flags_v; // -> true ```

  • Enum type name

cpp Color color = Color::RED; auto type_name = magic_enum::enum_type_name<decltype(color)>(); // type_name -> "Color"

  • I/O stream operators for enums

cpp using magic_enum::iostream_operators::operator<<; // out-of-the-box ostream operators for enums. Color color = Color::BLUE; std::cout << color << std::endl; // "BLUE"

cpp using magic_enum::iostream_operators::operator>>; // out-of-the-box istream operators for enums. Color color; std::cin >> color;

  • Bitwise operators for enums

cpp enum class Flags { A = 1 << 0, B = 1 << 1, C = 1 << 2, D = 1 << 3 }; using namespace magic_enum::bitwise_operators; // Use with care; operators are enabled for all enums. // Support operators: ~, |, &, ^, |=, &=, ^=. Flags flags = Flags::A | (Flags::B & ~Flags::C);

  • Formatting

```cpp #include #include

std::format("{}", Color::RED); // -> "RED" std::format("{}", Color{42}); // -> "42" ```

Include {fmt} before magic_enum_format.hpp to enable {fmt} formatter support.

```cpp enum color { red, green, blue }; enum class direction { left, right };

magic_enum::is_unscoped_enum_v -> true magic_enum::is_unscoped_enum_v -> false ```

```cpp enum color { red, green, blue }; enum class direction { left, right };

magic_enum::is_scoped_enum_v -> false magic_enum::is_scoped_enum_v -> true ```

  • Compile-time enum value to string. This overload compiles faster and is not restricted by enum_range limitation.

cpp constexpr Color color = Color::BLUE; constexpr auto color_name = magic_enum::enum_name<color>(); // color_name -> "BLUE"

  • containers::array array container for enums.

```cpp constexpr auto color_rgb_values = magic_enum::containers::make_array(RGB{255, 0, 0}, RGB{0, 255, 0}, RGB{0, 0, 255});

magic_enum::containers::array color_rgb_array {}; color_rgb_array[Color::RED] = {255, 0, 0}; color_rgb_array[Color::GREEN] = {0, 255, 0}; color_rgb_array[Color::BLUE] = {0, 0, 255}; magic_enum::containers::get(color_rgb_array); // -> RGB{0, 0, 255} ```

  • containers::bitset bitset container for enums.

```cpp constexpr magic_enum::containers::bitset color_bitset {Color::RED, Color::GREEN}; color_bitset.test(Color::RED); // -> true color_bitset.test(Color::BLUE); // -> false

std::uint8_t incoming = 0b00000011; auto raw_bitset = magic_enum::containers::bitset {magic_enum::containers::raw_access, incoming}; ```

  • containers::set set container for enums.

```cpp auto color_set = magic_enum::containers::set(); bool empty = color_set.empty(); // empty -> true color_set.insert(Color::GREEN); color_set.insert(Color::BLUE); color_set.insert(Color::RED); std::size_t size = color_set.size(); // size -> 3

using color_name_set = magic_enum::containers::set<Color, magic_enum::containers::name_less<>>; color_name_set colors_by_name {Color::RED, Color::GREEN, Color::BLUE}; ```

cpp magic_enum::underlying_type<Color>::type -> int magic_enum::underlying_type_t<Color> -> int

Integration

  • Copy required headers from include/magic_enum or use release archive. magic_enum_all.hpp includes all public headers.
  • Use CMake with add_subdirectory or find_package(magic_enum CONFIG REQUIRED), then link magic_enum::magic_enum.
  • Use vcpkg, Conan, Build2, or Meson.
  • Fetch sources with CMake FetchContent or CPM.cmake. Release tags use vx.y.z format.
  • Use Bazel with MODULE.bazel or http_archive; target is @magic_enum//:magic_enum.
  • Use ROS with <depend>magic_enum</depend> in package.xml, then link magic_enum::magic_enum.

  • CMake targets:

  • magic_enum::magic_enum is the header-only target.
  • magic_enum::magic_enum_module is the C++20 module target. Enable it with MAGIC_ENUM_USE_MODULES=ON. CMake 3.28+ is required.

Build the module target: sh cmake -S . -B build -G Ninja -DMAGIC_ENUM_USE_MODULES=ON cmake --build build

Link the module target: cmake find_package(magic_enum CONFIG REQUIRED) target_link_libraries(your_executable PRIVATE magic_enum::magic_enum_module) set_target_properties(your_executable PROPERTIES CXX_EXTENSIONS OFF CXX_SCAN_FOR_MODULES ON)

Import the module: ```cpp import magic_enum;

enum class Color { RED, GREEN, BLUE }; auto name = magic_enum::enum_name(Color::RED); // "RED" ```

Do not use #include <magic_enum/...> and import magic_enum; in the same program. Use the same compiler, standard library, and C++ standard when building and consuming an installed module. The pkg-config package supports only the header-only target.

Optional settings: - Set MAGIC_ENUM_MODULE_WITH_FMT=ON to enable {fmt} support through fmt::fmt. It is disabled by default. The {fmt} C++ module is not supported. - Set MAGIC_ENUM_MODULE_IMPORT_STD=ON to enable import std support. This requires a compatible CMake toolchain.

Header-only compiler compatibility

  • Clang/LLVM >= 5
  • MSVC++ >= 15.3 / Visual Studio >= 2017
  • Xcode >= 10
  • GCC >= 9

C++26 reflection is selected automatically when available; see limitations.

Licensed under the MIT License

📈 近 7 天 Star 趋势

每日新增 Star(柱)与累计 Star(线)· 数据来自 GitHub

🏆 排名变化趋势

在各榜单中的排名历史(数字越小越靠前)

📋 历史上榜记录

每次快照的详细数据
日期 榜单 排名 周期新增 总 STAR