1 /* Licensed under LGPLv2+ - see LICENSE file for details */
10 typedef unsigned long bitmap_word;
12 #define BITMAP_WORD_BITS (sizeof(bitmap_word) * CHAR_BIT)
13 #define BITMAP_NWORDS(_n) (((_n) + BITMAP_WORD_BITS - 1) / BITMAP_WORD_BITS)
16 * We wrap each word in a structure for type checking.
22 static inline size_t bitmap_sizeof(int nbits)
24 return BITMAP_NWORDS(nbits) * sizeof(bitmap_word);
27 static inline bitmap *bitmap_alloc(int nbits)
29 return malloc(bitmap_sizeof(nbits));
32 #define BYTE(_bm, _n) (((unsigned char *)(_bm))[(_n) / CHAR_BIT])
33 #define BIT(_n) (0x80 >> ((_n) % 8))
34 #define WORD(_bm, _n) ((_bm)[(_n) / BITMAP_WORD_BITS].w)
36 #define BYTES(_nbits) ((_nbits) / 8)
37 #define BITS(_nbits) ((~(0xff >> ((_nbits) % 8))) & 0xff)
39 static inline void bitmap_set_bit(bitmap *bitmap, int n)
41 BYTE(bitmap, n) |= BIT(n);
44 static inline void bitmap_clear_bit(bitmap *bitmap, int n)
46 BYTE(bitmap, n) &= ~BIT(n);
49 static inline void bitmap_change_bit(bitmap *bitmap, int n)
51 BYTE(bitmap, n) ^= BIT(n);
54 static inline bool bitmap_test_bit(bitmap *bitmap, int n)
56 return !!(BYTE(bitmap, n) & BIT(n));
60 static inline void bitmap_zero(bitmap *bitmap, int nbits)
62 memset(bitmap, 0, BYTES(nbits));
64 BYTE(bitmap, nbits) &= ~BITS(nbits);
67 static inline void bitmap_fill(bitmap *bitmap, int nbits)
69 memset(bitmap, 0xff, BYTES(nbits));
71 BYTE(bitmap, nbits) |= BITS(nbits);
74 static inline void bitmap_copy(bitmap *dst, bitmap *src, int nbits)
76 memcpy(dst, src, BYTES(nbits));
78 BYTE(dst, nbits) &= ~BITS(nbits);
79 BYTE(dst, nbits) |= BYTE(src, nbits) & BITS(nbits);
83 #define DEF_BINOP(_name, _op) \
84 static inline void bitmap_##_name(bitmap *dst, bitmap *src1, bitmap *src2, \
88 while ((nbits - n) >= BITMAP_WORD_BITS) { \
89 WORD(dst, n) = WORD(src1, n) _op WORD(src2, n); \
90 n += BITMAP_WORD_BITS; \
92 while ((nbits - n) >= 8) { \
93 BYTE(dst, n) = BYTE(src1, n) _op BYTE(src2, n); \
97 BYTE(dst, nbits) &= ~BITS(nbits); \
98 BYTE(dst, nbits) |= (BYTE(src1, nbits) _op BYTE(src2, nbits)) \
106 DEF_BINOP(andnot, & ~)
110 static inline void bitmap_complement(bitmap *dst, bitmap *src, int nbits)
114 while ((nbits - n) >= BITMAP_WORD_BITS) {
115 WORD(dst, n) = ~WORD(src, n);
116 n += BITMAP_WORD_BITS;
118 while ((nbits - n) >= 8) {
119 BYTE(dst, n) = ~BYTE(src, n);
123 BYTE(dst, nbits) &= ~BITS(nbits);
124 BYTE(dst, nbits) |= ~BYTE(src, nbits) & BITS(nbits);
128 static inline bool bitmap_equal(bitmap *src1, bitmap *src2, int nbits)
130 if (memcmp(src1, src2, BYTES(nbits)) != 0)
132 if ((BYTE(src1, nbits) & BITS(nbits))
133 != (BYTE(src2, nbits) & BITS(nbits)))
138 static inline bool bitmap_intersects(bitmap *src1, bitmap *src2, int nbits)
142 while ((nbits - n) >= BITMAP_WORD_BITS) {
143 if (WORD(src1, n) & WORD(src2, n))
145 n += BITMAP_WORD_BITS;
147 while ((nbits - n) >= 8) {
148 if (BYTE(src1, n) & BYTE(src2, n))
152 if (BITS(nbits) & BYTE(src1, nbits) & BYTE(src2, nbits)) {
158 static inline bool bitmap_subset(bitmap *src1, bitmap *src2, int nbits)
162 while ((nbits - n) >= BITMAP_WORD_BITS) {
163 if (WORD(src1, n) & ~WORD(src2, n))
165 n += BITMAP_WORD_BITS;
167 while ((nbits - n) >= 8) {
168 if (BYTE(src1, n) & ~BYTE(src2, n))
172 if (BITS(nbits) & (BYTE(src1, nbits) & ~BYTE(src2, nbits))) {
178 static inline bool bitmap_full(bitmap *bitmap, int nbits)
182 while ((nbits - n) >= BITMAP_WORD_BITS) {
183 if (WORD(bitmap, n) != -1UL)
185 n += BITMAP_WORD_BITS;
187 while ((nbits - n) >= 8) {
188 if (BYTE(bitmap, n) != 0xff)
193 && ((BITS(nbits) & BYTE(bitmap, nbits)) != BITS(nbits))) {
199 static inline bool bitmap_empty(bitmap *bitmap, int nbits)
203 while ((nbits - n) >= BITMAP_WORD_BITS) {
206 n += BITMAP_WORD_BITS;
208 while ((nbits - n) >= 8) {
213 if (BITS(nbits) && ((BITS(nbits) & BYTE(bitmap, nbits)))) {
226 #endif /* CCAN_BITMAP_H_ */