Reduct  v4.0.5-1-g4851deb
A functional and immutable language.
Loading...
Searching...
No Matches
bitmap.h
Go to the documentation of this file.
1#ifndef REDUCT_BITMAP_H
2#define REDUCT_BITMAP_H 1
3
4#include <reduct/defs.h>
5
6/**
7 * @file bitmap.h
8 * @brief Bitmap utilities.
9 * @defgroup bitmap Bitmap
10 *
11 * @{
12 */
13
14typedef uint64_t reduct_bitmap_t; ///< A single word in a bitmap.
15
16#define REDUCT_BITMAP_WIDTH 64 ///< The number of bits in a bitmap word.
17
18#define REDUCT_BITMAP_INDEX_NONE (~(uint64_t)0) ///< Invalid bitmap index.
19
20/**
21 * @brief Calculate the number of 64-bit words needed for a bitmap of a given size.
22 *
23 * @param _size The number of bits.
24 */
25#define REDUCT_BITMAP_SIZE(_size) (((_size) + (REDUCT_BITMAP_WIDTH - 1)) / REDUCT_BITMAP_WIDTH)
26
27/**
28 * @brief Set a bit in a bitmap.
29 *
30 * @param _bitmap The bitmap array.
31 * @param _bit The bit index to set.
32 */
33#define REDUCT_BITMAP_SET(_bitmap, _bit) \
34 ((_bitmap)[(_bit) / REDUCT_BITMAP_WIDTH] |= (1ULL << ((_bit) % REDUCT_BITMAP_WIDTH)))
35
36/**
37 * @brief Clear a bit in a bitmap.
38 *
39 * @param _bitmap The bitmap array.
40 * @param _bit The bit index to clear.
41 */
42#define REDUCT_BITMAP_CLEAR(_bitmap, _bit) \
43 ((_bitmap)[(_bit) / REDUCT_BITMAP_WIDTH] &= ~(1ULL << ((_bit) % REDUCT_BITMAP_WIDTH)))
44
45/**
46 * @brief Check if a bit is set in a bitmap.
47 *
48 * @param _bitmap The bitmap array.
49 * @param _bit The bit index to check.
50 * @return Non-zero if the bit is set, zero otherwise.
51 */
52#define REDUCT_BITMAP_TEST(_bitmap, _bit) \
53 (((_bitmap)[(_bit) / REDUCT_BITMAP_WIDTH] & (1ULL << ((_bit) % REDUCT_BITMAP_WIDTH))) != 0)
54
55/**
56 * @brief Set a range of bits in a bitmap.
57 *
58 * @param bitmap The bitmap array.
59 * @param start The starting bit index to set.
60 * @param count The number of bits to set.
61 * @return The starting bit index that was set.
62 */
63static inline size_t reduct_bitmap_set_range(reduct_bitmap_t* bitmap, size_t start, size_t count)
64{
65 for (size_t i = 0; i < count; i++)
66 {
67 REDUCT_BITMAP_SET(bitmap, start + i);
68 }
69 return start;
70}
71
72/**
73 * @brief Find the first clear bit in a bitmap.
74 *
75 * @param bitmap The bitmap array.
76 * @param size The number of words in the bitmap array.
77 * @return The index of the first clear bit, or `REDUCT_BITMAP_INDEX_NONE` if all bits are set.
78 */
79static inline size_t reduct_bitmap_find_first_clear(const reduct_bitmap_t* bitmap, size_t size)
80{
81 for (size_t i = 0; i < size; i++)
82 {
83 if (bitmap[i] != ~(uint64_t)0)
84 {
85 for (uint32_t b = 0; b < REDUCT_BITMAP_WIDTH; b++)
86 {
87 if (!(bitmap[i] & (1ULL << b)))
88 {
89 return i * REDUCT_BITMAP_WIDTH + b;
90 }
91 }
92 }
93 }
95}
96
97/**
98 * @brief Find the next set bit in a bitmap starting from a given index.
99 *
100 * @param bitmap The bitmap array.
101 * @param size The number of words in the bitmap array.
102 * @param start The bit index to start searching from.
103 * @return The index of the next set bit, or `REDUCT_BITMAP_INDEX_NONE` if no more bits are set.
104 */
105static inline size_t reduct_bitmap_next_set(const reduct_bitmap_t* bitmap, size_t size, size_t start)
106{
107 size_t i = start / REDUCT_BITMAP_WIDTH;
108 if (i >= size)
109 {
111 }
112
113 uint32_t b = (uint32_t)(start % REDUCT_BITMAP_WIDTH);
114 reduct_bitmap_t word = bitmap[i] & (~0ULL << b);
115
116 if (word != 0)
117 {
118 for (; b < REDUCT_BITMAP_WIDTH; b++)
119 {
120 if (word & (1ULL << b))
121 {
122 return i * REDUCT_BITMAP_WIDTH + b;
123 }
124 }
125 }
126
127 for (i++; i < size; i++)
128 {
129 if (bitmap[i] != 0)
130 {
131 for (b = 0; b < REDUCT_BITMAP_WIDTH; b++)
132 {
133 if (bitmap[i] & (1ULL << b))
134 {
135 return i * REDUCT_BITMAP_WIDTH + b;
136 }
137 }
138 }
139 }
140
142}
143
144/**
145 * @brief Find the next clear bit in a bitmap starting from a given index.
146 *
147 * @param bitmap The bitmap array.
148 * @param size The number of words in the bitmap array.
149 * @param start The bit index to start searching from.
150 * @return The index of the next clear bit, or `REDUCT_BITMAP_INDEX_NONE` if no more bits are clear.
151 */
152static inline size_t reduct_bitmap_next_clear(const reduct_bitmap_t* bitmap, size_t size, size_t start)
153{
154 size_t i = start / REDUCT_BITMAP_WIDTH;
155 if (i >= size)
156 {
158 }
159
160 uint32_t b = (uint32_t)(start % REDUCT_BITMAP_WIDTH);
161 reduct_bitmap_t word = (~bitmap[i]) & (~0ULL << b);
162
163 if (word != 0)
164 {
165 for (; b < REDUCT_BITMAP_WIDTH; b++)
166 {
167 if (word & (1ULL << b))
168 {
169 return i * REDUCT_BITMAP_WIDTH + b;
170 }
171 }
172 }
173
174 for (i++; i < size; i++)
175 {
176 if (bitmap[i] != ~(uint64_t)0)
177 {
178 for (b = 0; b < REDUCT_BITMAP_WIDTH; b++)
179 {
180 if (!(bitmap[i] & (1ULL << b)))
181 {
182 return i * REDUCT_BITMAP_WIDTH + b;
183 }
184 }
185 }
186 }
187
189}
190
191/**
192 * @brief Find the last set bit in a bitmap.
193 *
194 * @param bitmap The bitmap array.
195 * @param size The number of words in the bitmap array.
196 * @return The index of the last set bit, or `REDUCT_BITMAP_INDEX_NONE` if all bits are clear.
197 */
198static inline size_t reduct_bitmap_find_last_set(const reduct_bitmap_t* bitmap, size_t size)
199{
200 if (size == 0)
201 {
203 }
204
205 for (size_t i = size; i > 0; i--)
206 {
207 size_t idx = i - 1;
208 if (bitmap[idx] != 0)
209 {
210 for (int32_t b = REDUCT_BITMAP_WIDTH - 1; b >= 0; b--)
211 {
212 if (bitmap[idx] & (1ULL << b))
213 {
214 return idx * REDUCT_BITMAP_WIDTH + (size_t)b;
215 }
216 }
217 }
218 }
220}
221
222/** @} */
223
224#endif
#define REDUCT_BITMAP_INDEX_NONE
Invalid bitmap index.
Definition bitmap.h:18
uint64_t reduct_bitmap_t
A single word in a bitmap.
Definition bitmap.h:14
#define REDUCT_BITMAP_SET(_bitmap, _bit)
Set a bit in a bitmap.
Definition bitmap.h:33
static size_t reduct_bitmap_next_clear(const reduct_bitmap_t *bitmap, size_t size, size_t start)
Find the next clear bit in a bitmap starting from a given index.
Definition bitmap.h:152
#define REDUCT_BITMAP_WIDTH
The number of bits in a bitmap word.
Definition bitmap.h:16
static size_t reduct_bitmap_set_range(reduct_bitmap_t *bitmap, size_t start, size_t count)
Set a range of bits in a bitmap.
Definition bitmap.h:63
static size_t reduct_bitmap_find_first_clear(const reduct_bitmap_t *bitmap, size_t size)
Find the first clear bit in a bitmap.
Definition bitmap.h:79
static size_t reduct_bitmap_find_last_set(const reduct_bitmap_t *bitmap, size_t size)
Find the last set bit in a bitmap.
Definition bitmap.h:198
static size_t reduct_bitmap_next_set(const reduct_bitmap_t *bitmap, size_t size, size_t start)
Find the next set bit in a bitmap starting from a given index.
Definition bitmap.h:105