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