diff --git a/doc/reference.md b/doc/reference.md index adbf075..742946a 100644 --- a/doc/reference.md +++ b/doc/reference.md @@ -330,16 +330,16 @@ constexpr string_view enum_type_name() noexcept; ```cpp template -[[nodiscard]] constexpr optional enum_fuse(Es... values); +[[nodiscard]] constexpr optional enum_fuse(Es... values); ``` * Returns a typesafe bijective mix of several enum values. This can be used to emulate 2D switch/case statements. -* Return type is `optional` where FusedEnum is an incomplete enum. It is unique for any given combination of `Es...`. +* Return type is `optional` where `enum_fuse_t` is an incomplete enum, it is unique for any given combination of `Es...`. * Switch/case statement over an incomplete enum is a Visual Studio warning C4064 * You have to silent (/wd4064) or ignore it. - * Alternatively, define MAGIC_ENUM_NO_TYPESAFE_ENUM_FUSE to disable type-safety (FusedEnum equals std::uintmax_t). + * Alternatively, define `MAGIC_ENUM_NO_TYPESAFE_ENUM_FUSE` to disable type-safety (`enum_fuse_t` equals `std::uintmax_t`). * Examples diff --git a/include/magic_enum.hpp b/include/magic_enum.hpp index ea5339f..03dc557 100644 --- a/include/magic_enum.hpp +++ b/include/magic_enum.hpp @@ -911,13 +911,13 @@ template > return enum_cast>(value, std::move_if_noexcept(p)).has_value(); } -namespace fusion_detail { +namespace detail { template constexpr optional fuse_one_enum(optional hash, E value) noexcept { if (hash.has_value()) { if (const auto index = enum_index(value); index.has_value()) { - return (hash.value() << detail::log2(enum_count() + 1)) | index.value(); + return (hash.value() << log2(enum_count() + 1)) | index.value(); } } return {}; @@ -935,25 +935,26 @@ constexpr optional fuse_enum(E head, Es... tail) noexcept { template constexpr auto typesafe_fuse_enum(Es... values) noexcept { - enum class Enum : std::uintmax_t; - auto hash = fuse_enum(values...); - if (hash.has_value()) - return optional(static_cast(hash.value())); - return optional{}; + enum class enum_fuse_t : std::uintmax_t; + const auto fuse = fuse_enum(values...); + if (fuse.has_value()) { + return optional{static_cast(fuse.value())}; + } + return optional{}; } -} // namespace magic_enum::fusion_detail +} // namespace magic_enum::detail // Returns a bijective mix of several enum values. This can be used to emulate 2D switch/case statements. template -[[nodiscard]] constexpr auto enum_fuse(Es... values) { - static_assert((std::is_enum_v> && ...), "magic_enum::enum_fuse works only with enums"); - static_assert(sizeof...(Es) >= 2, "magic_enum::enum_fuse requires at least 2 enums"); +[[nodiscard]] constexpr auto enum_fuse(Es... values) noexcept { + static_assert((std::is_enum_v> && ...), "magic_enum::enum_fuse requires enum type."); + static_assert(sizeof...(Es) >= 2, "magic_enum::enum_fuse requires at least 2 values."); static_assert((detail::log2(enum_count() + 1) + ...) <= (sizeof(std::uintmax_t) * 8), "magic_enum::enum_fuse does not work for large enums"); -#ifdef MAGIC_ENUM_NO_TYPESAFE_ENUM_FUSE - const auto fuse = fusion_detail::fuse_enum(values...); +#if defined(MAGIC_ENUM_NO_TYPESAFE_ENUM_FUSE) + const auto fuse = detail::fuse_enum...>(values...); #else - const auto fuse = fusion_detail::typesafe_fuse_enum(values...); + const auto fuse = detail::typesafe_fuse_enum...>(values...); #endif return assert(fuse.has_value()), fuse; }