From 14251ea378e456d8461cf5aeb82df871efc79314 Mon Sep 17 00:00:00 2001 From: Leonardo Date: Sat, 16 May 2020 08:17:52 -0300 Subject: [PATCH] Added more bitset functions --- src/cmc/bitset.h | 70 ++++++++++++++++++++++------ tests/main/src/bitset.c | 61 +++++++++++++++++------- tests/main/unt/bitset.c | 100 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 200 insertions(+), 31 deletions(-) diff --git a/src/cmc/bitset.h b/src/cmc/bitset.h index f34fb91..7431636 100644 --- a/src/cmc/bitset.h +++ b/src/cmc/bitset.h @@ -127,18 +127,24 @@ static const char *cmc_string_fmt_bitset = "struct %s " bool PFX##_clear_range(struct SNAME *_bitset_, size_t from, size_t to); \ bool PFX##_flip(struct SNAME *_bitset_, size_t bit_index); \ bool PFX##_flip_range(struct SNAME *_bitset_, size_t from, size_t to); \ - bool PFX##_put(struct SNAME *_bitset_, size_t bit_index); \ - bool PFX##_put_range(struct SNAME *_bitset_, size_t from, size_t to); \ - bool PFX##_fill(struct SNAME *_bitset_); \ - bool PFX##_empty(struct SNAME *_bitset_); \ + bool PFX##_put(struct SNAME *_bitset_, size_t bit_index, bool state); \ + bool PFX##_put_range(struct SNAME *_bitset_, size_t from, size_t to, \ + bool state); \ + bool PFX##_set_all(struct SNAME *_bitset_); \ + bool PFX##_clear_all(struct SNAME *_bitset_); \ + bool PFX##_flip_all(struct SNAME *_bitset_); \ /* Element Access */ \ bool PFX##_get(struct SNAME *_bitset_, size_t bit_index); \ - \ /* Collection State */ \ - \ /* Collection Utility */ \ bool PFX##_resize(struct SNAME *_bitset_, size_t n_bits); \ \ + /* Iterator Functions */ \ + /* Iterator Initialization */ \ + /* Iterator State */ \ + /* Iterator Movement */ \ + /* Iterator Access */ \ + \ /* Utility Methods */ \ /* Translates a bit index to a word index */ \ static inline size_t PFX##_bit_to_index(size_t idx) \ @@ -456,28 +462,64 @@ static const char *cmc_string_fmt_bitset = "struct %s " _bitset_->flag = cmc_flags.OK; \ \ if (_bitset_->callbacks && _bitset_->callbacks->update) \ - _bitset_->callbacks->update (); \ + _bitset_->callbacks->update(); \ \ return true; \ } \ \ - bool PFX##_put(struct SNAME *_bitset_, size_t bit_index) \ + bool PFX##_put(struct SNAME *_bitset_, size_t bit_index, bool state) \ { \ + if (state) \ + return PFX##_set(_bitset_, bit_index); \ + else \ + return PFX##_clear(_bitset_, bit_index); \ + } \ + \ + bool PFX##_put_range(struct SNAME *_bitset_, size_t from, size_t to, \ + bool state) \ + { \ + if (state) \ + return PFX##_set_range(_bitset_, from, to); \ + else \ + return PFX##_clear_range(_bitset_, from, to); \ + } \ + \ + bool PFX##_set_all(struct SNAME *_bitset_) \ + { \ + for (size_t i = 0; i < _bitset_->capacity; i++) \ + _bitset_->buffer[i] = ~((cmc_bitset_word)0); \ + \ + _bitset_->flag = cmc_flags.OK; \ + \ + if (_bitset_->callbacks && _bitset_->callbacks->create) \ + _bitset_->callbacks->create(); \ + \ return true; \ } \ \ - bool PFX##_put_range(struct SNAME *_bitset_, size_t from, size_t to) \ + bool PFX##_clear_all(struct SNAME *_bitset_) \ { \ + for (size_t i = 0; i < _bitset_->capacity; i++) \ + _bitset_->buffer[i] = 0; \ + \ + _bitset_->flag = cmc_flags.OK; \ + \ + if (_bitset_->callbacks && _bitset_->callbacks->delete) \ + _bitset_->callbacks->delete (); \ + \ return true; \ } \ \ - bool PFX##_fill(struct SNAME *_bitset_) \ + bool PFX##_flip_all(struct SNAME *_bitset_) \ { \ - return true; \ - } \ + for (size_t i = 0; i < _bitset_->capacity; i++) \ + _bitset_->buffer[i] ^= ~((cmc_bitset_word)0); \ + \ + _bitset_->flag = cmc_flags.OK; \ + \ + if (_bitset_->callbacks && _bitset_->callbacks->create) \ + _bitset_->callbacks->create(); \ \ - bool PFX##_empty(struct SNAME *_bitset_) \ - { \ return true; \ } \ \ diff --git a/tests/main/src/bitset.c b/tests/main/src/bitset.c index fbad19e..07c7094 100644 --- a/tests/main/src/bitset.c +++ b/tests/main/src/bitset.c @@ -31,10 +31,12 @@ _Bool bs_clear(struct bitset *_bitset_, size_t bit_index); _Bool bs_clear_range(struct bitset *_bitset_, size_t from, size_t to); _Bool bs_flip(struct bitset *_bitset_, size_t bit_index); _Bool bs_flip_range(struct bitset *_bitset_, size_t from, size_t to); -_Bool bs_put(struct bitset *_bitset_, size_t bit_index); -_Bool bs_put_range(struct bitset *_bitset_, size_t from, size_t to); -_Bool bs_fill(struct bitset *_bitset_); -_Bool bs_empty(struct bitset *_bitset_); +_Bool bs_put(struct bitset *_bitset_, size_t bit_index, _Bool state); +_Bool bs_put_range(struct bitset *_bitset_, size_t from, size_t to, + _Bool state); +_Bool bs_set_all(struct bitset *_bitset_); +_Bool bs_clear_all(struct bitset *_bitset_); +_Bool bs_flip_all(struct bitset *_bitset_); _Bool bs_get(struct bitset *_bitset_, size_t bit_index); _Bool bs_resize(struct bitset *_bitset_, size_t n_bits); static inline size_t bs_bit_to_index(size_t idx) @@ -247,24 +249,49 @@ _Bool bs_flip_range(struct bitset *_bitset_, size_t from, size_t to) _bitset_->buffer[end_index] ^= end_mask; } _bitset_->flag = cmc_flags.OK; + if (_bitset_->callbacks && _bitset_->callbacks->update) + _bitset_->callbacks->update(); + return 1; +} +_Bool bs_put(struct bitset *_bitset_, size_t bit_index, _Bool state) +{ + if (state) + return bs_set(_bitset_, bit_index); + else + return bs_clear(_bitset_, bit_index); +} +_Bool bs_put_range(struct bitset *_bitset_, size_t from, size_t to, _Bool state) +{ + if (state) + return bs_set_range(_bitset_, from, to); + else + return bs_clear_range(_bitset_, from, to); +} +_Bool bs_set_all(struct bitset *_bitset_) +{ + for (size_t i = 0; i < _bitset_->capacity; i++) + _bitset_->buffer[i] = ~((cmc_bitset_word)0); + _bitset_->flag = cmc_flags.OK; + if (_bitset_->callbacks && _bitset_->callbacks->create) + _bitset_->callbacks->create(); + return 1; +} +_Bool bs_clear_all(struct bitset *_bitset_) +{ + for (size_t i = 0; i < _bitset_->capacity; i++) + _bitset_->buffer[i] = 0; + _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) -{ - return 1; -} -_Bool bs_put_range(struct bitset *_bitset_, size_t from, size_t to) -{ - return 1; -} -_Bool bs_fill(struct bitset *_bitset_) -{ - return 1; -} -_Bool bs_empty(struct bitset *_bitset_) +_Bool bs_flip_all(struct bitset *_bitset_) { + for (size_t i = 0; i < _bitset_->capacity; i++) + _bitset_->buffer[i] ^= ~((cmc_bitset_word)0); + _bitset_->flag = cmc_flags.OK; + if (_bitset_->callbacks && _bitset_->callbacks->create) + _bitset_->callbacks->create(); return 1; } _Bool bs_get(struct bitset *_bitset_, size_t bit_index) diff --git a/tests/main/unt/bitset.c b/tests/main/unt/bitset.c index 3888b1c..3759a08 100644 --- a/tests/main/unt/bitset.c +++ b/tests/main/unt/bitset.c @@ -315,6 +315,106 @@ CMC_CREATE_UNIT(BitSet, true, { bs_free(bs); }); + CMC_CREATE_TEST(PFX##_put(), { + 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_put(bs, 1, true)); // 0010 + cmc_assert_equals(CMC_BITSET_WORD_TYPE, 2, bs->buffer[0]); + cmc_assert(bs_put(bs, 0, false)); // 0010 + cmc_assert_equals(CMC_BITSET_WORD_TYPE, 2, bs->buffer[0]); + cmc_assert(bs_put(bs, 1, false)); // 0000 + cmc_assert_equals(CMC_BITSET_WORD_TYPE, 0, bs->buffer[0]); + cmc_assert(bs_put(bs, 3, true)); // 1000 + cmc_assert_equals(CMC_BITSET_WORD_TYPE, 8, bs->buffer[0]); + cmc_assert(bs_put(bs, 0, true)); // 1001 + cmc_assert_equals(CMC_BITSET_WORD_TYPE, 9, bs->buffer[0]); + cmc_assert(bs_put(bs, 3, false)); // 0001 + cmc_assert_equals(CMC_BITSET_WORD_TYPE, 1, bs->buffer[0]); + + cmc_assert(bs_put(bs, word_bits * 100 - 1, true)); + cmc_assert_equals(size_t, 100, bs->capacity); + + bs_free(bs); + }); + + CMC_CREATE_TEST(PFX##_put_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_put_range(bs, 1, 2, true)); // 0110 + cmc_assert_equals(CMC_BITSET_WORD_TYPE, 6, bs->buffer[0]); + cmc_assert(bs_put_range(bs, 0, 1, false)); // 0100 + cmc_assert_equals(CMC_BITSET_WORD_TYPE, 4, bs->buffer[0]); + cmc_assert(bs_put_range(bs, 1, 3, true)); // 1110 + cmc_assert_equals(CMC_BITSET_WORD_TYPE, 14, bs->buffer[0]); + cmc_assert(bs_put_range(bs, 2, 3, false)); // 0010 + cmc_assert_equals(CMC_BITSET_WORD_TYPE, 2, bs->buffer[0]); + + cmc_assert(bs_put_range(bs, 0, word_bits * 100 - 1, true)); + 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(bs_put_range(bs, 0, word_bits * 100 - 1, false)); + for (size_t i = 0; i < bs->capacity; i++) + cmc_assert_equals(CMC_BITSET_WORD_TYPE, 0, + bs->buffer[i]); + + bs_free(bs); + }); + + CMC_CREATE_TEST(PFX##_set_all(), { + struct bitset *bs = bs_new(word_bits * 10 - 1); + + cmc_assert_not_equals(ptr, NULL, bs); + + cmc_assert(bs_set_all(bs)); + + 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); + }); + + CMC_CREATE_TEST(PFX##_clear_all(), { + struct bitset *bs = bs_new(word_bits * 10 - 1); + + cmc_assert_not_equals(ptr, NULL, bs); + + cmc_assert(bs_set_all(bs)); + cmc_assert(bs_clear_all(bs)); + + for (size_t i = 0; i < bs->capacity; i++) + cmc_assert_equals(CMC_BITSET_WORD_TYPE, 0, bs->buffer[i]); + + bs_free(bs); + }); + + CMC_CREATE_TEST(PFX##_flip_all(), { + struct bitset *bs = bs_new(word_bits * 10 - 1); + + cmc_assert_not_equals(ptr, NULL, bs); + + cmc_assert(bs_flip_all(bs)); + 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(bs_flip_all(bs)); + for (size_t i = 0; i < bs->capacity; i++) + cmc_assert_equals(CMC_BITSET_WORD_TYPE, 0, bs->buffer[i]); + + bs_free(bs); + }); + CMC_CREATE_TEST(PFX##_get(), { struct bitset *bs = bs_new(64);