diff --git a/README.md b/README.md index cc68b28..650b47c 100644 --- a/README.md +++ b/README.md @@ -62,6 +62,7 @@ enum Color { RED = 2, BLUE = 4, GREEN = 8 }; ``` * Enum value to string + ```cpp Color color = Color::RED; auto color_name = magic_enum::enum_name(color); @@ -69,6 +70,7 @@ enum Color { RED = 2, BLUE = 4, GREEN = 8 }; ``` * String to enum value + ```cpp std::string color_name{"GREEN"}; auto color = magic_enum::enum_cast(color_name); @@ -78,6 +80,7 @@ enum Color { RED = 2, BLUE = 4, GREEN = 8 }; ``` * Integer to enum value + ```cpp int color_integer = 2; auto color = magic_enum::enum_cast(color_integer); @@ -87,6 +90,7 @@ enum Color { RED = 2, BLUE = 4, GREEN = 8 }; ``` * Indexed access to enum value + ```cpp int i = 1; Color color = magic_enum::enum_value(i); @@ -94,6 +98,7 @@ enum Color { RED = 2, BLUE = 4, GREEN = 8 }; ``` * Enum value sequence + ```cpp constexpr auto colors = magic_enum::enum_values(); // colors -> {Color::RED, Color::BLUE, Color::GREEN} @@ -101,12 +106,14 @@ enum Color { RED = 2, BLUE = 4, GREEN = 8 }; ``` * Number of enum elements + ```cpp constexpr std::size_t color_count = magic_enum::enum_count(); // color_count -> 3 ``` * Enum value to integer + ```cpp Color color = Color::RED; auto color_integer = magic_enum::enum_integer(color); @@ -114,6 +121,7 @@ enum Color { RED = 2, BLUE = 4, GREEN = 8 }; ``` * Enum names sequence + ```cpp constexpr auto color_names = magic_enum::enum_names(); // color_names -> {"RED", "BLUE", "GREEN"} @@ -121,6 +129,7 @@ enum Color { RED = 2, BLUE = 4, GREEN = 8 }; ``` * Enum entries sequence + ```cpp constexpr auto color_entries = magic_enum::enum_entries(); // color_entries -> {{Color::RED, "RED"}, {Color::BLUE, "BLUE"}, {Color::GREEN, "GREEN"}} @@ -129,6 +138,7 @@ enum Color { RED = 2, BLUE = 4, GREEN = 8 }; ``` * Ostream operator for enum + ```cpp using namespace magic_enum::ostream_operators; // out-of-the-box ostream operators for enums. Color color = Color::BLUE; @@ -136,6 +146,7 @@ enum Color { RED = 2, BLUE = 4, GREEN = 8 }; ``` * Bitwise operator for enum + ```cpp 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. @@ -144,6 +155,7 @@ enum Color { RED = 2, BLUE = 4, GREEN = 8 }; ``` * Checks whether type is an [Unscoped enumeration](https://en.cppreference.com/w/cpp/language/enum#Unscoped_enumeration). + ```cpp enum color { red, green, blue }; enum class direction { left, right }; @@ -157,6 +169,7 @@ enum Color { RED = 2, BLUE = 4, GREEN = 8 }; ``` * 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 }; @@ -171,12 +184,19 @@ enum Color { RED = 2, BLUE = 4, GREEN = 8 }; * Static storage enum variable to string This version is much lighter on the compile times and is not restricted to the enum_range [limitation](doc/limitations.md). + ```cpp constexpr Color color = Color::BLUE; constexpr auto color_name = magic_enum::enum_name(); // 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](limitations.md) of functionality. + ## Integration You should add the required file [magic_enum.hpp](include/magic_enum.hpp). diff --git a/doc/limitations.md b/doc/limitations.md index cbd8b73..15db543 100644 --- a/doc/limitations.md +++ b/doc/limitations.md @@ -8,29 +8,48 @@ * 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`. - ```cpp - #define MAGIC_ENUM_RANGE_MIN 0 - #define MAGIC_ENUM_RANGE_MAX 256 - #include + * `MAGIC_ENUM_RANGE_MAX` must be greater than `0` and must be less than `INT16_MAX`. + + * `MAGIC_ENUM_RANGE_MIN` must be less or equals than `0` and must be greater than `INT16_MIN`. + + * If need another range for all enum types by default, redefine the macro `MAGIC_ENUM_RANGE_MIN` and `MAGIC_ENUM_RANGE_MAX`. + + ```cpp + #define MAGIC_ENUM_RANGE_MIN 0 + #define MAGIC_ENUM_RANGE_MAX 256 + #include + ``` + + If need another range for specific enum type, add specialization `enum_range` for necessary enum type. + + ```cpp + #include + + enum number { one = 100, two = 200, three = 300 }; + + namespace magic_enum { + template <> + struct enum_range { + static constexpr int min = 100; // Must be greater than `INT16_MIN`. + static constexpr int max = 300; // Must be less than `INT16_MAX`. + }; + } + ``` + +* If you hit a message like this: + + ```text + [...] + note: constexpr evaluation hit maximum step limit; possible infinite loop? ``` - If need another range for specific enum type, add specialization `enum_range` for necessary enum type. - ```cpp - #include - - enum number { one = 100, two = 200, three = 300 }; - - namespace magic_enum { - template <> - struct enum_range { - static constexpr int min = 100; - static constexpr int max = 300; - }; - } - ``` + Change the limit for the number of constexpr evaluated: + * MSVC `/constexpr:depthN`, `/constexpr:stepsN` + * Clang `-fconstexpr-depth=N`, `-fconstexpr-steps=N` + * GCC `-fconstexpr-depth=n`, `-fconstexpr-loop-limit=n`, `-fconstexpr-ops-limit=n` * `magic_enum` obtains the first defined value enums, and won't work if value are aliased. + ```cpp enum ShapeKind { ConvexBegin = 0, @@ -44,7 +63,9 @@ // magic_enum::enum_cast("Box") -> std::nullopt // magic_enum::enum_name(ShapeKind::Box) -> "ConvexBegin" ``` + Work around the issue: + ```cpp enum ShapeKind { // Convex shapes, see ConvexBegin and ConvexEnd below. diff --git a/doc/reference.md b/doc/reference.md index 566028f..8a2b20d 100644 --- a/doc/reference.md +++ b/doc/reference.md @@ -15,7 +15,7 @@ * [`ostream_operators` ostream operators for enums.](#ostream_operators) * [`bitwise_operators` bitwise operators for enums.](#bitwise_operators) -# Synopsis +## Synopsis * Before use, read the [limitations](limitations.md) of functionality. @@ -23,6 +23,7 @@ If magic_enum used on unsupported compiler, occurs the compilation error. To suppress error define macro `MAGIC_ENUM_NO_CHECK_SUPPORT`. ## `enum_cast` + ```cpp template constexpr optional enum_cast(string_view value) noexcept; @@ -38,7 +39,9 @@ constexpr optional enum_cast(underlying_type_t value) noexcept; * If argument does not enum value, returns empty `std::optional`. * Examples - * String to enum value. + + * String to enum value. + ```cpp std::string color_name{"GREEN"}; auto color = magic_enum::enum_cast(color_name); @@ -46,7 +49,9 @@ constexpr optional enum_cast(underlying_type_t value) noexcept; // color.value() -> Color::GREEN } ``` - * Integer to enum value. + + * Integer to enum value. + ```cpp int color_integer = 2; auto color = magic_enum::enum_cast(color_integer); @@ -56,6 +61,7 @@ constexpr optional enum_cast(underlying_type_t value) noexcept; ``` ## `enum_value` + ```cpp template constexpr E enum_value(size_t index) noexcept; @@ -66,6 +72,7 @@ constexpr E enum_value(size_t index) noexcept; * No bounds checking is performed: the behavior is undefined if `index >= number of enum values`. * Examples + ```cpp int i = 1; Color color = magic_enum::enum_value(i); @@ -73,6 +80,7 @@ constexpr E enum_value(size_t index) noexcept; ```` ## `enum_values` + ```cpp template constexpr array enum_values() noexcept; @@ -81,6 +89,7 @@ constexpr array enum_values() noexcept; * Returns `std::array` with all enum value where `N = number of enum values`, sorted by enum value. * Examples + ```cpp constexpr auto colors = magic_enum::enum_values(); // colors -> {Color::RED, Color::BLUE, Color::GREEN} @@ -88,6 +97,7 @@ constexpr array enum_values() noexcept; ``` ## `enum_count` + ```cpp template constexpr size_t enum_count() noexcept; @@ -96,12 +106,14 @@ constexpr size_t enum_count() noexcept; * Returns number of enum values. * Examples + ```cpp constexpr std::size_t color_count = magic_enum::enum_count(); // color_count -> 3 ``` ## `enum_integer` + ```cpp template constexpr underlying_type_t enum_integer(E value) noexcept; @@ -110,6 +122,7 @@ constexpr underlying_type_t enum_integer(E value) noexcept; * Returns integer value from enum value. * Examples + ```cpp Color color = Color::RED; auto color_integer = magic_enum::enum_integer(color); @@ -117,6 +130,7 @@ constexpr underlying_type_t enum_integer(E value) noexcept; ``` ## `enum_name` + ```cpp template constexpr string_view enum_name(E value) noexcept; @@ -128,14 +142,18 @@ constexpr string_view enum_name() noexcept; * Returns `std::string_view`. If enum value does not have name, returns empty string. * Examples - * Enum value to string. + + * Enum value to string. + ```cpp Color color = Color::RED; auto color_name = magic_enum::enum_name(color); // color_name -> "RED" ``` - * Static storage enum variable to string. + + * Static storage enum variable to string. This version is much lighter on the compile times and is not restricted to the enum_range [limitation](doc/limitations.md). + ```cpp constexpr Color color = Color::BLUE; constexpr auto color_name = magic_enum::enum_name(); @@ -144,8 +162,8 @@ constexpr string_view enum_name() noexcept; * `magic_enum::enum_name()` is much lighter on the compile times and is not restricted to the enum_range [limitation](limitation.md). - ## `enum_names` + ```cpp template constexpr array enum_names() noexcept; @@ -154,6 +172,7 @@ constexpr array enum_names() noexcept; * Returns `std::array` with all string enum name where `N = number of enum values`, sorted by enum value. * Examples + ```cpp constexpr auto color_names = magic_enum::enum_names(); // color_names -> {"RED", "BLUE", "GREEN"} @@ -161,6 +180,7 @@ constexpr array enum_names() noexcept; ``` ## `enum_entries` + ```cpp template constexpr array, N> enum_entries() noexcept; @@ -169,6 +189,7 @@ constexpr array, N> enum_entries() noexcept; * Returns `std::array, N>` with all `std::pair` (value enum, string enum name) where `N = number of enum values`, sorted by enum value. * Examples + ```cpp constexpr auto color_entries = magic_enum::enum_entries(); // color_entries -> {{Color::RED, "RED"}, {Color::BLUE, "BLUE"}, {Color::GREEN, "GREEN"}} @@ -177,6 +198,7 @@ constexpr array, N> enum_entries() noexcept; ``` ## `is_unscoped_enum` + ```cpp template struct is_unscoped_enum; @@ -190,6 +212,7 @@ inline constexpr bool is_unscoped_enum_v = is_unscoped_enum::value; * Provides the member constant value which is equal to true, if T is an [Unscoped enumeration](https://en.cppreference.com/w/cpp/language/enum#Unscoped_enumeration) type. Otherwise, value is equal to false. * Examples + ```cpp magic_enum::is_unscoped_enum::value -> true magic_enum::is_unscoped_enum::value -> false @@ -199,6 +222,7 @@ inline constexpr bool is_unscoped_enum_v = is_unscoped_enum::value; ``` ## `is_scoped_enum` + ```cpp template struct is_scoped_enum; @@ -212,6 +236,7 @@ inline constexpr bool is_scoped_enum_v = is_scoped_enum::value; * Provides the member constant value which is equal to true, if T is an [Scoped enumeration](https://en.cppreference.com/w/cpp/language/enum#Scoped_enumerations) type. Otherwise, value is equal to false. * Examples + ```cpp magic_enum::is_scoped_enum::value -> false magic_enum::is_scoped_enum::value -> true @@ -235,6 +260,7 @@ using underlying_type_t = typename underlying_type::type; * If T is a complete enumeration type, provides a member typedef type that names the underlying type of T. Otherwise, if T is not an enumeration type, there is no member type. Otherwise (T is an incomplete enumeration type), the program is ill-formed. * Examples + ```cpp magic_enum::underlying_type::type -> int @@ -243,6 +269,7 @@ using underlying_type_t = typename underlying_type::type; ``` ## `ostream_operators` + ```cpp template basic_ostream& operator<<(basic_ostream& os, E value); @@ -251,9 +278,11 @@ template basic_ostream& operator<<(basic_ostream& os, optional value); ``` + * Out-of-the-box ostream operators for all enums. * Examples + ```cpp using namespace magic_enum::ostream_operators; // out-of-the-box ostream operators for enums. Color color = Color::BLUE; @@ -261,6 +290,7 @@ basic_ostream& operator<<(basic_ostream& os, optiona ``` ## `bitwise_operators` + ```cpp template constexpr E operator~(E rhs) noexcept; @@ -287,6 +317,7 @@ constexpr E& operator^=(E& lhs, E rhs) noexcept; * Out-of-the-box bitwise operators for all enums. * Examples + ```cpp 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.