Popularity
3.8
Growing
Activity
8.4
Growing
390
16
16

Description

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_name obtains string name from enum value. enum_names obtains string enum name sequence. is_unscoped_enum checks whether type is an Unscoped enumeration. is_scoped_enum checks whether type is an Scoped enumeration.

Programming language: C++
Tags: Serialization     Meta Programming     C++17     Cpp17     Cpp     Reflection    

Magic Enum C++ alternatives and similar libraries

Based on the "Serialization" category

Do you think we are missing an alternative of Magic Enum C++ or a related project?

Add another 'Serialization' Library

README

 __  __             _        ______                          _____
|  \/  |           (_)      |  ____|                        / ____|_     _
| \  / | __ _  __ _ _  ___  | |__   _ __  _   _ _ __ ___   | |   _| |_ _| |_
| |\/| |/ _` |/ _` | |/ __| |  __| | '_ \| | | | '_ ` _ \  | |  |_   _|_   _|
| |  | | (_| | (_| | | (__  | |____| | | | |_| | | | | | | | |____|_|   |_|
|_|  |_|\__,_|\__, |_|\___| |______|_| |_|\__,_|_| |_| |_|  \_____|
               __/ |
              |___/

Github Releases [License](LICENSE) Build Status Build status Codacy Badge Try online

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 string name from enum value.
  • enum_names obtains string enum name sequence.
  • enum_entries obtains pair (value enum, string enum name) sequence.
  • is_unscoped_enum checks whether type is an Unscoped enumeration.
  • is_scoped_enum checks whether type is an Scoped enumeration.
  • is_fixed_enum checks whether type is an Fixed enumeration.
  • underlying_type port of C++20 improved UB-free "SFINAE-friendly" std::underlying_type.
  • using namespace magic_enum::ostream_operators; // out-of-the-box ostream operators for enums.
  • using namespace magic_enum::bitwise_operators; // out-of-the-box bitwise operators for enums.

Features

  • C++17
  • Header-only
  • Dependency-free
  • Compile-time
  • Enum to string
  • String to enum
  • Iterating over enum

[Examples](example/example.cpp)

// For example color enum.
enum 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 (colo.has_value()) {
    // color.value() -> Color::RED
    }
    
  • Indexed access to enum value

    int i = 1;
    Color colo = 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"
    
  • Stream 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::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


* Checks whether type is an [Scoped enumeration](https://en.cppreference.com/w/cpp/language/enum#Scoped_enumerations).
  ```cpp
  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 cpp constexpr Color color = Color::BLUE; constexpr auto color_name = magic_enum::enum_name<color>(); // color_name -> "BLUE"

Remarks

  • magic_enum::enum_cast(value) returns std::optional<E>, using has_value() to check contains enum value and value() to get the enum value.

  • magic_enum::enum_value(index) no bounds checking is performed: the behavior is undefined if index >= number of enum values.

  • magic_enum::enum_values<E>() returns std::array<E, N> with all enum value where N = number of enum values, sorted by enum value.

  • magic_enum::enum_name(value) returns std::string_view. If enum value does not have name, returns empty string.

  • magic_enum::enum_name<value>() is much lighter on the compile times and is not restricted to the enum_range limitation.

  • magic_enum::enum_names<E>() returns std::array<std::string_view, N> with all string enum name where N = number of enum values, sorted by enum value.

  • magic_enum::enum_entries<E>() returns std::array<std::pair<E, std::string_view>, N> with all std::pair (value enum, string enum name) where N = number of enum values, sorted by enum value.

  • Enum value must be in range [MAGIC_ENUM_RANGE_MIN, MAGIC_ENUM_RANGE_MAX]. By default MAGIC_ENUM_RANGE_MIN = -128, MAGIC_ENUM_RANGE_MAX = 128.

If need another range for all enum types by default, redefine the macro MAGIC_ENUM_RANGE_MIN and MAGIC_ENUM_RANGE_MAX.

  #define MAGIC_ENUM_RANGE_MIN 0
  #define MAGIC_ENUM_RANGE_MAX 256
  #include <magic_enum.hpp>

If need another range for specific enum type, add specialization enum_range for necessary enum type.

  #include <magic_enum.hpp>

  enum number { one = 100, two = 200, three = 300 };

  namespace magic_enum {
  template <>
  struct enum_range<number> {
    static constexpr int min = 100;
    static constexpr int max = 300;
  };
  }
  • magic_enum obtains the first defined value enums, and won't work if value are aliased.

    enum ShapeKind {
    ConvexBegin = 0,
    Box = 0, // Won't work.
    Sphere = 1,
    ConvexEnd = 2,
    Donut = 2, // Won't work too.
    Banana = 3,
    COUNT = 4,
    };
    // magic_enum::enum_cast<ShapeKind>("Box") -> std::nullopt
    // magic_enum::enum_name(ShapeKind::Box) -> "ConvexBegin"
    

    Work around the issue:

    enum ShapeKind {
    // Convex shapes, see ConvexBegin and ConvexEnd below.
    Box = 0,
    Sphere = 1,
    
    // Non-convex shapes.
    Donut = 2,
    Banana = 3,
    
    COUNT = Banana + 1,
    
    // Non-reflected aliases.
    ConvexBegin = Box,
    ConvexEnd = Sphere + 1,
    };
    // magic_enum::enum_cast<ShapeKind>("Box") -> ShapeKind::Box
    // magic_enum::enum_name(ShapeKind::Box) -> "Box"
    

// Non-reflected aliases. // magic_enum::enum_cast("ConvexBegin") -> std::nullopt // magic_enum::enum_name(ShapeKind::ConvexBegin) -> "Box"


## Integration

You should add the required file [magic_enum.hpp](include/magic_enum.hpp).

## Compiler compatibility

* Clang/LLVM >= 5
* Visual C++ >= 15.3 / Visual Studio >= 2017
* Xcode >= 10.2
* GCC >= 9

## Licensed under the [MIT License](LICENSE)


*Note that all licence references and agreements mentioned in the Magic Enum C++ README section above are relevant to that project's source code only.