| 849 | |
| 850 | template <typename E, enum_subtype S, typename U = std::underlying_type_t<E>> |
| 851 | constexpr bool is_sparse() noexcept { |
| 852 | if constexpr (count_v<E, S> == 0) { |
| 853 | return false; |
| 854 | } else if constexpr (std::is_same_v<U, bool>) { // bool special case |
| 855 | return false; |
| 856 | } else { |
| 857 | constexpr auto max = (S == enum_subtype::flags) ? log2(max_v<E, S>) : max_v<E, S>; |
| 858 | constexpr auto min = (S == enum_subtype::flags) ? log2(min_v<E, S>) : min_v<E, S>; |
| 859 | constexpr auto range_size = max - min + 1; |
| 860 | |
| 861 | return range_size != count_v<E, S>; |
| 862 | } |
| 863 | } |
| 864 | |
| 865 | template <typename E, enum_subtype S = subtype_v<E>> |
| 866 | inline constexpr bool is_sparse_v = is_sparse<E, S>(); |