bitset.h revision 7ec681f3
1/*
2 * Mesa 3-D graphics library
3 *
4 * Copyright (C) 2006  Brian Paul   All Rights Reserved.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the "Software"),
8 * to deal in the Software without restriction, including without limitation
9 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 * and/or sell copies of the Software, and to permit persons to whom the
11 * Software is furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included
14 * in all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
17 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
20 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22 * OTHER DEALINGS IN THE SOFTWARE.
23 */
24
25/**
26 * \file bitset.h
27 * \brief Bitset of arbitrary size definitions.
28 * \author Michal Krol
29 */
30
31#ifndef BITSET_H
32#define BITSET_H
33
34#include "util/bitscan.h"
35#include "util/macros.h"
36
37/****************************************************************************
38 * generic bitset implementation
39 */
40
41#define BITSET_WORD unsigned int
42#define BITSET_WORDBITS (sizeof (BITSET_WORD) * 8)
43
44/* bitset declarations
45 */
46#define BITSET_WORDS(bits) (((bits) + BITSET_WORDBITS - 1) / BITSET_WORDBITS)
47#define BITSET_DECLARE(name, bits) BITSET_WORD name[BITSET_WORDS(bits)]
48
49/* bitset operations
50 */
51#define BITSET_COPY(x, y) memcpy( (x), (y), sizeof (x) )
52#define BITSET_EQUAL(x, y) (memcmp( (x), (y), sizeof (x) ) == 0)
53#define BITSET_ZERO(x) memset( (x), 0, sizeof (x) )
54#define BITSET_ONES(x) memset( (x), 0xff, sizeof (x) )
55
56#define BITSET_BITWORD(b) ((b) / BITSET_WORDBITS)
57#define BITSET_BIT(b) (1u << ((b) % BITSET_WORDBITS))
58
59/* single bit operations
60 */
61#define BITSET_TEST(x, b) (((x)[BITSET_BITWORD(b)] & BITSET_BIT(b)) != 0)
62#define BITSET_SET(x, b) ((x)[BITSET_BITWORD(b)] |= BITSET_BIT(b))
63#define BITSET_CLEAR(x, b) ((x)[BITSET_BITWORD(b)] &= ~BITSET_BIT(b))
64
65#define BITSET_MASK(b) (((b) % BITSET_WORDBITS == 0) ? ~0 : BITSET_BIT(b) - 1)
66#define BITSET_RANGE(b, e) ((BITSET_MASK((e) + 1)) & ~(BITSET_BIT(b) - 1))
67
68/* logic bit operations
69 */
70static inline void
71__bitset_and(BITSET_WORD *r, const BITSET_WORD *x, const BITSET_WORD *y, unsigned n)
72{
73   for (unsigned i = 0; i < n; i++)
74      r[i] = x[i] & y[i];
75}
76
77static inline void
78__bitset_or(BITSET_WORD *r, const BITSET_WORD *x, const BITSET_WORD *y, unsigned n)
79{
80   for (unsigned i = 0; i < n; i++)
81      r[i] = x[i] | y[i];
82}
83
84static inline void
85__bitset_not(BITSET_WORD *x, unsigned n)
86{
87   for (unsigned i = 0; i < n; i++)
88      x[i] = ~x[i];
89}
90
91#define BITSET_AND(r, x, y)   \
92   do { \
93      assert(ARRAY_SIZE(r) == ARRAY_SIZE(x)); \
94      assert(ARRAY_SIZE(r) == ARRAY_SIZE(y)); \
95      __bitset_and(r, x, y, ARRAY_SIZE(r)); \
96   } while (0)
97
98#define BITSET_OR(r, x, y)   \
99   do { \
100      assert(ARRAY_SIZE(r) == ARRAY_SIZE(x)); \
101      assert(ARRAY_SIZE(r) == ARRAY_SIZE(y)); \
102      __bitset_or(r, x, y, ARRAY_SIZE(r)); \
103   } while (0)
104
105#define BITSET_NOT(x)   \
106   __bitset_not(x, ARRAY_SIZE(x))
107
108static inline void
109__bitset_rotate_right(BITSET_WORD *x, unsigned amount, unsigned n)
110{
111   assert(amount < BITSET_WORDBITS);
112
113   if (amount == 0)
114      return;
115
116   for (unsigned i = 0; i < n - 1; i++) {
117      x[i] = (x[i] >> amount) | (x[i + 1] << (BITSET_WORDBITS - amount));
118   }
119
120   x[n - 1] = x[n - 1] >> amount;
121}
122
123static inline void
124__bitset_rotate_left(BITSET_WORD *x, unsigned amount, unsigned n)
125{
126   assert(amount < BITSET_WORDBITS);
127
128   if (amount == 0)
129      return;
130
131   for (int i = n - 1; i > 0; i--) {
132      x[i] = (x[i] << amount) | (x[i - 1] >> (BITSET_WORDBITS - amount));
133   }
134
135   x[0] = x[0] << amount;
136}
137
138static inline void
139__bitset_shr(BITSET_WORD *x, unsigned amount, unsigned n)
140{
141   const unsigned int words = amount / BITSET_WORDBITS;
142
143   if (amount == 0)
144      return;
145
146   if (words) {
147      unsigned i;
148
149      for (i = 0; i < n - words; i++)
150         x[i] = x[i + words];
151
152      while (i < n)
153         x[i++] = 0;
154
155      amount %= BITSET_WORDBITS;
156   }
157
158   __bitset_rotate_right(x, amount, n);
159}
160
161
162static inline void
163__bitset_shl(BITSET_WORD *x, unsigned amount, unsigned n)
164{
165   const int words = amount / BITSET_WORDBITS;
166
167   if (amount == 0)
168      return;
169
170   if (words) {
171      int i;
172
173      for (i = n - 1; i >= words; i--) {
174         x[i] = x[i - words];
175      }
176
177      while (i >= 0) {
178         x[i--] = 0;
179      }
180
181      amount %= BITSET_WORDBITS;
182   }
183
184   __bitset_rotate_left(x, amount, n);
185}
186
187#define BITSET_SHR(x, n)   \
188   __bitset_shr(x, n, ARRAY_SIZE(x));
189
190#define BITSET_SHL(x, n)   \
191   __bitset_shl(x, n, ARRAY_SIZE(x));
192
193/* bit range operations
194 */
195#define BITSET_TEST_RANGE(x, b, e) \
196   (BITSET_BITWORD(b) == BITSET_BITWORD(e) ? \
197   (((x)[BITSET_BITWORD(b)] & BITSET_RANGE(b, e)) != 0) : \
198   (assert (!"BITSET_TEST_RANGE: bit range crosses word boundary"), 0))
199#define BITSET_SET_RANGE_INSIDE_WORD(x, b, e) \
200   (BITSET_BITWORD(b) == BITSET_BITWORD(e) ? \
201   ((x)[BITSET_BITWORD(b)] |= BITSET_RANGE(b, e)) : \
202   (assert (!"BITSET_SET_RANGE_INSIDE_WORD: bit range crosses word boundary"), 0))
203#define BITSET_CLEAR_RANGE(x, b, e) \
204   (BITSET_BITWORD(b) == BITSET_BITWORD(e) ? \
205   ((x)[BITSET_BITWORD(b)] &= ~BITSET_RANGE(b, e)) : \
206   (assert (!"BITSET_CLEAR_RANGE: bit range crosses word boundary"), 0))
207
208static inline void
209__bitset_set_range(BITSET_WORD *r, unsigned start, unsigned end)
210{
211   const unsigned size = end - start;
212   const unsigned start_mod = start % BITSET_WORDBITS;
213
214   if (start_mod + size <= BITSET_WORDBITS) {
215      BITSET_SET_RANGE_INSIDE_WORD(r, start, end);
216   } else {
217      const unsigned first_size = BITSET_WORDBITS - start_mod;
218
219      __bitset_set_range(r, start, start + first_size - 1);
220      __bitset_set_range(r, start + first_size, end);
221   }
222}
223
224#define BITSET_SET_RANGE(x, b, e) \
225   __bitset_set_range(x, b, e)
226
227static inline unsigned
228__bitset_prefix_sum(const BITSET_WORD *x, unsigned b, unsigned n)
229{
230   unsigned prefix = 0;
231
232   for (unsigned i = 0; i < n; i++) {
233      if ((i + 1) * BITSET_WORDBITS <= b) {
234         prefix += util_bitcount(x[i]);
235      } else {
236         prefix += util_bitcount(x[i] & BITFIELD_MASK(b - i * BITSET_WORDBITS));
237         break;
238      }
239   }
240   return prefix;
241}
242
243/* Count set bits in the bitset (compute the size/cardinality of the bitset).
244 * This is a special case of prefix sum, but this convenience method is more
245 * natural when applicable.
246 */
247
248static inline unsigned
249__bitset_count(const BITSET_WORD *x, unsigned n)
250{
251   return __bitset_prefix_sum(x, ~0, n);
252}
253
254#define BITSET_PREFIX_SUM(x, b) \
255   __bitset_prefix_sum(x, b, ARRAY_SIZE(x))
256
257#define BITSET_COUNT(x) \
258   __bitset_count(x, ARRAY_SIZE(x))
259
260/* Get first bit set in a bitset.
261 */
262static inline int
263__bitset_ffs(const BITSET_WORD *x, int n)
264{
265   int i;
266
267   for (i = 0; i < n; i++) {
268      if (x[i])
269	 return ffs(x[i]) + BITSET_WORDBITS * i;
270   }
271
272   return 0;
273}
274
275/* Get the last bit set in a bitset.
276 */
277static inline int
278__bitset_last_bit(const BITSET_WORD *x, int n)
279{
280   for (int i = n - 1; i >= 0; i--) {
281      if (x[i])
282         return util_last_bit(x[i]) + BITSET_WORDBITS * i;
283   }
284
285   return 0;
286}
287
288#define BITSET_FFS(x) __bitset_ffs(x, ARRAY_SIZE(x))
289#define BITSET_LAST_BIT(x) __bitset_last_bit(x, ARRAY_SIZE(x))
290#define BITSET_LAST_BIT_SIZED(x, size) __bitset_last_bit(x, size)
291
292static inline unsigned
293__bitset_next_set(unsigned i, BITSET_WORD *tmp,
294                  const BITSET_WORD *set, unsigned size)
295{
296   unsigned bit, word;
297
298   /* NOTE: The initial conditions for this function are very specific.  At
299    * the start of the loop, the tmp variable must be set to *set and the
300    * initial i value set to 0.  This way, if there is a bit set in the first
301    * word, we ignore the i-value and just grab that bit (so 0 is ok, even
302    * though 0 may be returned).  If the first word is 0, then the value of
303    * `word` will be 0 and we will go on to look at the second word.
304    */
305   word = BITSET_BITWORD(i);
306   while (*tmp == 0) {
307      word++;
308
309      if (word >= BITSET_WORDS(size))
310         return size;
311
312      *tmp = set[word];
313   }
314
315   /* Find the next set bit in the non-zero word */
316   bit = ffs(*tmp) - 1;
317
318   /* Unset the bit */
319   *tmp &= ~(1ull << bit);
320
321   return word * BITSET_WORDBITS + bit;
322}
323
324/**
325 * Iterates over each set bit in a set
326 *
327 * @param __i    iteration variable, bit number
328 * @param __set  the bitset to iterate (will not be modified)
329 * @param __size number of bits in the set to consider
330 */
331#define BITSET_FOREACH_SET(__i, __set, __size) \
332   for (BITSET_WORD __tmp = (__size) == 0 ? 0 : *(__set), *__foo = &__tmp; __foo != NULL; __foo = NULL) \
333      for (__i = 0; \
334           (__i = __bitset_next_set(__i, &__tmp, __set, __size)) < __size;)
335
336static inline void
337__bitset_next_range(unsigned *start, unsigned *end, const BITSET_WORD *set,
338                    unsigned size)
339{
340   /* To find the next start, start searching from end. In the first iteration
341    * it will be at 0, in every subsequent iteration it will be at the first
342    * 0-bit after the range.
343    */
344   unsigned word = BITSET_BITWORD(*end);
345   if (word >= BITSET_WORDS(size)) {
346      *start = *end = size;
347      return;
348   }
349   BITSET_WORD tmp = set[word] & ~(BITSET_BIT(*end) - 1);
350   while (!tmp) {
351      word++;
352      if (word >= BITSET_WORDS(size)) {
353         *start = *end = size;
354         return;
355      }
356      tmp = set[word];
357   }
358
359   *start = word * BITSET_WORDBITS + ffs(tmp) - 1;
360
361   /* Now do the opposite to find end. Here we can start at start + 1, because
362    * we know that the bit at start is 1 and we're searching for the first
363    * 0-bit.
364    */
365   word = BITSET_BITWORD(*start + 1);
366   if (word >= BITSET_WORDS(size)) {
367      *end = size;
368      return;
369   }
370   tmp = set[word] | (BITSET_BIT(*start + 1) - 1);
371   while (~tmp == 0) {
372      word++;
373      if (word >= BITSET_WORDS(size)) {
374         *end = size;
375         return;
376      }
377      tmp = set[word];
378   }
379
380   /* Cap "end" at "size" in case there are extra bits past "size" set in the
381    * word. This is only necessary for "end" because we terminate the loop if
382    * "start" goes past "size".
383    */
384   *end = MIN2(word * BITSET_WORDBITS + ffs(~tmp) - 1, size);
385}
386
387/**
388 * Iterates over each contiguous range of set bits in a set
389 *
390 * @param __start the first 1 bit of the current range
391 * @param __end   the bit after the last 1 bit of the current range
392 * @param __set   the bitset to iterate (will not be modified)
393 * @param __size  number of bits in the set to consider
394 */
395#define BITSET_FOREACH_RANGE(__start, __end, __set, __size) \
396   for (__start = 0, __end = 0, \
397        __bitset_next_range(&__start, &__end, __set, __size); \
398        __start < __size; \
399        __bitset_next_range(&__start, &__end, __set, __size))
400
401
402#ifdef __cplusplus
403
404/**
405 * Simple C++ wrapper of a bitset type of static size, with value semantics
406 * and basic bitwise arithmetic operators.  The operators defined below are
407 * expected to have the same semantics as the same operator applied to other
408 * fundamental integer types.  T is the name of the struct to instantiate
409 * it as, and N is the number of bits in the bitset.
410 */
411#define DECLARE_BITSET_T(T, N) struct T {                       \
412      EXPLICIT_CONVERSION                                       \
413      operator bool() const                                     \
414      {                                                         \
415         for (unsigned i = 0; i < BITSET_WORDS(N); i++)         \
416            if (words[i])                                       \
417               return true;                                     \
418         return false;                                          \
419      }                                                         \
420                                                                \
421      T &                                                       \
422      operator=(int x)                                          \
423      {                                                         \
424         const T c = {{ (BITSET_WORD)x }};                      \
425         return *this = c;                                      \
426      }                                                         \
427                                                                \
428      friend bool                                               \
429      operator==(const T &b, const T &c)                        \
430      {                                                         \
431         return BITSET_EQUAL(b.words, c.words);                 \
432      }                                                         \
433                                                                \
434      friend bool                                               \
435      operator!=(const T &b, const T &c)                        \
436      {                                                         \
437         return !(b == c);                                      \
438      }                                                         \
439                                                                \
440      friend bool                                               \
441      operator==(const T &b, int x)                             \
442      {                                                         \
443         const T c = {{ (BITSET_WORD)x }};                      \
444         return b == c;                                         \
445      }                                                         \
446                                                                \
447      friend bool                                               \
448      operator!=(const T &b, int x)                             \
449      {                                                         \
450         return !(b == x);                                      \
451      }                                                         \
452                                                                \
453      friend T                                                  \
454      operator~(const T &b)                                     \
455      {                                                         \
456         T c;                                                   \
457         for (unsigned i = 0; i < BITSET_WORDS(N); i++)         \
458            c.words[i] = ~b.words[i];                           \
459         return c;                                              \
460      }                                                         \
461                                                                \
462      T &                                                       \
463      operator|=(const T &b)                                    \
464      {                                                         \
465         for (unsigned i = 0; i < BITSET_WORDS(N); i++)         \
466            words[i] |= b.words[i];                             \
467         return *this;                                          \
468      }                                                         \
469                                                                \
470      friend T                                                  \
471      operator|(const T &b, const T &c)                         \
472      {                                                         \
473         T d = b;                                               \
474         d |= c;                                                \
475         return d;                                              \
476      }                                                         \
477                                                                \
478      T &                                                       \
479      operator&=(const T &b)                                    \
480      {                                                         \
481         for (unsigned i = 0; i < BITSET_WORDS(N); i++)         \
482            words[i] &= b.words[i];                             \
483         return *this;                                          \
484      }                                                         \
485                                                                \
486      friend T                                                  \
487      operator&(const T &b, const T &c)                         \
488      {                                                         \
489         T d = b;                                               \
490         d &= c;                                                \
491         return d;                                              \
492      }                                                         \
493                                                                \
494      bool                                                      \
495      test(unsigned i) const                                    \
496      {                                                         \
497         return BITSET_TEST(words, i);                          \
498      }                                                         \
499                                                                \
500      T &                                                       \
501      set(unsigned i)                                           \
502      {                                                         \
503         BITSET_SET(words, i);                                  \
504         return *this;                                          \
505      }                                                         \
506                                                                \
507      T &                                                       \
508      clear(unsigned i)                                         \
509      {                                                         \
510         BITSET_CLEAR(words, i);                                \
511         return *this;                                          \
512      }                                                         \
513                                                                \
514      BITSET_WORD words[BITSET_WORDS(N)];                       \
515   }
516
517#endif
518
519#endif
520