neargye / magic_enum Goto Github PK
View Code? Open in Web Editor NEWStatic reflection for enums (to string, from string, iteration) for modern C++, work with any enum type without any macro or boilerplate code
License: MIT License
Static reflection for enums (to string, from string, iteration) for modern C++, work with any enum type without any macro or boilerplate code
License: MIT License
enum class Color1
{
red = 0xab,
blue = 0xcd
};
enum class Color2
{
red = 0x12,
blue = 0x34
};
int main()
{
magic_enum::enum_name(Color1::red); // compile error!
magic_enum::enum_name(Color2::red); // okay
}
This code should be invalid and shouldn't compile but it does, and even optimizes to have 0 be returned implying the string ":dog" is equal to the enum horse.
Why are we allowed to compare a enum foo
vs an optional<enum foo>
with boolean operations.
I have an enum like this:
enum QUEUE_ENTRY_TYPE : unsigned int {
QUEUE_ENTRY_UNKNOWN,
TRN_GET_PROCESS_LIST = 100,
TRN_GET_TOP_WINDOWS,
TRN_GET_PROCESS_WINDOWS = 200,
TRN_GET_CHILD_WINDOWS,
TRN_GET_POPUP_WINDOWS = 300,
TRN_GET_WINDOW_INFO,...
But when I try to get the name with the code below it does not work:
QUEUE_ENTRY_TYPE qet = TRN_GET_CHILD_WINDOWS;
auto qet_name = magic_enum::enum_name(qet);
It only works for values below 128.
In the index() function on line 349 it decides the value is bigger than max_v.
What can I do?
It would be nice to have a convenient way to check if the bitmask value contains enum flag, for example:
enum class AnimalFlags : std::uint64_t { None = 0, HasClaws = 1 << 0, CanFly = 1 << 1, EatsFish = 1 << 2, Endangered = 1 << 3 };
using namespace magic_enum::bitwise_operators;
AnimalFlags animal_mask = AnimalFlags::HasClaws | AnimalFlags::CanFly;
if (animal_mask & AnimalFlags::CanFly) // compiler error here
std::cout << "This animal can fly!";
This won't compile because there's no auomatic enum class
casting to bool
or uint64_t
, so it won't compile without proper casting or comparison against 0
enum value of the bitwise expression result:
if (static_cast<uint64_t>(animal_mask & AnimalFlags::CanFly))
std::cout << "This animal can fly!";
or
if ((animal_mask & AnimalFlags::CanFly) != AnimalFlags::None)
std::cout << "This animal can fly!";
Would it be possible to support this use-case out of the box and provide more convenient way to check that bitmask contains particular flag? Maybe add a helper function magic_enum::empty(mask)
, for example:
if (!magic_enum::empty(animal_mask & AnimalFlags::CanFly))
std::cout << "This animal can fly!";
0.6.6 and master.
The latest clang, libstdc++ 10.2 (from fedora 32).
Code:
#include <magic_enum.hpp>
enum class BuildState
{
NotStarted,
};
void f()
{
auto state = BuildState::NotStarted;
magic_enum::enum_name(state);
}
Error:
[sw.client.core-0.4.2]/src/sw/core/build.cpp
In file included from D:/dev/cppan2/client2/src/sw/core/build.cpp:1:
d:/temp/9/magic_enum/include\magic_enum.hpp:409:81: fatal error: instantiating fold expression with 257 arguments exceeded expression nesting limit of 256
constexpr std::size_t count = ((valid[I] ? std::size_t{1} : std::size_t{0}) + ...);
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~
d:/temp/9/magic_enum/include\magic_enum.hpp:428:10: note: in instantiation of function template specialization 'magic_enum::detail::values<BuildState, false, -128, 0, 1, 2, 3, 4, 5, 6,
7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52,
53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97,
98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133,
134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169,
170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205,
206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241,
242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256>' requested here
return values<E, IsFlags, reflected_min_v<E, IsFlags>>(std::make_index_sequence<range_size>{});
^
d:/temp/9/magic_enum/include\magic_enum.hpp:432:34: note: in instantiation of function template specialization 'magic_enum::detail::values<BuildState, false, int>' requested here
inline constexpr auto values_v = values<E, IsFlags>();
^
d:/temp/9/magic_enum/include\magic_enum.hpp:438:33: note: in instantiation of variable template specialization 'magic_enum::detail::values_v' requested here
inline constexpr auto count_v = values_v<E, IsFlags>.size();
^
d:/temp/9/magic_enum/include\magic_enum.hpp:559:17: note: in instantiation of variable template specialization 'magic_enum::detail::count_v' requested here
static_assert(count_v<D, false> > 0, "magic_enum requires enum implementation and valid max and min.");
^
d:/temp/9/magic_enum/include\magic_enum.hpp:571:1: note: in instantiation of template class 'magic_enum::detail::enable_if_enum<true, false, BuildState, std::basic_string_view<char,
std::char_traits<char>>>' requested here
using enable_if_enum_t = typename enable_if_enum<std::is_enum_v<std::decay_t<T>>, false, T, R>::type;
^
d:/temp/9/magic_enum/include\magic_enum.hpp:682:69: note: in instantiation of template type alias 'enable_if_enum_t' requested here
[[nodiscard]] constexpr auto enum_name(E value) noexcept -> detail::enable_if_enum_t<E, string_view> {
^
D:/dev/cppan2/client2/src/sw/core/build.cpp:9:5: note: while substituting deduced template arguments into function template 'enum_name' [with E = BuildState]
magic_enum::enum_name(state);
^
d:/temp/9/magic_enum/include\magic_enum.hpp:409:81: note: use -fbracket-depth=N to increase maximum nesting level
constexpr std::size_t count = ((valid[I] ? std::size_t{1} : std::size_t{0}) + ...);
^
1 error generated.
Error code: 1
Adding -fbracket-depth=260
helps.
From the limitations, I see that aliases don't work, this would be fine, but I seem to be getting an odd case where the first-use of a value, is NOT the one used, furthermore, I'm getting 0x0
for a string, instead of the alias. (Either in my case would be fine, but not an empty string)
THEN, debugging in vs17, when I look at the strings
table (which I guess is all the names baked into an array) my values START at 128 instead of 0
this is the enum https://github.com/SoylentGraham/SoyLib/blob/master/src/SoyPixels.h#L22
I've been using this library for a while now without problems, even with this enum, so perhaps I've just missed this case, or in this particular code I'm using it in a strange way... (still investigating :)
I'm building a cross platform program. I'm using Visual Studio to build, and VS still uses Android NDK 16b with Clang 5 to build native libs for Android. I get the following errors:
As an alternative to wandbox
https://godbolt.org/z/lX6L-B
to get the hash for the include link just go to the file and press the y key
Hi,
Is there anything preventing the various std::string&std::string_view functions to be overloaded with their wstring&wstring_view equivalent?
This library is a very welcome and useful addition ! Thanks!
Jean
Also I'm not sure why this is not mentioned anywhere in the documentation, seems kind of important, no?
Hi,
I just tried to compile a library that used your magic_enum library with the current MinGW 64 version 8.1.0. The compilation failed because magic_enum does not propwerly support current MinGW 64 compiler. The version 8.1.0 is the latest official release and also the version that ships with Qt. So this is the version that can be considered stable.
Would be great, if it would be possible to use magic_enum with a current MinGW compiler.
Apart from that magic_enum is a great library and it is great that you made it available on GitHub.
In order to limit memory required to access enum values, a convenience function to get the smallest datatype able to represent all valid indexes for an enum from uint8_t, uint16_t, uint32_t, and uint64_t would be nice.
SO has a relevant page: https://stackoverflow.com/questions/7038797/automatically-pick-a-variable-type-big-enough-to-hold-a-specified-number
C++ number standards: https://en.cppreference.com/w/cpp/types/integer
I could do this one, but figure I should ask before I submit a PR out of nowhere.
See #16
Hi there. I am trying to compile for PS4, using Clang 8.0.1:
-- The CXX compiler identification is Clang 8.0.1
-- The C compiler identification is Clang 8.0.1
However, I run into these errors:
[...]\magic_enum.hpp(458,23): error : constexpr variable 'values_v<ColorType, false>' must be initialized by a constant expression
[...]\magic_enum.hpp(467,23): error : constexpr variable 'min_v<ColorType, false, std::underlying_type<ColorType>::type>' must be initialized by a constant expression
[...]\magic_enum.hpp(470,23): error : constexpr variable 'max_v<ColorType, false, std::underlying_type<ColorType>::type>' must be initialized by a constant expression
[...]\magic_enum.hpp(475,18): error : constexpr variable 'max' must be initialized by a constant expression
[...]\magic_enum.hpp(476,18): error : constexpr variable 'min' must be initialized by a constant expression
[...]\magic_enum.hpp(477,18): error : constexpr variable 'range_size' must be initialized by a constant expression
[...]\magic_enum.hpp(478,17): error : static_assert expression is not an integral constant expression
Any help with this would be appreciated. Thank you!
There's a problem with (even the current trunk version) of clang with this code:
#include <https://raw.githubusercontent.com/Neargye/magic_enum/master/include/magic_enum.hpp>
template <typename T = int>
struct test {
enum class Color { RED, BLUE, GREEN};
};
template <typename type>
static constexpr bool are_values_sequential = []() constexpr noexcept -> bool {
const auto vals = magic_enum::enum_values<type>();
for (std::size_t i = 0; i < vals.size(); ++i)
if (magic_enum::enum_integer(vals[i]) != i)
return false;
return true;
}();
static_assert(are_values_sequential<test<int>::Color>);
https://raw.githubusercontent.com/Neargye/magic_enum/master/include/magic_enum.hpp:653:3: error: static_assert failed due to requirement 'detail::count_v<test<int>::Color, false> > 0' "magic_enum requires enum implementation and valid max and min."
The above code works in GCC though.
The problem seems to appear when the enum is inside a templated class.
Hello,
I am currently using C++17 with LLVM clang version 9.0.1.1 in a VxWorks environment and when I attempt to compile example/example.cpp I am prompted with (along with many other constexpr variables):
magic_enum.hpp:281:23: Error: constexpr variable 'values_v<Color>' must be initialized by a constant expression.
inline constexpr auto values_v = values<E>(std::make_integer_sequence<int, range_size<E, reflected_min_v<E>, reflected_max_v<E>>()>{});
I have the latest version of Magic_Enum and to my understanding, it's supposed to work with clang >=5.
Thank you very much for your work, please let me know if I can provide more info.
I need constexpr check that will tell me if for given enum, magic_enum will work:
template <typename EnumT>
(...)
EnumT v = ....;
(...)
if constexpr (magic_enum::is_magic_enum_supported && magic_enum::is_supported_enum_v<EnumT>) {
return format_to(ctx.out(), "{}", magic_enum::enum_name(v));
} else {
return format_to(ctx.out(), "{}", (int) v);
}
Specifically EnumT
in above code may have values outside scope of MAGIC_ENUM_RANGE_MIN, MAGIC_ENUM_RANGE_MAX
Hello,
I wanted to write a piece of code that checks that all the values in an enum are unique.
Looking at the limitations of magic_enum
, I read that "magic_enum
won't work if a value is aliased". Well, that's what I want to do: detect if at least one value is aliased in my enum.
During my tests, I wrote the following code:
enum class Color {
RED = 8, BLUE = 4, GREEN = 8
};
int main() {
#ifdef MAGIC_ENUM_SUPPORTED_ALIASES
std::cout << "supported " << MAGIC_ENUM_SUPPORTED_ALIASES << '\n';
#else
std::cout << "NOT supported" << '\n';
#endif
auto colors = magic_enum::enum_values<Color>();
for (auto& color:colors) {
using namespace magic_enum::ostream_operators;
std::cout << color << '\n';
}
return colors.size();
}
It prints:
supported 1
BLUE
RED
The problem is visible with Compiler Explorer using gcc 10.2: https://godbolt.org/z/4TTerr
The aliased value GREEN doesn't appears in the list returned by enum_values<Color>()
.
This seems to be a bug because MAGIC_ENUM_SUPPORTED_ALIASES is defined to be 1.
Am I missing something?
Currently when my enum is to big for magic_enum and I use enum_name
, empty string is returned.
It would be better if magic_enum detected it and threw exception instead.
It would be best if it instead refused to compile.
https://godbolt.org/z/TTMx1v
#include <iostream>
#include "https://raw.githubusercontent.com/Neargye/magic_enum/master/include/magic_enum.hpp"
enum class Color1 {
RED = 0, BLUE = 4, GREEN = 800 // beyond standard range
};
enum class Color2 {
RED = 0, BLUE = 4, GREEN = 800000 // beyond max range
};
int main() {
std::cout <<"[" << magic_enum::enum_name(Color1::GREEN) <<"]" << std::endl;
std::cout <<"[" << magic_enum::enum_name(Color2::GREEN) <<"]" << std::endl;
return 0;
}
Prints
[]
[]
Should fail to compile or throw
Hello,
We have been trying to use magic_enum::enum_count. It works well with Visual Studio 2017 but does not compile with gcc 9.2.1. Here is the code:
enum class MyEnum : std::size_t
{
Value0,
Value1,
Value2
};
constexpr std::size_t countEnum = magic_enum::enum_count<MyEnum>();
And with gcc 9.2.1 we have the following issue:
MagicEnum.h:442:26: error: static assertion failed: magic_enum::enum_range requires enum implementation and valid max and min.
static_assert( count > 0, "magic_enum::enum_range requires enum implementation and valid max and min." );
We have the latest version of MagicEnum as of today. We have looked at the limitations, we don't seem to be in one of those situations. Did we miss anything? It looks like it is supposed to work from gcc 9 and upward.
Thank you so much for your work and very nice contribution. Magic enum seems pretty cool.
Cheers,
Olivier
Hello,
I'd like to use magic_enum on macOS but unfortunately I have to keep backward compatibility to an older 10.9 release.
That makes things like std::optional
unavailable:
PacketParser.cpp:381:33: error: 'value' is unavailable: introduced in macOS 10.14
reasonBits).value();
I could see three ways of working around:
enum_foo_or_throw()
methods which completely avoid using std::optional
and throw instead.optional
implementation (like better enums does).boost::optional
instead of std::optional
Thanks,
Gregor
It would be great to use this lib using cmake and conan
According to the README, magic_enum is supported by clang >= 5 and MSVS 2017, but the check to set MAGIC_ENUM_SUPPORTED only checks the version number for gcc:
#if defined(__clang__) || defined(__GNUC__) && __GNUC__ >= 9 || defined(_MSC_VER)
# undef MAGIC_ENUM_SUPPORTED
# define MAGIC_ENUM_SUPPORTED 1
#endif
Shouldn't this be
#if defined(__clang__) && __clang_major__ >= 5 || defined(__GNUC__) && __GNUC__ >= 9 || defined(_MSC_VER) && _MSC_VER >= 1910
# undef MAGIC_ENUM_SUPPORTED
# define MAGIC_ENUM_SUPPORTED 1
#endif
EDIT: Thinking a bit harder, it might be better that this functionality be moved to a new method, perhaps called enum_name_of_bits_set
or something and leave enum_name alone...
Hi, I have no clue about github or pull requests, so I thought I'd write my proposed enhancement to enum_name here...
If an enum contains bitfield values, there exists already the ability to bitwise AND and OR the values together to create flag fields. But there is no way to print such a flag.
Example :
using namespace magic_enum;
using namespace magic_enum::bitwise_operators;
enum Rooms { None = 0, Bedroom = 1 << 0, Lounge = 1 << 1, Kitchen = 1 << 2 };
Rooms toPaint = Rooms::Bedroom | Rooms::Kitchen;
std::cout << "My wife want me to paint these : " << enum_name<Rooms>(toPaint) << '\n';
Desired output :
My wife want me to paint these : Bedroom|Kitchen
Actual output :
My wife want me to paint these :
Here is a replacement
// Returns string enum name from enum value.
// If enum value does not have name or value out of range, returns empty string.
template <typename E>
[[nodiscard]] constexpr auto enum_name(E value) noexcept
-> detail::enable_if_enum_t<E, std::string_view>
{
// Begin Changes ga2k 2020-05-29
// return enum_traits<E>::name(value);
auto n = enum_traits<E>::name(value);
if (!n.empty())
return n;
// See if there is a name for each bit set in value.
// If so, concatenate them with '|' separator
// First find largest value
constexpr auto values = enum_values<E>();
constexpr auto largest = values[values.size() - 1];
static std::string s;
for (int b = 0; (1 << b) <= largest; ++b)
{
if ((value & (1 << b)) == (1 << b)) // This bit is set in value
{
auto n2 = enum_traits<E>::name(static_cast<E>(1 << b));
if (n2.empty())
return n2; // No name at this bt value : not a bitfield value, so bail
if (!s.empty())
{
s += '|';
}
s += n2;
}
}
return static_cast<std::string_view>(s);
// End Additions ga2k 2020-05-29
}
Thoughts?
vcpkg search magic_enum yields nothing with latest vcpkg. The readme says it should be in vcpkg. What's going on?
Following up #47.
I'm not really happy with the current syntax for defining custom enum names, specially because you need to deal with functions defined in the namespace detail
which does not seem right. Furthermore, a function named n
is not a very intuitive name for people using the library.
Threrefore, I have 2 suggestions on how to improve it:
template <auto V> std::string_view magic_enum::custom_name()
to the API:template <auto V>
constexpr std::string_view magic_enum::custom_name() noexcept { return ""; }
...
// a small change in `n()`
template <typename E, E V>
std::string_view magic_enum::n() {
if constexpr (auto s = custom_name<V>(); !s.empty())
return s;
else {
... // current `n()` implementation
}
}
...
// example of usage
template <>
constexpr std::string_view magic_enum::custom_name<Color::red> noexcept { return "the red color"; }
Pros:
typename E
.magic_enum
, not in magic_enum::detail
custom_name
instead of n
.Cons:
if constexpr
in n()
is a bit ugly...#define MAGIC_ENUM_CUSTOM_NAME(VALUE, TEXT) \
template <> constexpr auto magic_enum::detail::n<decltype(VALUE), VALUE>() noexcept { return std::string_view{TEXT}; }
...
// example of usage
MAGIC_ENUM_CUSTOM_NAME(Color::red, "the red color")
Pros:
Cons:
class
/namespace
.Let me know what you think.
With imminent versions of centos, Ubuntu etc still on GCC 8.x stream, consider a workaround for the issues preventing GCC 8 support.
The patches to GCC 8 compiler to fix the issues aren't really possible to use either for a lot of organisations or individuals.
Ctrl+clicking on anything in my project stalls waiting for intellisense to complete if I include magic_enum 0.6.1 or newer. Version 0.6.0 doesn't have this problem.
Edit: Only happens on 32bit projects.
Tested in Visual Studio 2019 and Visual Studio 2017.
/ E2719 integer constant must be greater than or equal to zero
on this line ...
inline constexpr auto type_name_v = n();
any ideas what these errors could be? it compiles and works ... just not sure why intellisense is unhappy
Imagine a scenario like the below test. Because magic_enum returns a string_view
, it is not compatible with C-style APIs.
Can we do anything to support legacy C-style code? The below code will result in a read buffer overflow as it'll keep reading past the end of the string until it hits a null terminator.
TEST("Read buffer overflow bug")
{
enum class TestEnum
{
MODE_1,
MODE_2
};
TestEnum test = TestEnum::MODE_2;
auto name = magic_enum::enum_name(test);
printf("%s", name.data());
}
For a runtime value to string conversion it generates a list of strings and a string_view map. In theory data usage could be reduced to 1/4 by using an index plus a small size squeezed into a uint32_t instead of string_view if the strings could be forced into a contiguous array.
Hi,
magic_enum/include/magic_enum/magic_enum.hpp:411:71: fatal error: instantiating fold expression with 257 arguments exceeded expression nesting limit of 256
constexpr std::size_t count = (static_caststd::size_t(valid[I]) + ...);
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~
How could I fix this compile error?
Hi, thanks for doing a great job with this library.
magic_enum
works amazingly well in most of the cases, but sometimes, the string conversion must be different from the enum value identifier.
For example, I would like to be able to convert the enum value Red
to "the red color"
instead of "Red"
and also convert "the red color"
back to Red
. That's not possible in the current version of magic_enum
as far as I know.
Better Enums has an alternative for this, which is depicted in the example https://github.com/aantron/better-enums/blob/master/example/5-map.cc
Would it be possible to add a feature that allows custom definitions of names for enum values?
It would be useful to optionally pass a comparison predicate to use for the equality comparison in enum_cast(std::string_view value)
. In my case, I'd like to perform case-insensitive comparisons.
magic_enum::enum_names
seems only works in function.
enum class Color : int { RED = -10, BLUE = 0, GREEN = 10 };
constexpr auto color_names0 = magic_enum::enum_names<Color>();
int main()
{
constexpr auto color_names = magic_enum::enum_names<Color>();
std::cout << color_names0[0] << "\n"; // this give out some random string
std::cout << color_names[0] << "\n"; // this is fine.
}
I use the following skill to add the dereference operator (like in std::optional for example):
template< typename T >
struct Dereferencable;`
template< typename T, typename Parameter, template< typename > class ... Skills >
struct Dereferencable< fluent::NamedType< T, Parameter, Skills... > > : fluent::crtp< fluent::NamedType< T, Parameter, Skills... >, Dereferencable >
{
constexpr const T& operator*() const &
{
return this->underlying().get();
}
constexpr T& operator*() &
{
return this->underlying().get();
}
constexpr T && operator*() &&
{
return std::move( this->underlying().get() );
}
constexpr const T && operator*() const&&
{
return std::move( this->underlying().get() );
}
};
Example usage:
void Fct( double value );
...
Fct( *strongType );
I recently tried the library via vcpkg on MSVC. I had a problem that the following property is specified in magic_enumConfig.cmake
INTERFACE_COMPILE_FEATURES "cxx_std_17"
This is a problem as our code builds uses what MSVC calls "std::c++latest" which is newer than 17. Im not sure what should happen but it appears that the magic enum value overrides ours so we get downgraded to 17 which means a bunch of our code no longer compiles.
In the nameof library you mention in issue Neargye/nameof#12 that "I set c++17 for hand, because old cmake can't set c++17 for msvc++." I don't know if if makes sense for a package to require a specific version. If my projects use say c++ 11 and I try to include magic_enum.hpp I get a very clear error message from the compiler telling me I need to use c++ 17. I did look around vcpkg but couldn't find any documentation on best practice for settting c++ language standard.
I think what is really wanted is to require a minimum version but allow newer ones like latest or 20. I don't know how to do that in CMake/VCPKG.
For now we commented out the explicit setting of C++ 17 and things work great.
The recipe given in the integration section of the README file to download the library using conan is not accurate:
"If you are using Conan to manage your dependencies, merely add magic_enum/x.y.z@neargye/stable to your conan's requires, where x.y.z is the release version you want to use."
The package is not available in conan-center, so nothing is found juste by following the previous steps.
To make it work, I had to add @Neargye's personal repository (found in this closed issue #3).
It would be great if the package is pushed to conan-center to make it easily accessible.
Hi there,
I had a close look at this lib and love it so far. However, I have two following questions/issues.
How to use the full potential of 16 bit?
It seems that the real Max Range Limit is 2^10 - 1. As soon you set #define MAGIC_ENUM_RANGE_MAX 1024 Following error message is shown:
I also tried useing enum Direction (Line 51) from https://github.com/Neargye/magic_enum/blob/master/test/test_flags.cpp and use enum_cast or enum_name with no success. I receive following error:
C2975 '_Test': invalid template argument for 'std::conditional_t', expected compile-time constant expression
I also used code exactly like it is on Line 374-376.
Why not using 32 bit?
Beside from the above issue, I tired to replace all (u)int16_t with (u)int32_t and everything looks fine so far, as long the max range is not set at 1024 or above. Is there a specific reason not to do this?
PS: I’m mainly using enum_name or enum_cast.
Thank you so much for your work.
The using
keyword in a header can create conflicts in other headers when magic_enum is imported :
/usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/optional:656:11: note: candidate found by name lookup is 'std::optional'
1406
class optional
1407
^
1408
../magic_enum/include/magic_enum.hpp:99:1: note: candidate found by name lookup is 'magic_enum::optional'
1409
using optional = std::optional<T>;
It would be preferable to use a typedef
or a macro to define an other type that would be used elsewhere in the code.
If you agree I can make a PR.
Hi I recently switched my project from using gcc
to clang
, and ran into this error:
_deps/magic_enum_content-src/include/magic_enum.hpp:116:18: error: constexpr variable 'prefix' must be initialized by a constant expression
constexpr auto prefix = name.find_last_of(" :,-)") + 1;
^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Clang version:
clang version 8.0.0 (Fedora 8.0.0-1.fc30)
Target: x86_64-unknown-linux-gnu
Gcc version:
g++ (GCC) 9.1.1 20190503 (Red Hat 9.1.1-1)
Flag list:
-Wall
-Wextra
-Werror
-Wnon-virtual-dtor
-Wold-style-cast
-Woverloaded-virtual
-Wsign-conversion
-Wconversion
-Wnull-dereference
-Wformat=2
-Wdouble-promotion
-fasynchronous-unwind-tables
-fstack-protector
-fstack-protector-strong
-fPIC
-pipe
-fsanitize=address
-fsanitize=undefined
-g
-fdiagnostics-color=always
-fno-omit-frame-pointer
Thank you for your work in this library, please let me know if I can provide more info.
It would be nice to read an overview of the technique used here. I tried reading through it but got a lost around n()
If a enum is forward declaration, enum_values() cannot get valid values.
enum class MyEnum;
for (auto enum_value : magic_enum::enum_values<MyEnum>()) {
// some print statement
}
Is there any solution?
Is there a way to get the name of an enum type? E.g.:
enum class e_color { red, blue };
using my_enum = e_color;
constexpr std::string_view name = magic_enum::enum_type_name<my_enum>();
then name
would be "e_color".
Is there a way to do O(1) conversion of Color::BLUE to 1 (rather than 4, as enum_integer
would do)?
Motivation: I have an enum generated by an external tool which may have gaps in it, and I need to pack the enums into a contiguous sequence of integers starting at 0 (so that I can more efficiently store it in memory somewhere else). I don't need this packing to be stable across invocations of the program, but it should be stable within the program.
Now we have
std::optional<E> enum_cast(std::string_view value) noexcept
std::optional<E> enum_cast(std::underlying_type_t<E> value) noexcept
Is it necessary to add the following functions? Will it be useful to someone?
std::optional<E> enum_from_string_nothrow(std::string_view value) noexcept
std::optional<E> enum_from_string_nocase_nothrow(std::string_view value) noexcept
E enum_from_string(std::string_view value)
E enum_from_string_nocase(std::string_view value)
std::optional<E> enum_from_integral_nothrow(std::underlying_type_t<E> value) noexcept
E enum_from_integral(std::underlying_type_t<E> value)
E enum_from_integral_unchecked(std::underlying_type_t<E> value)
Hi, the newest version hasn't been sent to vcpkg yet. That caused me a heart attack! Namespace customize doesn't exist in the old version.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.