| 1266 | // Returns optional with index. |
| 1267 | template <typename E, detail::enum_subtype S = detail::subtype_v<E>> |
| 1268 | [[nodiscard]] constexpr auto enum_index(E value) noexcept -> detail::enable_if_t<E, optional<std::size_t>> { |
| 1269 | using D = std::decay_t<E>; |
| 1270 | using U = underlying_type_t<D>; |
| 1271 | static_assert(detail::is_reflected_v<D, S>, "magic_enum requires enum implementation and valid max and min."); |
| 1272 | |
| 1273 | if constexpr (detail::is_sparse_v<D, S> || (S == detail::enum_subtype::flags)) { |
| 1274 | #if defined(MAGIC_ENUM_ENABLE_HASH) |
| 1275 | return detail::constexpr_switch<&detail::values_v<D, S>, detail::case_call_t::index>( |
| 1276 | [](std::size_t i) { return optional<std::size_t>{i}; }, |
| 1277 | value, |
| 1278 | detail::default_result_type_lambda<optional<std::size_t>>); |
| 1279 | #else |
| 1280 | for (std::size_t i = 0; i < detail::count_v<D, S>; ++i) { |
| 1281 | if (enum_value<D, S>(i) == value) { |
| 1282 | return i; |
| 1283 | } |
| 1284 | } |
| 1285 | return {}; // Invalid value or out of range. |
| 1286 | #endif |
| 1287 | } else { |
| 1288 | const auto v = static_cast<U>(value); |
| 1289 | if (v >= detail::min_v<D, S> && v <= detail::max_v<D, S>) { |
| 1290 | return static_cast<std::size_t>(v - detail::min_v<D, S>); |
| 1291 | } |
| 1292 | return {}; // Invalid value or out of range. |
| 1293 | } |
| 1294 | } |
| 1295 | |
| 1296 | // Returns index in enum values from enum value. |
| 1297 | // Returns optional with index. |
no outgoing calls
no test coverage detected