1
0
Fork 0
mirror of https://github.com/Neargye/magic_enum.git synced 2026-01-09 23:34:23 +00:00

remove throw from enum_fuse

This commit is contained in:
neargye 2022-02-16 19:01:14 +02:00
parent 9bfb90760a
commit 756b139368
2 changed files with 12 additions and 14 deletions

View file

@ -912,8 +912,7 @@ namespace fusion_detail {
template <typename E>
constexpr std::size_t fuse_one_enum(std::size_t hash, E value) noexcept {
// Add 1 to prevent matching 2D fusions with 3D fusions etc.
std::size_t index = enum_index(value).has_value() ? (enum_index(value).value() + 1) : 0;
return (hash << detail::log2(enum_count<E>() + 1)) | index;
return (hash << detail::log2(enum_count<E>() + 1)) | (enum_index(value).value() + 1);
}
template <typename E>
@ -930,16 +929,15 @@ constexpr std::size_t fuse_enum(E head, Es... tail) noexcept {
// Returns a bijective mix of several enum values. This can be used to emulate 2D switch/case statements.
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>{
[[nodiscard]] constexpr auto enum_fuse(Es... values) -> std::enable_if_t<(std::is_enum_v<std::decay_t<Es>> && ...), std::optional<std::size_t>> {
static_assert(sizeof...(Es) >= 2, "magic_enum::enum_fuse requires at least 2 enums");
static_assert((detail::log2(enum_count<Es>() + 1) + ...) <= (sizeof(std::size_t) * 8), "magic_enum::enum_fuse does not work for large enums");
const bool has_values = (enum_index(values).has_value() && ...);
#if defined(__cpp_lib_is_constant_evaluated) && (defined(__cpp_exceptions) || defined(__EXCEPTIONS) || (defined(_HAS_EXCEPTIONS) && _HAS_EXCEPTIONS))
if (std::is_constant_evaluated() && !has_values) {
throw std::logic_error{"magic_enum::enum_fuse accepts only in-range enum values"};
if (has_values) {
return fusion_detail::fuse_enum(values...);
} else {
return assert(has_values), std::nullopt;
}
#endif
return assert(has_values), (has_values ? fusion_detail::fuse_enum(values...) : 0);
}
namespace ostream_operators {

View file

@ -1015,10 +1015,10 @@ TEST_CASE("constexpr_for") {
}
static int switch_case_2d(Color color, Directions direction) {
switch (magic_enum::enum_fuse(color, direction)) {
case magic_enum::enum_fuse(Color::RED, Directions::Up):
switch (magic_enum::enum_fuse(color, direction).value()) {
case magic_enum::enum_fuse(Color::RED, Directions::Up).value():
return 1;
case magic_enum::enum_fuse(Color::BLUE, Directions::Down):
case magic_enum::enum_fuse(Color::BLUE, Directions::Down).value():
return 2;
default:
return 0;
@ -1028,11 +1028,11 @@ static int switch_case_2d(Color color, Directions direction) {
enum class Index { zero = 0, one = 1, two = 2 };
static int switch_case_3d(Color color, Directions direction, Index index) {
switch (magic_enum::enum_fuse(color, direction, index)) {
case magic_enum::enum_fuse(Color::RED, Directions::Up, Index::zero):
switch (magic_enum::enum_fuse(color, direction, index).value()) {
case magic_enum::enum_fuse(Color::RED, Directions::Up, Index::zero).value():
return 1;
// model accidental removal of last index, must not match anything
case magic_enum::enum_fuse(Color::BLUE, Directions::Up):
case magic_enum::enum_fuse(Color::BLUE, Directions::Up).value():
return 2;
default:
return 0;