Painless
A framework to ease parallelization of sequential CDCL SAT solvers
Loading...
Searching...
No Matches
Bitset.hpp
1#include <algorithm>
2#include <cstring>
3#include <functional>
4#include <vector>
5
13class Bitset
14{
15
16 public:
26 Bitset(size_t size, bool default_value = false)
27 : num_bits(size)
28 {
29 bits.resize(num_blocks(), default_value ? ~0ULL : 0ULL);
30
31 // Set out of bound bits to zero
32 if (num_bits % BITS_PER_BLOCK != 0) {
33 // | out of bound |
34 // (1ULL << 40) - 1 = 00000000 00000000 00000000 11111111 11111111 11111111 11111111 11111111
35 bits.back() &= (1ULL << (num_bits % BITS_PER_BLOCK)) - 1;
36 }
37 }
38
43 size_t num_blocks() const { return (num_bits + BITS_PER_BLOCK - 1) / BITS_PER_BLOCK; }
44
50 bool operator[](size_t pos) const
51 {
52 assert(pos < num_bits);
53 return (bits[pos / BITS_PER_BLOCK] & (1ULL << (pos % BITS_PER_BLOCK))) != 0;
54 }
55
61 void set(size_t pos, bool value = true)
62 {
63 if (value) {
64 bits[pos / BITS_PER_BLOCK] |= (1ULL << (pos % BITS_PER_BLOCK));
65 } else {
66 bits[pos / BITS_PER_BLOCK] &= ~(1ULL << (pos % BITS_PER_BLOCK));
67 }
68 }
69
73 void clear() { std::fill(bits.begin(), bits.end(), 0ULL); }
74
79 void resize(size_t new_size)
80 {
81 // size_t old_num_blocks = num_blocks();
82 num_bits = new_size;
83 bits.resize(num_blocks(), 0ULL);
84 if (num_bits % BITS_PER_BLOCK != 0) {
85 bits.back() &= (1ULL << (num_bits % BITS_PER_BLOCK)) - 1;
86 }
87 }
88
93 size_t size() const { return num_bits; }
94
122 template<typename BinaryOp>
123 void merge(const std::vector<Bitset>& other_bitsets, BinaryOp op)
124 {
125 for (const auto& other : other_bitsets) {
126 size_t min_blocks = std::min(num_blocks(), other.num_blocks());
127 for (size_t i = 0; i < min_blocks; ++i) {
128 bits[i] = op(bits[i], other.bits[i]);
129 }
130 }
131 if (num_bits % BITS_PER_BLOCK != 0) {
132 bits.back() &= (1ULL << (num_bits % BITS_PER_BLOCK)) - 1;
133 }
134 }
135
140 void merge_or(const std::vector<Bitset>& other_bitsets) { merge(other_bitsets, std::bit_or<unsigned long long>()); }
141
146 void merge_and(const std::vector<Bitset>& other_bitsets)
147 {
148 merge(other_bitsets, std::bit_and<unsigned long long>());
149 }
150
155 unsigned long long* data() { return bits.data(); }
156
161 const unsigned long long* data() const { return bits.data(); }
162
163 private:
164 std::vector<unsigned long long> bits;
165 size_t num_bits;
166 static const size_t BITS_PER_BLOCK = sizeof(unsigned long long) * 8;
167};
A class representing a bitset with dynamic size.
Definition Bitset.hpp:14
void set(size_t pos, bool value=true)
Set a bit in the bitset.
Definition Bitset.hpp:61
void merge_or(const std::vector< Bitset > &other_bitsets)
Merge multiple bitsets using the OR operation.
Definition Bitset.hpp:140
bool operator[](size_t pos) const
Access a bit in the bitset.
Definition Bitset.hpp:50
void clear()
Clear all bits in the bitset.
Definition Bitset.hpp:73
size_t size() const
Get the size of the bitset.
Definition Bitset.hpp:93
unsigned long long * data()
Get a pointer to the underlying data.
Definition Bitset.hpp:155
size_t num_blocks() const
Calculate the number of blocks needed to store the bits.
Definition Bitset.hpp:43
const unsigned long long * data() const
Get a const pointer to the underlying data.
Definition Bitset.hpp:161
void resize(size_t new_size)
Resize the bitset.
Definition Bitset.hpp:79
Bitset(size_t size, bool default_value=false)
Construct a new Bitset object.
Definition Bitset.hpp:26
void merge(const std::vector< Bitset > &other_bitsets, BinaryOp op)
Merge multiple bitsets with this bitset using a custom binary operation.
Definition Bitset.hpp:123
void merge_and(const std::vector< Bitset > &other_bitsets)
Merge multiple bitsets using the AND operation.
Definition Bitset.hpp:146