5#include "iterationStream.h"
10 using underlying_type = uint64_t;
12 static constexpr int64_t BLOCK_MAX_SIZE =
sizeof(underlying_type) * 8;
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);
27 static int64_t toOuterIdx(uint32_t cur_block, int64_t cur_bit);
30 mutable int64_t cur_bit;
31 mutable int64_t cur_block;
32 mutable underlying_type* block_;
33 const bitSet* container_;
35 explicit Iterator(int64_t bit, int64_t block, underlying_type* block_p,
const bitSet*
container);
36 bool equalPtr(
const iterator *other)
const override;
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;
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;
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;
78 template<
typename Callback = transform<
bool>>
79 void forEach(Callback operation = Callback{}) =
delete;
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);
93 inline auto original::bitSet::bitsetInit(
const uint32_t size) ->
void
95 this->map = array<underlying_type>((size + BLOCK_MAX_SIZE - 1) / BLOCK_MAX_SIZE);
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;
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;
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);
111 inline auto original::bitSet::clearHigherBitsFromBlock(
const underlying_type block_value,
const int64_t bit) -> underlying_type
113 return block_value & (
static_cast<underlying_type
>(1) << bit + 1) -
static_cast<underlying_type
>(1);
116 inline auto original::bitSet::clearRedundantBits() ->
void
118 this->map.set(-1, clearHigherBitsFromBlock(this->map.get(-1), toInnerIdx(this->size() - 1).second()));
121 inline auto original::bitSet::getBit(
const int64_t bit,
const int64_t block)
const ->
bool {
122 return getBitFromBlock(this->map.get(block), bit);
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));
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));
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);
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};
141 inline auto original::bitSet::toOuterIdx(
const uint32_t cur_block,
const int64_t cur_bit) -> int64_t
143 return cur_block * BLOCK_MAX_SIZE + cur_bit;
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) {}
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;
156 inline auto original::bitSet::Iterator::clone() const ->
Iterator* {
160 inline auto original::bitSet::Iterator::hasNext() const ->
bool {
161 return toOuterIdx(this->cur_block, this->cur_bit) < this->container_->size() - 1;
164 inline auto original::bitSet::Iterator::hasPrev() const ->
bool {
165 return toOuterIdx(this->cur_block, this->cur_bit) > 0;
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)
172 return this->operator-(*other_it) == -1;
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)
179 return this->operator-(*other_it) == 1;
182 inline auto original::bitSet::Iterator::next() const ->
void {
186 inline auto original::bitSet::Iterator::prev() const ->
void {
190 inline auto original::bitSet::Iterator::getPrev() const ->
Iterator* {
191 if (!this->isValid())
throw outOfBoundError();
192 auto* it = this->clone();
197 inline auto original::bitSet::Iterator::getNext() const ->
Iterator* {
198 if (!this->isValid())
throw outOfBoundError();
199 auto* it = this->clone();
204 inline auto original::bitSet::Iterator::operator+=(
const int64_t steps)
const ->
void
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();
211 inline auto original::bitSet::Iterator::operator-=(
const int64_t steps)
const ->
void
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();
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();
229 return toOuterIdx(this->cur_block, this->cur_bit) - toOuterIdx(other_it->cur_block, other_it->cur_bit);
232 inline auto original::bitSet::Iterator::get() ->
bool & {
233 throw unSupportedMethodError();
236 inline auto original::bitSet::Iterator::className() const -> std::
string {
237 return "bitSet::Iterator";
240 inline auto original::bitSet::Iterator::get() const ->
bool
242 if (!this->isValid())
throw outOfBoundError();
243 return getBitFromBlock(*this->block_, this->cur_bit);
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);
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();
257 inline original::bitSet::bitSet(
const uint32_t size)
260 this->bitsetInit(size);
263 inline original::bitSet::bitSet(
const std::initializer_list<bool>& lst) : bitSet(lst.size()) {
265 for (
const auto& e : lst) {
266 auto idx = toInnerIdx(i);
267 this->writeBit(idx.second(), idx.first(), e);
272 inline original::bitSet::bitSet(
const bitSet &other) : bitSet(other.size()) {
273 this->operator=(other);
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_;
283 inline original::bitSet::bitSet(bitSet&& other) noexcept : bitSet(0)
285 this->operator=(std::move(other));
288 inline auto original::bitSet::operator=(bitSet&& other)
noexcept -> bitSet&
293 this->map = std::move(other.map);
294 this->size_ = other.size_;
299 inline auto original::bitSet::count() const -> uint32_t {
301 for (
const auto& e : this->map) {
311 inline auto original::bitSet::resize(
const uint32_t new_size)
const -> bitSet {
312 if (this->size() == new_size) {
316 auto nb = bitSet(new_size);
317 const uint32_t blocks_min = min(nb.map.size(),
319 for (uint32_t i = 0; i < blocks_min; i++) {
320 nb.map.set(i, this->map.get(i));
322 nb.clearRedundantBits();
326 inline auto original::bitSet::size() const -> uint32_t {
330 inline auto original::bitSet::begins() const ->
Iterator* {
331 return new Iterator(0, 0, &this->map.data(),
this);
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);
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());
346 inline auto original::bitSet::operator[](int64_t index) ->
bool& {
347 throw unSupportedMethodError();
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);
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())) {
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));
374 for (uint32_t i = 0; i < this->map.size(); i++) {
375 this->map.set(i, this->map.get(i) & other.map.get(i));
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));
388 for (uint32_t i = 0; i < this->map.size(); i++) {
389 this->map.set(i, this->map.get(i) | other.map.get(i));
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));
402 for (uint32_t i = 0; i < this->map.size(); i++) {
403 this->map.set(i, this->map.get(i) ^ other.map.get(i));
409 inline auto original::bitSet::className() const -> std::
string {
413 inline auto original::operator&(
const bitSet &lbs,
const bitSet &rbs) -> bitSet {
418 inline auto original::operator|(
const bitSet &lbs,
const bitSet &rbs) -> bitSet {
423 inline auto original::operator^(
const bitSet &lbs,
const bitSet &rbs) -> bitSet {
428 inline auto original::operator~(
const bitSet &bs) -> bitSet {
430 for (uint32_t i = 0; i < nbs.map.size(); i++) {
431 nbs.map.set(i, ~nbs.map.get(i));
433 nbs.clearRedundantBits();
Definition container.h:10
Definition iterationStream.h:12