xo-arena: bugfix: backwards iteration working now

This commit is contained in:
Roland Conybeare 2026-01-08 18:20:27 -05:00
commit ba6a75e686
3 changed files with 84 additions and 1 deletions

View file

@ -379,6 +379,19 @@ namespace xo {
return *this;
}
DArenaHashMapIterator & operator--() {
/* simpler than forward iteration, since bookend immediately
* precedes control byte for first slot
*/
do {
--ctrl_;
--pos_;
} while (is_sentinel(*ctrl_)
&& (*ctrl_ != c_iterator_bookend));
return *this;
}
private:
uint8_t * ctrl_ = nullptr;
value_type * pos_ = nullptr;

View file

@ -207,6 +207,9 @@ namespace xo {
ok_flag &= HashMapUtil<HashMap>::check_forward_iterator(0.0 /*dvalue*/,
dbg_flag, hash_map);
/* regular forward iterator, but start at hash_map.end() and use operator-- */
ok_flag &= HashMapUtil<HashMap>::check_backward_iterator(0.0 /*dvalue*/,
dbg_flag, hash_map);
ok_flag &= HashMapUtil<HashMap>::random_lookups(0.0 /*dvalue*/,
dbg_flag, &rgen, hash_map);

View file

@ -378,7 +378,7 @@ namespace utest {
/* Require:
* - hash has keys [0..n-1] where n=map size
* - tree value at key k is dvalue+10*k
* - hash value at key k is dvalue+10*k
*/
static bool
check_forward_iterator(uint32_t dvalue,
@ -443,6 +443,73 @@ namespace utest {
return ok_flag;
}
/* Require:
* - hash has keys [0..n-1] where n=map size
* - hash value at key k is dvalue+10*k
*/
static bool
check_backward_iterator(uint32_t dvalue,
bool catch_flag,
HashMap & map)
{
catch_flag=true;
using xo::scope;
using xo::xtag;
/* -> flase if/when verification fails */
bool ok_flag = true;
std::size_t const n = map.size();
scope log(XO_DEBUG(catch_flag));
log && log("map with size n", xtag("n", n));
std::unordered_set<std::size_t> keys;
{
auto end_ix = map.end();
//log && log(xtag("end_ix", end_ix));
auto begin_ix = map.begin();
auto ix = end_ix;
if (ix == begin_ix) [[unlikely]] {
return ok_flag;
}
while (ix != begin_ix) {
log && log("backward loop top",
xtag("n", n)
);
--ix;
/* verify: keys in map are in [0 .. n) */
REQUIRE_ORFAIL(ok_flag, catch_flag, 0 <= ix->first);
REQUIRE_ORFAIL(ok_flag, catch_flag, ix->first < n);
log && log(xtag("ix->first", ix->first));
/* verify: keys in map are unique */
REQUIRE_ORFAIL(ok_flag, catch_flag, !keys.contains(ix->first));
keys.insert(ix->first);
REQUIRE_ORFAIL(ok_flag, catch_flag, ix->second == dvalue + 10 * ix->first);
}
/* should have visited exactly n locations */
REQUIRE_ORFAIL(ok_flag, catch_flag, map.size() == keys.size());
REQUIRE_ORFAIL(ok_flag, catch_flag, ix == begin_ix);
//log && log(xtag("ix", ix), xtag("begin_ix", begin_ix));
}
return ok_flag;
}
#ifdef NOT_YET
/* Require:
* - tree has keys [0..n-1], where n=treẹsize()