jack1 codebase
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

113 lines
3.1KB

  1. /*
  2. * bitset.h -- some simple bit vector set operations.
  3. *
  4. * This is useful for sets of small non-negative integers. There are
  5. * some obvious set operations that are not implemented because I
  6. * don't need them right now.
  7. *
  8. * These functions represent sets as arrays of unsigned 32-bit
  9. * integers allocated on the heap. The first entry contains the set
  10. * cardinality (number of elements allowed), followed by one or more
  11. * words containing bit vectors.
  12. *
  13. * $Id$
  14. */
  15. /*
  16. * Copyright (C) 2005 Jack O'Quin
  17. *
  18. * This program is free software; you can redistribute it and/or
  19. * modify it under the terms of the GNU General Public License as
  20. * published by the Free Software Foundation; either version 2 of the
  21. * License, or (at your option) any later version.
  22. *
  23. * This program is distributed in the hope that it will be useful,
  24. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  25. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  26. * General Public License for more details.
  27. *
  28. * You should have received a copy of the GNU General Public License
  29. * along with this program; if not, write to the Free Software
  30. * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  31. */
  32. #ifndef __bitset_h__
  33. #define __bitset_h__
  34. #include <inttypes.h> /* POSIX standard fixed-size types */
  35. #include <assert.h> /* `#define NDEBUG' to disable */
  36. /* On some 64-bit machines, this implementation may be slightly
  37. * inefficient, depending on how compilers allocate space for
  38. * uint32_t. For the set sizes I currently need, this is acceptable.
  39. * It should not be hard to pack the bits better, if that becomes
  40. * worthwhile.
  41. */
  42. typedef uint32_t _bitset_word_t;
  43. typedef _bitset_word_t *bitset_t;
  44. #define WORD_SIZE(cardinality) (1+((cardinality)+31)/32)
  45. #define BYTE_SIZE(cardinality) (WORD_SIZE(cardinality)*sizeof(_bitset_word_t))
  46. #define WORD_INDEX(element) (1+(element)/32)
  47. #define BIT_INDEX(element) ((element)&037)
  48. static inline void
  49. bitset_add(bitset_t set, unsigned int element)
  50. {
  51. assert(element < set[0]);
  52. set[WORD_INDEX(element)] |= (1 << BIT_INDEX(element));
  53. }
  54. static inline void
  55. bitset_copy(bitset_t to_set, bitset_t from_set)
  56. {
  57. assert(to_set[0] == from_set[0]);
  58. memcpy(to_set, from_set, BYTE_SIZE(to_set[0]));
  59. }
  60. static inline void
  61. bitset_create(bitset_t *set, unsigned int cardinality)
  62. {
  63. *set = (bitset_t) calloc(WORD_SIZE(cardinality),
  64. sizeof(_bitset_word_t));
  65. assert(*set);
  66. *set[0] = cardinality;
  67. }
  68. static inline void
  69. bitset_destroy(bitset_t *set)
  70. {
  71. if (*set) {
  72. free(*set);
  73. *set = (bitset_t) 0;
  74. }
  75. }
  76. static inline int
  77. bitset_empty(bitset_t set)
  78. {
  79. int i;
  80. _bitset_word_t result = 0;
  81. int nwords = WORD_SIZE(set[0]);
  82. for (i = 1; i < nwords; i++) {
  83. result |= set[i];
  84. }
  85. return (result == 0);
  86. }
  87. static inline int
  88. bitset_contains(bitset_t set, unsigned int element)
  89. {
  90. assert(element < set[0]);
  91. return (0 != (set[WORD_INDEX(element)] & (1<<BIT_INDEX(element))));
  92. }
  93. static inline void
  94. bitset_remove(bitset_t set, unsigned int element)
  95. {
  96. assert(element < set[0]);
  97. set[WORD_INDEX(element)] &= ~(1<<BIT_INDEX(element));
  98. }
  99. #endif /* __bitset_h__ */