diff --git a/include/bitops.h b/include/bitops.h index abee5a9..9a1a25f 100644 --- a/include/bitops.h +++ b/include/bitops.h @@ -1,3 +1,10 @@ #pragma once +#include + unsigned ilog2(unsigned n); +int is_bit_set(void *base, size_t n); +void set_bit(void *base, size_t n); +void clear_bit(void *base, size_t n); +size_t next_set_bit(void *base, size_t n); +size_t next_clear_bit(void *base, size_t n); diff --git a/include/bitset.h b/include/bitset.h deleted file mode 100644 index 003c75b..0000000 --- a/include/bitset.h +++ /dev/null @@ -1,10 +0,0 @@ -#pragma once - -#include -#include - -int is_bit_set(void *set, size_t n); -void set_bit(void *set, size_t n); -void clear_bit(void *set, size_t n); -size_t next_set_bit(void *set, size_t len); -size_t next_clear_bit(void *set, size_t len); diff --git a/source/bitops.c b/source/bitops.c index 59048e2..2411497 100644 --- a/source/bitops.c +++ b/source/bitops.c @@ -1,4 +1,10 @@ +#include + #include +#include + +#define BIT_WORD(n) ((n) / BIT_SIZE(unsigned long)) +#define BIT_MASK(n) (1UL << ((n) % BIT_SIZE(unsigned long))) unsigned ilog2(unsigned n) { @@ -9,3 +15,51 @@ unsigned ilog2(unsigned n) return ret; } + +int is_bit_set(void *base, size_t n) +{ + unsigned long *word = (unsigned long *)base + BIT_WORD(n); + unsigned long mask = BIT_MASK(n); + + return (*word & mask) ? 1 : 0; +} + +void set_bit(void *base, size_t n) +{ + unsigned long *word = (unsigned long *)base + BIT_WORD(n); + unsigned long mask = BIT_MASK(n); + + *word |= mask; +} + +void clear_bit(void *base, size_t n) +{ + unsigned long *word = (unsigned long *)base + BIT_WORD(n); + unsigned long mask = BIT_MASK(n); + + *word &= ~mask; +} + +size_t next_set_bit(void *base, size_t n) +{ + size_t i; + + for (i = 0; i < n; ++i) { + if (is_bit_set(base, i)) + return i; + } + + return SIZE_MAX; +} + +size_t next_clear_bit(void *base, size_t n) +{ + size_t i; + + for (i = 0; i < n; ++i) { + if (!is_bit_set(base, i)) + return i; + } + + return SIZE_MAX; +} diff --git a/source/bitset.c b/source/bitset.c deleted file mode 100644 index 7a563fd..0000000 --- a/source/bitset.c +++ /dev/null @@ -1,61 +0,0 @@ -#include -#include - -int is_bit_set(void *set_, size_t n) -{ - uint8_t *set = set_; - uint8_t *word, mask; - - word = set + n / BIT_SIZE(*set); - mask = (1 << (n % BIT_SIZE(*set))); - - return (*word & mask) ? 1 : 0; -} - -void set_bit(void *set_, size_t n) -{ - uint8_t *set = set_; - uint8_t *word, mask; - - word = set + n / BIT_SIZE(*set); - mask = (1 << (n % BIT_SIZE(*set))); - - *word |= mask; -} - -void clear_bit(void *set_, size_t n) -{ - uint8_t *set = set_; - uint8_t *word, mask; - - word = set + n / BIT_SIZE(*set); - mask = (1 << (n % BIT_SIZE(*set))); - - *word &= ~mask; -} - -size_t next_set_bit(void *set_, size_t len) -{ - uint8_t *set = set_; - size_t n; - - for (n = 0; n < len; ++n) { - if (is_bit_set(set, n)) - return n; - } - - return SIZE_MAX; -} - -size_t next_clear_bit(void *set_, size_t len) -{ - uint8_t *set = set_; - size_t n; - - for (n = 0; n < len; ++n) { - if (!is_bit_set(set, n)) - return n; - } - - return SIZE_MAX; -}