From 40ecd7dfb428546f5091b1a039d1483ba4938905 Mon Sep 17 00:00:00 2001 From: Walter <44253688+svew@users.noreply.github.com> Date: Sun, 21 Jan 2024 02:13:49 -0800 Subject: [PATCH] Tidy up Limitations page (#332) --- doc/limitations.md | 155 ++++++++++++++++++++++++--------------------- 1 file changed, 82 insertions(+), 73 deletions(-) diff --git a/doc/limitations.md b/doc/limitations.md index 965d77a..d99d025 100644 --- a/doc/limitations.md +++ b/doc/limitations.md @@ -1,32 +1,37 @@ # Limitations -* This library uses a compiler-specific hack (based on `__PRETTY_FUNCTION__` / `__FUNCSIG__`). +* This library uses a compiler-specific hack based on `__PRETTY_FUNCTION__` / `__FUNCSIG__`. -* To check is magic_enum supported compiler use macro `MAGIC_ENUM_SUPPORTED` or constexpr constant `magic_enum::is_magic_enum_supported`.
- If magic_enum used on unsupported compiler, occurs the compilation error. To suppress error define macro `MAGIC_ENUM_NO_CHECK_SUPPORT`. +* To check if magic_enum is supported with your compiler, use macro `MAGIC_ENUM_SUPPORTED` or constexpr constant `magic_enum::is_magic_enum_supported`. + If magic_enum is used on an unsupported compiler, a compilation error will occur. + To suppress the error, define macro `MAGIC_ENUM_NO_CHECK_SUPPORT`. -* Enum can't reflect if the enum is a forward declaration. +* magic_enum can't reflect if the enum is a forward declaration. -* For enum-flags add `is_flags` to specialization `enum_range` for necessary enum type. Specialization of `enum_range` must be injected in `namespace magic_enum::customize`. +## Enum Flags + +* For enum flags, add `is_flags` to specialization `enum_range` for necessary enum type. Specializations of `enum_range` must be injected in `namespace magic_enum::customize`. ```cpp - enum class Directions { Up = 1 << 1, Down = 1 << 2, Right = 1 << 3, Left = 1 << 4 }; + enum class Directions { Up = 1 << 0, Down = 1 << 1, Right = 1 << 2, Left = 1 << 3 }; template <> struct magic_enum::customize::enum_range { static constexpr bool is_flags = true; }; ``` - * `MAGIC_ENUM_RANGE_MAX/MAGIC_ENUM_RANGE_MIN` does not affect the maximum amount of flags. +* `MAGIC_ENUM_RANGE_MAX` / `MAGIC_ENUM_RANGE_MIN` does not affect the maximum number of enum flags. - * If enum is declared as flags, then it will not reflect the value of zero and is logically AND. +* If an enum is declared as a flag enum, its zero value will not be reflected. -* Enum value must be in range `[MAGIC_ENUM_RANGE_MIN, MAGIC_ENUM_RANGE_MAX]`. +## Enum Range - * By default `MAGIC_ENUM_RANGE_MIN = -128`, `MAGIC_ENUM_RANGE_MAX = 128`. +* Enum values must be in the range `[MAGIC_ENUM_RANGE_MIN, MAGIC_ENUM_RANGE_MAX]`. - * `MAGIC_ENUM_RANGE = (MAGIC_ENUM_RANGE_MAX - MAGIC_ENUM_RANGE_MIN)` must be less than `UINT16_MAX`. +* By default, `MAGIC_ENUM_RANGE_MIN = -128`, `MAGIC_ENUM_RANGE_MAX = 127`. - * If need another range for all enum types by default, redefine the macro `MAGIC_ENUM_RANGE_MIN` and `MAGIC_ENUM_RANGE_MAX`. +* `MAGIC_ENUM_RANGE = (MAGIC_ENUM_RANGE_MAX - MAGIC_ENUM_RANGE_MIN)` must be less than `UINT16_MAX`. + +* If you need a different 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 @@ -34,75 +39,79 @@ #include ``` - * If need another range for specific enum type, add specialization `enum_range` for necessary enum type. Specialization of `enum_range` must be injected in `namespace magic_enum::customize`. - - ```cpp - #include - - enum class number { one = 100, two = 200, three = 300 }; - - template <> - struct magic_enum::customize::enum_range { - static constexpr int min = 100; - static constexpr int max = 300; - // (max - min) must be less than UINT16_MAX. - }; - ``` - -* `magic_enum` [won't work if a value is aliased](https://github.com/Neargye/magic_enum/issues/68). Work with enum-aliases is compiler-implementation-defined. +* If you need a different range for a specific enum type, add the specialization `enum_range` for the enum type. Specializations of `enum_range` must be injected in `namespace magic_enum::customize`. ```cpp - enum ShapeKind { - ConvexBegin = 0, - Box = 0, // Won't work. - Sphere = 1, - ConvexEnd = 2, - Donut = 2, // Won't work too. - Banana = 3, - COUNT = 4 + #include + + enum class number { one = 100, two = 200, three = 300 }; + + template <> + struct magic_enum::customize::enum_range { + static constexpr int min = 100; + static constexpr int max = 300; + // (max - min) must be less than UINT16_MAX. }; - // magic_enum::enum_cast("Box") -> nullopt - // magic_enum::enum_name(ShapeKind::Box) -> "ConvexBegin" ``` - One of the possible workaround the issue: +## Aliasing - ```cpp - enum ShapeKind { - // Convex shapes, see ConvexBegin and ConvexEnd below. - Box = 0, - Sphere = 1, +magic_enum [won't work if a value is aliased](https://github.com/Neargye/magic_enum/issues/68). How magic_enum works with aliases is compiler-implementation-defined. - // Non-convex shapes. - Donut = 2, - Banana = 3, +```cpp +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("Box") -> nullopt +// magic_enum::enum_name(ShapeKind::Box) -> "ConvexBegin" +``` - COUNT = Banana + 1, +One possible workaround for the issue is to define the enum values you want reflected before their aliases: - // Non-reflected aliases. - ConvexBegin = Box, - ConvexEnd = Sphere + 1 - }; - // magic_enum::enum_cast("Box") -> ShapeKind::Box - // magic_enum::enum_name(ShapeKind::Box) -> "Box" +```cpp +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. - // magic_enum::enum_cast("ConvexBegin") -> nullopt - // magic_enum::enum_name(ShapeKind::ConvexBegin) -> "Box" - ``` + ConvexBegin = Box, + ConvexEnd = Sphere + 1 +}; +// magic_enum::enum_cast("Box") -> ShapeKind::Box +// magic_enum::enum_name(ShapeKind::Box) -> "Box" - On some compiler enum-aliases not supported, [for example Visual Studio 2017](https://github.com/Neargye/magic_enum/issues/36), macro `MAGIC_ENUM_SUPPORTED_ALIASES` will be undefined. +// Non-reflected aliases. +// magic_enum::enum_cast("ConvexBegin") -> nullopt +// magic_enum::enum_name(ShapeKind::ConvexBegin) -> "Box" +``` - ```cpp - enum Number { - one = 1, - ONE = 1 - }; - // magic_enum::enum_cast("one") -> nullopt - // magic_enum::enum_name(Number::one) -> "" - // magic_enum::enum_cast("ONE") -> nullopt - // magic_enum::enum_name(Number::ONE) -> "" - ``` +On some compilers, enum aliases are not supported, [for example Visual Studio 2017](https://github.com/Neargye/magic_enum/issues/36), macro `MAGIC_ENUM_SUPPORTED_ALIASES` will be undefined. + +```cpp +enum Number { + one = 1, + ONE = 1 +}; +// magic_enum::enum_cast("one") -> nullopt +// magic_enum::enum_name(Number::one) -> "" +// magic_enum::enum_cast("ONE") -> nullopt +// magic_enum::enum_name(Number::ONE) -> "" +``` + +## Other Compiler Issues * If you hit a message like this: @@ -112,11 +121,11 @@ ``` 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` + * MSVC: `/constexpr:depthN`, `/constexpr:stepsN` + * Clang: `-fconstexpr-depth=N`, `-fconstexpr-steps=N` + * GCC: `-fconstexpr-depth=N`, `-fconstexpr-loop-limit=N`, `-fconstexpr-ops-limit=N` -* Intellisense Visual Studio may have some problems analyzing `magic_enum`. +* Visual Studio's Intellisense may have some problems analyzing magic_enum. -* Enums in template may work incorrectly (especially on Сlang) +* Enums in templates may not work correctly (especially on Сlang). See [#164](https://github.com/Neargye/magic_enum/issues/164), [#65](https://github.com/Neargye/magic_enum/issues/65)