@@ -766,34 +766,37 @@ constexpr int reflected_max() noexcept {
766766 T (192 )T(193 )T(194 )T(195 )T(196 )T(197 )T(198 )T(199 )T(200 )T(201 )T(202 )T(203 )T(204 )T(205 )T(206 )T(207 )T(208 )T(209 )T(210 )T(211 )T(212 )T(213 )T(214 )T(215 )T(216 )T(217 )T(218 )T(219 )T(220 )T(221 )T(222 )T(223 ) \
767767 T (224 )T(225 )T(226 )T(227 )T(228 )T(229 )T(230 )T(231 )T(232 )T(233 )T(234 )T(235 )T(236 )T(237 )T(238 )T(239 )T(240 )T(241 )T(242 )T(243 )T(244 )T(245 )T(246 )T(247 )T(248 )T(249 )T(250 )T(251 )T(252 )T(253 )T(254 )T(255 )
768768
769+ template <std::size_t N>
770+ struct valid_count_t {
771+ std::uint16_t count = 0 ;
772+ std::uint16_t offsets[N] = {};
773+
774+ constexpr void set (std::size_t i) noexcept {
775+ offsets[count++] = static_cast <std::uint16_t >(i);
776+ }
777+ };
778+
769779template <typename E, enum_subtype S, std::size_t Size, int Min, std::size_t I>
770- constexpr void valid_count (bool * valid, std:: size_t & count ) noexcept {
780+ constexpr void valid_count (valid_count_t <Size>& vc ) noexcept {
771781#define MAGIC_ENUM_V (O ) \
772782 if constexpr ((I + O) < Size) { \
773783 if constexpr (is_valid<E, ualue<E, Min, S>(I + O)>()) { \
774- valid[I + O] = true ; \
775- ++count; \
784+ vc.set (I + O); \
776785 } \
777786 }
778787
779788 MAGIC_ENUM_FOR_EACH_256 (MAGIC_ENUM_V )
780789
781790 if constexpr ((I + 256 ) < Size) {
782- valid_count<E, S, Size, Min, I + 256 >(valid, count );
791+ valid_count<E, S, Size, Min, I + 256 >(vc );
783792 }
784793#undef MAGIC_ENUM_V
785794}
786795
787- template <std::size_t N>
788- struct valid_count_t {
789- std::size_t count = 0 ;
790- bool valid[N] = {};
791- };
792-
793796template <typename E, enum_subtype S, std::size_t Size, int Min>
794797constexpr auto valid_count () noexcept {
795798 valid_count_t <Size> vc;
796- valid_count<E, S, Size, Min, 0 >(vc. valid , vc. count );
799+ valid_count<E, S, Size, Min, 0 >(vc);
797800 return vc;
798801}
799802
@@ -807,9 +810,13 @@ constexpr auto values() noexcept {
807810#else
808811 E values[vc.count ] = {};
809812#endif
810- for (std::size_t i = 0 , v = 0 ; v < vc.count ; ++i) {
811- if (vc.valid [i]) {
812- values[v++] = value<E, Min, S>(i);
813+ if constexpr (vc.count == Size) {
814+ for (std::size_t i = 0 ; i < vc.count ; ++i) {
815+ values[i] = value<E, Min, S>(i);
816+ }
817+ } else {
818+ for (std::size_t i = 0 ; i < vc.count ; ++i) {
819+ values[i] = value<E, Min, S>(vc.offsets [i]);
813820 }
814821 }
815822#if defined(MAGIC_ENUM_ARRAY_CONSTEXPR)
@@ -828,6 +835,7 @@ constexpr auto values() noexcept {
828835 constexpr auto max = reflected_max<E, S>();
829836 constexpr auto range_size = max - min + 1 ;
830837 static_assert (range_size > 0 , " magic_enum::enum_range requires valid size." );
838+ static_assert (range_size <= (std::numeric_limits<std::uint16_t >::max)(), " magic_enum::enum_range requires valid size." );
831839
832840 return values<E, S, range_size, min>();
833841}
0 commit comments