Bruno, is this what you had in mind? I could use macros to reduce to boilerplate, but whether to factor completely with macros, or avoid macros as much as possible at the cost of possible redundancy depends on people: which one do you want?
It did catch a bug, in expandable's implementation of 'not'. commit 1b9ea5ef4cdc15e0ade3852d0ff145e7f07ef6d7 Author: Akim Demaille <akim.demai...@gmail.com> Date: Wed Nov 28 05:56:21 2018 +0100 bitset: check the operations * tests/test-bitset.c (bitset_random): New. Use it. * lib/bitset/expandable.c (ebitset_not): Fix typo. diff --git a/ChangeLog b/ChangeLog index c1a132956..0eb8f2a73 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2018-11-28 Akim Demaille <a...@lrde.epita.fr> + + bitset: check the operations + * tests/test-bitset.c (bitset_random): New. + Use it. + * lib/bitset/expandable.c (ebitset_not): Fix typo. + 2018-11-28 Akim Demaille <a...@lrde.epita.fr> bitset: properly use false/true instead of 0/1 for Booleans diff --git a/lib/bitset/expandable.c b/lib/bitset/expandable.c index 439112aa9..c9f2d88e8 100644 --- a/lib/bitset/expandable.c +++ b/lib/bitset/expandable.c @@ -844,7 +844,7 @@ ebitset_not (bitset dst, bitset src) /* Create new elements for dst if they cannot be found or substitute zero elements if src elements not found. */ ebitset_elt *selt = - ebitset_elt_find (dst, j * EBITSET_ELT_BITS, EBITSET_SUBST); + ebitset_elt_find (src, j * EBITSET_ELT_BITS, EBITSET_SUBST); ebitset_elt *delt = ebitset_elt_find (dst, j * EBITSET_ELT_BITS, EBITSET_CREATE); diff --git a/tests/test-bitset.c b/tests/test-bitset.c index b673d188c..c303de754 100644 --- a/tests/test-bitset.c +++ b/tests/test-bitset.c @@ -20,6 +20,102 @@ #include "macros.h" +#define RANDOM(n) (rand () % (n)) + +static +void assert_bitset_equal (bitset bs1, bitset bs2) +{ + debug_bitset (bs1); + debug_bitset (bs2); + ASSERT (bitset_size (bs1) == bitset_size (bs2)); + for (bitset_bindex i = 0; i < bitset_size (bs1); ++i) + ASSERT (bitset_test (bs1, i) == bitset_test (bs2, i)); +} + +void bitset_random (bitset bs) +{ + for (bitset_bindex i = 0; i < bitset_size (bs); ++i) + bitset_set (bs, RANDOM(2)); +} + +void compare (enum bitset_attr a, enum bitset_attr b) +{ + const int nbits = RANDOM(256); + + bitset asrc0 = bitset_create (nbits, a); + bitset_random (asrc0); + bitset asrc1 = bitset_create (nbits, a); + bitset_random (asrc1); + bitset asrc2 = bitset_create (nbits, a); + bitset_random (asrc2); + bitset asrc3 = bitset_create (nbits, a); + bitset_random (asrc3); + bitset adst = bitset_create (nbits, a); + + bitset bsrc0 = bitset_create (nbits, b); + bitset_copy (bsrc0, asrc0); + bitset bsrc1 = bitset_create (nbits, b); + bitset_copy (bsrc1, asrc1); + bitset bsrc2 = bitset_create (nbits, b); + bitset_copy (bsrc2, asrc2); + bitset bsrc3 = bitset_create (nbits, b); + bitset_copy (bsrc3, asrc3); + bitset bdst = bitset_create (nbits, b); + + bitset_not (adst, asrc0); + bitset_not (bdst, bsrc0); + assert_bitset_equal (adst, bdst); + + bitset_and (adst, asrc0, asrc1); + bitset_and (bdst, bsrc0, bsrc1); + assert_bitset_equal (adst, bdst); + ASSERT(bitset_and_cmp (adst, asrc0, asrc1) + == bitset_and_cmp (bdst, bsrc0, bsrc1)); + assert_bitset_equal (adst, bdst); + + bitset_andn (adst, asrc0, asrc1); + bitset_andn (bdst, bsrc0, bsrc1); + assert_bitset_equal (adst, bdst); + ASSERT(bitset_andn_cmp (adst, asrc0, asrc1) + == bitset_andn_cmp (bdst, bsrc0, bsrc1)); + assert_bitset_equal (adst, bdst); + + bitset_or (adst, asrc0, asrc1); + bitset_or (bdst, bsrc0, bsrc1); + assert_bitset_equal (adst, bdst); + ASSERT(bitset_or_cmp (adst, asrc0, asrc1) + == bitset_or_cmp (bdst, bsrc0, bsrc1)); + assert_bitset_equal (adst, bdst); + + bitset_xor (adst, asrc0, asrc1); + bitset_xor (bdst, bsrc0, bsrc1); + assert_bitset_equal (adst, bdst); + ASSERT(bitset_xor_cmp (adst, asrc0, asrc1) + == bitset_xor_cmp (bdst, bsrc0, bsrc1)); + assert_bitset_equal (adst, bdst); + + bitset_and_or (adst, asrc0, asrc1, asrc2); + bitset_and_or (bdst, bsrc0, bsrc1, bsrc2); + assert_bitset_equal (adst, bdst); + ASSERT(bitset_and_or_cmp (adst, asrc0, asrc1, asrc2) + == bitset_and_or_cmp (bdst, bsrc0, bsrc1, bsrc2)); + assert_bitset_equal (adst, bdst); + + bitset_andn_or (adst, asrc0, asrc1, asrc2); + bitset_andn_or (bdst, bsrc0, bsrc1, bsrc2); + assert_bitset_equal (adst, bdst); + ASSERT(bitset_andn_or_cmp (adst, asrc0, asrc1, asrc2) + == bitset_andn_or_cmp (bdst, bsrc0, bsrc1, bsrc2)); + assert_bitset_equal (adst, bdst); + + bitset_or_and (adst, asrc0, asrc1, asrc2); + bitset_or_and (bdst, bsrc0, bsrc1, bsrc2); + assert_bitset_equal (adst, bdst); + ASSERT(bitset_or_and_cmp (adst, asrc0, asrc1, asrc2) + == bitset_or_and_cmp (bdst, bsrc0, bsrc1, bsrc2)); + assert_bitset_equal (adst, bdst); +} + void check_attributes (enum bitset_attr attr) { enum { nbits = 32 }; @@ -62,5 +158,12 @@ int main (void) check_attributes (BITSET_SPARSE); check_attributes (BITSET_FRUGAL); check_attributes (BITSET_GREEDY); + + compare (BITSET_FIXED, BITSET_FIXED); + compare (BITSET_FIXED, BITSET_VARIABLE); + compare (BITSET_FIXED, BITSET_DENSE); + compare (BITSET_FIXED, BITSET_SPARSE); + compare (BITSET_FIXED, BITSET_FRUGAL); + compare (BITSET_FIXED, BITSET_GREEDY); return 0; }