Skip to content

enum_flags_name: return name for 0, if it exists#376

Open
masbug wants to merge 1 commit into
Neargye:masterfrom
masbug:patch-1
Open

enum_flags_name: return name for 0, if it exists#376
masbug wants to merge 1 commit into
Neargye:masterfrom
masbug:patch-1

Conversation

@masbug

@masbug masbug commented Sep 4, 2024

Copy link
Copy Markdown

Added constexpr that returns name for the value zero, if it exists.

@ZXShady

ZXShady commented Oct 4, 2025

Copy link
Copy Markdown
Contributor

Since this changes behavior it should probably be opt in

@masbug

masbug commented Oct 9, 2025

Copy link
Copy Markdown
Author

I don't think it should be opt in. It fixes a bug. If 0 isn't defined as an enum value then it will still work as before.

// this works same as before
enum E1 {
    A = 1<<0,
    B = 2<<1
}

vs.

// this will now resolve value 0 to "None"
enum E2 {
    None = 0,
    A = 1<<0,
    B = 2<<1
}```

@ZXShady

ZXShady commented Oct 9, 2025

Copy link
Copy Markdown
Contributor

I don't think it should be opt in. It fixes a bug. If 0 isn't defined as an enum value then it will still work as before.

// this works same as before
enum E1 {
    A = 1<<0,
    B = 2<<1
}

vs.

// this will now resolve value 0 to "None"
enum E2 {
    None = 0,
    A = 1<<0,
    B = 2<<1
}```

I understand, but magic_enum::enum_values()[0] isn't 0 either, so this seems inconsistent to only apply it here, how about enum_cast<Bitflag>("None") ?

@masbug

masbug commented Oct 9, 2025

Copy link
Copy Markdown
Author

It already works for both cases.
See this test https://godbolt.org/z/nEKoP6j4n

#include <magic_enum/magic_enum.hpp>
#include <iostream>

enum class E1 : int {
    None = 0,
    Flag1 = 1 << 0,
    Flag2 = 2 << 1
};

int main() {
    static_assert(magic_enum::enum_values<E1>()[0] == E1::None);
    static_assert(magic_enum::enum_cast<E1>("None") == E1::None);

    return 0;
}

@ZXShady

ZXShady commented Oct 9, 2025

Copy link
Copy Markdown
Contributor

@masbug

This is not a bitflag, you must do this

template <>
struct magic_enum::customize::enum_range<E1> {
  static constexpr bool is_flags = true;
};

// now your code fails

otherwise you will be reflecting from [-128,127] instead of N^2

@Neargye

It seems alot of people forget to set this boolean to true themselves, shouls it auto deduce?

@masbug

masbug commented Oct 9, 2025

Copy link
Copy Markdown
Author

@ZXShady
Thanks for pointing that out. I see now what you mean.
I suppose this is the correct behavior for flags, since 0 is a special state.

static_assert(magic_enum::enum_values<E1>()[0] == E1::Flag1);

But this is missing:

static_assert(magic_enum::enum_cast<E1>("None") == E1::None);

@ZXShady

ZXShady commented Oct 10, 2025

Copy link
Copy Markdown
Contributor

There was some discussion about it including the 0 value.

#314

@Neargye

Neargye commented Nov 21, 2025

Copy link
Copy Markdown
Owner

@ZXShady

It seems alot of people forget to set this boolean to true themselves, shouls it auto deduce?

It would be great, but I haven't found a reliable way to detect that these are flags yet.

Personally, I don't think zero should be included by default. I would prefer two separate options: flags and flags_with_zero (or flags_and_zero), though this is open for discussion.

@ZXShady

ZXShady commented Nov 21, 2025

Copy link
Copy Markdown
Contributor

@ZXShady
It would be great, but I haven't found a reliable way to detect that these are flags yet.

I do it myself by checking for & and | operators if they are overloaded.

@Neargye

Neargye commented Nov 22, 2025

Copy link
Copy Markdown
Owner

Could try adding auto detection. Then we definitely need swith using namespace magic_enum::bitwise_operators to enable_bitwise_operators = true 😁

@Neargye Neargye added this to the 0.10.0 milestone Jan 25, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants