28 template<
typename ALLOC = allocator<
bool>>
40 using rebind_alloc_underlying =
typename ALLOC::template rebind_alloc<underlying_type>;
42 static constexpr integer BLOCK_MAX_SIZE =
sizeof(underlying_type) * 8;
67 [[nodiscard]]
static bool getBitFromBlock(underlying_type block_value,
integer bit);
75 [[nodiscard]]
static underlying_type setBitFromBlock(underlying_type block_value,
integer bit);
83 [[nodiscard]]
static underlying_type clearBitFromBlock(underlying_type block_value,
integer bit);
91 [[nodiscard]]
static underlying_type clearHigherBitsFromBlock(underlying_type block_value,
integer bit);
96 void clearRedundantBits();
155 mutable underlying_type* block_;
156 const bitSet* container_;
172 bool equalPtr(
const iterator *other)
const override;
181 Iterator*
clone()
const override;
187 [[nodiscard]]
bool hasNext()
const override;
193 [[nodiscard]]
bool hasPrev()
const override;
212 void next()
const override;
217 void prev()
const override;
223 Iterator*
getPrev()
const override;
229 Iterator*
getNext()
const override;
254 bool&
get()
override;
260 [[nodiscard]] std::string
className()
const override;
266 [[nodiscard]]
bool get()
const override;
272 void set(
const bool &data)
override;
278 [[nodiscard]]
bool isValid()
const override;
294 bitSet(
const std::initializer_list<bool>& lst);
355 [[nodiscard]] Iterator*
begins()
const override;
361 [[nodiscard]] Iterator*
ends()
const override;
368 [[nodiscard]]
bool get(
integer index)
const override;
382 void set(
integer index,
const bool &e)
override;
418 [[nodiscard]] std::string
className()
const override;
421 template<
typename Callback = transform<
bool>>
422 void forEach(Callback operation = Callback{}) =
delete;
430 template<
typename ALLOC_>
439 template<
typename ALLOC_>
448 template<
typename ALLOC_>
456 template<
typename ALLOC_>
460 template<
typename ALLOC_>
463 template<
typename ALLOC_>
466 template<
typename ALLOC_>
469 template<
typename ALLOC_>
473 template<
typename ALLOC>
474 auto original::bitSet<ALLOC>::bitsetInit(
const u_integer size) ->
void
476 this->map = array<underlying_type, rebind_alloc_underlying>((size + BLOCK_MAX_SIZE - 1) / BLOCK_MAX_SIZE, rebind_alloc_underlying{});
480 template<
typename ALLOC>
481 auto original::bitSet<ALLOC>::getBitFromBlock(
const underlying_type block_value,
const integer bit) ->
bool {
482 return block_value &
static_cast<underlying_type
>(1) << bit;
485 template<
typename ALLOC>
486 auto original::bitSet<ALLOC>::setBitFromBlock(
const underlying_type block_value,
const integer bit) -> underlying_type {
487 return block_value |
static_cast<underlying_type
>(1) << bit;
490 template<
typename ALLOC>
491 auto original::bitSet<ALLOC>::clearBitFromBlock(
const underlying_type block_value,
const integer bit) -> underlying_type {
492 return block_value & ~(
static_cast<underlying_type
>(1) << bit);
495 template<
typename ALLOC>
496 auto original::bitSet<ALLOC>::clearHigherBitsFromBlock(
const underlying_type block_value,
const integer bit) -> underlying_type
498 return block_value & (
static_cast<underlying_type
>(1) << (bit + 1)) -
static_cast<underlying_type
>(1);
501 template<
typename ALLOC>
502 auto original::bitSet<ALLOC>::clearRedundantBits() ->
void
504 this->map.
set(-1, clearHigherBitsFromBlock(this->map.
get(-1), toInnerIdx(this->size() - 1).second()));
507 template<
typename ALLOC>
508 auto original::bitSet<ALLOC>::getBit(
const integer bit,
const integer block)
const ->
bool {
509 return getBitFromBlock(this->map.
get(block), bit);
512 template<
typename ALLOC>
513 auto original::bitSet<ALLOC>::setBit(
const integer bit,
const integer block) ->
void {
514 this->map.
set(block, setBitFromBlock(this->map.
get(block), bit));
517 template<
typename ALLOC>
518 auto original::bitSet<ALLOC>::clearBit(
const integer bit,
const integer block) ->
void {
519 this->map.
set(block, clearBitFromBlock(this->map.
get(block), bit));
522 template<
typename ALLOC>
523 auto original::bitSet<ALLOC>::writeBit(
const integer bit,
const integer block,
const bool value) ->
void {
524 value ? this->setBit(bit, block) : this->clearBit(bit, block);
527 template<
typename ALLOC>
528 auto original::bitSet<ALLOC>::toInnerIdx(
const integer index) -> couple<u_integer, integer> {
529 return {
static_cast<u_integer>(index / BLOCK_MAX_SIZE), index % BLOCK_MAX_SIZE};
532 template<
typename ALLOC>
533 auto original::bitSet<ALLOC>::toOuterIdx(
const u_integer cur_block,
const integer cur_bit) ->
integer
535 return cur_block * BLOCK_MAX_SIZE + cur_bit;
538 template<
typename ALLOC>
539 original::bitSet<ALLOC>::Iterator::Iterator(
const integer bit,
const integer block, underlying_type* block_p,
const bitSet* container)
540 : cur_bit(bit), cur_block(block), block_(block_p), container_(container) {}
542 template<
typename ALLOC>
543 auto original::bitSet<ALLOC>::Iterator::equalPtr(
const iterator *other)
const ->
bool {
544 auto* other_it =
dynamic_cast<const Iterator*
>(other);
545 return other_it !=
nullptr
546 && this->cur_bit == other_it->cur_bit
547 && this->cur_block == other_it->cur_block;
550 template<
typename ALLOC>
552 return new Iterator(*
this);
555 template<
typename ALLOC>
557 return toOuterIdx(this->cur_block, this->cur_bit) < this->container_->size() - 1;
560 template<
typename ALLOC>
562 return toOuterIdx(this->cur_block, this->cur_bit) > 0;
565 template<
typename ALLOC>
567 auto* other_it =
dynamic_cast<const Iterator*
>(other);
568 if (other_it ==
nullptr)
573 template<
typename ALLOC>
575 auto* other_it =
dynamic_cast<const Iterator*
>(other);
576 if (other_it ==
nullptr)
581 template<
typename ALLOC>
586 template<
typename ALLOC>
591 template<
typename ALLOC>
594 auto* it = this->
clone();
599 template<
typename ALLOC>
602 auto* it = this->
clone();
607 template<
typename ALLOC>
610 auto new_idx = toInnerIdx(toOuterIdx(this->cur_block, this->cur_bit) + steps);
611 this->cur_block = new_idx.first();
612 this->cur_bit = new_idx.second();
615 template<
typename ALLOC>
618 auto new_idx = toInnerIdx(toOuterIdx(this->cur_block, this->cur_bit) - steps);
619 this->cur_block = new_idx.first();
620 this->cur_bit = new_idx.second();
623 template<
typename ALLOC>
625 auto* other_it =
dynamic_cast<const Iterator*
>(&other);
626 if (other_it ==
nullptr)
627 return this > &other ?
628 std::numeric_limits<integer>::max() :
629 std::numeric_limits<integer>::min();
630 if (this->container_ != other_it->container_)
631 return this->container_ > other_it->container_ ?
632 std::numeric_limits<integer>::max() :
633 std::numeric_limits<integer>::min();
635 return toOuterIdx(this->cur_block, this->cur_bit) - toOuterIdx(other_it->cur_block, other_it->cur_bit);
638 template<
typename ALLOC>
643 template<
typename ALLOC>
645 return "bitSet::Iterator";
648 template<
typename ALLOC>
652 return getBitFromBlock(*this->block_, this->cur_bit);
655 template<
typename ALLOC>
658 *this->block_ = data ?
659 setBitFromBlock(*this->block_, this->cur_bit) : clearBitFromBlock(*this->block_, this->cur_bit);
662 template<
typename ALLOC>
664 const auto outer = toOuterIdx(this->cur_block, this->cur_bit);
665 return outer >= 0 && outer < this->container_->size();
668 template<
typename ALLOC>
671 this->bitsetInit(
size);
674 template<
typename ALLOC>
677 for (
const auto& e : lst) {
678 auto idx = toInnerIdx(i);
679 this->writeBit(idx.second(), idx.first(), e);
684 template<
typename ALLOC>
689 template<
typename ALLOC>
691 if (
this == &other)
return *
this;
692 this->map = other.map;
693 this->size_ = other.size_;
694 if constexpr (ALLOC::propagate_on_container_copy_assignment::value){
700 template<
typename ALLOC>
706 template<
typename ALLOC>
712 this->map = std::move(other.map);
713 this->size_ = other.size_;
714 if constexpr (ALLOC::propagate_on_container_move_assignment::value){
721 template<
typename ALLOC>
724 for (
const auto& e : this->map) {
734 template<
typename ALLOC>
736 if (this->size() == new_size) {
740 auto nb =
bitSet(new_size);
743 for (
u_integer i = 0; i < blocks_min; i++) {
744 nb.map.set(i, this->map.
get(i));
746 nb.clearRedundantBits();
750 template<
typename ALLOC>
756 template<
typename ALLOC>
761 template<
typename ALLOC>
763 return new Iterator(toInnerIdx(this->size() - 1).second(), this->map.
size() - 1,
764 &this->map.data() + this->map.size() - 1,
this);
767 template<
typename ALLOC>
771 auto idx = toInnerIdx(index);
772 return this->getBit(idx.second(), idx.first());
775 template<
typename ALLOC>
780 template<
typename ALLOC>
784 auto idx = toInnerIdx(index);
785 this->writeBit(idx.second(), idx.first(), e);
788 template<
typename ALLOC>
790 for (
u_integer i = 0; i < this->size(); i++) {
791 if (
auto idx = toInnerIdx(i);
792 e == this->getBit(idx.second(), idx.first())) {
799 template<
typename ALLOC>
801 if (this->size() != other.size()) {
802 const auto resized = other.resize(this->size());
804 this->map.
set(i, this->map.
get(i) & resized.map.get(i));
808 this->map.
set(i, this->map.
get(i) & other.map.get(i));
814 template<
typename ALLOC>
816 if (this->size() != other.size()) {
817 const auto resized = other.resize(this->size());
819 this->map.
set(i, this->map.
get(i) | resized.map.get(i));
823 this->map.
set(i, this->map.
get(i) | other.map.get(i));
829 template<
typename ALLOC>
831 if (this->size() != other.size()) {
832 const auto resized = other.resize(this->size());
834 this->map.
set(i, this->map.
get(i) ^ resized.map.get(i));
838 this->map.
set(i, this->map.
get(i) ^ other.map.get(i));
844 template<
typename ALLOC>
849 template<
typename ALLOC_>
855 template<
typename ALLOC_>
856 auto original::operator|(
const bitSet<ALLOC_> &lbs,
const bitSet<ALLOC_> &rbs) -> bitSet<ALLOC_> {
861 template<
typename ALLOC_>
867 template<
typename ALLOC_>
870 for (
u_integer i = 0; i < nbs.map.size(); i++) {
871 nbs.map.set(i, ~nbs.map.get(i));
873 nbs.clearRedundantBits();
Provides the array class for a fixed-size container with random access.
Default memory allocator using allocators utilities.
Definition allocator.h:154
A fixed-size array container with random access.
Definition array.h:41
void set(integer index, const TYPE &e) override
Sets the value of an element at the specified index.
Definition array.h:411
TYPE get(integer index) const override
Retrieves an element at a specified index.
Definition array.h:393
TYPE & data() const
Returns a reference to the first element of the array.
Definition array.h:388
u_integer size() const override
Returns the size of the array.
Definition array.h:382
Base class for fixed-size serial containers.
Definition baseArray.h:43
A base class for basic iterators.
Definition iterator.h:259
An iterator for traversing the bits in a bitSet.
Definition bitSet.h:152
bool hasPrev() const override
Checks if there is a previous element.
Definition bitSet.h:561
bool hasNext() const override
Checks if there is a next element.
Definition bitSet.h:556
Iterator * getPrev() const override
Gets the previous iterator.
Definition bitSet.h:592
bool atNext(const iterator *other) const override
Checks if the iterator is at the next element.
Definition bitSet.h:574
bool & get() override
Gets the value of the current bit.
Definition bitSet.h:639
void next() const override
Moves the iterator to the next element.
Definition bitSet.h:582
Iterator * clone() const override
Clones the iterator.
Definition bitSet.h:551
bool atPrev(const iterator *other) const override
Checks if the iterator is at the previous element.
Definition bitSet.h:566
std::string className() const override
Returns the class name of this iterator.
Definition bitSet.h:644
void operator+=(integer steps) const override
Advances the iterator by the given number of steps.
Definition bitSet.h:608
integer operator-(const iterator &other) const override
Computes the distance between two iterators.
Definition bitSet.h:624
void operator-=(integer steps) const override
Moves the iterator backward by the given number of steps.
Definition bitSet.h:616
void set(const bool &data) override
Sets the value of the current bit.
Definition bitSet.h:656
void prev() const override
Moves the iterator to the previous element.
Definition bitSet.h:587
bool isValid() const override
Checks if the iterator is valid.
Definition bitSet.h:663
Iterator * getNext() const override
Gets the next iterator.
Definition bitSet.h:600
A class representing a set of bits, offering functionality to manipulate and query individual bits.
Definition bitSet.h:29
Iterator * begins() const override
Gets the iterator to the beginning of the bitSet.
Definition bitSet.h:757
friend bitSet< ALLOC_ > operator^(const bitSet< ALLOC_ > &lbs, const bitSet< ALLOC_ > &rbs)
Performs a bitwise XOR operation between two bitSets.
bitSet & operator|=(const bitSet &other)
Performs a bitwise OR operation between two bitSets.
Definition bitSet.h:815
u_integer indexOf(const bool &e) const override
Finds the index of the first occurrence of a specific value.
Definition bitSet.h:789
bitSet & operator&=(const bitSet &other)
Performs a bitwise AND operation between two bitSets.
Definition bitSet.h:800
bitSet(u_integer size, ALLOC allocator=ALLOC{})
Constructs a bitSet with the given size.
Definition bitSet.h:669
Iterator * ends() const override
Gets the iterator to the end of the bitSet.
Definition bitSet.h:762
bool & operator[](integer index) override
Gets the reference of a specific bit by index.
Definition bitSet.h:776
void set(integer index, const bool &e) override
Sets the value of a specific bit by index.
Definition bitSet.h:781
bitSet & operator^=(const bitSet &other)
Performs a bitwise XOR operation between two bitSets.
Definition bitSet.h:830
u_integer size() const override
Gets the size of the bitSet.
Definition bitSet.h:751
bitSet resize(u_integer new_size) const
Resizes the bitSet to the given size.
Definition bitSet.h:735
bool get(integer index) const override
Gets the value of a specific bit by index.
Definition bitSet.h:768
friend bitSet< ALLOC_ > operator&(const bitSet< ALLOC_ > &lbs, const bitSet< ALLOC_ > &rbs)
Performs a bitwise AND operation between two bitSets.
u_integer count() const
Counts the number of bits set to true.
Definition bitSet.h:722
friend bitSet< ALLOC_ > operator~(const bitSet< ALLOC_ > &bs)
Performs a bitwise NOT operation on a bitSet.
friend bitSet< ALLOC_ > operator|(const bitSet< ALLOC_ > &lbs, const bitSet< ALLOC_ > &rbs)
Performs a bitwise OR operation between two bitSets.
std::string className() const override
Gets the class name for the bitSet.
Definition bitSet.h:845
bitSet & operator=(const bitSet &other)
Copy assignment operator.
Definition bitSet.h:690
Abstract base class for containers.
Definition container.h:28
Container for two heterogeneous elements.
Definition couple.h:34
A stream class that allows iteration, comparison, and printing.
Definition iterationStream.h:33
Base iterator interface that supports common operations for iteration.
Definition iterator.h:35
Exception for container index out-of-range errors.
Definition error.h:84
bool indexOutOfBound(integer index) const
Checks if the provided index is out of bounds.
Definition serial.h:133
integer parseNegIndex(integer index) const
Converts negative indices into valid positive indices.
Definition serial.h:140
Exception for unimplemented method calls.
Definition error.h:123
Generic pair container implementation.
Provides functionality for an iteration stream.
Main namespace for the project Original.
Definition algorithms.h:21
TYPE min(TYPE a, TYPE b)
Returns the smaller of two given values.
std::uint32_t u_integer
32-bit unsigned integer type for sizes/indexes
Definition config.h:17
auto operator-(const iterator< T > &it, integer steps) -> iterator< T > *
Subtracts a number of steps from the iterator's current position and returns a new iterator.
std::int64_t integer
64-bit signed integer type for arithmetic operations
Definition config.h:15
bitSet< ALLOC_ > operator^(const bitSet< ALLOC_ > &lbs, const bitSet< ALLOC_ > &rbs)
bitSet< ALLOC_ > operator~(const bitSet< ALLOC_ > &bs)
bitSet< ALLOC_ > operator&(const bitSet< ALLOC_ > &lbs, const bitSet< ALLOC_ > &rbs)
bitSet< ALLOC_ > operator|(const bitSet< ALLOC_ > &lbs, const bitSet< ALLOC_ > &rbs)