22#include <spot/misc/hashfunc.hh>
23#include <spot/misc/common.hh>
24#include <spot/misc/clz.hh>
31 [[noreturn]] SPOT_API
void report_bit_shift_too_big();
32 [[noreturn]] SPOT_API
void report_bit_out_of_bounds();
39 using word_t = unsigned;
41 static_assert(8*N*
sizeof(word_t) < -1U,
"too many bits in bitset");
43 std::array<word_t, N> data;
46 struct minus_one_tag {};
47 explicit bitset(minus_one_tag)
53 constexpr explicit bitset(word_t s)
56 SPOT_ASSERT(s == 0
U || s == 1U);
71 explicit operator bool()
const
73 for (
const auto& v : data)
81 return fnv_hash(data.begin(), data.end());
84 bool operator==(
const bitset& other)
const
87 for (
unsigned i = 0; i != N; ++i)
88 if (data[i] != other.data[i])
93 bool operator!=(
const bitset& other)
const
95 return !this->operator==(other);
98 bool operator<(
const bitset& other)
const
100 for (
unsigned i = 0; i != N; ++i)
101 if (data[i] < other.data[i])
103 else if (data[i] > other.data[i])
108 bool operator<=(
const bitset& other)
const
110 for (
unsigned i = 0; i != N; ++i)
111 if (data[i] < other.data[i])
113 else if (data[i] > other.data[i])
118 bool operator>(
const bitset& other)
const
120 return other.operator<(*this);
123 bool operator>=(
const bitset& other)
const
125 return other.operator<=(*this);
130#if SPOT_DEBUG || defined(SWIGPYTHON)
131 if (SPOT_UNLIKELY(s >= 8 * N *
sizeof(word_t)))
132 internal::report_bit_out_of_bounds();
134 SPOT_ASSUME(s < 8 * N *
sizeof(word_t));
136 data[s / (8*
sizeof(word_t))] |= 1U << (s % (8*
sizeof(word_t)));
139 void clear(
unsigned s)
141#if SPOT_DEBUG || defined(SWIGPYTHON)
142 if (SPOT_UNLIKELY(s >= 8 * N *
sizeof(word_t)))
143 internal::report_bit_out_of_bounds();
145 SPOT_ASSUME(s < 8 * N *
sizeof(word_t));
147 data[s / (8*
sizeof(word_t))] &= ~(1U << (s % (8*
sizeof(word_t))));
150 bitset operator<<(
unsigned s)
const
156 bitset operator>>(
unsigned s)
const
163 bitset& operator<<=(
unsigned s)
165#if SPOT_DEBUG || defined(SWIGPYTHON)
166 if (SPOT_UNLIKELY(s >= 8 * N *
sizeof(word_t)))
167 internal::report_bit_shift_too_big();
169 SPOT_ASSUME(s < 8 * N *
sizeof(word_t));
183 const unsigned wshift = s / (8 *
sizeof(word_t));
184 const unsigned offset = s % (8 *
sizeof(word_t));
188 for (
unsigned i = N - 1; i >= wshift; --i)
189 data[i] = data[i - wshift];
193 const unsigned sub_offset = 8 *
sizeof(word_t) - offset;
194 for (
unsigned i = N - 1; i > wshift; --i)
195 data[i] = ((data[i - wshift] << offset) |
196 (data[i - wshift - 1] >> sub_offset));
197 data[wshift] = data[0] << offset;
199 std::fill(data.begin(), data.begin() + wshift, word_t(0));
203 bitset& operator>>=(
unsigned s)
205#if SPOT_DEBUG || defined(SWIGPYTHON)
206 if (SPOT_UNLIKELY(s >= 8 * N *
sizeof(word_t)))
207 internal::report_bit_shift_too_big();
209 SPOT_ASSUME(s < 8 * N *
sizeof(word_t));
222 const unsigned wshift = s / (8 *
sizeof(word_t));
223 const unsigned offset = s % (8 *
sizeof(word_t));
224 const unsigned limit = N - wshift - 1;
228 for (
unsigned i = 0; i <= limit; ++i)
229 data[i] = data[i + wshift];
233 const unsigned sub_offset = 8 *
sizeof(word_t) - offset;
234 for (
unsigned i = 0; i < limit; ++i)
235 data[i] = ((data[i + wshift] >> offset) |
236 (data[i + wshift + 1] << sub_offset));
237 data[limit] = data[N - 1] >> offset;
239 std::fill(data.begin() + limit + 1, data.end(), word_t(0));
243 bitset operator~()
const
246 for (
auto& v : r.data)
251 bitset operator&(
const bitset& other)
const
258 bitset
operator|(
const bitset& other)
const
265 bitset operator^(
const bitset& other)
const
272 bitset& operator&=(
const bitset& other)
274 for (
unsigned i = 0; i != N; ++i)
275 data[i] &= other.data[i];
278 bitset& operator|=(
const bitset& other)
280 for (
unsigned i = 0; i != N; ++i)
281 data[i] |= other.data[i];
284 bitset& operator^=(
const bitset& other)
286 for (
unsigned i = 0; i != N; ++i)
287 data[i] ^= other.data[i];
291 bitset operator-(word_t s)
const
297 bitset& operator-=(word_t s)
314 bitset operator-()
const
318 for (
auto& v : res.data)
327 unsigned count()
const
333 c += __builtin_popcount(v);
345 unsigned highest()
const
347 unsigned res = (N-1)*8*
sizeof(word_t);
354 res -= CHAR_BIT*
sizeof(word_t);
357 return res + CHAR_BIT*
sizeof(word_t) - clz(v) - 1;
362 unsigned lowest()
const
373 res += __builtin_ctz(v);
static bitset mone()
the -1 (all bits are set to 1)
Definition: bitset.hh:69
static constexpr bitset zero()
the 0
Definition: bitset.hh:65
static constexpr bitset one()
the 1
Definition: bitset.hh:67
size_t fnv_hash(It begin, It end)
Fowler-Noll-Vo hash function.
Definition: hashfunc.hh:95
Definition: automata.hh:26
const mc_rvalue operator|(const mc_rvalue &lhs, const mc_rvalue &rhs)
This function helps to find the output value from a set of threads that may have different values.
Definition: mc.hh:130