1b8e80941Smrg/*
2b8e80941Smrg * Mesa 3-D graphics library
3b8e80941Smrg *
4b8e80941Smrg * Copyright (C) 2006  Brian Paul   All Rights Reserved.
5b8e80941Smrg *
6b8e80941Smrg * Permission is hereby granted, free of charge, to any person obtaining a
7b8e80941Smrg * copy of this software and associated documentation files (the "Software"),
8b8e80941Smrg * to deal in the Software without restriction, including without limitation
9b8e80941Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10b8e80941Smrg * and/or sell copies of the Software, and to permit persons to whom the
11b8e80941Smrg * Software is furnished to do so, subject to the following conditions:
12b8e80941Smrg *
13b8e80941Smrg * The above copyright notice and this permission notice shall be included
14b8e80941Smrg * in all copies or substantial portions of the Software.
15b8e80941Smrg *
16b8e80941Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
17b8e80941Smrg * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18b8e80941Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
19b8e80941Smrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
20b8e80941Smrg * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21b8e80941Smrg * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22b8e80941Smrg * OTHER DEALINGS IN THE SOFTWARE.
23b8e80941Smrg */
24b8e80941Smrg
25b8e80941Smrg/**
26b8e80941Smrg * \file bitset.h
27b8e80941Smrg * \brief Bitset of arbitrary size definitions.
28b8e80941Smrg * \author Michal Krol
29b8e80941Smrg */
30b8e80941Smrg
31b8e80941Smrg#ifndef BITSET_H
32b8e80941Smrg#define BITSET_H
33b8e80941Smrg
34b8e80941Smrg#include "util/bitscan.h"
35b8e80941Smrg#include "util/macros.h"
36b8e80941Smrg
37b8e80941Smrg/****************************************************************************
38b8e80941Smrg * generic bitset implementation
39b8e80941Smrg */
40b8e80941Smrg
41b8e80941Smrg#define BITSET_WORD unsigned int
42b8e80941Smrg#define BITSET_WORDBITS (sizeof (BITSET_WORD) * 8)
43b8e80941Smrg
44b8e80941Smrg/* bitset declarations
45b8e80941Smrg */
46b8e80941Smrg#define BITSET_WORDS(bits) (((bits) + BITSET_WORDBITS - 1) / BITSET_WORDBITS)
47b8e80941Smrg#define BITSET_DECLARE(name, bits) BITSET_WORD name[BITSET_WORDS(bits)]
48b8e80941Smrg
49b8e80941Smrg/* bitset operations
50b8e80941Smrg */
51b8e80941Smrg#define BITSET_COPY(x, y) memcpy( (x), (y), sizeof (x) )
52b8e80941Smrg#define BITSET_EQUAL(x, y) (memcmp( (x), (y), sizeof (x) ) == 0)
53b8e80941Smrg#define BITSET_ZERO(x) memset( (x), 0, sizeof (x) )
54b8e80941Smrg#define BITSET_ONES(x) memset( (x), 0xff, sizeof (x) )
55b8e80941Smrg
56b8e80941Smrg#define BITSET_BITWORD(b) ((b) / BITSET_WORDBITS)
57b8e80941Smrg#define BITSET_BIT(b) (1u << ((b) % BITSET_WORDBITS))
58b8e80941Smrg
59b8e80941Smrg/* single bit operations
60b8e80941Smrg */
61b8e80941Smrg#define BITSET_TEST(x, b) (((x)[BITSET_BITWORD(b)] & BITSET_BIT(b)) != 0)
62b8e80941Smrg#define BITSET_SET(x, b) ((x)[BITSET_BITWORD(b)] |= BITSET_BIT(b))
63b8e80941Smrg#define BITSET_CLEAR(x, b) ((x)[BITSET_BITWORD(b)] &= ~BITSET_BIT(b))
64b8e80941Smrg
65b8e80941Smrg#define BITSET_MASK(b) (((b) % BITSET_WORDBITS == 0) ? ~0 : BITSET_BIT(b) - 1)
66b8e80941Smrg#define BITSET_RANGE(b, e) ((BITSET_MASK((e) + 1)) & ~(BITSET_BIT(b) - 1))
67b8e80941Smrg
68b8e80941Smrg/* bit range operations
69b8e80941Smrg */
70b8e80941Smrg#define BITSET_TEST_RANGE(x, b, e) \
71b8e80941Smrg   (BITSET_BITWORD(b) == BITSET_BITWORD(e) ? \
72b8e80941Smrg   (((x)[BITSET_BITWORD(b)] & BITSET_RANGE(b, e)) != 0) : \
73b8e80941Smrg   (assert (!"BITSET_TEST_RANGE: bit range crosses word boundary"), 0))
74b8e80941Smrg#define BITSET_SET_RANGE(x, b, e) \
75b8e80941Smrg   (BITSET_BITWORD(b) == BITSET_BITWORD(e) ? \
76b8e80941Smrg   ((x)[BITSET_BITWORD(b)] |= BITSET_RANGE(b, e)) : \
77b8e80941Smrg   (assert (!"BITSET_SET_RANGE: bit range crosses word boundary"), 0))
78b8e80941Smrg#define BITSET_CLEAR_RANGE(x, b, e) \
79b8e80941Smrg   (BITSET_BITWORD(b) == BITSET_BITWORD(e) ? \
80b8e80941Smrg   ((x)[BITSET_BITWORD(b)] &= ~BITSET_RANGE(b, e)) : \
81b8e80941Smrg   (assert (!"BITSET_CLEAR_RANGE: bit range crosses word boundary"), 0))
82b8e80941Smrg
83b8e80941Smrg/* Get first bit set in a bitset.
84b8e80941Smrg */
85b8e80941Smrgstatic inline int
86b8e80941Smrg__bitset_ffs(const BITSET_WORD *x, int n)
87b8e80941Smrg{
88b8e80941Smrg   int i;
89b8e80941Smrg
90b8e80941Smrg   for (i = 0; i < n; i++) {
91b8e80941Smrg      if (x[i])
92b8e80941Smrg	 return ffs(x[i]) + BITSET_WORDBITS * i;
93b8e80941Smrg   }
94b8e80941Smrg
95b8e80941Smrg   return 0;
96b8e80941Smrg}
97b8e80941Smrg
98b8e80941Smrg#define BITSET_FFS(x) __bitset_ffs(x, ARRAY_SIZE(x))
99b8e80941Smrg
100b8e80941Smrgstatic inline unsigned
101b8e80941Smrg__bitset_next_set(unsigned i, BITSET_WORD *tmp,
102b8e80941Smrg                  const BITSET_WORD *set, unsigned size)
103b8e80941Smrg{
104b8e80941Smrg   unsigned bit, word;
105b8e80941Smrg
106b8e80941Smrg   /* NOTE: The initial conditions for this function are very specific.  At
107b8e80941Smrg    * the start of the loop, the tmp variable must be set to *set and the
108b8e80941Smrg    * initial i value set to 0.  This way, if there is a bit set in the first
109b8e80941Smrg    * word, we ignore the i-value and just grab that bit (so 0 is ok, even
110b8e80941Smrg    * though 0 may be returned).  If the first word is 0, then the value of
111b8e80941Smrg    * `word` will be 0 and we will go on to look at the second word.
112b8e80941Smrg    */
113b8e80941Smrg   word = BITSET_BITWORD(i);
114b8e80941Smrg   while (*tmp == 0) {
115b8e80941Smrg      word++;
116b8e80941Smrg
117b8e80941Smrg      if (word >= BITSET_WORDS(size))
118b8e80941Smrg         return size;
119b8e80941Smrg
120b8e80941Smrg      *tmp = set[word];
121b8e80941Smrg   }
122b8e80941Smrg
123b8e80941Smrg   /* Find the next set bit in the non-zero word */
124b8e80941Smrg   bit = ffs(*tmp) - 1;
125b8e80941Smrg
126b8e80941Smrg   /* Unset the bit */
127b8e80941Smrg   *tmp &= ~(1ull << bit);
128b8e80941Smrg
129b8e80941Smrg   return word * BITSET_WORDBITS + bit;
130b8e80941Smrg}
131b8e80941Smrg
132b8e80941Smrg#define BITSET_FOREACH_SET(__i, __tmp, __set, __size) \
133b8e80941Smrg   for (__tmp = *(__set), __i = 0; \
134b8e80941Smrg        (__i = __bitset_next_set(__i, &__tmp, __set, __size)) < __size;)
135b8e80941Smrg
136b8e80941Smrg#ifdef __cplusplus
137b8e80941Smrg
138b8e80941Smrg/**
139b8e80941Smrg * Simple C++ wrapper of a bitset type of static size, with value semantics
140b8e80941Smrg * and basic bitwise arithmetic operators.  The operators defined below are
141b8e80941Smrg * expected to have the same semantics as the same operator applied to other
142b8e80941Smrg * fundamental integer types.  T is the name of the struct to instantiate
143b8e80941Smrg * it as, and N is the number of bits in the bitset.
144b8e80941Smrg */
145b8e80941Smrg#define DECLARE_BITSET_T(T, N) struct T {                       \
146b8e80941Smrg      EXPLICIT_CONVERSION                                       \
147b8e80941Smrg      operator bool() const                                     \
148b8e80941Smrg      {                                                         \
149b8e80941Smrg         for (unsigned i = 0; i < BITSET_WORDS(N); i++)         \
150b8e80941Smrg            if (words[i])                                       \
151b8e80941Smrg               return true;                                     \
152b8e80941Smrg         return false;                                          \
153b8e80941Smrg      }                                                         \
154b8e80941Smrg                                                                \
155b8e80941Smrg      T &                                                       \
156b8e80941Smrg      operator=(int x)                                          \
157b8e80941Smrg      {                                                         \
158b8e80941Smrg         const T c = {{ (BITSET_WORD)x }};                      \
159b8e80941Smrg         return *this = c;                                      \
160b8e80941Smrg      }                                                         \
161b8e80941Smrg                                                                \
162b8e80941Smrg      friend bool                                               \
163b8e80941Smrg      operator==(const T &b, const T &c)                        \
164b8e80941Smrg      {                                                         \
165b8e80941Smrg         return BITSET_EQUAL(b.words, c.words);                 \
166b8e80941Smrg      }                                                         \
167b8e80941Smrg                                                                \
168b8e80941Smrg      friend bool                                               \
169b8e80941Smrg      operator!=(const T &b, const T &c)                        \
170b8e80941Smrg      {                                                         \
171b8e80941Smrg         return !(b == c);                                      \
172b8e80941Smrg      }                                                         \
173b8e80941Smrg                                                                \
174b8e80941Smrg      friend bool                                               \
175b8e80941Smrg      operator==(const T &b, int x)                             \
176b8e80941Smrg      {                                                         \
177b8e80941Smrg         const T c = {{ (BITSET_WORD)x }};                      \
178b8e80941Smrg         return b == c;                                         \
179b8e80941Smrg      }                                                         \
180b8e80941Smrg                                                                \
181b8e80941Smrg      friend bool                                               \
182b8e80941Smrg      operator!=(const T &b, int x)                             \
183b8e80941Smrg      {                                                         \
184b8e80941Smrg         return !(b == x);                                      \
185b8e80941Smrg      }                                                         \
186b8e80941Smrg                                                                \
187b8e80941Smrg      friend T                                                  \
188b8e80941Smrg      operator~(const T &b)                                     \
189b8e80941Smrg      {                                                         \
190b8e80941Smrg         T c;                                                   \
191b8e80941Smrg         for (unsigned i = 0; i < BITSET_WORDS(N); i++)         \
192b8e80941Smrg            c.words[i] = ~b.words[i];                           \
193b8e80941Smrg         return c;                                              \
194b8e80941Smrg      }                                                         \
195b8e80941Smrg                                                                \
196b8e80941Smrg      T &                                                       \
197b8e80941Smrg      operator|=(const T &b)                                    \
198b8e80941Smrg      {                                                         \
199b8e80941Smrg         for (unsigned i = 0; i < BITSET_WORDS(N); i++)         \
200b8e80941Smrg            words[i] |= b.words[i];                             \
201b8e80941Smrg         return *this;                                          \
202b8e80941Smrg      }                                                         \
203b8e80941Smrg                                                                \
204b8e80941Smrg      friend T                                                  \
205b8e80941Smrg      operator|(const T &b, const T &c)                         \
206b8e80941Smrg      {                                                         \
207b8e80941Smrg         T d = b;                                               \
208b8e80941Smrg         d |= c;                                                \
209b8e80941Smrg         return d;                                              \
210b8e80941Smrg      }                                                         \
211b8e80941Smrg                                                                \
212b8e80941Smrg      T &                                                       \
213b8e80941Smrg      operator&=(const T &b)                                    \
214b8e80941Smrg      {                                                         \
215b8e80941Smrg         for (unsigned i = 0; i < BITSET_WORDS(N); i++)         \
216b8e80941Smrg            words[i] &= b.words[i];                             \
217b8e80941Smrg         return *this;                                          \
218b8e80941Smrg      }                                                         \
219b8e80941Smrg                                                                \
220b8e80941Smrg      friend T                                                  \
221b8e80941Smrg      operator&(const T &b, const T &c)                         \
222b8e80941Smrg      {                                                         \
223b8e80941Smrg         T d = b;                                               \
224b8e80941Smrg         d &= c;                                                \
225b8e80941Smrg         return d;                                              \
226b8e80941Smrg      }                                                         \
227b8e80941Smrg                                                                \
228b8e80941Smrg      bool                                                      \
229b8e80941Smrg      test(unsigned i) const                                    \
230b8e80941Smrg      {                                                         \
231b8e80941Smrg         return BITSET_TEST(words, i);                          \
232b8e80941Smrg      }                                                         \
233b8e80941Smrg                                                                \
234b8e80941Smrg      T &                                                       \
235b8e80941Smrg      set(unsigned i)                                           \
236b8e80941Smrg      {                                                         \
237b8e80941Smrg         BITSET_SET(words, i);                                  \
238b8e80941Smrg         return *this;                                          \
239b8e80941Smrg      }                                                         \
240b8e80941Smrg                                                                \
241b8e80941Smrg      T &                                                       \
242b8e80941Smrg      clear(unsigned i)                                         \
243b8e80941Smrg      {                                                         \
244b8e80941Smrg         BITSET_CLEAR(words, i);                                \
245b8e80941Smrg         return *this;                                          \
246b8e80941Smrg      }                                                         \
247b8e80941Smrg                                                                \
248b8e80941Smrg      BITSET_WORD words[BITSET_WORDS(N)];                       \
249b8e80941Smrg   }
250b8e80941Smrg
251b8e80941Smrg#endif
252b8e80941Smrg
253b8e80941Smrg#endif
254