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.

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