X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Futil%2Fbitset.h;h=0fdfe205f39e93ed525ae8f74bebd5310bce06dc;hb=8c9b9aac7d09e65195dca6681d59c10e4ef713d9;hp=2404ce7f630296b1c7622201e443f8b58e619406;hpb=83c86e09a8d7610022eae49731ac1ed03ee4f67b;p=mesa.git diff --git a/src/util/bitset.h b/src/util/bitset.h index 2404ce7f630..0fdfe205f39 100644 --- a/src/util/bitset.h +++ b/src/util/bitset.h @@ -31,7 +31,8 @@ #ifndef BITSET_H #define BITSET_H -#include "util/u_math.h" +#include "util/bitscan.h" +#include "util/macros.h" /**************************************************************************** * generic bitset implementation @@ -53,22 +54,22 @@ #define BITSET_ONES(x) memset( (x), 0xff, sizeof (x) ) #define BITSET_BITWORD(b) ((b) / BITSET_WORDBITS) -#define BITSET_BIT(b) (1 << ((b) % BITSET_WORDBITS)) +#define BITSET_BIT(b) (1u << ((b) % BITSET_WORDBITS)) /* single bit operations */ -#define BITSET_TEST(x, b) ((x)[BITSET_BITWORD(b)] & BITSET_BIT(b)) +#define BITSET_TEST(x, b) (((x)[BITSET_BITWORD(b)] & BITSET_BIT(b)) != 0) #define BITSET_SET(x, b) ((x)[BITSET_BITWORD(b)] |= BITSET_BIT(b)) #define BITSET_CLEAR(x, b) ((x)[BITSET_BITWORD(b)] &= ~BITSET_BIT(b)) -#define BITSET_MASK(b) ((b) == BITSET_WORDBITS ? ~0 : BITSET_BIT(b) - 1) -#define BITSET_RANGE(b, e) (BITSET_MASK((e) + 1) & ~BITSET_MASK(b)) +#define BITSET_MASK(b) (((b) % BITSET_WORDBITS == 0) ? ~0 : BITSET_BIT(b) - 1) +#define BITSET_RANGE(b, e) ((BITSET_MASK((e) + 1)) & ~(BITSET_BIT(b) - 1)) /* bit range operations */ #define BITSET_TEST_RANGE(x, b, e) \ (BITSET_BITWORD(b) == BITSET_BITWORD(e) ? \ - ((x)[BITSET_BITWORD(b)] & BITSET_RANGE(b, e)) : \ + (((x)[BITSET_BITWORD(b)] & BITSET_RANGE(b, e)) != 0) : \ (assert (!"BITSET_TEST_RANGE: bit range crosses word boundary"), 0)) #define BITSET_SET_RANGE(x, b, e) \ (BITSET_BITWORD(b) == BITSET_BITWORD(e) ? \ @@ -128,8 +129,133 @@ __bitset_next_set(unsigned i, BITSET_WORD *tmp, return word * BITSET_WORDBITS + bit; } -#define BITSET_FOREACH_SET(__i, __tmp, __set, __size) \ - for (__tmp = *(__set), __i = 0; \ - (__i = __bitset_next_set(__i, &__tmp, __set, __size)) < __size;) +/** + * Iterates over each set bit in a set + * + * @param __i iteration variable, bit number + * @param __set the bitset to iterate (will not be modified) + * @param __size number of bits in the set to consider + */ +#define BITSET_FOREACH_SET(__i, __set, __size) \ + for (BITSET_WORD __tmp = *(__set), *__foo = &__tmp; __foo != NULL; __foo = NULL) \ + for (__i = 0; \ + (__i = __bitset_next_set(__i, &__tmp, __set, __size)) < __size;) + +#ifdef __cplusplus + +/** + * Simple C++ wrapper of a bitset type of static size, with value semantics + * and basic bitwise arithmetic operators. The operators defined below are + * expected to have the same semantics as the same operator applied to other + * fundamental integer types. T is the name of the struct to instantiate + * it as, and N is the number of bits in the bitset. + */ +#define DECLARE_BITSET_T(T, N) struct T { \ + EXPLICIT_CONVERSION \ + operator bool() const \ + { \ + for (unsigned i = 0; i < BITSET_WORDS(N); i++) \ + if (words[i]) \ + return true; \ + return false; \ + } \ + \ + T & \ + operator=(int x) \ + { \ + const T c = {{ (BITSET_WORD)x }}; \ + return *this = c; \ + } \ + \ + friend bool \ + operator==(const T &b, const T &c) \ + { \ + return BITSET_EQUAL(b.words, c.words); \ + } \ + \ + friend bool \ + operator!=(const T &b, const T &c) \ + { \ + return !(b == c); \ + } \ + \ + friend bool \ + operator==(const T &b, int x) \ + { \ + const T c = {{ (BITSET_WORD)x }}; \ + return b == c; \ + } \ + \ + friend bool \ + operator!=(const T &b, int x) \ + { \ + return !(b == x); \ + } \ + \ + friend T \ + operator~(const T &b) \ + { \ + T c; \ + for (unsigned i = 0; i < BITSET_WORDS(N); i++) \ + c.words[i] = ~b.words[i]; \ + return c; \ + } \ + \ + T & \ + operator|=(const T &b) \ + { \ + for (unsigned i = 0; i < BITSET_WORDS(N); i++) \ + words[i] |= b.words[i]; \ + return *this; \ + } \ + \ + friend T \ + operator|(const T &b, const T &c) \ + { \ + T d = b; \ + d |= c; \ + return d; \ + } \ + \ + T & \ + operator&=(const T &b) \ + { \ + for (unsigned i = 0; i < BITSET_WORDS(N); i++) \ + words[i] &= b.words[i]; \ + return *this; \ + } \ + \ + friend T \ + operator&(const T &b, const T &c) \ + { \ + T d = b; \ + d &= c; \ + return d; \ + } \ + \ + bool \ + test(unsigned i) const \ + { \ + return BITSET_TEST(words, i); \ + } \ + \ + T & \ + set(unsigned i) \ + { \ + BITSET_SET(words, i); \ + return *this; \ + } \ + \ + T & \ + clear(unsigned i) \ + { \ + BITSET_CLEAR(words, i); \ + return *this; \ + } \ + \ + BITSET_WORD words[BITSET_WORDS(N)]; \ + } + +#endif #endif