diff --git a/include/lookup/lookup.hpp b/include/lookup/lookup.hpp index c5527490..80e99134 100644 --- a/include/lookup/lookup.hpp +++ b/include/lookup/lookup.hpp @@ -10,6 +10,6 @@ namespace lookup { [[nodiscard]] CONSTEVAL static auto make(compile_time auto input) { return strategies, - pseudo_pext_lookup>::make(input); + pseudo_pext_lookup>::make(input); } } // namespace lookup diff --git a/include/lookup/pseudo_pext_lookup.hpp b/include/lookup/pseudo_pext_lookup.hpp index fce28b46..c0453277 100644 --- a/include/lookup/pseudo_pext_lookup.hpp +++ b/include/lookup/pseudo_pext_lookup.hpp @@ -122,7 +122,7 @@ constexpr auto count_duplicates(std::array keys) -> std::size_t { return dups; } -/// count the length of the longest run of identical values (n log n) +/// count the length of the longest run of identical values (n) template constexpr auto count_longest_run(std::array keys) -> std::size_t { std::sort(keys.begin(), keys.end()); @@ -138,8 +138,11 @@ constexpr auto count_longest_run(std::array keys) -> std::size_t { if (curr_value == prev_value) { current_run++; - } else { - longest_run = std::max(longest_run, current_run); + } + + longest_run = std::max(longest_run, current_run); + + if (curr_value != prev_value) { current_run = 0; } @@ -241,7 +244,7 @@ constexpr auto calc_pseudo_pext_mask(std::array, S> const &pairs, while (max_search_len > 1 && std::popcount(mask) > 4) { auto try_mask = remove_cheapest_bit(mask, keys); auto current_longest_run = count_longest_run(with_mask(try_mask, keys)); - if (current_longest_run < max_search_len) { + if (current_longest_run <= max_search_len) { mask = try_mask; prev_longest_run = current_longest_run; } else { @@ -249,7 +252,7 @@ constexpr auto calc_pseudo_pext_mask(std::array, S> const &pairs, } } - return std::make_tuple(mask, std::size_t{}); + return std::make_tuple(mask, prev_longest_run); } } // namespace detail diff --git a/test/lookup/pseudo_pext_lookup.cpp b/test/lookup/pseudo_pext_lookup.cpp index 637aee17..5c210c52 100644 --- a/test/lookup/pseudo_pext_lookup.cpp +++ b/test/lookup/pseudo_pext_lookup.cpp @@ -98,3 +98,39 @@ TEMPLATE_TEST_CASE("lookup with scoped enum entries", "[pseudo pext lookup]", CHECK(lookup[some_key_t::KAPPA] == 87); CHECK(lookup[some_key_t::GAMMA] == 4); } + +TEST_CASE("pbt regression 0", "[pseudo pext lookup]") { + constexpr auto lookup = lookup::pseudo_pext_lookup::make( + CX_VALUE(lookup::input{ + 0, std::array, 5>{ + lookup::entry{1, 0}, + lookup::entry{3, 0}, + lookup::entry{11, 0}, + lookup::entry{16, 0}, + lookup::entry{0, 1}}})); + + CHECK(lookup[1] == 0); + CHECK(lookup[3] == 0); + CHECK(lookup[11] == 0); + CHECK(lookup[16] == 0); + CHECK(lookup[0] == 1); +} + +TEST_CASE("pbt regression 1", "[pseudo pext lookup]") { + constexpr auto lookup = lookup::pseudo_pext_lookup::make( + CX_VALUE(lookup::input{ + 0, std::array, 6>{ + lookup::entry{1, 0}, + lookup::entry{3, 0}, + lookup::entry{4, 0}, + lookup::entry{15, 0}, + lookup::entry{30, 0}, + lookup::entry{31, 1}}})); + + CHECK(lookup[1] == 0); + CHECK(lookup[3] == 0); + CHECK(lookup[4] == 0); + CHECK(lookup[15] == 0); + CHECK(lookup[30] == 0); + CHECK(lookup[31] == 1); +}