| 894 | |
| 895 | template <typename E, enum_subtype S, typename U = std::underlying_type_t<E>> |
| 896 | constexpr bool is_sparse() noexcept { |
| 897 | if constexpr (count_v<E, S> == 0) { |
| 898 | return false; |
| 899 | } else if constexpr (std::is_same_v<U, bool>) { // bool special case |
| 900 | return false; |
| 901 | } else { |
| 902 | constexpr auto max = (S == enum_subtype::flags) ? log2(max_v<E, S>) : max_v<E, S>; |
| 903 | constexpr auto min = (S == enum_subtype::flags) ? log2(min_v<E, S>) : min_v<E, S>; |
| 904 | constexpr auto range_size = max - min + 1; |
| 905 | |
| 906 | return range_size != count_v<E, S>; |
| 907 | } |
| 908 | } |
| 909 | |
| 910 | template <typename E, enum_subtype S = subtype_v<E>> |
| 911 | inline constexpr bool is_sparse_v = is_sparse<E, S>(); |