Lely core libraries 2.3.2
bitset.c
Go to the documentation of this file.
1
24#include "util.h"
25
26#if !LELY_NO_MALLOC
27
28#include <lely/libc/strings.h>
29#include <lely/util/bitset.h>
30#include <lely/util/errnum.h>
31
32#include <assert.h>
33#include <stdlib.h>
34
35#undef INT_BIT
36#define INT_BIT (sizeof(int) * CHAR_BIT)
37
38int
39bitset_init(struct bitset *set, int size)
40{
41 assert(set);
42
43 size = MAX(0, (size + INT_BIT - 1) / INT_BIT);
44
45 unsigned int *bits = malloc(size * sizeof(unsigned int));
46 if (!bits && size) {
47#if !LELY_NO_ERRNO
48 set_errc(errno2c(errno));
49#endif
50 return -1;
51 }
52
53 set->size = size;
54 set->bits = bits;
55
56 return 0;
57}
58
59void
60bitset_fini(struct bitset *set)
61{
62 assert(set);
63
64 set->size = 0;
65 free(set->bits);
66 set->bits = NULL;
67}
68
69int
70bitset_size(const struct bitset *set)
71{
72 return set->size * INT_BIT;
73}
74
75int
76bitset_resize(struct bitset *set, int size)
77{
78 assert(set);
79 assert(set->size >= 0);
80
81 size = MAX(0, (size + INT_BIT - 1) / INT_BIT);
82
83 unsigned int *bits = realloc(set->bits, size * sizeof(unsigned int));
84 if (!bits && size) {
85#if !LELY_NO_ERRNO
86 set_errc(errno2c(errno));
87#endif
88 return 0;
89 }
90
91 // If the size increased, clear the new bits.
92 for (int i = set->size; i < size; i++)
93 bits[i] = 0;
94
95 set->size = size;
96 set->bits = bits;
97
98 return bitset_size(set);
99}
100
101int
102bitset_get_size(const struct bitset *set)
103{
104 return set->size * INT_BIT;
105}
106
107int
108bitset_test(const struct bitset *set, int n)
109{
110 if (n < 0 || n >= bitset_size(set))
111 return 0;
112 return (set->bits[n / INT_BIT] >> (n & (INT_BIT - 1))) & 1u;
113}
114
115void
116bitset_set(struct bitset *set, int n)
117{
118 if (n < 0 || n >= bitset_size(set))
119 return;
120 set->bits[n / INT_BIT] |= 1u << (n & (INT_BIT - 1));
121}
122
123void
125{
126 for (int i = 0; i < set->size; i++)
127 set->bits[i] = ~0u;
128}
129
130void
131bitset_clr(struct bitset *set, int n)
132{
133 if (n < 0 || n >= bitset_size(set))
134 return;
135 set->bits[n / INT_BIT] &= ~(1u << (n & (INT_BIT - 1)));
136}
137
138void
140{
141 for (int i = 0; i < set->size; i++)
142 set->bits[i] = 0;
143}
144
145void
147{
148 for (int i = 0; i < set->size; i++)
149 set->bits[i] = ~set->bits[i];
150}
151
152int
153bitset_ffs(const struct bitset *set)
154{
155 const unsigned int *bits = set->bits;
156 int offset = 0;
157 for (int i = 0; i < set->size; i++) {
158 unsigned int x = *bits++;
159 if (x)
160 return offset + ffs(x);
161 offset += INT_BIT;
162 }
163 return 0;
164}
165
166int
167bitset_ffz(const struct bitset *set)
168{
169 const unsigned int *bits = set->bits;
170 int offset = 0;
171 for (int i = 0; i < set->size; i++) {
172 unsigned int x = *bits++;
173 if (~x)
174 return offset + ffs(~x);
175 offset += INT_BIT;
176 }
177 return 0;
178}
179
180int
181bitset_fns(const struct bitset *set, int n)
182{
183 if (n < 0)
184 n = 0;
185 if (n >= bitset_size(set))
186 return 0;
187
188 int size = set->size - n / INT_BIT;
189 const unsigned int *bits = set->bits + n / INT_BIT;
190 int offset = n & ~(INT_BIT - 1);
191 n -= offset;
192 while (size) {
193 unsigned int x = *bits++;
194 if (n) {
195 // Clear the bits smaller than n.
196 x &= ~0u << n;
197 n = 0;
198 }
199 if (x)
200 return offset + ffs(x);
201 size--;
202 offset += INT_BIT;
203 }
204 return 0;
205}
206
207int
208bitset_fnz(const struct bitset *set, int n)
209{
210 if (n < 0)
211 n = 0;
212 if (n >= bitset_size(set))
213 return 0;
214
215 int size = set->size - n / INT_BIT;
216 const unsigned int *bits = set->bits + n / INT_BIT;
217 int offset = n & ~(INT_BIT - 1);
218 n -= offset;
219 while (size) {
220 unsigned int x = *bits++;
221 if (n) {
222 // Set the bits smaller than n.
223 x |= ~0u >> (INT_BIT - n);
224 n = 0;
225 }
226 if (~x)
227 return offset + ffs(~x);
228 size--;
229 offset += INT_BIT;
230 }
231 return 0;
232}
233
234#endif // !LELY_NO_MALLOC
int bitset_ffs(const struct bitset *set)
Returns the index (starting from one) of the first set bit in set, or 0 if all bits are zero.
Definition: bitset.c:153
int bitset_test(const struct bitset *set, int n)
Returns 1 if bit n in set is set, and 0 otherwise.
Definition: bitset.c:108
int bitset_size(const struct bitset *set)
Returns the size (in number of bits) of set.
Definition: bitset.c:70
int bitset_ffz(const struct bitset *set)
Returns the index (starting from one) of the first zero bit in set, or 0 if all bits are set.
Definition: bitset.c:167
int bitset_resize(struct bitset *set, int size)
Resizes a bitset.
Definition: bitset.c:76
void bitset_set(struct bitset *set, int n)
Sets bit n in set.
Definition: bitset.c:116
int bitset_fnz(const struct bitset *set, int n)
Returns the index (starting from one) of the first zero bit higher or equal to n in set,...
Definition: bitset.c:208
void bitset_compl(struct bitset *set)
Flip all bits in set.
Definition: bitset.c:146
void bitset_clr_all(struct bitset *set)
Clears all bits in set.
Definition: bitset.c:139
void bitset_clr(struct bitset *set, int n)
Clears bit n in set.
Definition: bitset.c:131
void bitset_fini(struct bitset *set)
Finalizes a bitset.
Definition: bitset.c:60
int bitset_init(struct bitset *set, int size)
Initializes a bitset.
Definition: bitset.c:39
int bitset_fns(const struct bitset *set, int n)
Returns the index (starting from one) of the first set bit higher or equal to n in set,...
Definition: bitset.c:181
void bitset_set_all(struct bitset *set)
Sets all bits in set.
Definition: bitset.c:124
This header file is part of the utilities library; it contains the bitset declarations.
This header file is part of the utilities library; it contains the native and platform-independent er...
void set_errc(int errc)
Sets the current (thread-specific) native error code to errc.
Definition: errnum.c:944
int errno2c(int errnum)
Transforms a standard C error number to a native error code.
Definition: errnum.c:46
#define MAX(a, b)
Returns the maximum of a and b.
Definition: util.h:65
This is the internal header file of the utilities library.
This header file is part of the C11 and POSIX compatibility library; it includes <stdlib....
This header file is part of the C11 and POSIX compatibility library; it includes <strings....
int ffs(int i)
Finds the index of the first (least significant) bit set in i.
Definition: strings.h:58
A variable-sized bitset.
Definition: bitset.h:28
unsigned int * bits
An array of size integers.
Definition: bitset.h:32
int size
The number of integers in bits.
Definition: bitset.h:30