rewrite: update default dumb and smart prefixes
[elinks/elinks-j605.git] / src / util / bitfield.h
blob53086104437c6bd25b4e0cf3ff4b8a47835c1d52
1 #ifndef EL__UTIL_BITFIELD_H
2 #define EL__UTIL_BITFIELD_H
4 #include <string.h>
6 #include "util/memory.h"
8 /* Bitfield operations: */
10 /** A vector of bits. The size is fixed at initialization time. */
11 struct bitfield {
12 unsigned int bitsize; /**< Number of bits in the bitfield. */
13 unsigned char bits[1]; /**< Strawberry bitfields forever. */
16 /** @relates bitfield */
17 #define foreach_bitfield_set(bit, bitfield) \
18 for ((bit) = 0; (bit) < (bitfield)->bitsize; (bit)++) \
19 if (test_bitfield_bit(bitfield, bit))
21 /** @relates bitfield */
22 #define foreachback_bitfield_set(bit, bitfield) \
23 for ((bit) = (bitfield)->bitsize; (bit) > 0;) \
24 if (test_bitfield_bit(bitfield, --bit))
26 /** @relates bitfield */
27 #define foreach_bitfield_cleared(bit, bitfield) \
28 for ((bit) = 0; (bit) < (bitfield)->bitsize; (bit)++) \
29 if (!test_bitfield_bit(bitfield, bit))
31 /* By shifting when getting the bit offset it is ensured that only one bit is
32 * set in the resulting value. Idea from libbt by Kevin Smathers. */
33 #define get_bitfield_bit_offset(bit) ((size_t) (0x80 >> ((bit) % 8)))
34 #define get_bitfield_byte_offset(bit) ((size_t) ((bit) / 8))
35 /* +7 to round up to nearest byte. */
36 #define get_bitfield_byte_size(bits) ((size_t) (((bits) + 7) / 8))
38 /** Allocate a bitfield containing @a bits number of bits.
39 * @relates bitfield */
40 static inline struct bitfield *
41 init_bitfield(size_t bits)
43 size_t size = get_bitfield_byte_size(bits);
44 struct bitfield *bitfield;
46 bitfield = mem_calloc(1, offsetof(struct bitfield, bits) + size);
47 if (bitfield) bitfield->bitsize = bits;
49 return bitfield;
52 /** Update @a bitfield with the @a bytesize bytes from the bit string
53 * in @a bits.
54 * @relates bitfield */
55 static inline void
56 copy_bitfield(struct bitfield *bitfield,
57 const unsigned char *bits, unsigned int bytesize)
59 /* Only for exact size? */
60 if (bytesize <= get_bitfield_byte_size(bitfield->bitsize))
61 memcpy(bitfield->bits, bits, bytesize);
64 /** Test whether @a bit is set in the @a bitfield.
65 * @relates bitfield */
66 static inline int
67 test_bitfield_bit(struct bitfield *bitfield, unsigned int bit)
69 size_t byte_offset, bit_offset;
71 if (bit >= bitfield->bitsize)
72 return 0;
74 byte_offset = get_bitfield_byte_offset(bit);
75 bit_offset = get_bitfield_bit_offset(bit);
77 return !!(bitfield->bits[byte_offset] & bit_offset);
80 /** Set @a bit in the @a bitfield.
81 * @relates bitfield */
82 static inline void
83 set_bitfield_bit(struct bitfield *bitfield, unsigned int bit)
85 size_t byte_offset, bit_offset;
87 if (bit >= bitfield->bitsize)
88 return;
90 byte_offset = get_bitfield_byte_offset(bit);
91 bit_offset = get_bitfield_bit_offset(bit);
93 bitfield->bits[byte_offset] |= bit_offset;
96 /** Unset @a bit in the @a bitfield.
97 * @relates bitfield */
98 static inline void
99 clear_bitfield_bit(struct bitfield *bitfield, unsigned int bit)
101 size_t byte_offset, bit_offset;
103 if (bit >= bitfield->bitsize)
104 return;
106 byte_offset = get_bitfield_byte_offset(bit);
107 bit_offset = get_bitfield_bit_offset(bit);
109 bitfield->bits[byte_offset] &= ~bit_offset;
112 /** Count the set bits in @a bitfield.
113 * @relates bitfield */
114 static inline unsigned int
115 get_bitfield_set_count(struct bitfield *bitfield)
117 unsigned int bit, count = 0;
119 foreach_bitfield_set (bit, bitfield)
120 count++;
122 return count;
125 /** Count the unset bits in @a bitfield.
126 * @relates bitfield */
127 static inline unsigned int
128 get_bitfield_cleared_count(struct bitfield *bitfield)
130 unsigned int bit, count = 0;
132 foreach_bitfield_cleared (bit, bitfield)
133 count++;
135 return count;
138 /** Check whether all bits of @a bitfield are set.
139 * @relates bitfield */
140 static inline unsigned int
141 bitfield_is_set(struct bitfield *bitfield)
143 unsigned int bit;
145 foreach_bitfield_cleared (bit, bitfield)
146 return 0;
148 return 1;
151 /** Check whether all bits of @a bitfield are unset.
152 * @relates bitfield */
153 static inline unsigned int
154 bitfield_is_cleared(struct bitfield *bitfield)
156 unsigned int bit;
158 foreach_bitfield_set (bit, bitfield)
159 return 0;
161 return 1;
164 #endif