Skip to content

Commit d325b7b

Browse files
committed
optimize enum valid storage
1 parent 003cb5a commit d325b7b

1 file changed

Lines changed: 22 additions & 14 deletions

File tree

include/magic_enum/magic_enum.hpp

Lines changed: 22 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -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+
769779
template <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-
793796
template <typename E, enum_subtype S, std::size_t Size, int Min>
794797
constexpr 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

Comments
 (0)