BUG: bitSet &= operation does not mask out non-overlapping (#2456)

- the values from non-overlapping blocks were simply ignored,
  which meant that ('111111111111' & '111111') would not mask out
  the unset values at all.

- similar oddities in other operations (|=, ^= etc)
  where the original implementation tried hard to avoid touching the
  sizing at all, but now better resolved as follows:

  - '|=' : Set may grow to accommodate new 'on' bits.
  - '^=' : Set may grow to accommodate new 'on' bits.
  - '-=' : Never changes the original set size.
  - '&=' : Never changes the original set size.
           Non-overlapping elements are considered 'off'.

  These definitions are consistent with HashSet behaviour
  and also ensures that (a & b) == (b & a)

ENH: improve short-circuiting within bitSet ops

- in a few places can optimise by checking for none() instead of
  empty() and avoid unnecessary block operations.

ENH: added bitSet::resize_last() method

- as the name says: resizes to the last bit set.
  A friendlier way of writing `resize(find_last()+1)`
This commit is contained in:
Mark Olesen
2022-05-05 15:24:51 +02:00
parent a34357b1a6
commit 036abb8ecb
5 changed files with 126 additions and 136 deletions

View File

@ -344,12 +344,35 @@ int main(int argc, char *argv[])
Info<< "\noperator|=\n";
{
bitSet a; a.set(labelRange(15, 8));
bitSet b; b.set(labelRange(30, 8));
report(a, false);
report(b, false);
report((a |= b), true);
}
{
Info<< " other test\n";
bitSet list3 = list1;
report((list3 |= list2), true);
}
Info<< "\noperator&=\n";
{
bitSet a; a.set(labelRange(30, 8));
bitSet b; b.set(labelRange(0, 8));
report(a, false);
report(b, false);
Info<< " (a & b)\n";
report((a & b), true);
Info<< " (b & a)\n";
report((b & a), true);
}
{
Info<< " other test\n";
bitSet list3 = list1;
report((list3 &= list2), true);
}