| 1194 | // Returns optional with index. |
| 1195 | template <typename E, detail::enum_subtype S = detail::subtype_v<E>> |
| 1196 | [[nodiscard]] constexpr auto enum_index(E value) noexcept -> detail::enable_if_t<E, optional<std::size_t>> { |
| 1197 | using D = std::decay_t<E>; |
| 1198 | using U = underlying_type_t<D>; |
| 1199 | |
| 1200 | if constexpr (detail::count_v<D, S> == 0) { |
| 1201 | static_cast<void>(value); |
| 1202 | return {}; // Empty enum. |
| 1203 | } else if constexpr (detail::is_sparse_v<D, S> || (S == detail::enum_subtype::flags)) { |
| 1204 | #if defined(MAGIC_ENUM_ENABLE_HASH) |
| 1205 | return detail::constexpr_switch<&detail::values_v<D, S>, detail::case_call_t::index>( |
| 1206 | [](std::size_t i) { return optional<std::size_t>{i}; }, |
| 1207 | value, |
| 1208 | detail::default_result_type_lambda<optional<std::size_t>>); |
| 1209 | #else |
| 1210 | for (std::size_t i = 0; i < detail::count_v<D, S>; ++i) { |
| 1211 | if (enum_value<D, S>(i) == value) { |
| 1212 | return i; |
| 1213 | } |
| 1214 | } |
| 1215 | return {}; // Invalid value or out of range. |
| 1216 | #endif |
| 1217 | } else { |
| 1218 | const auto v = static_cast<U>(value); |
| 1219 | if (v >= detail::min_v<D, S> && v <= detail::max_v<D, S>) { |
| 1220 | return static_cast<std::size_t>(v - detail::min_v<D, S>); |
| 1221 | } |
| 1222 | return {}; // Invalid value or out of range. |
| 1223 | } |
| 1224 | } |
| 1225 | |
| 1226 | // Obtains index in enum values from enum value. |
| 1227 | // Returns optional with index. |
no outgoing calls
no test coverage detected