ORIGINAL
Loading...
Searching...
No Matches
forwardChain.h
Go to the documentation of this file.
1#ifndef FORWARDCHAIN_H
2#define FORWARDCHAIN_H
3
5#include "array.h"
6#include "baseList.h"
7
17
18
19namespace original {
20
32 template <typename TYPE, typename ALLOC = allocator<TYPE>>
33 class forwardChain final : public baseList<TYPE, ALLOC>, public iterationStream<TYPE, forwardChain<TYPE, ALLOC>>{
34
41 class forwardChainNode final : public wrapper<TYPE>{
42 public:
43 friend class iterator<TYPE>;
44 friend class forwardChain;
45
51 explicit forwardChainNode(const TYPE& data = TYPE{}, forwardChainNode* next = nullptr);
52 private:
53 TYPE data_;
54 forwardChainNode* next;
55 protected:
56
61 forwardChainNode(const forwardChainNode& other);
62
68 forwardChainNode& operator=(const forwardChainNode& other);
69
74 TYPE& getVal() override;
75
80 const TYPE& getVal() const override;
81
86 void setVal(TYPE data) override;
87
92 forwardChainNode* getPPrev() const override;
93
98 forwardChainNode* getPNext() const override;
99
104 void setPNext(forwardChainNode* new_next);
105
111 static void connect(forwardChainNode* prev, forwardChainNode* next);
112 };
113
119 using rebind_alloc_node = typename ALLOC::template rebind_alloc<forwardChainNode>;
120
121 u_integer size_;
122 forwardChainNode* begin_;
123 rebind_alloc_node rebind_alloc{};
124
125
130 forwardChainNode* beginNode() const;
131
137 forwardChainNode* findNode(integer index) const;
138
146 forwardChainNode* createNode(const TYPE& value = TYPE{}, forwardChainNode* next = nullptr);
147
154 void destroyNode(forwardChainNode* node) noexcept;
155
159 void chainInit();
160
165 void firstAdd(forwardChainNode* node);
166
171 forwardChainNode* lastDelete();
172
176 void chainDestruction();
177 public:
178
185 class Iterator final : public singleDirectionIterator<TYPE>
186 {
191 explicit Iterator(forwardChainNode* ptr);
192 public:
193 friend forwardChain;
194
199 Iterator(const Iterator& other);
200
206 Iterator& operator=(const Iterator& other);
207
212 Iterator* clone() const override;
213
219 bool atPrev(const iterator<TYPE> *other) const override;
220
226 bool atNext(const iterator<TYPE> *other) const override;
227
232 [[nodiscard]] std::string className() const override;
233 };
234
240 explicit forwardChain(ALLOC alloc = ALLOC{});
241
247 forwardChain(const forwardChain& other);
248
253 forwardChain(std::initializer_list<TYPE> list);
254
259 explicit forwardChain(const array<TYPE>& arr);
260
267 forwardChain& operator=(const forwardChain& other);
268
275 forwardChain(forwardChain&& other) noexcept;
276
283 forwardChain& operator=(forwardChain&& other) noexcept;
284
289 [[nodiscard]] u_integer size() const override;
290
296 TYPE get(integer index) const override;
297
303 TYPE& operator[](integer index) override;
304
310 void set(integer index, const TYPE &e) override;
311
317 u_integer indexOf(const TYPE &e) const override;
318
324 void pushBegin(const TYPE &e) override;
325
332 void push(integer index, const TYPE &e) override;
333
339 void pushEnd(const TYPE &e) override;
340
347 TYPE popBegin() override;
348
355 TYPE pop(integer index) override;
356
363 TYPE popEnd() override;
364
369 Iterator* begins() const override;
370
375 Iterator* ends() const override;
376
381 [[nodiscard]] std::string className() const override;
382
386 ~forwardChain() override;
387 };
388}
389
390 template <typename TYPE, typename ALLOC>
391 original::forwardChain<TYPE, ALLOC>::forwardChainNode::forwardChainNode(const TYPE& data, forwardChainNode* next)
392 : data_(data), next(next) {}
393
394 template <typename TYPE, typename ALLOC>
395 original::forwardChain<TYPE, ALLOC>::forwardChainNode::forwardChainNode(const forwardChainNode &other)
396 : data_(other.data_), next(other.next) {}
397
398 template <typename TYPE, typename ALLOC>
399 auto original::forwardChain<TYPE, ALLOC>::forwardChainNode::operator=(
400 const forwardChainNode &other) -> forwardChainNode & {
401 if (this != &other) {
402 data_ = other.data_;
403 next = other.next;
404 }
405 return *this;
406 }
407
408 template <typename TYPE, typename ALLOC>
409 auto original::forwardChain<TYPE, ALLOC>::forwardChainNode::getVal() -> TYPE& {
410 return this->data_;
411 }
412
413 template <typename TYPE, typename ALLOC>
414 auto original::forwardChain<TYPE, ALLOC>::forwardChainNode::getVal() const -> const TYPE& {
415 return this->data_;
416 }
417
418 template <typename TYPE, typename ALLOC>
419 auto original::forwardChain<TYPE, ALLOC>::forwardChainNode::setVal(TYPE data) -> void {
420 this->data_ = data;
421 }
422
423 template <typename TYPE, typename ALLOC>
424 auto original::forwardChain<TYPE, ALLOC>::forwardChainNode::getPPrev() const -> forwardChainNode* {
425 throw unSupportedMethodError();
426 }
427
428 template <typename TYPE, typename ALLOC>
429 auto original::forwardChain<TYPE, ALLOC>::forwardChainNode::getPNext() const -> forwardChainNode* {
430 return this->next;
431 }
432
433 template <typename TYPE, typename ALLOC>
434 auto original::forwardChain<TYPE, ALLOC>::forwardChainNode::setPNext(forwardChainNode *new_next) -> void {
435 this->next = new_next;
436 }
437
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);
442 }
443
444 template <typename TYPE, typename ALLOC>
445 auto original::forwardChain<TYPE, ALLOC>::beginNode() const -> forwardChainNode*
446 {
447 return this->begin_->getPNext();
448 }
449
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();
454 for(u_integer i = 0; i < index; i++)
455 {
456 cur = cur->getPNext();
457 }
458 return cur;
459 }
460
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);
465 return node;
466 }
467
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);
472 }
473
474 template <typename TYPE, typename ALLOC>
475 auto original::forwardChain<TYPE, ALLOC>::chainInit() -> void
476 {
477 auto pivot = this->createNode();
478 this->size_ = 0;
479 this->begin_ = pivot;
480 }
481
482 template <typename TYPE, typename ALLOC>
483 auto original::forwardChain<TYPE, ALLOC>::firstAdd(forwardChainNode* node) -> void
484 {
485 forwardChainNode::connect(this->findNode(0), node);
486 this->size_ += 1;
487 }
488
489 template <typename TYPE, typename ALLOC>
490 auto original::forwardChain<TYPE, ALLOC>::lastDelete() -> forwardChainNode*
491 {
492 auto last = this->beginNode();
493 this->destroyNode(this->begin_);
494 this->chainInit();
495 return last;
496 }
497
498 template <typename TYPE, typename ALLOC>
499 auto original::forwardChain<TYPE, ALLOC>::chainDestruction() -> void
500 {
501 auto cur = this->begin_;
502 while (cur)
503 {
504 auto next = cur->getPNext();
505 this->destroyNode(cur);
506 cur = next;
507 }
508 }
509
510 template <typename TYPE, typename ALLOC>
511 original::forwardChain<TYPE, ALLOC>::Iterator::Iterator(forwardChainNode *ptr)
512 : singleDirectionIterator<TYPE>(ptr) {}
513
514 template <typename TYPE, typename ALLOC>
515 original::forwardChain<TYPE, ALLOC>::Iterator::Iterator(const Iterator &other)
516 : singleDirectionIterator<TYPE>(nullptr) {
517 this->operator=(other);
518 }
519
520 template <typename TYPE, typename ALLOC>
521 auto original::forwardChain<TYPE, ALLOC>::Iterator::operator=(const Iterator &other) -> Iterator & {
522 if (this == &other) return *this;
524 return *this;
525 }
526
527 template <typename TYPE, typename ALLOC>
529 return new Iterator(*this);
530 }
531
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;
536 }
537
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;
542 }
543
544 template <typename TYPE, typename ALLOC>
546 return "forwardChain::Iterator";
547 }
548
549 template <typename TYPE, typename ALLOC>
551 : baseList<TYPE, ALLOC>(std::move(alloc)), size_(0) , rebind_alloc(std::move(rebind_alloc_node{}))
552 {
553 this->chainInit();
554 }
555
556 template <typename TYPE, typename ALLOC>
560
561 template <typename TYPE, typename ALLOC>
563 for (auto e: list) {
564 auto cur_node = this->createNode(e);
565 if (this->size() == 0)
566 {
567 this->firstAdd(cur_node);
568 }else
569 {
570 auto end = this->findNode(this->size() - 1);
571 forwardChainNode::connect(end, cur_node);
572 this->size_ += 1;
573 }
574 }
575 }
576
577 template <typename TYPE, typename ALLOC>
579 for (u_integer i = 0; i < arr.size(); i++) {
580 auto cur_node = this->createNode(arr.get(i));
581 if (this->size() == 0)
582 {
583 this->firstAdd(cur_node);
584 }else
585 {
586 auto end = this->findNode(this->size() - 1);
587 forwardChainNode::connect(end, cur_node);
588 this->size_ += 1;
589 }
590 }
591 }
592
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();
606 }
607 } else{
608 this->chainInit();
609 }
610 if constexpr (ALLOC::propagate_on_container_copy_assignment::value){
611 this->allocator = other.allocator;
612 this->rebind_alloc = other.rebind_alloc;
613 }
614 return *this;
615 }
616
617 template <typename TYPE, typename ALLOC>
619 this->operator=(std::move(other));
620 }
621
622 template <typename TYPE, typename ALLOC>
624 if (this == &other)
625 return *this;
626
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);
633 }
634 other.chainInit();
635 return *this;
636 }
637
638 template <typename TYPE, typename ALLOC>
640 {
641 return this->size_;
642 }
643
644 template <typename TYPE, typename ALLOC>
646 if (this->indexOutOfBound(index)){
647 throw outOfBoundError();
648 }
649 auto cur = this->findNode(this->parseNegIndex(index));
650 return cur->getVal();
651 }
652
653 template <typename TYPE, typename ALLOC>
655 if (this->indexOutOfBound(index)){
656 throw outOfBoundError();
657 }
658 auto cur = this->findNode(this->parseNegIndex(index));
659 return cur->getVal();
660 }
661
662 template <typename TYPE, typename ALLOC>
663 auto original::forwardChain<TYPE, ALLOC>::set(integer index, const TYPE &e) -> void {
664 if (this->indexOutOfBound(index)){
665 throw outOfBoundError();
666 }
667 auto cur = this->findNode(this->parseNegIndex(index));
668 cur->setVal(e);
669 }
670
671 template <typename TYPE, typename ALLOC>
673 u_integer i = 0;
674 for (auto current = this->begin_; current != nullptr; current = current->getPNext()) {
675 if (current->getVal() == e) {
676 return i;
677 }
678 i += 1;
679 }
680 return this->size();
681 }
682
683 template <typename TYPE, typename ALLOC>
685 auto new_node = this->createNode(e);
686 if (this->size() == 0){
687 this->firstAdd(new_node);
688 } else{
689 auto next = this->beginNode();
690 forwardChainNode::connect(this->begin_, new_node);
691 forwardChainNode::connect(new_node, next);
692 this->size_ += 1;
693 }
694 }
695
696 template <typename TYPE, typename ALLOC>
697 auto original::forwardChain<TYPE, ALLOC>::push(integer index, const TYPE &e) -> void {
698 index = this->parseNegIndex(index);
699 if (index == 0){
700 this->pushBegin(e);
701 } else if (index == this->size()){
702 this->pushEnd(e);
703 } else{
704 if (this->indexOutOfBound(index)){
705 throw outOfBoundError();
706 }
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);
712 this->size_ += 1;
713 }
714 }
715
716 template <typename TYPE, typename ALLOC>
718 auto new_node = this->createNode(e);
719 if (this->size() == 0){
720 this->firstAdd(new_node);
721 } else{
722 auto end = this->findNode(this->size() - 1);
723 forwardChainNode::connect(end, new_node);
724 this->size_ += 1;
725 }
726 }
727
728 template <typename TYPE, typename ALLOC>
730 TYPE res;
731 if (this->size() == 0){
732 throw noElementError();
733 }
734
735 res = this->beginNode()->getVal();
736 if (this->size() == 1){
737 this->destroyNode(this->lastDelete());
738 } else{
739 auto del = this->beginNode();
740 auto new_begin = del->getPNext();
741 this->destroyNode(del);
742 forwardChainNode::connect(this->begin_, new_begin);
743 this->size_ -= 1;
744 }
745 return res;
746 }
747
748 template <typename TYPE, typename ALLOC>
750 index = this->parseNegIndex(index);
751 if (index == 0){
752 return this->popBegin();
753 }
754 if (index == this->size() - 1){
755 return this->popEnd();
756 }
757 if (this->indexOutOfBound(index)){
758 throw outOfBoundError();
759 }
760 TYPE res;
761 auto prev = this->findNode(index - 1);
762 auto cur = prev->getPNext();
763 res = cur->getVal();
764 auto next = cur->getPNext();
765 forwardChainNode::connect(prev, next);
766 this->destroyNode(cur);
767 this->size_ -= 1;
768 return res;
769 }
770
771 template <typename TYPE, typename ALLOC>
773 TYPE res;
774 if (this->size() == 0){
775 throw noElementError();
776 }
777 if (this->size() == 1){
778 res = this->beginNode()->getVal();
779 this->destroyNode(this->lastDelete());
780 } else{
781 auto new_end = this->findNode(this->size() - 2);
782 auto end = new_end->getPNext();
783 res = end->getVal();
784 this->destroyNode(end);
785 forwardChainNode::connect(new_end, nullptr);
786 this->size_ -= 1;
787 }
788 return res;
789 }
790
791 template <typename TYPE, typename ALLOC>
793 return new Iterator(this->beginNode());
794 }
795
796 template <typename TYPE, typename ALLOC>
798 return new Iterator(this->findNode(this->size() - 1));
799 }
800
801 template <typename TYPE, typename ALLOC>
803 return "forwardChain";
804 }
805
806 template <typename TYPE, typename ALLOC>
808 this->chainDestruction();
809 }
810
811#endif //FORWARDCHAIN_H
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.