Neargye / magic_enum

Static reflection for enums (to string, from string, iteration) for modern C++, work with any enum type without any macro or boilerplate code
MIT License
4.88k stars 434 forks source link

enum_flags limitation? #314

Closed Benualdo closed 9 months ago

Benualdo commented 11 months ago

Hi, I did not know about the magic_enum::enum_flags funcs until recently but the limitations are unclear to me.

e.g. I use

#define MAGIC_ENUM_RANGE_MIN 0
#define MAGIC_ENUM_RANGE_MAX 256

and I have this enum

enum class Flags : u64
{
  A = 0x0000000000000001,
  B = 0x0000000000000002,
  C = 0x0000000000000004, 
  D = 0x0000000000000008, 
  E = 0x0000000000000010, 
  F = 0x0000000000000020,
  G = 0x0000000000000040, 
  H = 0x0000000000000080,  
  I = 0x0000000000000100,
  J = 0x0000000000000200,
  K = 0x0000000000000400
};

magic_enum::enum_name returns empty string for anything above 256 as expected but magic_enum::enum_flags_name(1026) works and returns "B|K".

Does the MAGIC_ENUM_RANGE_MAX apply to enum flags and how? Is it the maximum amount of flags avaible? Thanks

Neargye commented 11 months ago

Hi,

MAGIC_ENUM_RANGE_MAX does not affect the maximum amount of flags.

enumflags сhecks all 1<<(1 ... bit_count<Enum>) // bit_count = CHAR_BIT sizeof(Enum) but the limitation is that it doesn't check logical AND and '0' not сhecks

Example

enum class TestEnum {
A = 0,
B = 1,
C = 2,
D = 3,
E = 8192
};

enum_count<TestEnum>() = 4;
// '' - mean enmpty string
enum_name(TestEnum::A) = 'A'; vs enum_flags_name(TestEnum::A) = '';
enum_name(TestEnum::B) = 'B'; vs enum_flags_name(TestEnum::B) = 'B';
enum_name(TestEnum::C) = 'C'; vs enum_flags_name(TestEnum::C) = 'C';
enum_name(TestEnum::D) = 'D'; vs enum_flags_name(TestEnum::D) = 'B|C';
enum_name(TestEnum::E) = '';  vs enum_flags_name(TestEnum::E) = 'E';

enum_flags_cast('A') = nullopt; vs enum_cast('A') = TestEnum::A;
enum_flags_cast('D') = nullopt; vs enum_flags_cast('B|C') = TestEnum::D; vs  enum_cast('D') = TestEnum::D;
Neargye commented 11 months ago

I'll add a documentation update later.

Neargye commented 10 months ago

@Benualdo could you tell me what you think about the restriction that zero is not included in the flags? https://github.com/Neargye/magic_enum/issues/321

Benualdo commented 10 months ago

Hi @Neargye, about the zero not being included in the flags for me that's really not an issue. I mostly use magic_enum to generate UI to edit flags and the none/all cases are handled by my ImGui control anyway so I never put the 0 value in my enum flags. This is also how engines like e.g. Unity deal with C# enum flags so I got used to have MyEnum val = (MyEnum)0 instead of having a MyEnum::None entry in the enum flags.