]> git.ozlabs.org Git - ccan/blobdiff - junkcode/fork0@users.sf.net-bitmaps/bitmaps.h
More junkcode!
[ccan] / junkcode / fork0@users.sf.net-bitmaps / bitmaps.h
diff --git a/junkcode/fork0@users.sf.net-bitmaps/bitmaps.h b/junkcode/fork0@users.sf.net-bitmaps/bitmaps.h
new file mode 100644 (file)
index 0000000..05ecd96
--- /dev/null
@@ -0,0 +1,78 @@
+/* bitmaps and bitmap operations */
+#ifndef _BITMAPS_H_
+#define _BITMAPS_H_
+
+/*
+ * Bitmaps are arrays of unsigned ints, filled with bits in most-
+ * significant-first order. So bitmap[0] shall contain the bits from
+ * 0 to 31 on a 32bit architecture, bitmap[1] - 32-63, and so forth.
+ *
+ * The callers are responsible to do all the bounds-checking.
+ */
+enum { BITS_PER_BITMAP_ELEM = 8 * sizeof(unsigned) };
+
+typedef unsigned bitmap_elem_t;
+
+/* returned is the unshifted bit state. IOW: NOT 0 or 1, but something
+ * like 0x00001000 or 0x40000000 */
+static inline
+bitmap_elem_t bitmap_test_bit(const bitmap_elem_t* bits, unsigned bit)
+{
+    if ( sizeof(*bits) == 4 )
+       return bits[bit >> 5] & (0x80000000 >> (bit & 0x1f));
+    else if ( sizeof(*bits) == 8 )
+       return bits[bit >> 6] & (0x8000000000000000ull >> (bit & 0x3f));
+    else
+    {
+       return bits[bit / BITS_PER_BITMAP_ELEM] &
+           1 << ((BITS_PER_BITMAP_ELEM - bit % BITS_PER_BITMAP_ELEM) - 1);
+    }
+}
+
+static inline
+bitmap_elem_t bitmap_set_bit(bitmap_elem_t* bits, unsigned bit)
+{
+    if ( sizeof(*bits) == 4 )
+       return bits[bit >> 5] |= (0x80000000 >> (bit & 0x1f));
+    else if ( sizeof(*bits) == 8 )
+       return bits[bit >> 6] |= (0x8000000000000000ull >> (bit & 0x3f));
+    else
+    {
+       return bits[bit / BITS_PER_BITMAP_ELEM] |=
+           1 << ((BITS_PER_BITMAP_ELEM - bit % BITS_PER_BITMAP_ELEM) - 1);
+    }
+}
+
+/* pos must position the bits inside of a bitmap element, otherwise
+ * the index shift puts the bits in the wrong word (for simplicity).
+ * Only low 8 bits of b8 shall be used */
+static inline
+void bitmap_set_8bits_fast(bitmap_elem_t* bits, unsigned pos, unsigned b8)
+{
+    if ( sizeof(*bits) == 4 )
+       bits[pos >> 5] |= b8 << (24 - (pos & 0x1f));
+    else if ( sizeof(*bits) == 8 )
+       bits[pos >> 6] |= b8 << (56 - (pos & 0x3f));
+    else
+    {
+       bits[pos / BITS_PER_BITMAP_ELEM] |=
+           b8 << (BITS_PER_BITMAP_ELEM - 8 - pos % BITS_PER_BITMAP_ELEM);
+    }
+}
+
+static inline
+bitmap_elem_t bitmap_clear_bit(bitmap_elem_t* bits, unsigned bit)
+{
+    if ( sizeof(*bits) == 4 )
+       return bits[bit >> 5] &= ~(0x80000000 >> (bit & 0x1f));
+    else if ( sizeof(*bits) == 8 )
+       return bits[bit >> 6] &= ~(0x8000000000000000ull >> (bit & 0x3f));
+    else
+    {
+       return bits[bit / BITS_PER_BITMAP_ELEM] &=
+           ~(1 << ((BITS_PER_BITMAP_ELEM - bit % BITS_PER_BITMAP_ELEM) - 1));
+    }
+}
+
+#endif /* _BITMAPS_H_ */
+