]> git.ozlabs.org Git - ccan/blobdiff - ccan/bitmap/bitmap.h
bitmap: Rework types and sizing macros
[ccan] / ccan / bitmap / bitmap.h
index 4c6c9507f859886465c06cfad62fd5f940c6e2ee..4189fbd4392a922fccf34062fb21bf1e261a1d13 100644 (file)
@@ -5,52 +5,73 @@
 #include <stdbool.h>
 #include <stdlib.h>
 #include <string.h>
+#include <limits.h>
 
-#define BITS_PER_LONG  (sizeof(unsigned long) * 8)
+typedef unsigned long bitmap_word;
 
-#define BYTE(_bm, _n)  (((unsigned char *)(_bm))[(_n) / 8])
-#define LONG(_bm, _n)  (((unsigned long *)(_bm))[(_n) / BITS_PER_LONG])
+#define BITMAP_WORD_BITS       (sizeof(bitmap_word) * CHAR_BIT)
+#define BITMAP_NWORDS(_n)      (((_n) + BITMAP_WORD_BITS - 1) / BITMAP_WORD_BITS)
+
+/*
+ * We wrap each word in a structure for type checking.
+ */
+typedef struct {
+       bitmap_word w;
+} bitmap;
+
+static inline size_t bitmap_sizeof(int nbits)
+{
+       return BITMAP_NWORDS(nbits) * sizeof(bitmap_word);
+}
+
+static inline bitmap *bitmap_alloc(int nbits)
+{
+       return malloc(bitmap_sizeof(nbits));
+}
+
+#define BYTE(_bm, _n)  (((unsigned char *)(_bm))[(_n) / CHAR_BIT])
 #define BIT(_n)                (0x80 >> ((_n) % 8))
+#define WORD(_bm, _n)  ((_bm)[(_n) / BITMAP_WORD_BITS].w)
 
 #define BYTES(_nbits)  ((_nbits) / 8)
 #define BITS(_nbits)   ((~(0xff >> ((_nbits) % 8))) & 0xff)
 
-static inline void bitmap_set_bit(void *bitmap, int n)
+static inline void bitmap_set_bit(bitmap *bitmap, int n)
 {
        BYTE(bitmap, n) |= BIT(n);
 }
 
-static inline void bitmap_clear_bit(void *bitmap, int n)
+static inline void bitmap_clear_bit(bitmap *bitmap, int n)
 {
        BYTE(bitmap, n) &= ~BIT(n);
 }
 
-static inline void bitmap_change_bit(void *bitmap, int n)
+static inline void bitmap_change_bit(bitmap *bitmap, int n)
 {
        BYTE(bitmap, n) ^= BIT(n);
 }
 
-static inline bool bitmap_test_bit(void *bitmap, int n)
+static inline bool bitmap_test_bit(bitmap *bitmap, int n)
 {
        return !!(BYTE(bitmap, n) & BIT(n));
 }
 
 
-static inline void bitmap_zero(void *bitmap, int nbits)
+static inline void bitmap_zero(bitmap *bitmap, int nbits)
 {
        memset(bitmap, 0, BYTES(nbits));
        if (BITS(nbits))
                BYTE(bitmap, nbits) &= ~BITS(nbits);
 }
 
-static inline void bitmap_fill(void *bitmap, int nbits)
+static inline void bitmap_fill(bitmap *bitmap, int nbits)
 {
        memset(bitmap, 0xff, BYTES(nbits));
        if (BITS(nbits))
                BYTE(bitmap, nbits) |= BITS(nbits);
 }
 
-static inline void bitmap_copy(void *dst, void *src, int nbits)
+static inline void bitmap_copy(bitmap *dst, bitmap *src, int nbits)
 {
        memcpy(dst, src, BYTES(nbits));
        if (BITS(nbits)) {
@@ -60,13 +81,13 @@ static inline void bitmap_copy(void *dst, void *src, int nbits)
 }
 
 #define DEF_BINOP(_name, _op) \
-       static inline void bitmap_##_name(void *dst, void *src1, void *src2, \
+       static inline void bitmap_##_name(bitmap *dst, bitmap *src1, bitmap *src2, \
                                         int nbits) \
        { \
                int n = 0; \
-               while ((nbits - n) >= BITS_PER_LONG) { \
-                       LONG(dst, n) = LONG(src1, n) _op LONG(src2, n); \
-                       n += BITS_PER_LONG; \
+               while ((nbits - n) >= BITMAP_WORD_BITS) { \
+                       WORD(dst, n) = WORD(src1, n) _op WORD(src2, n); \
+                       n += BITMAP_WORD_BITS; \
                } \
                while ((nbits - n) >= 8) { \
                        BYTE(dst, n) = BYTE(src1, n) _op BYTE(src2, n); \
@@ -86,13 +107,13 @@ DEF_BINOP(andnot, & ~)
 
 #undef DEF_BINOP
 
-static inline void bitmap_complement(void *dst, void *src, int nbits)
+static inline void bitmap_complement(bitmap *dst, bitmap *src, int nbits)
 {
        int n = 0;
 
-       while ((nbits - n) >= BITS_PER_LONG) {
-               LONG(dst, n) = ~LONG(src, n);
-               n += BITS_PER_LONG;
+       while ((nbits - n) >= BITMAP_WORD_BITS) {
+               WORD(dst, n) = ~WORD(src, n);
+               n += BITMAP_WORD_BITS;
        }
        while ((nbits - n) >= 8) {
                BYTE(dst, n) = ~BYTE(src, n);
@@ -104,7 +125,7 @@ static inline void bitmap_complement(void *dst, void *src, int nbits)
        }
 }
 
-static inline bool bitmap_equal(void *src1, void *src2, int nbits)
+static inline bool bitmap_equal(bitmap *src1, bitmap *src2, int nbits)
 {
        if (memcmp(src1, src2, BYTES(nbits)) != 0)
                return false;
@@ -114,14 +135,14 @@ static inline bool bitmap_equal(void *src1, void *src2, int nbits)
        return true;
 }
 
-static inline bool bitmap_intersects(void *src1, void *src2, int nbits)
+static inline bool bitmap_intersects(bitmap *src1, bitmap *src2, int nbits)
 {
        int n = 0;
 
-       while ((nbits - n) >= BITS_PER_LONG) {
-               if (LONG(src1, n) & LONG(src2, n))
+       while ((nbits - n) >= BITMAP_WORD_BITS) {
+               if (WORD(src1, n) & WORD(src2, n))
                        return true;
-               n += BITS_PER_LONG;
+               n += BITMAP_WORD_BITS;
        }
        while ((nbits - n) >= 8) {
                if (BYTE(src1, n) & BYTE(src2, n))
@@ -134,14 +155,14 @@ static inline bool bitmap_intersects(void *src1, void *src2, int nbits)
        return false;
 }
 
-static inline bool bitmap_subset(void *src1, void *src2, int nbits)
+static inline bool bitmap_subset(bitmap *src1, bitmap *src2, int nbits)
 {
        int n = 0;
 
-       while ((nbits - n) >= BITS_PER_LONG) {
-               if (LONG(src1, n) & ~LONG(src2, n))
+       while ((nbits - n) >= BITMAP_WORD_BITS) {
+               if (WORD(src1, n) & ~WORD(src2, n))
                        return false;
-               n += BITS_PER_LONG;
+               n += BITMAP_WORD_BITS;
        }
        while ((nbits - n) >= 8) {
                if (BYTE(src1, n) & ~BYTE(src2, n))
@@ -154,14 +175,14 @@ static inline bool bitmap_subset(void *src1, void *src2, int nbits)
        return true;
 }
 
-static inline bool bitmap_full(void *bitmap, int nbits)
+static inline bool bitmap_full(bitmap *bitmap, int nbits)
 {
        int n = 0;
 
-       while ((nbits - n) >= BITS_PER_LONG) {
-               if (LONG(bitmap, n) != -1UL)
+       while ((nbits - n) >= BITMAP_WORD_BITS) {
+               if (WORD(bitmap, n) != -1UL)
                        return false;
-               n += BITS_PER_LONG;
+               n += BITMAP_WORD_BITS;
        }
        while ((nbits - n) >= 8) {
                if (BYTE(bitmap, n) != 0xff)
@@ -175,14 +196,14 @@ static inline bool bitmap_full(void *bitmap, int nbits)
        return true;
 }
 
-static inline bool bitmap_empty(void *bitmap, int nbits)
+static inline bool bitmap_empty(bitmap *bitmap, int nbits)
 {
        int n = 0;
 
-       while ((nbits - n) >= BITS_PER_LONG) {
-               if (LONG(bitmap, n))
+       while ((nbits - n) >= BITMAP_WORD_BITS) {
+               if (WORD(bitmap, n))
                        return false;
-               n += BITS_PER_LONG;
+               n += BITMAP_WORD_BITS;
        }
        while ((nbits - n) >= 8) {
                if (BYTE(bitmap, n))
@@ -196,13 +217,8 @@ static inline bool bitmap_empty(void *bitmap, int nbits)
 }
 
 
-static inline void *bitmap_alloc(int nbits)
-{
-       return malloc((nbits + 7) / 8);
-}
-
 #undef BYTE
-#undef LONG
+#undef WORD
 #undef BIT
 #undef BYTES
 #undef BITS