magic_enum

C/C++ 2025-08-04

魔术枚举C ++

仅标题C ++ 17库为枚举提供静态反射,使用任何枚举类型,而无需任何宏观或样板代码。

如果您喜欢这个项目,请考虑捐赠给有助于乌克兰战争受害者的资金之一:https://u24.gov.ua。

文档

  • 参考
  • 限制
  • 一体化

功能和示例

  • 基本的

    magic_enum .hpp> #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; }">
    # include < magic_enum / magic_enum .hpp >
    # include < iostream >
    
    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 ;
    }
  • 枚举值

    magic_enum::enum_name(color); // color_name -> "RED"">
    Color color = Color::RED;
    auto color_name = magic_enum ::enum_name(color);
    // color_name -> "RED"
  • 字符串到枚举值

    magic_enum::enum_cast(color_name); if (color.has_value()) { // color.value() -> Color::GREEN } // case insensitive enum_cast auto color = magic_enum ::enum_cast(value, magic_enum ::case_insensitive); // enum_cast with BinaryPredicate auto color = magic_enum ::enum_cast(value, [](char lhs, char rhs) { return std::tolower(lhs) == std::tolower(rhs); } // enum_cast with default auto color_or_default = magic_enum ::enum_cast(value).value_or(Color::NONE);">
    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 = magic_enum ::enum_cast(value, magic_enum ::case_insensitive);
    
    // enum_cast with BinaryPredicate
    auto color = magic_enum ::enum_cast(value, []( char lhs, char rhs) { return std::tolower (lhs) == std::tolower (rhs); }
    
    // enum_cast with default
    auto color_or_default = magic_enum ::enum_cast(value).value_or(Color::NONE);
  • 整数枚举价值

    magic_enum::enum_cast(color_integer); if (color.has_value()) { // color.value() -> Color::BLUE } auto color_or_default = magic_enum ::enum_cast(value).value_or(Color::NONE);">
     int color_integer = 2 ;
    auto color = magic_enum ::enum_cast(color_integer);
    if (color.has_value()) {
      // color.value() -> Color::BLUE
    }
    
    auto color_or_default = magic_enum ::enum_cast(value).value_or(Color::NONE);
  • 索引访问枚举价值

    magic_enum::enum_value(i); // color -> Color::RED">
    std:: size_t i = 0 ;
    Color color = magic_enum ::enum_value(i);
    // color -> Color::RED
  • 枚举值序列

    magic_enum::enum_values(); // colors -> {Color::RED, Color::BLUE, Color::GREEN} // colors[0] -> Color::RED">
     constexpr auto colors = magic_enum ::enum_values();
    // colors -> {Color::RED, Color::BLUE, Color::GREEN}
    // colors[0] -> Color::RED
  • 枚举元素数量

    magic_enum::enum_count(); // color_count -> 3">
     constexpr std:: size_t color_count = magic_enum ::enum_count();
    // color_count -> 3
  • 对整数的枚举价值

    magic_enum ::enum_underlying(color); // color_integer -> 1">
    Color color = Color::RED;
    auto color_integer = magic_enum ::enum_integer(color); // or magic_enum ::enum_underlying(color);
    // color_integer -> 1
  • 枚举名称序列

    magic_enum::enum_names(); // color_names -> {"RED", "BLUE", "GREEN"} // color_names[0] -> "RED"">
     constexpr auto color_names = magic_enum ::enum_names();
    // color_names -> {"RED", "BLUE", "GREEN"}
    // color_names[0] -> "RED"
  • enum条目序列

    magic_enum::enum_entries(); // color_entries -> {{Color::RED, "RED"}, {Color::BLUE, "BLUE"}, {Color::GREEN, "GREEN"}} // color_entries[0].first -> Color::RED // color_entries[0].second -> "RED"">
     constexpr auto color_entries = magic_enum ::enum_entries();
    // color_entries -> {{Color::RED, "RED"}, {Color::BLUE, "BLUE"}, {Color::GREEN, "GREEN"}}
    // color_entries[0].first -> Color::RED
    // color_entries[0].second -> "RED"
  • 多层开关/案例语句的枚举融合

    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(): // ... // ... }">
     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 (): // ...
    // ...
    }
  • 枚举开关运行时值作为constexpr常数

    magic_enum::enum_switch([] (auto val) { constexpr Color c_color = val; // ... }, color);">
    Color color = Color::RED;
    magic_enum ::enum_switch ([] ( auto val) {
      constexpr Color c_color = val;
      // ...
    }, color);
  • 每个枚举作为constexpr常数的枚举

    magic_enum::enum_for_each([] (auto val) { constexpr Color c_color = val; // ... });">
     magic_enum ::enum_for_each([] ( auto val) {
      constexpr Color c_color = val;
      // ...
    });
  • 检查枚举是否包含

    magic_enum::enum_contains(Color::GREEN); // -> true magic_enum ::enum_contains(2); // -> true magic_enum ::enum_contains(123); // -> false magic_enum ::enum_contains("GREEN"); // -> true magic_enum ::enum_contains("fda"); // -> false">
     magic_enum ::enum_contains (Color::GREEN); // -> true
    magic_enum ::enum_contains( 2 ); // -> true
    magic_enum ::enum_contains( 123 ); // -> false
    magic_enum ::enum_contains( " GREEN " ); // -> true
    magic_enum ::enum_contains( " fda " ); // -> false
  • 序列的枚举指数

    magic_enum::enum_index(Color::BLUE); // color_index.value() -> 1 // color_index.has_value() -> true">
     constexpr auto color_index = magic_enum ::enum_index(Color::BLUE);
    // color_index.value() -> 1
    // color_index.has_value() -> true
  • 标志的功能

    magic_enum::customize::enum_range { static constexpr bool is_flags = true; }; magic_enum ::enum_flags_name(Directions::Up | Directions::Right); // -> "Directions::Up|Directions::Right" magic_enum ::enum_flags_contains(Directions::Up | Directions::Right); // -> true magic_enum ::enum_flags_cast(3); // -> "Directions::Left|Directions::Down"">
     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 ;
    };
    
    magic_enum ::enum_flags_name (Directions::Up | Directions::Right); // -> "Directions::Up|Directions::Right"
    magic_enum ::enum_flags_contains (Directions::Up | Directions::Right); // -> true
    magic_enum ::enum_flags_cast ( 3 ); // -> "Directions::Left|Directions::Down"
  • 枚举类型名称

    magic_enum::enum_type_name(); // type_name -> "Color"">
    Color color = Color::RED;
    auto type_name = magic_enum ::enum_type_name< decltype (color)>();
    // type_name -> "Color"
  • 枚举的iostream运营商

    magic_enum::iostream_operators::operator<<; // out-of-the-box ostream operators for enums. Color color = Color::BLUE; std::cout << color << std::endl; // "BLUE"">
     using magic_enum ::iostream_operators:: operator <<; // out-of-the-box ostream operators for enums.
    Color color = Color::BLUE;
    std::cout << color << std::endl; // "BLUE" 
    magic_enum::iostream_operators::operator>>; // out-of-the-box istream operators for enums. Color color; std::cin >> color;">
     using magic_enum ::iostream_operators:: operator >>; // out-of-the-box istream operators for enums.
    Color color;
    std::cin >> color;
  • 枚举的位运算符

    magic_enum::bitwise_operators; // out-of-the-box bitwise operators for enums. // Support operators: ~, |, &, ^, |=, &=, ^=. Flags flags = Flags::A | Flags::B & ~Flags::C;">
     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;
  • 检查类型是否是未指挥的枚举。

    magic_enum::is_unscoped_enum::value -> true magic_enum ::is_unscoped_enum::value -> false magic_enum ::is_unscoped_enum::value -> false // Helper variable template. magic_enum ::is_unscoped_enum_v -> true">
     enum color { red, green, blue };
    enum class direction { left, right };
    
    magic_enum ::is_unscoped_enum::value -> true
    magic_enum ::is_unscoped_enum::value -> false
    magic_enum ::is_unscoped_enum< int >::value -> false
    
    // Helper variable template.
    magic_enum ::is_unscoped_enum_v -> true
  • 检查类型是否是范围的枚举。

    magic_enum::is_scoped_enum::value -> false magic_enum ::is_scoped_enum::value -> true magic_enum ::is_scoped_enum::value -> false // Helper variable template. magic_enum ::is_scoped_enum_v -> true">
     enum color { red, green, blue };
    enum class direction { left, right };
    
    magic_enum ::is_scoped_enum::value -> false
    magic_enum ::is_scoped_enum::value -> true
    magic_enum ::is_scoped_enum< int >::value -> false
    
    // Helper variable template.
    magic_enum ::is_scoped_enum_v -> true
  • 在编译时间,静态存储枚举变量此版本要轻得多,并且不仅限于enum_range限制。

    magic_enum::enum_name(); // color_name -> "BLUE"">
     constexpr Color color = Color::BLUE;
    constexpr auto color_name = magic_enum ::enum_name();
    // color_name -> "BLUE"
  • 容器::数组阵列容器用于枚举。

    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}">
     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}
  • 容器:: bitset bitset容器用于枚举。

    magic_enum::containers::bitset color_bitset_red_green {Color::RED|Color::GREEN}; bool all = color_bitset_red_green.all(); // all -> false // Color::BLUE is missing bool test = color_bitset_red_green.test(Color::RED); // test -> true">
     constexpr magic_enum ::containers::bitset color_bitset_red_green {Color::RED|Color::GREEN};
    bool all = color_bitset_red_green.all();
    // all -> false
    // Color::BLUE is missing
    bool test = color_bitset_red_green.test(Color::RED);
    // test -> true
  • 容器::设定的枚举容器。

    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">
     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
  • 改进了无UB“ Sfinae-Finae-Frylyly”的基础type。

    magic_enum::underlying_type::type -> int // Helper types. magic_enum ::underlying_type_t -> int">
     magic_enum ::underlying_type::type -> int
    
    // Helper types.
    magic_enum :: underlying_type_t  -> int 

评论

  • magic_enum并不假装是用于枚举的反射的银色子弹,它最初是为小枚举而设计的。

  • 使用前,请阅读功能的局限性。

一体化

  • 您应该添加所需的文件magic_enum .hpp,以及可选的其他标题,包括DIR或Release Archive。另外,您可以使用CMAKE构建库。

  • 如果您在项目上使用VCPKG来用于外部依赖项,则可以使用魔术包装包。

  • 如果您使用柯南来管理依赖项,则仅在柯南的要求中添加magic_enum /xyz,xyz是您要使用的发行版本。

  • 如果您使用build2来构建和管理依赖关系,则添加依赖性: magic_enum ^xyz到清单文件中xyz是您要使用的发行版本。然后,您可以使用magic_enum %lib { magic_enum }导入目标。

  • 另外,您可以使用基于CMAKE的Fetch_Content模块之类的CPM。

    magic_enum GITHUB_REPOSITORY Neargye/ magic_enum GIT_TAG vx.y.z # Where `x.y.z` is the release version you want to use. )">
     CPMAddPackage (
        NAME magic_enum
        GITHUB_REPOSITORY Neargye/ magic_enum
        GIT_TAG vx.y.z # Where `x.y.z` is the release version you want to use.
    )
  • 也支持Bazel,只需添加到您的工作区文件:

    magic_enum", strip_prefix = " magic_enum -", urls = ["https://*git*h*ub.com/Neargye/magic_enum/archive/.zip"], )">
    http_archive(
        name = " magic_enum ",
        strip_prefix = " magic_enum -",
        urls = ["https://*git*h*ub.com/Neargye/magic_enum/archive/.zip"],
    )
    

    要在存储库中使用Bazel,可以做:

    bazel build //...
    bazel test //...
    bazel run //example
    

    (请注意,您必须使用支持的编译器或使用导出CC = <编译器>指定它。)

  • 如果您使用的是ROS,则可以通过将 magic_enum 添加到poffage.xml中,并将此软件包包含在工作区中。在您的cmakelists.txt中添加以下内容:

    magic_enum CONFIG REQUIRED) ... target_link_libraries(your_executable magic_enum :: magic_enum )">
     find_package ( magic_enum CONFIG REQUIRED )
    ...
    target_link_libraries ( your_executable magic_enum :: magic_enum )

编译器兼容性

  • clang/llvm> = 5
  • MSVC ++> = 14.11 / Visual Studio> = 2017
  • Xcode> = 10
  • GCC> = 9
  • mingw> = 9

根据MIT许可证许可

下载源码

通过命令行克隆项目:

git clone https://github.com/Neargye/magic_enum.git