More added to bitset
This commit is contained in:
1 parent
963056c42d
commit
c58f3df50a
3 files changed
+131
-6
No files matched your search
+60
-2
@@ -124,10 +124,10 @@ static const char *cmc_string_fmt_bitset = "struct %s<%s> "
|
|||||||
\
|
\
|
||||||
/* Utility Methods */ \
|
/* Utility Methods */ \
|
||||||
/* Translates a bit index to a word index */ \
|
/* Translates a bit index to a word index */ \
|
||||||
static inline cmc_bitset_word PFX##_bit_to_index(cmc_bitset_word idx) \
|
static inline size_t PFX##_bit_to_index(size_t idx) \
|
||||||
{ \
|
{ \
|
||||||
/* Calculate how many shifts based on the size of cmc_bitset_word */ \
|
/* Calculate how many shifts based on the size of cmc_bitset_word */ \
|
||||||
static const cmc_bitset_word shift = \
|
static const size_t shift = \
|
||||||
((sizeof(cmc_bitset_word) * 8) >> 6) > 0 \
|
((sizeof(cmc_bitset_word) * 8) >> 6) > 0 \
|
||||||
? 6 \
|
? 6 \
|
||||||
: ((sizeof(cmc_bitset_word) * 8) >> 5) > 0 \
|
: ((sizeof(cmc_bitset_word) * 8) >> 5) > 0 \
|
||||||
@@ -310,11 +310,69 @@ static const char *cmc_string_fmt_bitset = "struct %s<%s> "
|
|||||||
\
|
\
|
||||||
bool PFX##_clear(struct SNAME *_bitset_, size_t bit_index) \
|
bool PFX##_clear(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->delete) \
|
||||||
|
_bitset_->callbacks->delete (); \
|
||||||
|
\
|
||||||
return true; \
|
return true; \
|
||||||
} \
|
} \
|
||||||
\
|
\
|
||||||
bool PFX##_clear_range(struct SNAME *_bitset_, size_t from, size_t to) \
|
bool PFX##_clear_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; i < end_index; i++) \
|
||||||
|
_bitset_->buffer[i] = 0; \
|
||||||
|
\
|
||||||
|
_bitset_->buffer[end_index] &= ~end_mask; \
|
||||||
|
} \
|
||||||
|
\
|
||||||
|
_bitset_->flag = cmc_flags.OK; \
|
||||||
|
\
|
||||||
|
if (_bitset_->callbacks && _bitset_->callbacks->delete) \
|
||||||
|
_bitset_->callbacks->delete (); \
|
||||||
|
\
|
||||||
return true; \
|
return true; \
|
||||||
} \
|
} \
|
||||||
\
|
\
|
||||||
|
|||||||
+39
-2
@@ -37,9 +37,9 @@ _Bool bs_fill(struct bitset *_bitset_);
|
|||||||
_Bool bs_empty(struct bitset *_bitset_);
|
_Bool bs_empty(struct bitset *_bitset_);
|
||||||
_Bool bs_get(struct bitset *_bitset_, size_t bit_index);
|
_Bool bs_get(struct bitset *_bitset_, size_t bit_index);
|
||||||
_Bool bs_resize(struct bitset *_bitset_, size_t n_bits);
|
_Bool bs_resize(struct bitset *_bitset_, size_t n_bits);
|
||||||
static inline cmc_bitset_word bs_bit_to_index(cmc_bitset_word idx)
|
static inline size_t bs_bit_to_index(size_t idx)
|
||||||
{
|
{
|
||||||
static const cmc_bitset_word shift =
|
static const size_t shift =
|
||||||
((sizeof(cmc_bitset_word) * 8) >> 6) > 0
|
((sizeof(cmc_bitset_word) * 8) >> 6) > 0
|
||||||
? 6
|
? 6
|
||||||
: ((sizeof(cmc_bitset_word) * 8) >> 5) > 0
|
: ((sizeof(cmc_bitset_word) * 8) >> 5) > 0
|
||||||
@@ -163,10 +163,47 @@ _Bool bs_set_range(struct bitset *_bitset_, size_t from, size_t to)
|
|||||||
}
|
}
|
||||||
_Bool bs_clear(struct bitset *_bitset_, size_t bit_index)
|
_Bool bs_clear(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->delete)
|
||||||
|
_bitset_->callbacks->delete ();
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
_Bool bs_clear_range(struct bitset *_bitset_, size_t from, size_t to)
|
_Bool bs_clear_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; i < end_index; i++)
|
||||||
|
_bitset_->buffer[i] = 0;
|
||||||
|
_bitset_->buffer[end_index] &= ~end_mask;
|
||||||
|
}
|
||||||
|
_bitset_->flag = cmc_flags.OK;
|
||||||
|
if (_bitset_->callbacks && _bitset_->callbacks->delete)
|
||||||
|
_bitset_->callbacks->delete ();
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
_Bool bs_flip(struct bitset *_bitset_, size_t bit_index)
|
_Bool bs_flip(struct bitset *_bitset_, size_t bit_index)
|
||||||
|
|||||||
+32
-2
@@ -183,9 +183,39 @@ CMC_CREATE_UNIT(BitSet, true, {
|
|||||||
});
|
});
|
||||||
|
|
||||||
CMC_CREATE_TEST(PFX##_clear(), {
|
CMC_CREATE_TEST(PFX##_clear(), {
|
||||||
struct bitset *bs = bs_new(64);
|
struct bitset *bs = bs_new(word_bits * 10 - 1);
|
||||||
|
|
||||||
// WIP
|
cmc_assert_not_equals(ptr, NULL, bs);
|
||||||
|
cmc_assert(0 == bs->buffer[0]);
|
||||||
|
|
||||||
|
bs->buffer[0] = 1; // 0001
|
||||||
|
cmc_assert(bs_clear(bs, 0));
|
||||||
|
cmc_assert(0 == bs->buffer[0]);
|
||||||
|
|
||||||
|
bs->buffer[0] = 10; // 1010
|
||||||
|
cmc_assert(bs_clear(bs, 1));
|
||||||
|
cmc_assert(bs_clear(bs, 3));
|
||||||
|
cmc_assert(0 == bs->buffer[0]);
|
||||||
|
|
||||||
|
cmc_assert(bs_clear(bs, word_bits * 100 - 1));
|
||||||
|
cmc_assert_equals(size_t, 100, bs->capacity);
|
||||||
|
|
||||||
|
bs_free(bs);
|
||||||
|
});
|
||||||
|
|
||||||
|
CMC_CREATE_TEST(PFX##_clear_range(), {
|
||||||
|
struct bitset *bs = bs_new(word_bits * 10 - 1);
|
||||||
|
|
||||||
|
cmc_assert_not_equals(ptr, NULL, bs);
|
||||||
|
cmc_assert(0 == bs->buffer[0]);
|
||||||
|
|
||||||
|
cmc_assert(bs_clear(bs, word_bits * 100 - 1));
|
||||||
|
cmc_assert_equals(size_t, 100, bs->capacity);
|
||||||
|
|
||||||
|
cmc_assert(bs_set_range(bs, word_bits * 20, word_bits * 21 - 1));
|
||||||
|
cmc_assert(bs_clear_range(bs, word_bits * 20, word_bits * 21 - 1));
|
||||||
|
|
||||||
|
cmc_assert_equals(uint32_t, 0, bs->buffer[bs_bit_to_index(word_bits * 20)]);
|
||||||
|
|
||||||
bs_free(bs);
|
bs_free(bs);
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in new issue
Block a user