ORIGINAL
Loading...
Searching...
No Matches
bitSet.h
1#ifndef BITSET_H
2#define BITSET_H
3#include "array.h"
4#include "couple.h"
5#include "iterationStream.h"
6
7
8namespace original {
9 class bitSet final : public baseArray<bool>, public iterationStream<bool, bitSet>{
10 using underlying_type = uint64_t;
11
12 static constexpr int64_t BLOCK_MAX_SIZE = sizeof(underlying_type) * 8;
14 uint32_t size_;
15
16 void bitsetInit(uint32_t size);
17 [[nodiscard]] static bool getBitFromBlock(underlying_type block_value, int64_t bit);
18 [[nodiscard]] static underlying_type setBitFromBlock(underlying_type block_value, int64_t bit);
19 [[nodiscard]] static underlying_type clearBitFromBlock(underlying_type block_value, int64_t bit);
20 [[nodiscard]] static underlying_type clearHigherBitsFromBlock(underlying_type block_value, int64_t bit);
21 void clearRedundantBits();
22 [[nodiscard]] bool getBit(int64_t bit, int64_t block) const;
23 void setBit(int64_t bit, int64_t block);
24 void clearBit(int64_t bit, int64_t block);
25 void writeBit(int64_t bit, int64_t block, bool value);
26 static couple<uint32_t, int64_t> toInnerIdx(int64_t index);
27 static int64_t toOuterIdx(uint32_t cur_block, int64_t cur_bit);
28 public:
29 class Iterator final : public baseIterator<bool> {
30 mutable int64_t cur_bit;
31 mutable int64_t cur_block;
32 mutable underlying_type* block_;
33 const bitSet* container_;
34
35 explicit Iterator(int64_t bit, int64_t block, underlying_type* block_p, const bitSet* container);
36 bool equalPtr(const iterator *other) const override;
37 public:
38 friend class bitSet;
39 Iterator* clone() const override;
40 [[nodiscard]] bool hasNext() const override;
41 [[nodiscard]] bool hasPrev() const override;
42 bool atPrev(const iterator *other) const override;
43 bool atNext(const iterator *other) const override;
44 void next() const override;
45 void prev() const override;
46 Iterator* getPrev() const override;
47 Iterator* getNext() const override;
48 void operator+=(int64_t steps) const override;
49 void operator-=(int64_t steps) const override;
50 int64_t operator-(const iterator& other) const override;
51 bool& get() override;
52 [[nodiscard]] std::string className() const override;
53 bool get() const override;
54 void set(const bool &data) override;
55 [[nodiscard]] bool isValid() const override;
56 };
57
58 explicit bitSet(uint32_t size);
59 bitSet(const std::initializer_list<bool>& lst);
60 bitSet(const bitSet& other);
61 bitSet& operator=(const bitSet& other);
62 bitSet(bitSet&& other) noexcept;
63 bitSet& operator=(bitSet&& other) noexcept;
64 [[nodiscard]] uint32_t count() const;
65 [[nodiscard]] bitSet resize(uint32_t new_size) const;
66 [[nodiscard]] uint32_t size() const override;
67 [[nodiscard]] Iterator* begins() const override;
68 [[nodiscard]] Iterator* ends() const override;
69 [[nodiscard]] bool get(int64_t index) const override;
70 bool& operator[](int64_t index) override;
71 void set(int64_t index, const bool &e) override;
72 [[nodiscard]] uint32_t indexOf(const bool &e) const override;
73 bitSet& operator&=(const bitSet& other);
74 bitSet& operator|=(const bitSet& other);
75 bitSet& operator^=(const bitSet& other);
76 [[nodiscard]] std::string className() const override;
77
78 template<typename Callback = transform<bool>>
79 void forEach(Callback operation = Callback{}) = delete;
80
81 friend bitSet operator&(const bitSet& lbs, const bitSet& rbs);
82 friend bitSet operator|(const bitSet& lbs, const bitSet& rbs);
83 friend bitSet operator^(const bitSet& lbs, const bitSet& rbs);
84 friend bitSet operator~(const bitSet& bs);
85 };
86
87 bitSet operator&(const bitSet& lbs, const bitSet& rbs);
88 bitSet operator|(const bitSet& lbs, const bitSet& rbs);
89 bitSet operator^(const bitSet& lbs, const bitSet& rbs);
90 bitSet operator~(const bitSet& bs);
91}
92
93 inline auto original::bitSet::bitsetInit(const uint32_t size) -> void
94 {
95 this->map = array<underlying_type>((size + BLOCK_MAX_SIZE - 1) / BLOCK_MAX_SIZE);
96 this->size_ = size;
97 }
98
99 inline auto original::bitSet::getBitFromBlock(const underlying_type block_value, const int64_t bit) -> bool {
100 return block_value & static_cast<underlying_type>(1) << bit;
101 }
102
103 inline auto original::bitSet::setBitFromBlock(const underlying_type block_value, const int64_t bit) -> underlying_type {
104 return block_value | static_cast<underlying_type>(1) << bit;
105 }
106
107 inline auto original::bitSet::clearBitFromBlock(const underlying_type block_value, const int64_t bit) -> underlying_type {
108 return block_value & ~(static_cast<underlying_type>(1) << bit);
109 }
110
111 inline auto original::bitSet::clearHigherBitsFromBlock(const underlying_type block_value, const int64_t bit) -> underlying_type
112 {
113 return block_value & (static_cast<underlying_type>(1) << bit + 1) - static_cast<underlying_type>(1);
114 }
115
116 inline auto original::bitSet::clearRedundantBits() -> void
117 {
118 this->map.set(-1, clearHigherBitsFromBlock(this->map.get(-1), toInnerIdx(this->size() - 1).second()));
119 }
120
121 inline auto original::bitSet::getBit(const int64_t bit, const int64_t block) const -> bool {
122 return getBitFromBlock(this->map.get(block), bit);
123 }
124
125 inline auto original::bitSet::setBit(const int64_t bit, const int64_t block) -> void {
126 this->map.set(block, setBitFromBlock(this->map.get(block), bit));
127 }
128
129 inline auto original::bitSet::clearBit(const int64_t bit, const int64_t block) -> void {
130 this->map.set(block, clearBitFromBlock(this->map.get(block), bit));
131 }
132
133 inline auto original::bitSet::writeBit(const int64_t bit, const int64_t block, const bool value) -> void {
134 value ? this->setBit(bit, block) : this->clearBit(bit, block);
135 }
136
137 inline auto original::bitSet::toInnerIdx(const int64_t index) -> couple<uint32_t, int64_t> {
138 return {static_cast<uint32_t>(index / BLOCK_MAX_SIZE), index % BLOCK_MAX_SIZE};
139 }
140
141 inline auto original::bitSet::toOuterIdx(const uint32_t cur_block, const int64_t cur_bit) -> int64_t
142 {
143 return cur_block * BLOCK_MAX_SIZE + cur_bit;
144 }
145
146 inline original::bitSet::Iterator::Iterator(const int64_t bit, const int64_t block, underlying_type* block_p, const bitSet* container)
147 : cur_bit(bit), cur_block(block), block_(block_p), container_(container) {}
148
149 inline auto original::bitSet::Iterator::equalPtr(const iterator *other) const -> bool {
150 auto* other_it = dynamic_cast<const Iterator*>(other);
151 return other_it != nullptr
152 && this->cur_bit == other_it->cur_bit
153 && this->cur_block == other_it->cur_block;
154 }
155
156 inline auto original::bitSet::Iterator::clone() const -> Iterator* {
157 return new Iterator(*this);
158 }
159
160 inline auto original::bitSet::Iterator::hasNext() const -> bool {
161 return toOuterIdx(this->cur_block, this->cur_bit) < this->container_->size() - 1;
162 }
163
164 inline auto original::bitSet::Iterator::hasPrev() const -> bool {
165 return toOuterIdx(this->cur_block, this->cur_bit) > 0;
166 }
167
168 inline auto original::bitSet::Iterator::atPrev(const iterator *other) const -> bool {
169 auto* other_it = dynamic_cast<const Iterator*>(other);
170 if (other_it == nullptr)
171 return false;
172 return this->operator-(*other_it) == -1;
173 }
174
175 inline auto original::bitSet::Iterator::atNext(const iterator *other) const -> bool {
176 auto* other_it = dynamic_cast<const Iterator*>(other);
177 if (other_it == nullptr)
178 return false;
179 return this->operator-(*other_it) == 1;
180 }
181
182 inline auto original::bitSet::Iterator::next() const -> void {
183 this->operator+=(1);
184 }
185
186 inline auto original::bitSet::Iterator::prev() const -> void {
187 this->operator-=(1);
188 }
189
190 inline auto original::bitSet::Iterator::getPrev() const -> Iterator* {
191 if (!this->isValid()) throw outOfBoundError();
192 auto* it = this->clone();
193 it->prev();
194 return it;
195 }
196
197 inline auto original::bitSet::Iterator::getNext() const -> Iterator* {
198 if (!this->isValid()) throw outOfBoundError();
199 auto* it = this->clone();
200 it->next();
201 return it;
202 }
203
204 inline auto original::bitSet::Iterator::operator+=(const int64_t steps) const -> void
205 {
206 auto new_idx = toInnerIdx(toOuterIdx(this->cur_block, this->cur_bit) + steps);
207 this->cur_block = new_idx.first();
208 this->cur_bit = new_idx.second();
209 }
210
211 inline auto original::bitSet::Iterator::operator-=(const int64_t steps) const -> void
212 {
213 auto new_idx = toInnerIdx(toOuterIdx(this->cur_block, this->cur_bit) - steps);
214 this->cur_block = new_idx.first();
215 this->cur_bit = new_idx.second();
216 }
217
218 inline auto original::bitSet::Iterator::operator-(const iterator &other) const -> int64_t {
219 auto* other_it = dynamic_cast<const Iterator*>(&other);
220 if (other_it == nullptr)
221 return this > &other ?
222 std::numeric_limits<int64_t>::max() :
223 std::numeric_limits<int64_t>::min();
224 if (this->container_ != other_it->container_)
225 return this->container_ > other_it->container_ ?
226 std::numeric_limits<int64_t>::max() :
227 std::numeric_limits<int64_t>::min();
228
229 return toOuterIdx(this->cur_block, this->cur_bit) - toOuterIdx(other_it->cur_block, other_it->cur_bit);
230 }
231
232 inline auto original::bitSet::Iterator::get() -> bool & {
233 throw unSupportedMethodError();
234 }
235
236 inline auto original::bitSet::Iterator::className() const -> std::string {
237 return "bitSet::Iterator";
238 }
239
240 inline auto original::bitSet::Iterator::get() const -> bool
241 {
242 if (!this->isValid()) throw outOfBoundError();
243 return getBitFromBlock(*this->block_, this->cur_bit);
244 }
245
246 inline auto original::bitSet::Iterator::set(const bool &data) -> void {
247 if (!this->isValid()) throw outOfBoundError();
248 *this->block_ = data ?
249 setBitFromBlock(*this->block_, this->cur_bit) : clearBitFromBlock(*this->block_, this->cur_bit);
250 }
251
252 inline auto original::bitSet::Iterator::isValid() const -> bool {
253 const auto outer = toOuterIdx(this->cur_block, this->cur_bit);
254 return outer >= 0 && outer < this->container_->size();
255 }
256
257 inline original::bitSet::bitSet(const uint32_t size)
258 : size_()
259 {
260 this->bitsetInit(size);
261 }
262
263 inline original::bitSet::bitSet(const std::initializer_list<bool>& lst) : bitSet(lst.size()) {
264 uint32_t i = 0;
265 for (const auto& e : lst) {
266 auto idx = toInnerIdx(i);
267 this->writeBit(idx.second(), idx.first(), e);
268 i += 1;
269 }
270 }
271
272 inline original::bitSet::bitSet(const bitSet &other) : bitSet(other.size()) {
273 this->operator=(other);
274 }
275
276 inline auto original::bitSet::operator=(const bitSet &other) -> bitSet& {
277 if (this == &other) return *this;
278 this->map = other.map;
279 this->size_ = other.size_;
280 return *this;
281 }
282
283 inline original::bitSet::bitSet(bitSet&& other) noexcept : bitSet(0)
284 {
285 this->operator=(std::move(other));
286 }
287
288 inline auto original::bitSet::operator=(bitSet&& other) noexcept -> bitSet&
289 {
290 if (this == &other)
291 return *this;
292
293 this->map = std::move(other.map);
294 this->size_ = other.size_;
295 other.bitsetInit(0);
296 return *this;
297 }
298
299 inline auto original::bitSet::count() const -> uint32_t {
300 uint32_t count = 0;
301 for (const auto& e : this->map) {
302 auto n = e;
303 while (n) {
304 n &= n - 1;
305 count += 1;
306 }
307 }
308 return count;
309 }
310
311 inline auto original::bitSet::resize(const uint32_t new_size) const -> bitSet {
312 if (this->size() == new_size) {
313 return *this;
314 }
315
316 auto nb = bitSet(new_size);
317 const uint32_t blocks_min = min(nb.map.size(),
318 this->map.size());
319 for (uint32_t i = 0; i < blocks_min; i++) {
320 nb.map.set(i, this->map.get(i));
321 }
322 nb.clearRedundantBits();
323 return nb;
324 }
325
326 inline auto original::bitSet::size() const -> uint32_t {
327 return this->size_;
328 }
329
330 inline auto original::bitSet::begins() const -> Iterator* {
331 return new Iterator(0, 0, &this->map.data(), this);
332 }
333
334 inline auto original::bitSet::ends() const -> Iterator* {
335 return new Iterator(toInnerIdx(this->size() - 1).second(), this->map.size() - 1,
336 &this->map.data() + this->map.size() - 1, this);
337 }
338
339 inline auto original::bitSet::get(int64_t index) const -> bool {
340 if (this->indexOutOfBound(index)) throw outOfBoundError();
341 index = this->parseNegIndex(index);
342 auto idx = toInnerIdx(index);
343 return this->getBit(idx.second(), idx.first());
344 }
345
346 inline auto original::bitSet::operator[](int64_t index) -> bool& {
347 throw unSupportedMethodError();
348 }
349
350 inline auto original::bitSet::set(int64_t index, const bool &e) -> void {
351 if (this->indexOutOfBound(index)) throw outOfBoundError();
352 index = this->parseNegIndex(index);
353 auto idx = toInnerIdx(index);
354 this->writeBit(idx.second(), idx.first(), e);
355 }
356
357 inline auto original::bitSet::indexOf(const bool &e) const -> uint32_t {
358 for (uint32_t i = 0; i < this->size(); i++) {
359 if (auto idx = toInnerIdx(i);
360 e == this->getBit(idx.second(), idx.first())) {
361 return i;
362 }
363 }
364 return this->size();
365 }
366
367 inline auto original::bitSet::operator&=(const bitSet &other) -> bitSet& {
368 if (this->size() != other.size()) {
369 const auto resized = other.resize(this->size());
370 for (uint32_t i = 0; i < this->map.size(); i++) {
371 this->map.set(i, this->map.get(i) & resized.map.get(i));
372 }
373 }else {
374 for (uint32_t i = 0; i < this->map.size(); i++) {
375 this->map.set(i, this->map.get(i) & other.map.get(i));
376 }
377 }
378 return *this;
379 }
380
381 inline auto original::bitSet::operator|=(const bitSet &other) -> bitSet& {
382 if (this->size() != other.size()) {
383 const auto resized = other.resize(this->size());
384 for (uint32_t i = 0; i < this->map.size(); i++) {
385 this->map.set(i, this->map.get(i) | resized.map.get(i));
386 }
387 }else {
388 for (uint32_t i = 0; i < this->map.size(); i++) {
389 this->map.set(i, this->map.get(i) | other.map.get(i));
390 }
391 }
392 return *this;
393 }
394
395 inline auto original::bitSet::operator^=(const bitSet &other) -> bitSet& {
396 if (this->size() != other.size()) {
397 const auto resized = other.resize(this->size());
398 for (uint32_t i = 0; i < this->map.size(); i++) {
399 this->map.set(i, this->map.get(i) ^ resized.map.get(i));
400 }
401 }else {
402 for (uint32_t i = 0; i < this->map.size(); i++) {
403 this->map.set(i, this->map.get(i) ^ other.map.get(i));
404 }
405 }
406 return *this;
407 }
408
409 inline auto original::bitSet::className() const -> std::string {
410 return "bitSet";
411 }
412
413 inline auto original::operator&(const bitSet &lbs, const bitSet &rbs) -> bitSet {
414 bitSet bs(lbs);
415 return bs &= rbs;
416 }
417
418 inline auto original::operator|(const bitSet &lbs, const bitSet &rbs) -> bitSet {
419 bitSet bs(lbs);
420 return bs |= rbs;
421 }
422
423 inline auto original::operator^(const bitSet &lbs, const bitSet &rbs) -> bitSet {
424 bitSet bs(lbs);
425 return bs ^= rbs;
426 }
427
428 inline auto original::operator~(const bitSet &bs) -> bitSet {
429 bitSet nbs(bs);
430 for (uint32_t i = 0; i < nbs.map.size(); i++) {
431 nbs.map.set(i, ~nbs.map.get(i));
432 }
433 nbs.clearRedundantBits();
434 return nbs;
435 }
436
437#endif //BITSET_H
Definition array.h:15
Definition baseArray.h:7
Definition iterator.h:56
Definition bitSet.h:29
Definition bitSet.h:9
Definition container.h:10
Definition couple.h:10
Definition iterationStream.h:12
Definition iterator.h:11