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 rebind_alloc(
std::
move(rebind_alloc_node{}))
604 template <
typename TYPE,
typename ALLOC>
609 template <
typename TYPE,
typename ALLOC>
612 for (
const auto&
e :
list) {
614 if (this->
size() == 0)
619 chainNode::connect(this->end_,
cur_node);
626 template <
typename TYPE,
typename ALLOC>
631 if (this->
size() == 0)
636 chainNode::connect(this->end_,
cur_node);
643 template <
typename TYPE,
typename ALLOC>
645 if (
this == &
other)
return *
this;
646 this->chainDestroy();
647 this->size_ =
other.size_;
648 if (this->size() != 0){
652 chainNode::connect(
pivot, this->createNode(
other_->getVal()));
653 this->begin_ =
pivot->getPNext();
654 auto this_ = this->begin_;
657 chainNode::connect(
this_, this->createNode(
other_->getVal()));
664 if constexpr (ALLOC::propagate_on_container_copy_assignment::value){
666 this->rebind_alloc =
other.rebind_alloc;
671 template <
typename TYPE,
typename ALLOC>
674 this->operator=(std::move(
other));
677 template <
typename TYPE,
typename ALLOC>
683 this->chainDestroy();
684 this->begin_ =
other.begin_;
685 this->end_ =
other.end_;
686 this->size_ =
other.size_;
687 if constexpr (ALLOC::propagate_on_container_move_assignment::value){
689 this->rebind_alloc = std::move(
other.rebind_alloc);
695 template <
typename TYPE,
typename ALLOC>
704 if constexpr (ALLOC::propagate_on_container_swap::value) {
710 template <
typename TYPE,
typename ALLOC>
713 if (
this == &
other ||
other.empty())
return *
this;
715 this->size_ +=
other.size_;
717 chainNode::connect(this->end_,
other.begin_);
718 this->end_ =
other.end_;
719 if constexpr (ALLOC::propagate_on_container_merge::value) {
721 this->rebind_alloc +=
other.rebind_alloc;
727 template <
typename TYPE,
typename ALLOC>
733 template <
typename TYPE,
typename ALLOC>
739 template <
typename TYPE,
typename ALLOC>
742 if (this->indexOutOfBound(index)){
746 chainNode*
cur = this->findNode(this->parseNegIndex(index));
747 return cur->getVal();
750 template <
typename TYPE,
typename ALLOC>
753 if (this->indexOutOfBound(index)){
757 chainNode*
cur = this->findNode(this->parseNegIndex(index));
758 return cur->getVal();
761 template <
typename TYPE,
typename ALLOC>
764 if (this->indexOutOfBound(index)){
768 auto cur = this->findNode(this->parseNegIndex(index));
772 template <
typename TYPE,
typename ALLOC>
784 template <
typename TYPE,
typename ALLOC>
788 if (this->size() == 0){
791 auto pivot = this->begin_->getPPrev();
792 chainNode::connect(
new_node, this->begin_);
799 template <
typename TYPE,
typename ALLOC>
802 index = this->parseNegIndex(index);
805 }
else if (index == this->size()){
808 if (this->indexOutOfBound(index)){
813 auto cur = this->findNode(index);
814 auto prev =
cur->getPPrev();
821 template <
typename TYPE,
typename ALLOC>
825 if (this->size() == 0){
828 chainNode::connect(this->end_,
new_node);
834 template <
typename TYPE,
typename ALLOC>
838 if (this->size() == 0){
839 throw noElementError(
"chain::popBegin: Cannot pop from empty chain");
841 if (this->size() == 1){
842 auto del = this->lastDelete();
844 this->destroyNode(
del);
846 res = this->begin_->getVal();
847 auto new_begin = this->begin_->getPNext();
848 auto pivot = this->begin_->getPPrev();
849 this->destroyNode(this->begin_);
851 chainNode::connect(
pivot, this->begin_);
857 template <
typename TYPE,
typename ALLOC>
860 index = this->parseNegIndex(index);
862 return this->popBegin();
864 if (index == this->size() - 1){
865 return this->popEnd();
867 if (this->indexOutOfBound(index)){
872 chainNode*
cur = this->findNode(index);
874 auto prev =
cur->getPPrev();
875 auto next =
cur->getPNext();
876 chainNode::connect(prev, next);
877 this->destroyNode(
cur);
882 template <
typename TYPE,
typename ALLOC>
886 if (this->size() == 0){
887 throw noElementError(
"chain::popEnd: Cannot pop from empty chain");
889 if (this->size() == 1){
890 auto del = this->lastDelete();
892 this->destroyNode(
del);
894 res = this->end_->getVal();
895 auto new_end = this->end_->getPPrev();
896 this->destroyNode(this->end_);
898 chainNode::connect(this->end_,
nullptr);
904 template <
typename TYPE,
typename ALLOC>
909 template <
typename TYPE,
typename ALLOC>
914 template <
typename TYPE,
typename ALLOC>
916 this->chainDestroy();
919 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:773
TYPE popEnd() override
Pops an element from the end of the chain.
Definition chain.h:883
TYPE pop(integer index) override
Pops an element at the specified index in the chain.
Definition chain.h:858
chain(chain &&other) noexcept
Move constructs a chain with optional allocator.
Definition chain.h:672
Iterator * ends() const override
Gets an iterator to the end of the chain.
Definition chain.h:910
u_integer size() const override
Gets the size of the chain.
Definition chain.h:728
Iterator * begins() const override
Gets an iterator to the beginning of the chain.
Definition chain.h:905
chain & operator=(chain &&other) noexcept
Move assignment operator with allocator propagation.
Definition chain.h:678
TYPE popBegin() override
Pops an element from the beginning of the chain.
Definition chain.h:835
std::string className() const override
Gets the class name of the chain.
Definition chain.h:734
chain(const array< TYPE > &arr)
Constructs a chain from an array.
Definition chain.h:627
TYPE get(integer index) const override
Gets the element at the specified index.
Definition chain.h:740
~chain() override
Destructor for the chain.
Definition chain.h:915
TYPE & operator[](integer index) override
Gets a reference to the element at the specified index.
Definition chain.h:751
void push(integer index, const TYPE &e) override
Pushes an element at the specified index in the chain.
Definition chain.h:800
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:605
void pushEnd(const TYPE &e) override
Pushes an element to the end of the chain.
Definition chain.h:822
void pushBegin(const TYPE &e) override
Pushes an element to the beginning of the chain.
Definition chain.h:785
chain & operator=(const chain &other)
Copy assignment operator with allocator propagation.
Definition chain.h:644
void swap(chain &other) noexcept
Swaps the contents of this chain with another.
Definition chain.h:696
chain(const std::initializer_list< TYPE > &list)
Constructs a chain from an initializer list.
Definition chain.h:610
void set(integer index, const TYPE &e) override
Sets the element at the specified index.
Definition chain.h:762
chain & operator+=(chain &other)
Concatenates another chain to this one.
Definition chain.h:711
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.
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.
Definition generators.h:655
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