Skip to content

Instantly share code, notes, and snippets.

@raalkml
Created July 6, 2010 10:35
Show Gist options
  • Save raalkml/465234 to your computer and use it in GitHub Desktop.
Save raalkml/465234 to your computer and use it in GitHub Desktop.
/* 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 will be the unshifted bit. 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);
}
}
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));
}
}
/* 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);
}
}
#endif /* _BITMAPS_H_ */
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment