ORIGINAL
Loading...
Searching...
No Matches
blocksList.h
Go to the documentation of this file.
1#ifndef BLOCKSLIST_H
2#define BLOCKSLIST_H
3
4#include "baseList.h"
5#include "couple.h"
6#include "vector.h"
7
15
16namespace original {
29 template <typename TYPE, typename ALLOC = allocator<TYPE>>
30 class blocksList final : public baseList<TYPE, ALLOC>, public iterationStream<TYPE, blocksList<TYPE, ALLOC>> {
31 static constexpr u_integer BLOCK_MAX_SIZE = 16;
32 static constexpr u_integer POS_INIT = (BLOCK_MAX_SIZE - 1) / 2 + 1;
33
39 vector<TYPE*> map;
40
41 u_integer size_;
42 u_integer first_;
43 u_integer last_;
44 u_integer first_block;
45 u_integer last_block;
46
47
54 TYPE* blockArrayInit();
55
61 void blocksListInit();
62
68 void blocksListDestruct() noexcept;
69
76 [[nodiscard]] static u_integer innerIdxToAbsIdx(u_integer block, u_integer pos);
77
82 [[nodiscard]] u_integer firstAbsIdx() const;
83
88 [[nodiscard]] u_integer lastAbsIdx() const;
89
95 [[nodiscard]] integer absIdxToOuterIdx(u_integer absIdx) const;
96
102 [[nodiscard]] u_integer outerIdxToAbsIdx(integer outerIdx) const;
103
109 [[nodiscard]] static couple<u_integer, u_integer> absIdxToInnerIdx(u_integer absIdx);
110
118 [[nodiscard]] static couple<u_integer, u_integer> innerIdxOffset(u_integer block, u_integer pos, integer offset);
119
125 [[nodiscard]] couple<u_integer, u_integer> outerIdxToInnerIdx(integer outerIdx) const;
126
133 [[nodiscard]] integer innerIdxToOuterIdx(u_integer block, u_integer pos) const;
134
141 TYPE& getElem(u_integer block, u_integer pos) const;
142
149 void setElem(u_integer block, u_integer pos, const TYPE& e);
150
157 [[nodiscard]] bool growNeeded(u_integer increment, bool is_first) const;
158
166 void moveElements(u_integer start_block, u_integer start_pos, u_integer len, integer offset);
167
174 void addBlock(bool is_first);
175
183 void adjust(u_integer increment, bool is_first);
184
185 public:
192 class Iterator final : public baseIterator<TYPE> {
193 mutable integer cur_pos;
194 mutable integer cur_block;
195 mutable TYPE** data_;
196 const blocksList* container_;
197
205 explicit Iterator(integer pos, integer block, TYPE** data_ptr, const blocksList* container);
206
212 bool equalPtr(const iterator<TYPE>* other) const override;
213
214 public:
215 friend blocksList;
216
221 Iterator(const Iterator& other);
222
228 Iterator& operator=(const Iterator& other);
229
234 Iterator* clone() const override;
235
240 [[nodiscard]] bool hasNext() const override;
241
246 [[nodiscard]] bool hasPrev() const override;
247
251 void next() const override;
252
256 void prev() const override;
257
262 void operator+=(integer steps) const override;
263
268 void operator-=(integer steps) const override;
269
275 integer operator-(const iterator<TYPE>& other) const override;
276
281 Iterator* getPrev() const override;
282
287 Iterator* getNext() const override;
288
293 TYPE& get() override;
294
299 TYPE get() const override;
300
305 void set(const TYPE& data) override;
306
311 [[nodiscard]] bool isValid() const override;
312
318 bool atPrev(const iterator<TYPE>* other) const override;
319
325 bool atNext(const iterator<TYPE>* other) const override;
326
331 [[nodiscard]] std::string className() const override;
332 };
333
334 friend Iterator;
335
342 explicit blocksList(ALLOC alloc = ALLOC{});
343
348 blocksList(const std::initializer_list<TYPE>& lst);
349
354 explicit blocksList(const array<TYPE>& arr);
355
362 blocksList(const blocksList& other);
363
372
379 blocksList(blocksList&& other) noexcept;
380
388 blocksList& operator=(blocksList&& other) noexcept;
389
395 TYPE get(integer index) const override;
396
401 [[nodiscard]] u_integer size() const override;
402
407 Iterator* begins() const override;
408
413 Iterator* ends() const override;
414
420 TYPE& operator[](integer index) override;
421
427 void set(integer index, const TYPE& e) override;
428
434 u_integer indexOf(const TYPE& e) const override;
435
441 void push(integer index, const TYPE& e) override;
442
448 TYPE pop(integer index) override;
449
454 void pushBegin(const TYPE& e) override;
455
460 TYPE popBegin() override;
461
466 void pushEnd(const TYPE& e) override;
467
472 TYPE popEnd() override;
473
478 [[nodiscard]] std::string className() const override;
479
483 ~blocksList() override;
484 };
485}// namespace original
486
487 template <typename TYPE, typename ALLOC>
488 auto original::blocksList<TYPE, ALLOC>::blocksListInit() -> void
489 {
490 this->map = vector({this->blockArrayInit()});
491 this->size_ = 0;
492 this->first_ = POS_INIT + 1;
493 this->last_ = POS_INIT;
494 this->first_block = this->map.size() / 2;
495 this->last_block = this->map.size() / 2;
496 }
497
498 template <typename TYPE, typename ALLOC>
499 auto original::blocksList<TYPE, ALLOC>::blocksListDestruct() noexcept -> void
500 {
501 for (auto* block : this->map) {
502 for (u_integer i = 0; i < BLOCK_MAX_SIZE; ++i) {
503 this->destroy(&block[i]);
504 }
505 this->deallocate(block, BLOCK_MAX_SIZE);
506 }
507 }
508
509 template <typename TYPE, typename ALLOC>
510 auto original::blocksList<TYPE, ALLOC>::blockArrayInit() -> TYPE* {
511 auto arr = this->allocate(BLOCK_MAX_SIZE);
512 for (u_integer i = 0; i < BLOCK_MAX_SIZE; i++) {
513 this->construct(&arr[i]);
514 }
515 return arr;
516 }
517
518 template <typename TYPE, typename ALLOC>
519 auto original::blocksList<TYPE, ALLOC>::innerIdxToAbsIdx(const u_integer block, const u_integer pos) -> u_integer
520 {
521 return block * BLOCK_MAX_SIZE + pos;
522 }
523
524 template <typename TYPE, typename ALLOC>
525 auto original::blocksList<TYPE, ALLOC>::firstAbsIdx() const -> u_integer
526 {
527 return innerIdxToAbsIdx(this->first_block, this->first_);
528 }
529
530 template <typename TYPE, typename ALLOC>
531 auto original::blocksList<TYPE, ALLOC>::lastAbsIdx() const -> u_integer
532 {
533 return innerIdxToAbsIdx(this->last_block, this->last_);
534 }
535
536 template <typename TYPE, typename ALLOC>
537 auto original::blocksList<TYPE, ALLOC>::absIdxToOuterIdx(const u_integer absIdx) const -> integer
538 {
539 return absIdx - this->firstAbsIdx();
540 }
541
542 template <typename TYPE, typename ALLOC>
543 auto original::blocksList<TYPE, ALLOC>::outerIdxToAbsIdx(const integer outerIdx) const -> u_integer
544 {
545 return this->firstAbsIdx() + outerIdx;
546 }
547
548 template <typename TYPE, typename ALLOC>
549 auto original::blocksList<TYPE, ALLOC>::absIdxToInnerIdx(const u_integer absIdx) -> couple<u_integer, u_integer>
550 {
551 return {absIdx / BLOCK_MAX_SIZE, absIdx % BLOCK_MAX_SIZE};
552 }
553
554 template <typename TYPE, typename ALLOC>
555 auto original::blocksList<TYPE, ALLOC>::innerIdxOffset(const u_integer block, const u_integer pos,
556 const integer offset) -> couple<u_integer, u_integer>
557 {
558 return absIdxToInnerIdx(static_cast<u_integer>(static_cast<integer>(innerIdxToAbsIdx(block, pos)) + offset));
559 }
560
561 template <typename TYPE, typename ALLOC>
562 auto original::blocksList<TYPE, ALLOC>::outerIdxToInnerIdx(const integer outerIdx) const -> couple<u_integer, u_integer>
563 {
564 return absIdxToInnerIdx(this->outerIdxToAbsIdx(outerIdx));
565 }
566
567 template <typename TYPE, typename ALLOC>
568 auto original::blocksList<TYPE, ALLOC>::innerIdxToOuterIdx(const u_integer block, const u_integer pos) const -> integer
569 {
570 return this->absIdxToOuterIdx(innerIdxToAbsIdx(block, pos));
571 }
572
573 template <typename TYPE, typename ALLOC>
574 auto original::blocksList<TYPE, ALLOC>::getElem(u_integer block, u_integer pos) const -> TYPE&
575 {
576 return this->map.get(block)[pos];
577 }
578
579 template <typename TYPE, typename ALLOC>
580 auto original::blocksList<TYPE, ALLOC>::setElem(u_integer block, u_integer pos, const TYPE& e) -> void
581 {
582 this->map.get(block)[pos] = e;
583 }
584
585 template <typename TYPE, typename ALLOC>
586 auto original::blocksList<TYPE, ALLOC>::growNeeded(const u_integer increment, bool is_first) const -> bool
587 {
588 return is_first ? firstAbsIdx() < increment
589 : lastAbsIdx() + increment > innerIdxToAbsIdx(this->map.size() - 1, BLOCK_MAX_SIZE - 1);
590 }
591
592 template <typename TYPE, typename ALLOC>
593 auto original::blocksList<TYPE, ALLOC>::moveElements(const u_integer start_block, const u_integer start_pos,
594 const u_integer len, const integer offset) -> void
595 {
596 if (offset > 0)
597 {
598 for (u_integer i = 0; i < len; i++)
599 {
600 auto idx = innerIdxOffset(start_block, start_pos, len - 1 - i);
601 auto idx_offset = innerIdxOffset(start_block, start_pos, len - 1 - i + offset);
602 this->setElem(idx_offset.first(), idx_offset.second(),
603 this->getElem(idx.first(), idx.second()));
604 }
605 }else
606 {
607 for (u_integer i = 0; i < len; i++)
608 {
609 auto idx = innerIdxOffset(start_block, start_pos, i);
610 auto idx_offset = innerIdxOffset(start_block, start_pos, i + offset);
611 this->setElem(idx_offset.first(), idx_offset.second(),
612 this->getElem(idx.first(), idx.second()));
613 }
614 }
615 }
616
617 template <typename TYPE, typename ALLOC>
618 auto original::blocksList<TYPE, ALLOC>::addBlock(bool is_first) -> void
619 {
620 auto* new_block = this->blockArrayInit();
621 is_first ? this->map.pushBegin(new_block) : this->map.pushEnd(new_block);
622 }
623
624 template <typename TYPE, typename ALLOC>
625 auto original::blocksList<TYPE, ALLOC>::adjust(const u_integer increment, const bool is_first) -> void
626 {
627 if (this->growNeeded(increment, is_first)){
628 u_integer new_blocks_cnt = increment / BLOCK_MAX_SIZE + 1;
629 for (u_integer i = 0; i < new_blocks_cnt; ++i) {
630 this->addBlock(is_first);
631 }
632 if (is_first){
633 this->first_block += new_blocks_cnt;
634 this->last_block += new_blocks_cnt;
635 }
636 }
637 }
638
639 template <typename TYPE, typename ALLOC>
640 original::blocksList<TYPE, ALLOC>::Iterator::Iterator(const integer pos, const integer block, TYPE** data_ptr, const blocksList* container)
641 : cur_pos(pos), cur_block(block), data_(data_ptr), container_(container) {}
642
643 template <typename TYPE, typename ALLOC>
644 auto original::blocksList<TYPE, ALLOC>::Iterator::equalPtr(const iterator<TYPE>* other) const -> bool
645 {
646 auto* other_it = dynamic_cast<const Iterator*>(other);
647 return other_it != nullptr
648 && this->cur_pos == other_it->cur_pos
649 && this->cur_block == other_it->cur_block
650 && this->data_ == other_it->data_
651 && this->container_ == other_it->container_;
652 }
653
654 template <typename TYPE, typename ALLOC>
655 original::blocksList<TYPE, ALLOC>::Iterator::Iterator(const Iterator& other) : Iterator(0, 0, nullptr, nullptr)
656 {
657 this->operator=(other);
658 }
659
660 template <typename TYPE, typename ALLOC>
661 auto original::blocksList<TYPE, ALLOC>::Iterator::operator=(const Iterator& other) -> Iterator&
662 {
663 if (this == &other)
664 return *this;
665
666 this->cur_pos = other.cur_pos;
667 this->cur_block = other.cur_block;
668 this->data_ = other.data_;
669 this->container_ = other.container_;
670 return *this;
671 }
672
673 template <typename TYPE, typename ALLOC>
675 {
676 return new Iterator(*this);
677 }
678
679 template <typename TYPE, typename ALLOC>
681 {
682 return blocksList::innerIdxToAbsIdx(this->cur_block, this->cur_pos) < this->container_->lastAbsIdx();
683 }
684
685 template <typename TYPE, typename ALLOC>
687 {
688 return blocksList::innerIdxToAbsIdx(this->cur_block, this->cur_pos) > this->container_->firstAbsIdx();
689 }
690
691 template <typename TYPE, typename ALLOC>
693 {
694 this->operator+=(1);
695 }
696
697 template <typename TYPE, typename ALLOC>
699 {
700 this->operator-=(1);
701 }
702
703 template <typename TYPE, typename ALLOC>
705 {
706 auto new_idx = innerIdxOffset(this->cur_block, this->cur_pos, steps);
707 this->cur_block = new_idx.first();
708 this->cur_pos = new_idx.second();
709 }
710
711 template <typename TYPE, typename ALLOC>
713 {
714 auto new_idx = innerIdxOffset(this->cur_block, this->cur_pos, -steps);
715 this->cur_block = new_idx.first();
716 this->cur_pos = new_idx.second();
717 }
718
719 template <typename TYPE, typename ALLOC>
721 {
722 auto* other_it = dynamic_cast<const Iterator*>(&other);
723 if (other_it == nullptr)
724 return this > &other ?
725 std::numeric_limits<integer>::max() :
726 std::numeric_limits<integer>::min();
727 if (this->container_ != other_it->container_)
728 return this->container_ > other_it->container_ ?
729 std::numeric_limits<integer>::max() :
730 std::numeric_limits<integer>::min();
731
732 return static_cast<integer>(innerIdxToAbsIdx(this->cur_block, this->cur_pos)) -
733 static_cast<integer>(innerIdxToAbsIdx(other_it->cur_block, other_it->cur_pos));
734 }
735
736 template <typename TYPE, typename ALLOC>
738 {
739 if (!this->isValid()) throw outOfBoundError();
740 auto* it = this->clone();
741 it->prev();
742 return it;
743 }
744
745 template <typename TYPE, typename ALLOC>
747 {
748 if (!this->isValid()) throw outOfBoundError();
749 auto* it = this->clone();
750 it->next();
751 return it;
752 }
753
754 template <typename TYPE, typename ALLOC>
756 {
757 if (!this->isValid()) throw outOfBoundError();
758 return this->data_[this->cur_block][this->cur_pos];
759 }
760
761 template <typename TYPE, typename ALLOC>
763 {
764 if (!this->isValid()) throw outOfBoundError();
765 return this->data_[this->cur_block][this->cur_pos];
766 }
767
768 template <typename TYPE, typename ALLOC>
770 {
771 if (!this->isValid()) throw outOfBoundError();
772 this->data_[this->cur_block][this->cur_pos] = data;
773 }
774
775 template <typename TYPE, typename ALLOC>
777 {
778 return this->container_->innerIdxToOuterIdx(this->cur_block, this->cur_pos) >= 0 &&
779 this->container_->innerIdxToOuterIdx(this->cur_block, this->cur_pos) < this->container_->size();
780 }
781
782 template <typename TYPE, typename ALLOC>
784 {
785 auto* other_it = dynamic_cast<const Iterator*>(other);
786 if (other_it == nullptr)
787 return false;
788 return this->operator-(*other_it) == -1;
789 }
790
791 template <typename TYPE, typename ALLOC>
793 {
794 auto* other_it = dynamic_cast<const Iterator*>(other);
795 if (other_it == nullptr)
796 return false;
797 return this->operator-(*other_it) == 1;
798 }
799
800 template <typename TYPE, typename ALLOC>
802 return "blocksList::Iterator";
803 }
804
805 template <typename TYPE, typename ALLOC>
807 : baseList<TYPE, ALLOC>(std::move(alloc)), map(), size_(), first_(), last_(), first_block(), last_block()
808 {
809 this->blocksListInit();
810 }
811
812 template <typename TYPE, typename ALLOC>
813 original::blocksList<TYPE, ALLOC>::blocksList(const std::initializer_list<TYPE>& lst) : blocksList() {
814 this->adjust(lst.size(), false);
815 for (const auto& e : lst) {
816 auto new_idx = innerIdxOffset(this->last_block, this->last_, 1);
817 this->last_block = new_idx.first();
818 this->last_ = new_idx.second();
819 this->setElem(this->last_block, this->last_, e);
820 this->size_ += 1;
821 }
822 }
823
824 template <typename TYPE, typename ALLOC>
826 this->adjust(arr.size(), false);
827 for (const auto& e : arr) {
828 auto new_idx = innerIdxOffset(this->last_block, this->last_, 1);
829 this->last_block = new_idx.first();
830 this->last_ = new_idx.second();
831 this->setElem(this->last_block, this->last_, e);
832 this->size_ += 1;
833 }
834 }
835
836 template <typename TYPE, typename ALLOC>
840
841 template <typename TYPE, typename ALLOC>
843 if (this == &other) return *this;
844
845 this->blocksListDestruct();
846 this->map = vector<TYPE*>{};
847
848 for (integer i = 0; i < other.map.size(); ++i) {
849 auto* block = this->blockArrayInit();
850 for (u_integer j = 0; j < BLOCK_MAX_SIZE; ++j) {
851 block[j] = other.getElem(i, j);
852 }
853 this->map.pushEnd(block);
854 }
855
856 this->first_ = other.first_;
857 this->last_ = other.last_;
858 this->size_ = other.size_;
859 this->first_block = other.first_block;
860 this->last_block = other.last_block;
861 if constexpr (ALLOC::propagate_on_container_copy_assignment::value){
862 this->allocator = other.allocator;
863 }
864 return *this;
865 }
866
867 template <typename TYPE, typename ALLOC>
869 {
870 this->operator=(std::move(other));
871 }
872
873 template <typename TYPE, typename ALLOC>
875 {
876 if (this == &other)
877 return *this;
878
879 this->blocksListDestruct();
880
881 this->map = std::move(other.map);
882 this->first_ = other.first_;
883 this->last_ = other.last_;
884 this->first_block = other.first_block;
885 this->last_block = other.last_block;
886 this->size_ = other.size_;
887 if constexpr (ALLOC::propagate_on_container_move_assignment::value){
888 this->allocator = std::move(other.allocator);
889 }
890 other.blocksListInit();
891 return *this;
892 }
893
894 template <typename TYPE, typename ALLOC>
896 if (this->indexOutOfBound(this->parseNegIndex(index))) throw outOfBoundError();
897 index = this->parseNegIndex(index);
898 auto inner_idx = this->outerIdxToInnerIdx(index);
899 return this->getElem(inner_idx.first(), inner_idx.second());
900 }
901
902 template <typename TYPE, typename ALLOC>
904 {
905 return this->size_;
906 }
907
908 template <typename TYPE, typename ALLOC>
910 return new Iterator(this->first_, this->first_block, &this->map.data(), this);
911 }
912
913 template <typename TYPE, typename ALLOC>
915 return new Iterator(this->last_, this->last_block, &this->map.data(), this);
916 }
917
918 template <typename TYPE, typename ALLOC>
920 if (this->indexOutOfBound(this->parseNegIndex(index))) throw outOfBoundError();
921 index = this->parseNegIndex(index);
922 auto inner_idx = this->outerIdxToInnerIdx(index);
923 return this->getElem(inner_idx.first(), inner_idx.second());
924 }
925
926 template <typename TYPE, typename ALLOC>
927 auto original::blocksList<TYPE, ALLOC>::set(integer index, const TYPE &e) -> void {
928 if (this->indexOutOfBound(index)) throw outOfBoundError();
929 index = this->parseNegIndex(index);
930 auto inner_idx = this->outerIdxToInnerIdx(index);
931 this->setElem(inner_idx.first(), inner_idx.second(), e);
932 }
933
934 template <typename TYPE, typename ALLOC>
936 for (u_integer i = 0; i < this->size(); ++i) {
937 if (auto idx = this->outerIdxToInnerIdx(i);
938 this->getElem(idx.first(), idx.second()) == e)
939 return i;
940 }
941 return this->size();
942 }
943
944 template <typename TYPE, typename ALLOC>
945 auto original::blocksList<TYPE, ALLOC>::push(integer index, const TYPE& e) -> void
946 {
947 if (this->parseNegIndex(index) == this->size())
948 {
949 this->pushEnd(e);
950 } else if (this->parseNegIndex(index) == 0)
951 {
952 this->pushBegin(e);
953 } else{
954 if (this->indexOutOfBound(index))
955 throw outOfBoundError();
956
957 index = this->parseNegIndex(index);
958 const bool is_first = index <= (this->size() - 1) / 2;
959 this->adjust(1, is_first);
960 if (is_first){
961 this->moveElements(this->first_block, this->first_, index + 1, -1);
962 auto new_idx = innerIdxOffset(this->first_block, this->first_, -1);
963 this->first_block = new_idx.first();
964 this->first_ = new_idx.second();
965 } else{
966 auto idx = outerIdxToInnerIdx(index);
967 this->moveElements(idx.first(), idx.second(), this->size() - index, 1);
968 auto new_idx = innerIdxOffset(this->last_block, this->last_, 1);
969 this->last_block = new_idx.first();
970 this->last_ = new_idx.second();
971 }
972 this->size_ += 1;
973 auto idx = outerIdxToInnerIdx(index);
974 this->setElem(idx.first(), idx.second(), e);
975 }
976 }
977
978 template <typename TYPE, typename ALLOC>
980 {
981 if (this->parseNegIndex(index) == 0)
982 return this->popBegin();
983 if (this->parseNegIndex(index) == this->size() - 1)
984 return this->popEnd();
985 if (this->indexOutOfBound(index))
986 throw outOfBoundError();
987
988 index = this->parseNegIndex(index);
989 auto idx = outerIdxToInnerIdx(index);
990 TYPE res = this->getElem(idx.first(), idx.second());
991 if (index <= (this->size() - 1) / 2){
992 moveElements(this->first_block, this->first_, index, 1);
993 auto new_idx = innerIdxOffset(this->first_block, this->first_, 1);
994 this->first_block = new_idx.first();
995 this->first_ = new_idx.second();
996 } else{
997 auto idx_offset = innerIdxOffset(idx.first(), idx.second(), 1);
998 moveElements(idx_offset.first(), idx_offset.second(), this->size() - 1 - index, -1);
999 auto new_idx = innerIdxOffset(this->last_block, this->last_, -1);
1000 this->last_block = new_idx.first();
1001 this->last_ = new_idx.second();
1002 }
1003 this->size_ -= 1;
1004 return res;
1005 }
1006
1007 template <typename TYPE, typename ALLOC>
1009 {
1010 this->adjust(1, true);
1011 auto new_idx = innerIdxOffset(this->first_block, this->first_, -1);
1012 this->first_block = new_idx.first();
1013 this->first_ = new_idx.second();
1014 this->setElem(this->first_block, this->first_, e);
1015 this->size_ += 1;
1016 }
1017
1018 template <typename TYPE, typename ALLOC>
1020 {
1021 if (this->empty()) throw noElementError();
1022
1023 TYPE res = this->getElem(this->first_block, this->first_);
1024 auto new_idx = innerIdxOffset(this->first_block, this->first_, 1);
1025 this->first_block = new_idx.first();
1026 this->first_ = new_idx.second();
1027 this->size_ -= 1;
1028 return res;
1029 }
1030
1031 template <typename TYPE, typename ALLOC>
1033 {
1034 this->adjust(1, false);
1035 auto new_idx = innerIdxOffset(this->last_block, this->last_, 1);
1036 this->last_block = new_idx.first();
1037 this->last_ = new_idx.second();
1038 this->setElem(this->last_block, this->last_, e);
1039 this->size_ += 1;
1040 }
1041
1042 template <typename TYPE, typename ALLOC>
1044 {
1045 if (this->empty()) throw noElementError();
1046
1047 TYPE res = this->getElem(this->last_block, this->last_);
1048 auto new_idx = innerIdxOffset(this->last_block, this->last_, -1);
1049 this->last_block = new_idx.first();
1050 this->last_ = new_idx.second();
1051 this->size_ -= 1;
1052 return res;
1053 }
1054
1055 template <typename TYPE, typename ALLOC>
1057 return "blocksList";
1058 }
1059
1060 template <typename TYPE, typename ALLOC>
1062 this->blocksListDestruct();
1063 }
1064
1065#endif //BLOCKSLIST_H
Provides a base class for variable-size serial containers.
Default memory allocator using allocators utilities.
Definition allocator.h:154
A fixed-size array container with random access.
Definition array.h:41
u_integer size() const override
Returns the size of the array.
Definition array.h:382
A base class for basic iterators.
Definition iterator.h:259
Base class for variable-size serial containers.
Definition baseList.h:43
Iterator for blocksList, supports forward and backward iteration.
Definition blocksList.h:192
Iterator * getNext() const override
Gets the next iterator.
Definition blocksList.h:746
Iterator * clone() const override
Clones the iterator.
Definition blocksList.h:674
void operator-=(integer steps) const override
Moves the iterator backward by the specified number of steps.
Definition blocksList.h:712
Iterator & operator=(const Iterator &other)
Assignment operator for the Iterator.
Definition blocksList.h:661
void prev() const override
Moves the iterator to the previous element.
Definition blocksList.h:698
bool hasNext() const override
Checks if there is a next element.
Definition blocksList.h:680
Iterator * getPrev() const override
Gets the previous iterator.
Definition blocksList.h:737
void next() const override
Moves the iterator to the next element.
Definition blocksList.h:692
bool hasPrev() const override
Checks if there is a previous element.
Definition blocksList.h:686
void operator+=(integer steps) const override
Advances the iterator by the specified number of steps.
Definition blocksList.h:704
void set(const TYPE &data) override
Sets the value of the element pointed to by the iterator.
Definition blocksList.h:769
TYPE & get() override
Gets the element pointed to by the iterator.
Definition blocksList.h:755
bool isValid() const override
Checks if the iterator is valid.
Definition blocksList.h:776
bool atPrev(const iterator< TYPE > *other) const override
Checks if the iterator is at the previous element relative to another iterator.
Definition blocksList.h:783
bool atNext(const iterator< TYPE > *other) const override
Checks if the iterator is at the next element relative to another iterator.
Definition blocksList.h:792
std::string className() const override
Gets the class name of the iterator.
Definition blocksList.h:801
integer operator-(const iterator< TYPE > &other) const override
Computes the distance between two iterators.
Definition blocksList.h:720
A block-based list implementation.
Definition blocksList.h:30
std::string className() const override
Gets the class name of the blocksList.
Definition blocksList.h:1056
u_integer indexOf(const TYPE &e) const override
Finds the index of the first occurrence of the specified element.
Definition blocksList.h:935
void pushEnd(const TYPE &e) override
Pushes an element to the end of the blocksList.
Definition blocksList.h:1032
TYPE get(integer index) const override
Gets the element at the specified index.
Definition blocksList.h:895
blocksList(blocksList &&other) noexcept
Move constructor.
Definition blocksList.h:868
void pushBegin(const TYPE &e) override
Pushes an element to the beginning of the blocksList.
Definition blocksList.h:1008
TYPE popEnd() override
Pops the element from the end of the blocksList.
Definition blocksList.h:1043
blocksList(ALLOC alloc=ALLOC{})
Constructs an empty blocksList.
Definition blocksList.h:806
u_integer size() const override
Gets the size of the blocksList.
Definition blocksList.h:903
Iterator * begins() const override
Gets an iterator to the beginning of the blocksList.
Definition blocksList.h:909
void set(integer index, const TYPE &e) override
Sets the element at the specified index.
Definition blocksList.h:927
blocksList(const array< TYPE > &arr)
Constructs a blocksList from an array.
Definition blocksList.h:825
TYPE popBegin() override
Pops the element from the beginning of the blocksList.
Definition blocksList.h:1019
void push(integer index, const TYPE &e) override
Pushes an element to the specified index in the blocksList.
Definition blocksList.h:945
blocksList & operator=(blocksList &&other) noexcept
Move assignment operator.
Definition blocksList.h:874
blocksList(const std::initializer_list< TYPE > &lst)
Constructs a blocksList from an initializer list.
Definition blocksList.h:813
TYPE pop(integer index) override
Pops the element at the specified index in the blocksList.
Definition blocksList.h:979
blocksList(const blocksList &other)
Copy constructor.
Definition blocksList.h:837
Iterator * ends() const override
Gets an iterator to the end of the blocksList.
Definition blocksList.h:914
blocksList & operator=(const blocksList &other)
Copy assignment operator.
Definition blocksList.h:842
~blocksList() override
Destructor for the blocksList.
Definition blocksList.h:1061
TYPE & operator[](integer index) override
Gets a reference to the element at the specified index.
Definition blocksList.h:919
Abstract base class for containers.
Definition container.h:28
ALLOC allocator
The allocator instance used for memory management.
Definition container.h:34
bool empty() const
Checks if the container is empty.
Definition container.h:155
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 missing element requests.
Definition error.h:136
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
Dynamic array container with amortized constant time operations.
Definition vector.h:42
u_integer size() const override
Gets the size of the vector.
Definition vector.h:557
Generic pair container implementation.
Main namespace for the project Original.
Definition algorithms.h:21
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
Dynamic array container with automatic resizing.