diff --git a/include/magic_enum.hpp b/include/magic_enum.hpp index 877c438..2e36ce7 100644 --- a/include/magic_enum.hpp +++ b/include/magic_enum.hpp @@ -859,26 +859,34 @@ template // Returns string name from enum-flags value. // If enum-flags value does not have name or value out of range, returns empty string. -template -[[nodiscard]] auto enum_name(E value) -> detail::enable_if_enum_flags_t { +template +[[nodiscard]] auto enum_name(E value) -> detail::enable_if_enum_flags_t> { using D = std::decay_t; using U = underlying_type_t; - std::string name; - auto check_value = U{0}; - for (std::size_t i = 0; i < detail::count_v; ++i) { - if (const auto v = enum_value(i); (static_cast(value) & static_cast(v)) != 0) { - check_value |= static_cast(v); - const auto n = detail::names_v[i]; - if (!name.empty()) { - name.append(1, '|'); + if constexpr (Strict) { + for (std::size_t i = 0; i < detail::count_v; ++i) { + if (enum_value(i) == value) { + return detail::names_v[i]; + } + } + } else { + std::string name; + auto check_value = U{0}; + for (std::size_t i = 0; i < detail::count_v; ++i) { + if (const auto v = enum_value(i); (static_cast(value) & static_cast(v)) != 0) { + check_value |= static_cast(v); + const auto n = detail::names_v[i]; + if (!name.empty()) { + name.append(1, '|'); + } + name.append(n.data(), n.size()); } - name.append(n.data(), n.size()); } - } - if (check_value == static_cast(value)) { - return name; + if (check_value == static_cast(value)) { + return name; + } } return {}; // Invalid value or out of range. @@ -901,35 +909,47 @@ template } // Checks whether enum-flags contains enumerator with such integer value. -template +template [[nodiscard]] constexpr auto enum_contains(underlying_type_t value) noexcept -> detail::enable_if_enum_flags_t { using D = std::decay_t; - if constexpr (detail::is_sparse_v) { - using U = underlying_type_t; - auto check_value = U{0}; - for (std::size_t i = 0; i < detail::count_v; ++i) { - if (const auto v = static_cast(enum_value(i)); (static_cast(value) & v) != 0) { - check_value |= v; + if constexpr(Strict) { + if constexpr (detail::is_sparse_v) { + for (std::size_t i = 0; i < detail::count_v; ++i) { + if (value == enum_value(i)) { + return true; + } } + + return false; } - - return check_value == value; } else { - constexpr auto min = detail::min_v; - constexpr auto max = detail::value_ors(); + if constexpr (detail::is_sparse_v) { + using U = underlying_type_t; + auto check_value = U{0}; + for (std::size_t i = 0; i < detail::count_v; ++i) { + if (const auto v = static_cast(enum_value(i)); (static_cast(value) & v) != 0) { + check_value |= v; + } + } - return value >= min && value <= max; + return check_value == value; + } else { + constexpr auto min = detail::min_v; + constexpr auto max = detail::value_ors(); + + return value >= min && value <= max; + } } } // Checks whether enum-flags contains enumerator with such enum-flags value. -template +template [[nodiscard]] constexpr auto enum_contains(E value) noexcept -> detail::enable_if_enum_flags_t { using D = std::decay_t; using U = underlying_type_t; - return enum_contains(static_cast(value)); + return enum_contains(static_cast(value)); } // Checks whether enum-flags contains enumerator with such string name. @@ -942,7 +962,6 @@ template return {}; } - // Checks whether enum-flags contains enumerator with such string name. template [[nodiscard]] constexpr auto enum_contains(std::string_view value) noexcept -> detail::enable_if_enum_flags_t { @@ -953,11 +972,11 @@ template // Obtains enum-flags value from integer value. // Returns std::optional with enum-flags value. -template +template [[nodiscard]] constexpr auto enum_cast(underlying_type_t value) noexcept -> detail::enable_if_enum_flags_t>> { using D = std::decay_t; - if (enum_contains(value)) { + if (enum_contains(value)) { return static_cast(value); }