Added bitset flip and flip_range
This commit is contained in:
1 parent
bd96dfdc8f
commit
1380d131ea
3 files changed
+186
-15
No files matched your search
+59
-1
@@ -379,7 +379,7 @@ static const char *cmc_string_fmt_bitset = "struct %s "
|
||||
{ \
|
||||
_bitset_->buffer[start_index] &= ~start_mask; \
|
||||
\
|
||||
for (size_t i = start_index; i < end_index; i++) \
|
||||
for (size_t i = start_index + 1; i < end_index; i++) \
|
||||
_bitset_->buffer[i] = 0; \
|
||||
\
|
||||
_bitset_->buffer[end_index] &= ~end_mask; \
|
||||
@@ -395,11 +395,69 @@ static const char *cmc_string_fmt_bitset = "struct %s "
|
||||
\
|
||||
bool PFX##_flip(struct SNAME *_bitset_, size_t bit_index) \
|
||||
{ \
|
||||
if (!PFX##_impl_resize(_bitset_, bit_index + 1, false)) \
|
||||
return false; \
|
||||
\
|
||||
/* How many bits in a word */ \
|
||||
const cmc_bitset_word bits = sizeof(cmc_bitset_word) * CHAR_BIT; \
|
||||
\
|
||||
size_t i = PFX##_bit_to_index(bit_index); \
|
||||
\
|
||||
_bitset_->buffer[i] ^= ((cmc_bitset_word)1) << (bit_index % bits); \
|
||||
\
|
||||
_bitset_->flag = cmc_flags.OK; \
|
||||
\
|
||||
if (_bitset_->callbacks && _bitset_->callbacks->update) \
|
||||
_bitset_->callbacks->update(); \
|
||||
\
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
bool PFX##_flip_range(struct SNAME *_bitset_, size_t from, size_t to) \
|
||||
{ \
|
||||
if (to < from) \
|
||||
{ \
|
||||
_bitset_->flag = cmc_flags.INVALID; \
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
if (!PFX##_impl_resize(_bitset_, to + 1, false)) \
|
||||
return false; \
|
||||
\
|
||||
size_t start_index = PFX##_bit_to_index(from); \
|
||||
size_t end_index = PFX##_bit_to_index(to); \
|
||||
\
|
||||
/* How many bits in a word */ \
|
||||
const cmc_bitset_word bits = sizeof(cmc_bitset_word) * CHAR_BIT; \
|
||||
\
|
||||
/* 1111 ... 1111 */ \
|
||||
const cmc_bitset_word ones = ~((cmc_bitset_word)0); \
|
||||
\
|
||||
cmc_bitset_word shift_start = from % bits; \
|
||||
cmc_bitset_word shift_end = (cmc_bitset_word)(-(to + 1)) % bits; \
|
||||
\
|
||||
cmc_bitset_word start_mask = ones << shift_start; \
|
||||
cmc_bitset_word end_mask = ones >> shift_end; \
|
||||
\
|
||||
if (start_index == end_index) \
|
||||
{ \
|
||||
_bitset_->buffer[end_index] ^= (start_mask & end_mask); \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
_bitset_->buffer[start_index] ^= start_mask; \
|
||||
\
|
||||
for (size_t i = start_index + 1; i < end_index; i++) \
|
||||
_bitset_->buffer[i] ^= ones; \
|
||||
\
|
||||
_bitset_->buffer[end_index] ^= end_mask; \
|
||||
} \
|
||||
\
|
||||
_bitset_->flag = cmc_flags.OK; \
|
||||
\
|
||||
if (_bitset_->callbacks && _bitset_->callbacks->update) \
|
||||
_bitset_->callbacks->update (); \
|
||||
\
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
|
||||
+38
-1
@@ -197,7 +197,7 @@ _Bool bs_clear_range(struct bitset *_bitset_, size_t from, size_t to)
|
||||
else
|
||||
{
|
||||
_bitset_->buffer[start_index] &= ~start_mask;
|
||||
for (size_t i = start_index; i < end_index; i++)
|
||||
for (size_t i = start_index + 1; i < end_index; i++)
|
||||
_bitset_->buffer[i] = 0;
|
||||
_bitset_->buffer[end_index] &= ~end_mask;
|
||||
}
|
||||
@@ -208,10 +208,47 @@ _Bool bs_clear_range(struct bitset *_bitset_, size_t from, size_t to)
|
||||
}
|
||||
_Bool bs_flip(struct bitset *_bitset_, size_t bit_index)
|
||||
{
|
||||
if (!bs_impl_resize(_bitset_, bit_index + 1, 0))
|
||||
return 0;
|
||||
const cmc_bitset_word bits = sizeof(cmc_bitset_word) * 8;
|
||||
size_t i = bs_bit_to_index(bit_index);
|
||||
_bitset_->buffer[i] ^= ((cmc_bitset_word)1) << (bit_index % bits);
|
||||
_bitset_->flag = cmc_flags.OK;
|
||||
if (_bitset_->callbacks && _bitset_->callbacks->update)
|
||||
_bitset_->callbacks->update();
|
||||
return 1;
|
||||
}
|
||||
_Bool bs_flip_range(struct bitset *_bitset_, size_t from, size_t to)
|
||||
{
|
||||
if (to < from)
|
||||
{
|
||||
_bitset_->flag = cmc_flags.INVALID;
|
||||
return 0;
|
||||
}
|
||||
if (!bs_impl_resize(_bitset_, to + 1, 0))
|
||||
return 0;
|
||||
size_t start_index = bs_bit_to_index(from);
|
||||
size_t end_index = bs_bit_to_index(to);
|
||||
const cmc_bitset_word bits = sizeof(cmc_bitset_word) * 8;
|
||||
const cmc_bitset_word ones = ~((cmc_bitset_word)0);
|
||||
cmc_bitset_word shift_start = from % bits;
|
||||
cmc_bitset_word shift_end = (cmc_bitset_word)(-(to + 1)) % bits;
|
||||
cmc_bitset_word start_mask = ones << shift_start;
|
||||
cmc_bitset_word end_mask = ones >> shift_end;
|
||||
if (start_index == end_index)
|
||||
{
|
||||
_bitset_->buffer[end_index] ^= (start_mask & end_mask);
|
||||
}
|
||||
else
|
||||
{
|
||||
_bitset_->buffer[start_index] ^= start_mask;
|
||||
for (size_t i = start_index + 1; i < end_index; i++)
|
||||
_bitset_->buffer[i] ^= ones;
|
||||
_bitset_->buffer[end_index] ^= end_mask;
|
||||
}
|
||||
_bitset_->flag = cmc_flags.OK;
|
||||
if (_bitset_->callbacks && _bitset_->callbacks->delete)
|
||||
_bitset_->callbacks->delete ();
|
||||
return 1;
|
||||
}
|
||||
_Bool bs_put(struct bitset *_bitset_, size_t bit_index)
|
||||
|
||||
+89
-13
@@ -13,7 +13,7 @@ CMC_CREATE_UNIT(BitSet, true, {
|
||||
const size_t word_bits = sizeof(cmc_bitset_word) * CHAR_BIT;
|
||||
|
||||
printf("%s", cmc_test_color(5));
|
||||
printf(" BitSet<"CMC_TO_STRING(CMC_BITSET_WORD_TYPE)">\n");
|
||||
printf(" BitSet<" CMC_TO_STRING(CMC_BITSET_WORD_TYPE) ">\n");
|
||||
printf("%s", cmc_test_color(0));
|
||||
|
||||
CMC_CREATE_TEST(PFX##_new(), {
|
||||
@@ -137,14 +137,18 @@ CMC_CREATE_UNIT(BitSet, true, {
|
||||
bs->buffer[0] = 0;
|
||||
|
||||
cmc_assert(bs_set(bs, word_bits - 1));
|
||||
cmc_assert_equals(CMC_BITSET_WORD_TYPE, ((cmc_bitset_word)1 << (word_bits - 1)), bs->buffer[0]);
|
||||
cmc_assert_equals(CMC_BITSET_WORD_TYPE,
|
||||
((cmc_bitset_word)1 << (word_bits - 1)),
|
||||
bs->buffer[0]);
|
||||
|
||||
cmc_assert(bs_set(bs, word_bits * 8 - 1));
|
||||
cmc_assert_equals(CMC_BITSET_WORD_TYPE, ((cmc_bitset_word)1 << (word_bits - 1)),
|
||||
cmc_assert_equals(CMC_BITSET_WORD_TYPE,
|
||||
((cmc_bitset_word)1 << (word_bits - 1)),
|
||||
bs->buffer[bs_bit_to_index(word_bits * 8 - 1)]);
|
||||
|
||||
cmc_assert(bs_set(bs, word_bits * 18 - 2));
|
||||
cmc_assert_equals(CMC_BITSET_WORD_TYPE, ((cmc_bitset_word)1 << (word_bits - 2)),
|
||||
cmc_assert_equals(CMC_BITSET_WORD_TYPE,
|
||||
((cmc_bitset_word)1 << (word_bits - 2)),
|
||||
bs->buffer[bs_bit_to_index(word_bits * 18 - 2)]);
|
||||
|
||||
bs_free(bs);
|
||||
@@ -161,6 +165,9 @@ CMC_CREATE_UNIT(BitSet, true, {
|
||||
cmc_assert_equals(uint8_t, 1, bs->buffer[0]);
|
||||
cmc_assert_equals(int32_t, cmc_flags.OK, bs->flag);
|
||||
|
||||
cmc_assert(!bs_set_range(bs, 1, 0));
|
||||
cmc_assert_equals(int32_t, cmc_flags.INVALID, bs->flag);
|
||||
|
||||
bs->buffer[0] = 0;
|
||||
|
||||
cmc_assert(bs_set_range(bs, 4, 7)); /* 1111 0000 */
|
||||
@@ -170,7 +177,8 @@ CMC_CREATE_UNIT(BitSet, true, {
|
||||
cmc_assert_equals(uint8_t, 244, bs->buffer[0]);
|
||||
|
||||
cmc_assert(bs_set_range(bs, word_bits * 6 - 2, word_bits * 6 - 2));
|
||||
cmc_assert_equals(CMC_BITSET_WORD_TYPE, ((cmc_bitset_word)1 << (word_bits - 2)),
|
||||
cmc_assert_equals(CMC_BITSET_WORD_TYPE,
|
||||
((cmc_bitset_word)1 << (word_bits - 2)),
|
||||
bs->buffer[bs_bit_to_index(word_bits * 6 - 2)]);
|
||||
|
||||
// Make sure we have at least word_bits * 40 slots
|
||||
@@ -180,14 +188,17 @@ CMC_CREATE_UNIT(BitSet, true, {
|
||||
cmc_assert_equals(CMC_BITSET_WORD_TYPE, (~(cmc_bitset_word)0),
|
||||
bs->buffer[bs_bit_to_index(word_bits * 20)]);
|
||||
|
||||
cmc_assert_equals(CMC_BITSET_WORD_TYPE, 0, bs->buffer[bs_bit_to_index(word_bits * 20 - 1)]);
|
||||
cmc_assert_equals(CMC_BITSET_WORD_TYPE, 0, bs->buffer[bs_bit_to_index(word_bits * 21 + 1)]);
|
||||
cmc_assert_equals(CMC_BITSET_WORD_TYPE, 0,
|
||||
bs->buffer[bs_bit_to_index(word_bits * 20 - 1)]);
|
||||
cmc_assert_equals(CMC_BITSET_WORD_TYPE, 0,
|
||||
bs->buffer[bs_bit_to_index(word_bits * 21 + 1)]);
|
||||
|
||||
cmc_assert(bs_set_range(bs, 0, word_bits * 100 - 1));
|
||||
cmc_assert_equals(size_t, 100, bs->capacity);
|
||||
|
||||
for (size_t i = 0; i < bs->capacity; i++)
|
||||
cmc_assert_equals(CMC_BITSET_WORD_TYPE, ~((cmc_bitset_word)0), bs->buffer[i]);
|
||||
cmc_assert_equals(CMC_BITSET_WORD_TYPE, ~((cmc_bitset_word)0),
|
||||
bs->buffer[i]);
|
||||
|
||||
bs_free(bs);
|
||||
});
|
||||
@@ -219,6 +230,9 @@ CMC_CREATE_UNIT(BitSet, true, {
|
||||
cmc_assert_not_equals(ptr, NULL, bs);
|
||||
cmc_assert_equals(CMC_BITSET_WORD_TYPE, 0, bs->buffer[0]);
|
||||
|
||||
cmc_assert(!bs_clear_range(bs, 1, 0));
|
||||
cmc_assert_equals(int32_t, cmc_flags.INVALID, bs->flag);
|
||||
|
||||
cmc_assert(bs_clear_range(bs, 0, word_bits * 100 - 1));
|
||||
cmc_assert_equals(size_t, 100, bs->capacity);
|
||||
|
||||
@@ -231,13 +245,73 @@ CMC_CREATE_UNIT(BitSet, true, {
|
||||
for (size_t i = 0; i < bs->capacity; i++)
|
||||
bs->buffer[i] = ~((cmc_bitset_word)0);
|
||||
|
||||
cmc_assert(bs_clear_range(bs, 0, word_bits * 200 - 1));
|
||||
cmc_assert(bs_set_range(bs, 0, word_bits * 100 - 1));
|
||||
cmc_assert(bs_clear_range(bs, 0, word_bits * 100 - 1));
|
||||
|
||||
cmc_assert_equals(size_t, 200, bs->capacity);
|
||||
cmc_assert_equals(size_t, 100, bs->capacity);
|
||||
|
||||
for (size_t i = 0; i < bs->capacity; i++)
|
||||
cmc_assert_equals(size_t, 0, bs->buffer[0]);
|
||||
|
||||
cmc_assert(bs_clear_range(bs, 0, word_bits * 200 - 1));
|
||||
cmc_assert_equals(size_t, 200, bs->capacity);
|
||||
|
||||
bs_free(bs);
|
||||
});
|
||||
|
||||
CMC_CREATE_TEST(PFX##_flip(), {
|
||||
struct bitset *bs = bs_new(word_bits * 10 - 1);
|
||||
|
||||
cmc_assert_not_equals(ptr, NULL, bs);
|
||||
cmc_assert_equals(CMC_BITSET_WORD_TYPE, 0, bs->buffer[0]);
|
||||
|
||||
cmc_assert(bs_flip(bs, 0));
|
||||
cmc_assert_equals(CMC_BITSET_WORD_TYPE, 1, bs->buffer[0]);
|
||||
|
||||
cmc_assert(bs_flip(bs, 0));
|
||||
cmc_assert_equals(CMC_BITSET_WORD_TYPE, 0, bs->buffer[0]);
|
||||
|
||||
cmc_assert(bs_set_range(bs, 0, 2)); // 0111
|
||||
cmc_assert_equals(CMC_BITSET_WORD_TYPE, 7, bs->buffer[0]);
|
||||
cmc_assert(bs_flip(bs, 1)); // 0101
|
||||
cmc_assert_equals(CMC_BITSET_WORD_TYPE, 5, bs->buffer[0]);
|
||||
|
||||
cmc_assert(bs_flip(bs, word_bits * 100 - 1));
|
||||
cmc_assert_equals(size_t, 100, bs->capacity);
|
||||
|
||||
bs_free(bs);
|
||||
});
|
||||
|
||||
CMC_CREATE_TEST(PFX##_flip_range(), {
|
||||
struct bitset *bs = bs_new(word_bits * 10 - 1);
|
||||
|
||||
cmc_assert_not_equals(ptr, NULL, bs);
|
||||
cmc_assert_equals(CMC_BITSET_WORD_TYPE, 0, bs->buffer[0]);
|
||||
|
||||
cmc_assert(bs_flip_range(bs, 0, 0));
|
||||
cmc_assert_equals(CMC_BITSET_WORD_TYPE, 1, bs->buffer[0]);
|
||||
|
||||
cmc_assert(bs_flip_range(bs, 0, 0));
|
||||
cmc_assert_equals(CMC_BITSET_WORD_TYPE, 0, bs->buffer[0]);
|
||||
|
||||
cmc_assert(bs_flip_range(bs, 1, 4)); // 0001 1110
|
||||
cmc_assert_equals(CMC_BITSET_WORD_TYPE, 30, bs->buffer[0]);
|
||||
|
||||
cmc_assert(bs_flip_range(bs, 2, 3)); // 0001 0010
|
||||
cmc_assert_equals(CMC_BITSET_WORD_TYPE, 18, bs->buffer[0]);
|
||||
|
||||
cmc_assert(bs_flip_range(bs, 0, 2)); // 0001 0101
|
||||
cmc_assert_equals(CMC_BITSET_WORD_TYPE, 21, bs->buffer[0]);
|
||||
|
||||
bs->buffer[0] = 0;
|
||||
|
||||
cmc_assert(bs_flip_range(bs, 0, word_bits * 100 - 1));
|
||||
cmc_assert_equals(size_t, 100, bs->capacity);
|
||||
|
||||
for (size_t i = 0; i < bs->capacity; i++)
|
||||
cmc_assert_equals(CMC_BITSET_WORD_TYPE, ~((cmc_bitset_word)0),
|
||||
bs->buffer[i]);
|
||||
|
||||
bs_free(bs);
|
||||
});
|
||||
|
||||
@@ -267,7 +341,7 @@ CMC_CREATE_UNIT(BitSetIter, true, {
|
||||
const size_t word_bits = sizeof(cmc_bitset_word) * CHAR_BIT;
|
||||
|
||||
printf("%s", cmc_test_color(5));
|
||||
printf(" BitSet<"CMC_TO_STRING(CMC_BITSET_WORD_TYPE)">\n");
|
||||
printf(" BitSet<" CMC_TO_STRING(CMC_BITSET_WORD_TYPE) ">\n");
|
||||
printf("%s", cmc_test_color(0));
|
||||
|
||||
CMC_CREATE_TEST(PFX##_iter_start(), {
|
||||
@@ -284,10 +358,12 @@ int main(void)
|
||||
{
|
||||
int result = BitSet() + BitSetIter();
|
||||
|
||||
printf(" +---------------------------------------------------------------+");
|
||||
printf(
|
||||
" +---------------------------------------------------------------+");
|
||||
printf("\n");
|
||||
printf(" | BitSet Suit : %-47s |\n", result == 0 ? "PASSED" : "FAILED");
|
||||
printf(" +---------------------------------------------------------------+");
|
||||
printf(
|
||||
" +---------------------------------------------------------------+");
|
||||
printf("\n\n\n");
|
||||
|
||||
return result;
|
||||
|
||||
Reference in new issue
Block a user