35 template <
typename TYPE,
typename ALLOC = allocator<TYPE>>
57 explicit chainNode(
const TYPE& data =
TYPE{}, chainNode* prev =
nullptr, chainNode* next =
nullptr);
68 chainNode(
const chainNode&
other);
75 chainNode& operator=(
const chainNode&
other);
81 TYPE& getVal()
override;
87 const TYPE& getVal()
const override;
93 void setVal(
TYPE data)
override;
99 chainNode* getPPrev()
const override;
105 chainNode* getPNext()
const override;
124 static void connect(chainNode* prev, chainNode* next);
136 rebind_alloc_node rebind_alloc{};
144 chainNode* findNode(
integer index)
const;
153 chainNode* createNode(
const TYPE& value =
TYPE{}, chainNode* prev =
nullptr, chainNode* next =
nullptr);
160 void destroyNode(chainNode*
node)
noexcept;
171 void firstAdd(chainNode*
node);
177 chainNode* lastDelete();
392 Iterator*
ends()
const override;
415 template<
typename TYPE,
typename ALLOC>
419 template <
typename TYPE,
typename ALLOC>
421 : data_(data), prev(prev), next(next) {}
423 template <
typename TYPE,
typename ALLOC>
425 : data_(other.data_), prev(other.prev), next(other.next) {}
427 template <
typename TYPE,
typename ALLOC>
429 if (
this != &other) {
437 template <
typename TYPE,
typename ALLOC>
443 template <
typename TYPE,
typename ALLOC>
449 template <
typename TYPE,
typename ALLOC>
455 template <
typename TYPE,
typename ALLOC>
460 template <
typename TYPE,
typename ALLOC>
465 template <
typename TYPE,
typename ALLOC>
467 this->prev = new_prev;
470 template <
typename TYPE,
typename ALLOC>
472 this->next = new_next;
475 template <
typename TYPE,
typename ALLOC>
478 if (prev !=
nullptr) prev->setPNext(next);
479 if (next !=
nullptr) next->setPPrev(prev);
482 template <
typename TYPE,
typename ALLOC>
484 const bool reverse_visit = index <= this->size() / 2 ? 0 : 1;
488 for(u_integer i = 0; i < index; i++)
490 cur = cur->getPNext();
494 for(u_integer i = this->size() - 1; i > index; i -= 1)
496 cur = cur->getPPrev();
502 template<
typename TYPE,
typename ALLOC>
504 auto node = this->rebind_alloc.
allocate(1);
505 this->rebind_alloc.construct(node, value, prev, next);
509 template<
typename TYPE,
typename ALLOC>
511 this->rebind_alloc.
destroy(node);
512 this->rebind_alloc.deallocate(node, 1);
515 template <
typename TYPE,
typename ALLOC>
518 auto pivot = this->createNode();
520 this->begin_ = pivot->getPNext();
524 template <
typename TYPE,
typename ALLOC>
527 chainNode::connect(this->end_, node);
533 template <
typename TYPE,
typename ALLOC>
536 auto last = this->end_;
537 this->destroyNode(last->getPPrev());
538 chainNode::connect(
nullptr, last);
543 template <
typename TYPE,
typename ALLOC>
546 auto current = this->end_;
548 auto prev = current->getPPrev();
549 this->destroyNode(current);
554 template <
typename TYPE,
typename ALLOC>
556 : doubleDirectionIterator<TYPE>::doubleDirectionIterator(ptr) {}
558 template <
typename TYPE,
typename ALLOC>
564 template <
typename TYPE,
typename ALLOC>
566 if (
this == &
other)
return *
this;
571 template <
typename TYPE,
typename ALLOC>
576 template <
typename TYPE,
typename ALLOC>
582 template <
typename TYPE,
typename ALLOC>
588 template <
typename TYPE,
typename ALLOC>
590 return "chain::Iterator";
593 template <
typename TYPE,
typename ALLOC>
599 template <
typename TYPE,
typename ALLOC>
604 template <
typename TYPE,
typename ALLOC>
607 for (
const auto&
e :
list) {
609 if (this->
size() == 0)
614 chainNode::connect(this->end_,
cur_node);
621 template <
typename TYPE,
typename ALLOC>
626 if (this->
size() == 0)
631 chainNode::connect(this->end_,
cur_node);
638 template <
typename TYPE,
typename ALLOC>
640 if (
this == &
other)
return *
this;
641 this->chainDestroy();
642 this->size_ =
other.size_;
643 if (this->size() != 0){
647 chainNode::connect(
pivot, this->createNode(
other_->getVal()));
648 this->begin_ =
pivot->getPNext();
649 auto this_ = this->begin_;
652 chainNode::connect(
this_, this->createNode(
other_->getVal()));
659 if constexpr (ALLOC::propagate_on_container_copy_assignment::value){
661 this->rebind_alloc =
other.rebind_alloc;
666 template <
typename TYPE,
typename ALLOC>
669 this->operator=(std::move(
other));
672 template <
typename TYPE,
typename ALLOC>
678 this->chainDestroy();
679 this->begin_ =
other.begin_;
680 this->end_ =
other.end_;
681 this->size_ =
other.size_;
682 if constexpr (ALLOC::propagate_on_container_move_assignment::value){
684 this->rebind_alloc = std::move(
other.rebind_alloc);
690 template <
typename TYPE,
typename ALLOC>
699 if constexpr (ALLOC::propagate_on_container_swap::value) {
705 template <
typename TYPE,
typename ALLOC>
708 if (
this == &
other ||
other.empty())
return *
this;
710 this->size_ +=
other.size_;
712 chainNode::connect(this->end_,
other.begin_);
713 this->end_ =
other.end_;
714 if constexpr (ALLOC::propagate_on_container_merge::value) {
716 this->rebind_alloc +=
other.rebind_alloc;
722 template <
typename TYPE,
typename ALLOC>
728 template <
typename TYPE,
typename ALLOC>
734 template <
typename TYPE,
typename ALLOC>
737 if (this->indexOutOfBound(index)){
741 chainNode*
cur = this->findNode(this->parseNegIndex(index));
742 return cur->getVal();
745 template <
typename TYPE,
typename ALLOC>
748 if (this->indexOutOfBound(index)){
752 chainNode*
cur = this->findNode(this->parseNegIndex(index));
753 return cur->getVal();
756 template <
typename TYPE,
typename ALLOC>
759 if (this->indexOutOfBound(index)){
763 auto cur = this->findNode(this->parseNegIndex(index));
767 template <
typename TYPE,
typename ALLOC>
779 template <
typename TYPE,
typename ALLOC>
783 if (this->size() == 0){
786 auto pivot = this->begin_->getPPrev();
787 chainNode::connect(
new_node, this->begin_);
794 template <
typename TYPE,
typename ALLOC>
797 index = this->parseNegIndex(index);
800 }
else if (index == this->size()){
803 if (this->indexOutOfBound(index)){
808 auto cur = this->findNode(index);
809 auto prev =
cur->getPPrev();
816 template <
typename TYPE,
typename ALLOC>
820 if (this->size() == 0){
823 chainNode::connect(this->end_,
new_node);
829 template <
typename TYPE,
typename ALLOC>
833 if (this->size() == 0){
834 throw noElementError(
"chain::popBegin: Cannot pop from empty chain");
836 if (this->size() == 1){
837 auto del = this->lastDelete();
839 this->destroyNode(
del);
841 res = this->begin_->getVal();
842 auto new_begin = this->begin_->getPNext();
843 auto pivot = this->begin_->getPPrev();
844 this->destroyNode(this->begin_);
846 chainNode::connect(
pivot, this->begin_);
852 template <
typename TYPE,
typename ALLOC>
855 index = this->parseNegIndex(index);
857 return this->popBegin();
859 if (index == this->size() - 1){
860 return this->popEnd();
862 if (this->indexOutOfBound(index)){
867 chainNode*
cur = this->findNode(index);
869 auto prev =
cur->getPPrev();
870 auto next =
cur->getPNext();
871 chainNode::connect(prev, next);
872 this->destroyNode(
cur);
877 template <
typename TYPE,
typename ALLOC>
881 if (this->size() == 0){
882 throw noElementError(
"chain::popEnd: Cannot pop from empty chain");
884 if (this->size() == 1){
885 auto del = this->lastDelete();
887 this->destroyNode(
del);
889 res = this->end_->getVal();
890 auto new_end = this->end_->getPPrev();
891 this->destroyNode(this->end_);
893 chainNode::connect(this->end_,
nullptr);
899 template <
typename TYPE,
typename ALLOC>
904 template <
typename TYPE,
typename ALLOC>
909 template <
typename TYPE,
typename ALLOC>
911 this->chainDestroy();
914 template <
typename TYPE,
typename ALLOC>
Provides the array class for a fixed-size container with random access.
Provides a base class for variable-size serial containers.
Default memory allocator using allocators utilities.
Definition allocator.h:153
void swap(autoPtr &other) noexcept
Swaps the reference counters between two autoPtr instances.
Definition autoPtr.h:703
const TYPE * get() const
Get managed pointer const version.
Definition autoPtr.h:629
Base class for variable-size serial containers.
Definition baseList.h:43
Bidirectional iterator implementation for chain.
Definition chain.h:195
Iterator & operator=(const Iterator &other)
Assignment operator for Iterator.
Definition chain.h:565
std::string className() const override
Gets the class name of the iterator.
Definition chain.h:589
bool atNext(const iterator< TYPE > *other) const override
Checks if the iterator is at the next position relative to another iterator.
Definition chain.h:583
Iterator * clone() const override
Clones the iterator.
Definition chain.h:572
bool atPrev(const iterator< TYPE > *other) const override
Checks if the iterator is at the previous position relative to another iterator.
Definition chain.h:577
Non-cyclic doubly linked list container.
Definition chain.h:36
u_integer indexOf(const TYPE &e) const override
Finds the index of the first occurrence of the specified element.
Definition chain.h:768
TYPE popEnd() override
Pops an element from the end of the chain.
Definition chain.h:878
TYPE pop(integer index) override
Pops an element at the specified index in the chain.
Definition chain.h:853
chain(chain &&other) noexcept
Move constructs a chain with optional allocator.
Definition chain.h:667
Iterator * ends() const override
Gets an iterator to the end of the chain.
Definition chain.h:905
u_integer size() const override
Gets the size of the chain.
Definition chain.h:723
Iterator * begins() const override
Gets an iterator to the beginning of the chain.
Definition chain.h:900
chain & operator=(chain &&other) noexcept
Move assignment operator with allocator propagation.
Definition chain.h:673
TYPE popBegin() override
Pops an element from the beginning of the chain.
Definition chain.h:830
std::string className() const override
Gets the class name of the chain.
Definition chain.h:729
chain(const array< TYPE > &arr)
Constructs a chain from an array.
Definition chain.h:622
TYPE get(integer index) const override
Gets the element at the specified index.
Definition chain.h:735
~chain() override
Destructor for the chain.
Definition chain.h:910
TYPE & operator[](integer index) override
Gets a reference to the element at the specified index.
Definition chain.h:746
void push(integer index, const TYPE &e) override
Pushes an element at the specified index in the chain.
Definition chain.h:795
chain(ALLOC alloc=ALLOC{})
Constructs an empty chain with specified allocator.
Definition chain.h:594
chain(const chain &other)
Copy constructs a chain with optional allocator.
Definition chain.h:600
void pushEnd(const TYPE &e) override
Pushes an element to the end of the chain.
Definition chain.h:817
void pushBegin(const TYPE &e) override
Pushes an element to the beginning of the chain.
Definition chain.h:780
chain & operator=(const chain &other)
Copy assignment operator with allocator propagation.
Definition chain.h:639
void swap(chain &other) noexcept
Swaps the contents of this chain with another.
Definition chain.h:691
chain(const std::initializer_list< TYPE > &list)
Constructs a chain from an initializer list.
Definition chain.h:605
void set(integer index, const TYPE &e) override
Sets the element at the specified index.
Definition chain.h:757
chain & operator+=(chain &other)
Concatenates another chain to this one.
Definition chain.h:706
TYPE * allocate(u_integer size)
Allocates raw memory for elements.
Definition container.h:131
void destroy(O_TYPE *o_ptr)
Destroys an element.
Definition container.h:148
Abstract base class for double-direction iterators.
Definition doubleDirectionIterator.h:24
doubleDirectionIterator & operator=(const doubleDirectionIterator &other)
Copy assignment operator for doubleDirectionIterator.
Definition doubleDirectionIterator.h:77
A stream class that allows iteration, comparison, hashing and printing.
Definition iterationStream.h:60
Base iterator interface that supports common operations for iteration.
Definition iterator.h:37
Exception for missing element requests.
Definition error.h:298
Exception for container index out-of-range errors.
Definition error.h:192
Unique ownership smart pointer with move semantics.
Definition ownerPtr.h:37
static std::string formatString(const TYPE &t)
Universal value-to-string conversion with type-specific formatting.
Definition printable.h:339
Base class for linked value containers with formatted output.
Definition wrapper.h:28
Double-direction iterator base class.
std::uint32_t u_integer
32-bit unsigned integer type for sizes and indexes
Definition config.h:263
std::int64_t integer
64-bit signed integer type for arithmetic operations
Definition config.h:254
Provides functionality for an iteration stream with comparison, hashing and printing.
Main namespace for the project Original.
Definition algorithms.h:21
SERIAL< TYPE > list(coroutine::generator< TYPE > gen)
Collects generator elements into a list container.
Standard namespace extensions for original::alternative.
Definition allocator.h:351
void swap(original::objPoolAllocator< TYPE > &lhs, original::objPoolAllocator< TYPE > &rhs) noexcept
Specialization of std::swap for objPoolAllocator.
Definition allocator.h:635