Cthulhu  0.2.10
Cthulhu compiler collection
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
bitset.c
Go to the documentation of this file.
1 // SPDX-License-Identifier: LGPL-3.0-only
2 
3 #include "base/bitset.h"
4 
5 #include "base/panic.h"
6 #include "base/util.h"
7 #include "core/macros.h"
8 
9 #include <limits.h>
10 
11 typedef unsigned char bitset_word_t;
12 
13 #define BITSET_WORD_MAX (UCHAR_MAX)
14 #define WORD_SIZE (sizeof(bitset_word_t) * CHAR_BIT)
15 
16 // index of the word containing the bit
17 static size_t word_index(size_t bit)
18 {
19  return bit / WORD_SIZE;
20 }
21 
22 // offset of the bit within the word
23 static size_t word_offset(size_t bit)
24 {
25  return bit % WORD_SIZE;
26 }
27 
28 static bitset_word_t *bitset_start(bitset_t set)
29 {
30  CTASSERT(set.data != NULL);
31 
32  return (bitset_word_t*)set.data;
33 }
34 
35 static bitset_word_t *word_at(bitset_t set, size_t index)
36 {
37  return bitset_start(set) + index;
38 }
39 
41 bitset_t bitset_of(void *data, size_t words)
42 {
43  CTASSERT(data != NULL);
44  CTASSERT(words > 0);
45 
46  bitset_t bitset = {
47  .words = words,
48  .data = data
49  };
50 
51  return bitset;
52 }
53 
55 size_t bitset_set_first(bitset_t set, size_t start)
56 {
57  bitset_word_t *data = bitset_start(set);
58 
59  for (size_t i = word_index(start); i < set.words; i++)
60  {
61  bitset_word_t word = data[i];
62 
63  if (word == BITSET_WORD_MAX)
64  continue;
65 
66  size_t offset = word_offset(start);
67  for (size_t j = offset; j < WORD_SIZE; j++)
68  {
69  if ((word & (1 << j)) == 0)
70  {
71  // set bit
72  data[i] |= (1 << j);
73 
74  return i * WORD_SIZE + j;
75  }
76  }
77  }
78 
79  return SIZE_MAX;
80 }
81 
82 bool bitset_any(bitset_t set, bitset_t mask)
83 {
84  size_t words = CT_MIN(set.words, mask.words);
85 
86  bitset_word_t *data = bitset_start(set);
87  bitset_word_t *mask_data = bitset_start(mask);
88 
89  for (size_t i = 0; i < words; i++)
90  {
91  if ((data[i] & mask_data[i]) != 0)
92  {
93  return true;
94  }
95  }
96 
97  return false;
98 }
99 
100 bool bitset_all(bitset_t set, bitset_t mask)
101 {
102  size_t words = CT_MIN(set.words, mask.words);
103 
104  bitset_word_t *data = bitset_start(set);
105  bitset_word_t *mask_data = bitset_start(mask);
106 
107  for (size_t i = 0; i < words; i++)
108  {
109  if ((data[i] & mask_data[i]) != mask_data[i])
110  {
111  return false;
112  }
113  }
114 
115  return true;
116 }
117 
118 bool bitset_test(bitset_t set, size_t index)
119 {
120  CTASSERTF(bitset_len(set) > index, "index %zu is out of range %zu", index, bitset_len(set));
121 
122  size_t word = word_index(index);
123  size_t offset = word_offset(index);
124 
125  return (*word_at(set, word) & (1 << offset)) != 0;
126 }
127 
128 void bitset_set(bitset_t set, size_t index)
129 {
130  CTASSERTF(bitset_len(set) > index, "index %zu is out of range %zu", index, bitset_len(set));
131 
132  size_t word = word_index(index);
133  size_t offset = word_offset(index);
134 
135  *word_at(set, word) |= (1 << offset);
136 }
137 
138 void bitset_clear(bitset_t set, size_t index)
139 {
140  CTASSERTF(bitset_len(set) > index, "index %zu is out of range %zu", index, bitset_len(set));
141 
142  size_t word = word_index(index);
143  size_t offset = word_offset(index);
144 
145  *word_at(set, word) &= ~(1 << offset);
146 }
147 
149 {
150  bitset_word_t *data = bitset_start(set);
151  ctu_memset(data, 0, set.words);
152 }
153 
154 size_t bitset_len(bitset_t set)
155 {
156  CTASSERT(set.data != NULL);
157 
158  return set.words * WORD_SIZE;
159 }
#define BITSET_WORD_MAX
Definition: bitset.c:13
#define WORD_SIZE
Definition: bitset.c:14
unsigned char bitset_word_t
Definition: bitset.c:11
STA_DECL bitset_t bitset_of(void *data, size_t words)
Definition: bitset.c:41
#define STA_DECL
sal2 annotation on function implementations to copy annotations from the declaration
CT_NOALIAS CT_BASE_API void ctu_memset(STA_WRITES(size) void *dst, int value, size_t size)
set memory to a value equivalent to memset but with safety checks
size_t bitset_len(bitset_t set)
get the number of bits in a bitset
Definition: bitset.c:154
bool bitset_test(bitset_t set, size_t index)
test if a bit is set
Definition: bitset.c:118
bool bitset_any(bitset_t set, bitset_t mask)
test if any bits in a given mask are set
Definition: bitset.c:82
STA_DECL size_t bitset_set_first(bitset_t set, size_t start)
scan for the next free bit and set it
Definition: bitset.c:55
void bitset_reset(bitset_t set)
reset all bits in a bitset
Definition: bitset.c:148
bool bitset_all(bitset_t set, bitset_t mask)
test if all bits in a given mask are set
Definition: bitset.c:100
void bitset_set(bitset_t set, size_t index)
set a bit
Definition: bitset.c:128
void bitset_clear(bitset_t set, size_t index)
clear a bit
Definition: bitset.c:138
#define CT_MIN(L, R)
Definition: macros.h:38
#define CTASSERT(expr)
assert a condition, prints the condition as a message
Definition: panic.h:130
#define CTASSERTF(expr,...)
assert a condition with a message and optional format arguments
Definition: panic.h:116
a bitset
Definition: bitset.h:23