23 #include <spot/misc/hashfunc.hh>
24 #include <spot/misc/common.hh>
25 #include <spot/misc/clz.hh>
32 [[noreturn]] SPOT_API
void report_bit_shift_too_big();
33 [[noreturn]] SPOT_API
void report_bit_out_of_bounds();
40 using word_t = unsigned;
42 static_assert(8*N*
sizeof(word_t) < -1U,
"too many bits in bitset");
44 std::array<word_t, N> data;
47 struct minus_one_tag {};
48 explicit bitset(minus_one_tag)
54 constexpr
explicit bitset(word_t s)
57 SPOT_ASSERT(s == 0
U || s == 1U);
72 explicit operator bool()
const
74 for (
const auto& v : data)
82 return fnv_hash(data.begin(), data.end());
85 bool operator==(
const bitset& other)
const
88 for (
unsigned i = 0; i != N; ++i)
89 if (data[i] != other.data[i])
94 bool operator!=(
const bitset& other)
const
96 return !this->operator==(other);
99 bool operator<(
const bitset& other)
const
101 for (
unsigned i = 0; i != N; ++i)
102 if (data[i] < other.data[i])
104 else if (data[i] > other.data[i])
109 bool operator<=(
const bitset& other)
const
111 for (
unsigned i = 0; i != N; ++i)
112 if (data[i] < other.data[i])
114 else if (data[i] > other.data[i])
119 bool operator>(
const bitset& other)
const
121 return other.operator<(*this);
124 bool operator>=(
const bitset& other)
const
126 return other.operator<=(*this);
131 #if SPOT_DEBUG || defined(SWIGPYTHON)
132 if (SPOT_UNLIKELY(s >= 8 * N *
sizeof(word_t)))
133 internal::report_bit_out_of_bounds();
135 SPOT_ASSUME(s < 8 * N *
sizeof(word_t));
137 data[s / (8*
sizeof(word_t))] |= 1U << (s % (8*
sizeof(word_t)));
140 void clear(
unsigned s)
142 #if SPOT_DEBUG || defined(SWIGPYTHON)
143 if (SPOT_UNLIKELY(s >= 8 * N *
sizeof(word_t)))
144 internal::report_bit_out_of_bounds();
146 SPOT_ASSUME(s < 8 * N *
sizeof(word_t));
148 data[s / (8*
sizeof(word_t))] &= ~(1U << (s % (8*
sizeof(word_t))));
151 bitset operator<<(
unsigned s)
const
157 bitset operator>>(
unsigned s)
const
164 bitset& operator<<=(
unsigned s)
166 #if SPOT_DEBUG || defined(SWIGPYTHON)
167 if (SPOT_UNLIKELY(s >= 8 * N *
sizeof(word_t)))
168 internal::report_bit_shift_too_big();
170 SPOT_ASSUME(s < 8 * N *
sizeof(word_t));
184 const unsigned wshift = s / (8 *
sizeof(word_t));
185 const unsigned offset = s % (8 *
sizeof(word_t));
189 for (
unsigned i = N - 1; i >= wshift; --i)
190 data[i] = data[i - wshift];
194 const unsigned sub_offset = 8 *
sizeof(word_t) - offset;
195 for (
unsigned i = N - 1; i > wshift; --i)
196 data[i] = ((data[i - wshift] << offset) |
197 (data[i - wshift - 1] >> sub_offset));
198 data[wshift] = data[0] << offset;
200 std::fill(data.begin(), data.begin() + wshift, word_t(0));
204 bitset& operator>>=(
unsigned s)
206 #if SPOT_DEBUG || defined(SWIGPYTHON)
207 if (SPOT_UNLIKELY(s >= 8 * N *
sizeof(word_t)))
208 internal::report_bit_shift_too_big();
210 SPOT_ASSUME(s < 8 * N *
sizeof(word_t));
223 const unsigned wshift = s / (8 *
sizeof(word_t));
224 const unsigned offset = s % (8 *
sizeof(word_t));
225 const unsigned limit = N - wshift - 1;
229 for (
unsigned i = 0; i <= limit; ++i)
230 data[i] = data[i + wshift];
234 const unsigned sub_offset = 8 *
sizeof(word_t) - offset;
235 for (
unsigned i = 0; i < limit; ++i)
236 data[i] = ((data[i + wshift] >> offset) |
237 (data[i + wshift + 1] << sub_offset));
238 data[limit] = data[N - 1] >> offset;
240 std::fill(data.begin() + limit + 1, data.end(), word_t(0));
244 bitset operator~()
const
247 for (
auto& v : r.data)
252 bitset operator&(
const bitset& other)
const
259 bitset
operator|(
const bitset& other)
const
266 bitset operator^(
const bitset& other)
const
273 bitset& operator&=(
const bitset& other)
275 for (
unsigned i = 0; i != N; ++i)
276 data[i] &= other.data[i];
279 bitset& operator|=(
const bitset& other)
281 for (
unsigned i = 0; i != N; ++i)
282 data[i] |= other.data[i];
285 bitset& operator^=(
const bitset& other)
287 for (
unsigned i = 0; i != N; ++i)
288 data[i] ^= other.data[i];
292 bitset operator-(word_t s)
const
298 bitset& operator-=(word_t s)
315 bitset operator-()
const
319 for (
auto& v : res.data)
328 unsigned count()
const
334 c += __builtin_popcount(v);
346 unsigned highest()
const
348 unsigned res = (N-1)*8*
sizeof(word_t);
355 res -= CHAR_BIT*
sizeof(word_t);
358 return res + CHAR_BIT*
sizeof(word_t) - clz(v) - 1;
363 unsigned lowest()
const
374 res += __builtin_ctz(v);
static bitset mone()
the -1 (all bits are set to 1)
Definition: bitset.hh:70
static constexpr bitset zero()
the 0
Definition: bitset.hh:66
static constexpr bitset one()
the 1
Definition: bitset.hh:68
size_t fnv_hash(It begin, It end)
Fowler-Noll-Vo hash function.
Definition: hashfunc.hh:99
Definition: automata.hh:27
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:131