32 template <
typename TYPE,
typename ALLOC = allocator<TYPE>>
41 class forwardChainNode final :
public wrapper<TYPE>{
51 explicit forwardChainNode(
const TYPE& data = TYPE{}, forwardChainNode* next =
nullptr);
54 forwardChainNode* next;
61 forwardChainNode(
const forwardChainNode& other);
68 forwardChainNode&
operator=(
const forwardChainNode& other);
74 TYPE& getVal()
override;
80 const TYPE& getVal()
const override;
86 void setVal(TYPE data)
override;
92 forwardChainNode* getPPrev()
const override;
98 forwardChainNode* getPNext()
const override;
104 void setPNext(forwardChainNode* new_next);
111 static void connect(forwardChainNode* prev, forwardChainNode* next);
119 using rebind_alloc_node =
typename ALLOC::template rebind_alloc<forwardChainNode>;
122 forwardChainNode* begin_;
123 rebind_alloc_node rebind_alloc{};
130 forwardChainNode* beginNode()
const;
137 forwardChainNode* findNode(
integer index)
const;
146 forwardChainNode* createNode(
const TYPE& value = TYPE{}, forwardChainNode* next =
nullptr);
154 void destroyNode(forwardChainNode* node)
noexcept;
165 void firstAdd(forwardChainNode* node);
171 forwardChainNode* lastDelete();
176 void chainDestruction();
191 explicit Iterator(forwardChainNode* ptr);
199 Iterator(
const Iterator& other);
206 Iterator&
operator=(
const Iterator& other);
212 Iterator*
clone()
const override;
232 [[nodiscard]] std::string
className()
const override;
310 void set(
integer index,
const TYPE &e)
override;
339 void pushEnd(
const TYPE &e)
override;
369 Iterator*
begins()
const override;
375 Iterator*
ends()
const override;
381 [[nodiscard]] std::string
className()
const override;
390 template <
typename TYPE,
typename ALLOC>
391 original::forwardChain<TYPE, ALLOC>::forwardChainNode::forwardChainNode(
const TYPE& data, forwardChainNode* next)
392 : data_(data), next(next) {}
394 template <
typename TYPE,
typename ALLOC>
395 original::forwardChain<TYPE, ALLOC>::forwardChainNode::forwardChainNode(
const forwardChainNode &other)
396 : data_(other.data_), next(other.next) {}
398 template <
typename TYPE,
typename ALLOC>
399 auto original::forwardChain<TYPE, ALLOC>::forwardChainNode::operator=(
400 const forwardChainNode &other) -> forwardChainNode & {
401 if (
this != &other) {
408 template <
typename TYPE,
typename ALLOC>
409 auto original::forwardChain<TYPE, ALLOC>::forwardChainNode::getVal() -> TYPE& {
413 template <
typename TYPE,
typename ALLOC>
414 auto original::forwardChain<TYPE, ALLOC>::forwardChainNode::getVal() const -> const TYPE& {
418 template <
typename TYPE,
typename ALLOC>
419 auto original::forwardChain<TYPE, ALLOC>::forwardChainNode::setVal(TYPE data) ->
void {
423 template <
typename TYPE,
typename ALLOC>
424 auto original::forwardChain<TYPE, ALLOC>::forwardChainNode::getPPrev() const -> forwardChainNode* {
425 throw unSupportedMethodError();
428 template <
typename TYPE,
typename ALLOC>
429 auto original::forwardChain<TYPE, ALLOC>::forwardChainNode::getPNext() const -> forwardChainNode* {
433 template <
typename TYPE,
typename ALLOC>
434 auto original::forwardChain<TYPE, ALLOC>::forwardChainNode::setPNext(forwardChainNode *new_next) ->
void {
435 this->next = new_next;
438 template <
typename TYPE,
typename ALLOC>
439 auto original::forwardChain<TYPE, ALLOC>::forwardChainNode::connect(
440 forwardChainNode *prev, forwardChainNode *next) ->
void {
441 if (prev !=
nullptr) prev->setPNext(next);
444 template <
typename TYPE,
typename ALLOC>
445 auto original::forwardChain<TYPE, ALLOC>::beginNode() const -> forwardChainNode*
447 return this->begin_->getPNext();
450 template <
typename TYPE,
typename ALLOC>
451 auto original::forwardChain<TYPE, ALLOC>::findNode(
const integer index)
const -> forwardChainNode* {
452 if (this->
size() == 0)
return this->begin_;
453 auto cur = this->beginNode();
456 cur = cur->getPNext();
461 template<
typename TYPE,
typename ALLOC>
462 auto original::forwardChain<TYPE, ALLOC>::createNode(
const TYPE &value, forwardChainNode *next) -> forwardChainNode* {
463 auto node = this->rebind_alloc.allocate(1);
464 this->rebind_alloc.construct(node, value, next);
468 template<
typename TYPE,
typename ALLOC>
469 void original::forwardChain<TYPE, ALLOC>::destroyNode(forwardChainNode *node)
noexcept {
470 this->rebind_alloc.destroy(node);
471 this->rebind_alloc.deallocate(node, 1);
474 template <
typename TYPE,
typename ALLOC>
475 auto original::forwardChain<TYPE, ALLOC>::chainInit() ->
void
477 auto pivot = this->createNode();
479 this->begin_ = pivot;
482 template <
typename TYPE,
typename ALLOC>
483 auto original::forwardChain<TYPE, ALLOC>::firstAdd(forwardChainNode* node) ->
void
485 forwardChainNode::connect(this->findNode(0), node);
489 template <
typename TYPE,
typename ALLOC>
490 auto original::forwardChain<TYPE, ALLOC>::lastDelete() -> forwardChainNode*
492 auto last = this->beginNode();
493 this->destroyNode(this->begin_);
498 template <
typename TYPE,
typename ALLOC>
499 auto original::forwardChain<TYPE, ALLOC>::chainDestruction() ->
void
501 auto cur = this->begin_;
504 auto next = cur->getPNext();
505 this->destroyNode(cur);
510 template <
typename TYPE,
typename ALLOC>
511 original::forwardChain<TYPE, ALLOC>::Iterator::Iterator(forwardChainNode *ptr)
512 : singleDirectionIterator<TYPE>(ptr) {}
514 template <
typename TYPE,
typename ALLOC>
515 original::forwardChain<TYPE, ALLOC>::Iterator::Iterator(
const Iterator &other)
520 template <
typename TYPE,
typename ALLOC>
522 if (
this == &other)
return *
this;
527 template <
typename TYPE,
typename ALLOC>
529 return new Iterator(*
this);
532 template <
typename TYPE,
typename ALLOC>
534 auto other_it =
dynamic_cast<const Iterator*
>(other);
535 return other_it !=
nullptr && this->
_ptr->getPNext() == other_it->_ptr;
538 template <
typename TYPE,
typename ALLOC>
540 auto other_it =
dynamic_cast<const Iterator*
>(other);
541 return other_it !=
nullptr && other_it->_ptr->getPNext() == this->
_ptr;
544 template <
typename TYPE,
typename ALLOC>
546 return "forwardChain::Iterator";
549 template <
typename TYPE,
typename ALLOC>
551 :
baseList<TYPE, ALLOC>(std::move(alloc)), size_(0) , rebind_alloc(std::move(rebind_alloc_node{}))
556 template <
typename TYPE,
typename ALLOC>
561 template <
typename TYPE,
typename ALLOC>
564 auto cur_node = this->createNode(e);
565 if (this->
size() == 0)
567 this->firstAdd(cur_node);
570 auto end = this->findNode(this->
size() - 1);
571 forwardChainNode::connect(
end, cur_node);
577 template <
typename TYPE,
typename ALLOC>
580 auto cur_node = this->createNode(arr.
get(i));
581 if (this->
size() == 0)
583 this->firstAdd(cur_node);
586 auto end = this->findNode(this->
size() - 1);
587 forwardChainNode::connect(
end, cur_node);
593 template <
typename TYPE,
typename ALLOC>
595 if (
this == &other)
return *
this;
596 this->chainDestruction();
597 this->size_ = other.size_;
598 if (this->
size() != 0){
599 auto other_ = other.begin_;
600 this->begin_ = this->createNode(other_->getVal());
601 auto this_ = this->begin_;
602 while (other_->getPNext() !=
nullptr){
603 other_ = other_->getPNext();
604 forwardChainNode::connect(this_, this->createNode(other_->getVal()));
605 this_ = this_->getPNext();
610 if constexpr (ALLOC::propagate_on_container_copy_assignment::value){
617 template <
typename TYPE,
typename ALLOC>
622 template <
typename TYPE,
typename ALLOC>
627 this->chainDestruction();
628 this->begin_ = other.begin_;
629 this->size_ = other.size_;
630 if constexpr (ALLOC::propagate_on_container_move_assignment::value){
631 this->
allocator = std::move(other.allocator);
632 this->rebind_alloc = std::move(other.rebind_alloc);
638 template <
typename TYPE,
typename ALLOC>
644 template <
typename TYPE,
typename ALLOC>
650 return cur->getVal();
653 template <
typename TYPE,
typename ALLOC>
659 return cur->getVal();
662 template <
typename TYPE,
typename ALLOC>
671 template <
typename TYPE,
typename ALLOC>
674 for (
auto current = this->begin_; current !=
nullptr; current = current->getPNext()) {
675 if (current->getVal() == e) {
683 template <
typename TYPE,
typename ALLOC>
685 auto new_node = this->createNode(e);
686 if (this->
size() == 0){
687 this->firstAdd(new_node);
689 auto next = this->beginNode();
690 forwardChainNode::connect(this->begin_, new_node);
691 forwardChainNode::connect(new_node, next);
696 template <
typename TYPE,
typename ALLOC>
701 }
else if (index == this->
size()){
707 auto new_node = this->createNode(e);
708 auto prev = this->findNode(index - 1);
709 auto cur = prev->getPNext();
710 forwardChainNode::connect(prev, new_node);
711 forwardChainNode::connect(new_node, cur);
716 template <
typename TYPE,
typename ALLOC>
718 auto new_node = this->createNode(e);
719 if (this->
size() == 0){
720 this->firstAdd(new_node);
722 auto end = this->findNode(this->
size() - 1);
723 forwardChainNode::connect(
end, new_node);
728 template <
typename TYPE,
typename ALLOC>
731 if (this->
size() == 0){
735 res = this->beginNode()->getVal();
736 if (this->
size() == 1){
737 this->destroyNode(this->lastDelete());
739 auto del = this->beginNode();
740 auto new_begin = del->getPNext();
741 this->destroyNode(del);
742 forwardChainNode::connect(this->begin_, new_begin);
748 template <
typename TYPE,
typename ALLOC>
754 if (index == this->
size() - 1){
761 auto prev = this->findNode(index - 1);
762 auto cur = prev->getPNext();
764 auto next = cur->getPNext();
765 forwardChainNode::connect(prev, next);
766 this->destroyNode(cur);
771 template <
typename TYPE,
typename ALLOC>
774 if (this->
size() == 0){
777 if (this->
size() == 1){
778 res = this->beginNode()->getVal();
779 this->destroyNode(this->lastDelete());
781 auto new_end = this->findNode(this->
size() - 2);
782 auto end = new_end->getPNext();
784 this->destroyNode(
end);
785 forwardChainNode::connect(new_end,
nullptr);
791 template <
typename TYPE,
typename ALLOC>
793 return new Iterator(this->beginNode());
796 template <
typename TYPE,
typename ALLOC>
801 template <
typename TYPE,
typename ALLOC>
803 return "forwardChain";
806 template <
typename TYPE,
typename ALLOC>
808 this->chainDestruction();
Provides the array class for a fixed-size container with random access.
Provides a base class for variable-size serial containers.
DERIVED< O_TYPE > rebind_alloc
Rebinds allocator to different type.
Definition allocator.h:97
Default memory allocator using allocators utilities.
Definition allocator.h:154
A fixed-size array container with random access.
Definition array.h:41
TYPE get(integer index) const override
Retrieves an element at a specified index.
Definition array.h:393
u_integer size() const override
Returns the size of the array.
Definition array.h:382
Base class for variable-size serial containers.
Definition baseList.h:43
Iterator for forwardChain, supports single-direction traversal.
Definition forwardChain.h:186
bool atPrev(const iterator< TYPE > *other) const override
Checks if this iterator is at the previous element relative to another iterator.
Definition forwardChain.h:533
std::string className() const override
Gets the class name of the iterator.
Definition forwardChain.h:545
Iterator * clone() const override
Clones the iterator.
Definition forwardChain.h:528
Iterator & operator=(const Iterator &other)
Assignment operator for Iterator.
Definition forwardChain.h:521
bool atNext(const iterator< TYPE > *other) const override
Checks if this iterator is at the next element relative to another iterator.
Definition forwardChain.h:539
A singly linked list implementation.
Definition forwardChain.h:33
std::string className() const override
Gets the class name of the forwardChain.
Definition forwardChain.h:802
void pushBegin(const TYPE &e) override
Inserts element at the beginning of the chain.
Definition forwardChain.h:684
void pushEnd(const TYPE &e) override
Inserts element at the end of the chain.
Definition forwardChain.h:717
void push(integer index, const TYPE &e) override
Pushes an element at the specified index in the forwardChain.
Definition forwardChain.h:697
TYPE & operator[](integer index) override
Gets a reference to the element at the specified index.
Definition forwardChain.h:654
TYPE popBegin() override
Removes and returns the first element.
Definition forwardChain.h:729
void set(integer index, const TYPE &e) override
Sets the element at the specified index.
Definition forwardChain.h:663
forwardChain(ALLOC alloc=ALLOC{})
Constructs an empty forwardChain with specified allocator.
Definition forwardChain.h:550
Iterator * ends() const override
Gets an iterator to the end of the forwardChain.
Definition forwardChain.h:797
~forwardChain() override
Destructor for the forwardChain.
Definition forwardChain.h:807
u_integer indexOf(const TYPE &e) const override
Finds the index of the first occurrence of the specified element.
Definition forwardChain.h:672
TYPE pop(integer index) override
Pops an element at the specified index in the forwardChain.
Definition forwardChain.h:749
TYPE popEnd() override
Removes and returns the last element.
Definition forwardChain.h:772
Iterator * begins() const override
Gets an iterator to the beginning of the forwardChain.
Definition forwardChain.h:792
forwardChain & operator=(const forwardChain &other)
Assignment operator for forwardChain.
Definition forwardChain.h:594
TYPE get(integer index) const override
Gets the element at the specified index.
Definition forwardChain.h:645
u_integer size() const override
Gets the size of the forwardChain.
Definition forwardChain.h:639
iterAdaptor end()
Returns an iterator pointing to the end of the iterable container.
Definition iterable.h:453
iterAdaptor last()
Returns an iterator pointing to the last element.
Definition iterable.h:478
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
singleDirectionIterator(wrapper< TYPE > *ptr)
Protected constructor for singleDirectionIterator.
Definition singleDirectionIterator.h:56
singleDirectionIterator & operator=(const singleDirectionIterator &other)
Copy assignment operator for singleDirectionIterator.
Definition singleDirectionIterator.h:65
wrapper< TYPE > * _ptr
Pointer to the current wrapper.
Definition stepIterator.h:39
Base class for linked value containers with formatted output.
Definition wrapper.h:28
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
std::int64_t integer
64-bit signed integer type for arithmetic operations
Definition config.h:15
Single-direction iterator base class.