| 619 | |
| 620 | template <typename E, auto V> |
| 621 | constexpr bool is_valid() noexcept { |
| 622 | #if defined(__clang__) && __clang_major__ >= 16 |
| 623 | // https://reviews.llvm.org/D130058, https://reviews.llvm.org/D131307 |
| 624 | constexpr E v = __builtin_bit_cast(E, V); |
| 625 | #else |
| 626 | constexpr E v = static_cast<E>(V); |
| 627 | #endif |
| 628 | [[maybe_unused]] constexpr auto custom = customize::enum_name<E>(v); |
| 629 | static_assert(std::is_same_v<std::decay_t<decltype(custom)>, customize::customize_t>, "magic_enum::customize requires customize_t type."); |
| 630 | if constexpr (custom.first == customize::detail::customize_tag::custom_tag) { |
| 631 | constexpr auto name = custom.second; |
| 632 | static_assert(!name.empty(), "magic_enum::customize requires not empty string."); |
| 633 | return name.size() != 0; |
| 634 | } else if constexpr (custom.first == customize::detail::customize_tag::default_tag) { |
| 635 | #if defined(MAGIC_ENUM_VS_2017_WORKAROUND) |
| 636 | return n<E, v>().size_ != 0; |
| 637 | #else |
| 638 | return n<v>().size_ != 0; |
| 639 | #endif |
| 640 | } else { |
| 641 | return false; |
| 642 | } |
| 643 | } |
| 644 | |
| 645 | enum class enum_subtype { |
| 646 | common, |