mirror of
https://github.com/Neargye/magic_enum.git
synced 2026-01-10 23:44:29 +00:00
clean-up
This commit is contained in:
parent
1f8e29b140
commit
63ff515163
4 changed files with 43 additions and 41 deletions
|
|
@ -141,9 +141,9 @@ enum class Color { RED = 2, BLUE = 4, GREEN = 8 };
|
||||||
* Enum fusion for multi-level switch/case statements
|
* Enum fusion for multi-level switch/case statements
|
||||||
|
|
||||||
```cpp
|
```cpp
|
||||||
switch (magic_enum::enum_fuse(color1, color2)) {
|
switch (magic_enum::enum_fuse(color, direction)) {
|
||||||
case magic_enum::enum_fuse(RED, BLUE): // ...
|
case magic_enum::enum_fuse(Color::RED, Directions::Up): // ...
|
||||||
case magic_enum::enum_fuse(RED, RED): // ...
|
case magic_enum::enum_fuse(Color::BLUE, Directions::Down): // ...
|
||||||
// ...
|
// ...
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
|
||||||
|
|
@ -329,8 +329,8 @@ constexpr string_view enum_type_name() noexcept;
|
||||||
## `enum_fuse`
|
## `enum_fuse`
|
||||||
|
|
||||||
```cpp
|
```cpp
|
||||||
template<typename ... Es>
|
template <typename... Es>
|
||||||
[[nodiscard]] constexpr size_t enum_fuse(Es ... values);
|
[[nodiscard]] constexpr std::size_t enum_fuse(Es... values);
|
||||||
```
|
```
|
||||||
|
|
||||||
* Returns a bijective mix of several enum values with [Cantor pairing function](https://en.wikipedia.org/wiki/Pairing_function). This can be used to emulate 2D switch/case statements.
|
* Returns a bijective mix of several enum values with [Cantor pairing function](https://en.wikipedia.org/wiki/Pairing_function). This can be used to emulate 2D switch/case statements.
|
||||||
|
|
@ -338,9 +338,9 @@ template<typename ... Es>
|
||||||
* Examples
|
* Examples
|
||||||
|
|
||||||
```cpp
|
```cpp
|
||||||
switch (magic_enum::enum_fuse(color1, color2)) {
|
switch (magic_enum::enum_fuse(color, direction)) {
|
||||||
case magic_enum::enum_fuse(RED, BLUE): // ...
|
case magic_enum::enum_fuse(Color::RED, Directions::Up): // ...
|
||||||
case magic_enum::enum_fuse(RED, RED): // ...
|
case magic_enum::enum_fuse(Color::BLUE, Directions::Down): // ...
|
||||||
// ...
|
// ...
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
|
||||||
|
|
@ -324,6 +324,15 @@ constexpr I log2(I value) noexcept {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
constexpr std::size_t cantor_pair(size_t v1, size_t v2) noexcept {
|
||||||
|
return (((v1 + v2) * (v1 + v2 + 1)) >> 1) + v2;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename... Ts>
|
||||||
|
constexpr std::size_t cantor_pair(std::size_t v1, std::size_t head, Ts... tail) noexcept {
|
||||||
|
return cantor_pair(cantor_pair(v1, head), tail...);
|
||||||
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
inline constexpr bool is_enum_v = std::is_enum_v<T> && std::is_same_v<T, std::decay_t<T>>;
|
inline constexpr bool is_enum_v = std::is_enum_v<T> && std::is_same_v<T, std::decay_t<T>>;
|
||||||
|
|
||||||
|
|
@ -609,15 +618,6 @@ struct underlying_type {};
|
||||||
template <typename T>
|
template <typename T>
|
||||||
struct underlying_type<T, true> : std::underlying_type<std::decay_t<T>> {};
|
struct underlying_type<T, true> : std::underlying_type<std::decay_t<T>> {};
|
||||||
|
|
||||||
constexpr size_t cantor_pair(size_t v1, size_t v2) noexcept {
|
|
||||||
return (((v1 + v2) * (v1 + v2 + 1)) >> 1) + v2;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename ... Ts>
|
|
||||||
constexpr size_t cantor_pair(size_t v1, size_t head, Ts ... tail) noexcept {
|
|
||||||
return cantor_pair(cantor_pair(v1, head), tail...);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace magic_enum::detail
|
} // namespace magic_enum::detail
|
||||||
|
|
||||||
// Checks is magic_enum supported compiler.
|
// Checks is magic_enum supported compiler.
|
||||||
|
|
@ -887,11 +887,17 @@ template <typename E>
|
||||||
return {}; // Invalid value or out of range.
|
return {}; // Invalid value or out of range.
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename ... Es>
|
// Returns a bijective mix of several enum values with [Cantor pairing function](https://en.wikipedia.org/wiki/Pairing_function). This can be used to emulate 2D switch/case statements.
|
||||||
[[nodiscard]] constexpr size_t enum_fuse(Es ... enums) {
|
template <typename... Es>
|
||||||
|
[[nodiscard]] constexpr auto enum_fuse(Es... values) -> std::enable_if_t<(std::is_enum_v<std::decay_t<Es>> && ...), std::size_t>{
|
||||||
static_assert(sizeof...(Es) >= 2, "magic_enum::enum_fuse requires at least 2 enums");
|
static_assert(sizeof...(Es) >= 2, "magic_enum::enum_fuse requires at least 2 enums");
|
||||||
|
#ifdef __cpp_lib_is_constant_evaluated
|
||||||
|
if (std::is_constant_evaluated() && !(enum_index(values).has_value() && ...)) {
|
||||||
|
throw std::logic_error("magic_enum::enum_fuse accepts only in-range enum values");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
// Add 1 to prevent matching 2D fusions with 3D fusions etc.
|
// Add 1 to prevent matching 2D fusions with 3D fusions etc.
|
||||||
return detail::cantor_pair((enum_index(enums).value() + 1)...);
|
return assert((enum_index(values).has_value() && ...)), detail::cantor_pair((enum_index(values).value() + 1)...);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Checks whether enum contains enumerator with such enum value.
|
// Checks whether enum contains enumerator with such enum value.
|
||||||
|
|
|
||||||
|
|
@ -1014,32 +1014,28 @@ TEST_CASE("constexpr_for") {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
static int switch_case_2d(Color color, Directions number)
|
static int switch_case_2d(Color color, Directions direction) {
|
||||||
{
|
switch (magic_enum::enum_fuse(color, direction)) {
|
||||||
switch (magic_enum::enum_fuse(color, number))
|
case magic_enum::enum_fuse(Color::RED, Directions::Up):
|
||||||
{
|
return 1;
|
||||||
case magic_enum::enum_fuse(Color::RED, Directions::Up):
|
case magic_enum::enum_fuse(Color::BLUE, Directions::Down):
|
||||||
return 1;
|
return 2;
|
||||||
case magic_enum::enum_fuse(Color::BLUE, Directions::Down):
|
default:
|
||||||
return 2;
|
return 0;
|
||||||
default:
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
enum class Index { zero = 0, one = 1, two = 2 };
|
enum class Index { zero = 0, one = 1, two = 2 };
|
||||||
|
|
||||||
static int switch_case_3d(Color color, Directions number, Index index)
|
static int switch_case_3d(Color color, Directions direction, Index index) {
|
||||||
{
|
switch (magic_enum::enum_fuse(color, direction, index)) {
|
||||||
switch (magic_enum::enum_fuse(color, number, index))
|
case magic_enum::enum_fuse(Color::RED, Directions::Up, Index::zero):
|
||||||
{
|
return 1;
|
||||||
case magic_enum::enum_fuse(Color::RED, Directions::Up, Index::zero):
|
// model accidental removal of last index, must not match anything
|
||||||
return 1;
|
case magic_enum::enum_fuse(Color::BLUE, Directions::Up):
|
||||||
// model accidental removal of last index, must not match anything
|
return 2;
|
||||||
case magic_enum::enum_fuse(Color::BLUE, Directions::Up):
|
default:
|
||||||
return 2;
|
return 0;
|
||||||
default:
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue