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
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
42 class forwardChainNode final : public wrapper<TYPE>{
43 public:
44 friend class iterator<TYPE>;
45 friend class forwardChain;
46
52 explicit forwardChainNode(const TYPE& data = TYPE{}, forwardChainNode* next = nullptr);
53 private:
54 TYPE data_;
55 forwardChainNode* next;
56 protected:
57
62 forwardChainNode(const forwardChainNode& other);
63
69 forwardChainNode& operator=(const forwardChainNode& other);
70
75 TYPE& getVal() override;
76
81 const TYPE& getVal() const override;
82
87 void setVal(TYPE data) override;
88
94 forwardChainNode* getPPrev() const override;
95
100 forwardChainNode* getPNext() const override;
101
106 void setPNext(forwardChainNode* new_next);
107
114 static void connect(forwardChainNode* prev, forwardChainNode* next);
115 };
116
122 using rebind_alloc_node = ALLOC::template rebind_alloc<forwardChainNode>;
123
124 u_integer size_;
125 forwardChainNode* begin_;
126 rebind_alloc_node rebind_alloc{};
127
128
133 forwardChainNode* beginNode() const;
134
141 forwardChainNode* findNode(integer index) const;
142
151 forwardChainNode* createNode(const TYPE& value = TYPE{}, forwardChainNode* next = nullptr);
152
159 void destroyNode(forwardChainNode* node) noexcept;
160
165 void chainInit();
166
172 void firstAdd(forwardChainNode* node);
173
179 forwardChainNode* lastDelete();
180
185 void chainDestroy();
186 public:
187
196 {
201 explicit Iterator(forwardChainNode* ptr);
202 public:
203 friend forwardChain;
204
209 Iterator(const Iterator& other);
210
217
223 Iterator* clone() const override;
224
230 bool atPrev(const iterator<TYPE> *other) const override;
231
237 bool atNext(const iterator<TYPE> *other) const override;
238
243 [[nodiscard]] std::string className() const override;
244 };
245
251 explicit forwardChain(ALLOC alloc = ALLOC{});
252
259
264 forwardChain(std::initializer_list<TYPE> list);
265
270 explicit forwardChain(const array<TYPE>& arr);
271
279
286 forwardChain(forwardChain&& other) noexcept;
287
295
300 [[nodiscard]] u_integer size() const override;
301
307 TYPE get(integer index) const override;
308
314 TYPE& operator[](integer index) override;
315
321 void set(integer index, const TYPE &e) override;
322
328 u_integer indexOf(const TYPE &e) const override;
329
335 void pushBegin(const TYPE &e) override;
336
343 void push(integer index, const TYPE &e) override;
344
350 void pushEnd(const TYPE &e) override;
351
358 TYPE popBegin() override;
359
366 TYPE pop(integer index) override;
367
374 TYPE popEnd() override;
375
380 Iterator* begins() const override;
381
386 Iterator* ends() const override;
387
392 [[nodiscard]] std::string className() const override;
393
397 ~forwardChain() override;
398 };
399}
400
401 template <typename TYPE, typename ALLOC>
403 : data_(data), next(next) {}
404
405 template <typename TYPE, typename ALLOC>
407 : data_(other.data_), next(other.next) {}
408
409 template <typename TYPE, typename ALLOC>
411 const forwardChainNode &other) -> forwardChainNode & {
412 if (this != &other) {
413 data_ = other.data_;
414 next = other.next;
415 }
416 return *this;
417 }
418
419 template <typename TYPE, typename ALLOC>
421 return this->data_;
422 }
423
424 template <typename TYPE, typename ALLOC>
426 return this->data_;
427 }
428
429 template <typename TYPE, typename ALLOC>
431 this->data_ = data;
432 }
433
434 template <typename TYPE, typename ALLOC>
436 throw unSupportedMethodError();
437 }
438
439 template <typename TYPE, typename ALLOC>
441 return this->next;
442 }
443
444 template <typename TYPE, typename ALLOC>
445 auto original::forwardChain<TYPE, ALLOC>::forwardChainNode::setPNext(forwardChainNode *new_next) -> void {
446 this->next = new_next;
447 }
448
449 template <typename TYPE, typename ALLOC>
451 forwardChainNode *prev, forwardChainNode *next) -> void {
452 if (prev != nullptr) prev->setPNext(next);
453 }
454
455 template <typename TYPE, typename ALLOC>
456 auto original::forwardChain<TYPE, ALLOC>::beginNode() const -> forwardChainNode*
457 {
458 return this->begin_->getPNext();
459 }
460
461 template <typename TYPE, typename ALLOC>
462 auto original::forwardChain<TYPE, ALLOC>::findNode(const integer index) const -> forwardChainNode* {
463 if (this->size() == 0) return this->begin_;
464 auto cur = this->beginNode();
465 for(u_integer i = 0; i < index; i++)
466 {
467 cur = cur->getPNext();
468 }
469 return cur;
470 }
471
472 template<typename TYPE, typename ALLOC>
473 auto original::forwardChain<TYPE, ALLOC>::createNode(const TYPE &value, forwardChainNode *next) -> forwardChainNode* {
474 auto node = this->rebind_alloc.allocate(1);
475 this->rebind_alloc.construct(node, value, next);
476 return node;
477 }
478
479 template<typename TYPE, typename ALLOC>
480 void original::forwardChain<TYPE, ALLOC>::destroyNode(forwardChainNode *node) noexcept {
481 this->rebind_alloc.destroy(node);
482 this->rebind_alloc.deallocate(node, 1);
483 }
484
485 template <typename TYPE, typename ALLOC>
487 {
488 auto pivot = this->createNode();
489 this->size_ = 0;
490 this->begin_ = pivot;
491 }
492
493 template <typename TYPE, typename ALLOC>
494 auto original::forwardChain<TYPE, ALLOC>::firstAdd(forwardChainNode* node) -> void
495 {
496 forwardChainNode::connect(this->findNode(0), node);
497 this->size_ += 1;
498 }
499
500 template <typename TYPE, typename ALLOC>
501 auto original::forwardChain<TYPE, ALLOC>::lastDelete() -> forwardChainNode*
502 {
503 auto last = this->beginNode();
504 this->destroyNode(this->begin_);
505 this->chainInit();
506 return last;
507 }
508
509 template <typename TYPE, typename ALLOC>
511 {
512 auto cur = this->begin_;
513 while (cur)
514 {
515 auto next = cur->getPNext();
516 this->destroyNode(cur);
517 cur = next;
518 }
519 }
520
521 template <typename TYPE, typename ALLOC>
523 : singleDirectionIterator<TYPE>(ptr) {}
524
525 template <typename TYPE, typename ALLOC>
530
531 template <typename TYPE, typename ALLOC>
533 if (this == &other) return *this;
535 return *this;
536 }
537
538 template <typename TYPE, typename ALLOC>
542
543 template <typename TYPE, typename ALLOC>
545 auto other_it = dynamic_cast<const Iterator*>(other);
546 return other_it != nullptr && this->_ptr->getPNext() == other_it->_ptr;
547 }
548
549 template <typename TYPE, typename ALLOC>
551 auto other_it = dynamic_cast<const Iterator*>(other);
552 return other_it != nullptr && other_it->_ptr->getPNext() == this->_ptr;
553 }
554
555 template <typename TYPE, typename ALLOC>
557 return "forwardChain::Iterator";
558 }
559
560 template <typename TYPE, typename ALLOC>
563 size_(0),
564 begin_(nullptr),
565 rebind_alloc(std::move(rebind_alloc_node{}))
566 {
567 this->chainInit();
568 }
569
570 template <typename TYPE, typename ALLOC>
574
575 template <typename TYPE, typename ALLOC>
577 for (auto e: list) {
578 auto cur_node = this->createNode(e);
579 if (this->size() == 0)
580 {
581 this->firstAdd(cur_node);
582 }else
583 {
584 auto end = this->findNode(this->size() - 1);
585 forwardChainNode::connect(end, cur_node);
586 this->size_ += 1;
587 }
588 }
589 }
590
591 template <typename TYPE, typename ALLOC>
593 for (u_integer i = 0; i < arr.size(); i++) {
594 auto cur_node = this->createNode(arr.get(i));
595 if (this->size() == 0)
596 {
597 this->firstAdd(cur_node);
598 }else
599 {
600 auto end = this->findNode(this->size() - 1);
601 forwardChainNode::connect(end, cur_node);
602 this->size_ += 1;
603 }
604 }
605 }
606
607 template <typename TYPE, typename ALLOC>
609 if (this == &other) return *this;
610 this->chainDestroy();
611 this->size_ = other.size_;
612 if (this->size() != 0){
613 auto other_ = other.begin_;
614 this->begin_ = this->createNode(other_->getVal());
615 auto this_ = this->begin_;
616 while (other_->getPNext() != nullptr){
617 other_ = other_->getPNext();
618 forwardChainNode::connect(this_, this->createNode(other_->getVal()));
619 this_ = this_->getPNext();
620 }
621 } else{
622 this->chainInit();
623 }
624 if constexpr (ALLOC::propagate_on_container_copy_assignment::value){
625 this->allocator = other.allocator;
626 this->rebind_alloc = other.rebind_alloc;
627 }
628 return *this;
629 }
630
631 template <typename TYPE, typename ALLOC>
635
636 template <typename TYPE, typename ALLOC>
638 if (this == &other)
639 return *this;
640
641 this->chainDestroy();
642 this->begin_ = other.begin_;
643 this->size_ = other.size_;
644 if constexpr (ALLOC::propagate_on_container_move_assignment::value){
645 this->allocator = std::move(other.allocator);
646 this->rebind_alloc = std::move(other.rebind_alloc);
647 }
648 other.chainInit();
649 return *this;
650 }
651
652 template <typename TYPE, typename ALLOC>
654 {
655 return this->size_;
656 }
657
658 template <typename TYPE, typename ALLOC>
660 if (this->indexOutOfBound(index)){
661 throw outOfBoundError();
662 }
663 auto cur = this->findNode(this->parseNegIndex(index));
664 return cur->getVal();
665 }
666
667 template <typename TYPE, typename ALLOC>
669 if (this->indexOutOfBound(index)){
670 throw outOfBoundError();
671 }
672 auto cur = this->findNode(this->parseNegIndex(index));
673 return cur->getVal();
674 }
675
676 template <typename TYPE, typename ALLOC>
678 if (this->indexOutOfBound(index)){
679 throw outOfBoundError();
680 }
681 auto cur = this->findNode(this->parseNegIndex(index));
682 cur->setVal(e);
683 }
684
685 template <typename TYPE, typename ALLOC>
687 u_integer i = 0;
688 for (auto current = this->begin_; current != nullptr; current = current->getPNext()) {
689 if (current->getVal() == e) {
690 return i;
691 }
692 i += 1;
693 }
694 return this->size();
695 }
696
697 template <typename TYPE, typename ALLOC>
699 auto new_node = this->createNode(e);
700 if (this->size() == 0){
701 this->firstAdd(new_node);
702 } else{
703 auto next = this->beginNode();
704 forwardChainNode::connect(this->begin_, new_node);
705 forwardChainNode::connect(new_node, next);
706 this->size_ += 1;
707 }
708 }
709
710 template <typename TYPE, typename ALLOC>
712 index = this->parseNegIndex(index);
713 if (index == 0){
714 this->pushBegin(e);
715 } else if (index == this->size()){
716 this->pushEnd(e);
717 } else{
718 if (this->indexOutOfBound(index)){
719 throw outOfBoundError();
720 }
721 auto new_node = this->createNode(e);
722 auto prev = this->findNode(index - 1);
723 auto cur = prev->getPNext();
724 forwardChainNode::connect(prev, new_node);
725 forwardChainNode::connect(new_node, cur);
726 this->size_ += 1;
727 }
728 }
729
730 template <typename TYPE, typename ALLOC>
732 auto new_node = this->createNode(e);
733 if (this->size() == 0){
734 this->firstAdd(new_node);
735 } else{
736 auto end = this->findNode(this->size() - 1);
737 forwardChainNode::connect(end, new_node);
738 this->size_ += 1;
739 }
740 }
741
742 template <typename TYPE, typename ALLOC>
744 TYPE res;
745 if (this->size() == 0){
746 throw noElementError();
747 }
748
749 res = this->beginNode()->getVal();
750 if (this->size() == 1){
751 this->destroyNode(this->lastDelete());
752 } else{
753 auto del = this->beginNode();
754 auto new_begin = del->getPNext();
755 this->destroyNode(del);
756 forwardChainNode::connect(this->begin_, new_begin);
757 this->size_ -= 1;
758 }
759 return res;
760 }
761
762 template <typename TYPE, typename ALLOC>
764 index = this->parseNegIndex(index);
765 if (index == 0){
766 return this->popBegin();
767 }
768 if (index == this->size() - 1){
769 return this->popEnd();
770 }
771 if (this->indexOutOfBound(index)){
772 throw outOfBoundError();
773 }
774 TYPE res;
775 auto prev = this->findNode(index - 1);
776 auto cur = prev->getPNext();
777 res = cur->getVal();
778 auto next = cur->getPNext();
779 forwardChainNode::connect(prev, next);
780 this->destroyNode(cur);
781 this->size_ -= 1;
782 return res;
783 }
784
785 template <typename TYPE, typename ALLOC>
787 TYPE res;
788 if (this->size() == 0){
789 throw noElementError();
790 }
791 if (this->size() == 1){
792 res = this->beginNode()->getVal();
793 this->destroyNode(this->lastDelete());
794 } else{
795 auto new_end = this->findNode(this->size() - 2);
796 auto end = new_end->getPNext();
797 res = end->getVal();
798 this->destroyNode(end);
799 forwardChainNode::connect(new_end, nullptr);
800 this->size_ -= 1;
801 }
802 return res;
803 }
804
805 template <typename TYPE, typename ALLOC>
807 return new Iterator(this->beginNode());
808 }
809
810 template <typename TYPE, typename ALLOC>
812 return new Iterator(this->findNode(this->size() - 1));
813 }
814
815 template <typename TYPE, typename ALLOC>
817 return "forwardChain";
818 }
819
820 template <typename TYPE, typename ALLOC>
822 this->chainDestroy();
823 }
824
825#endif //FORWARDCHAIN_H
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
const TYPE * get() const
Get managed pointer const version.
Definition autoPtr.h:629
Base class for variable-size serial containers.
Definition baseList.h:43
Iterator for forwardChain, supports single-direction traversal.
Definition forwardChain.h:196
bool atPrev(const iterator< TYPE > *other) const override
Checks if this iterator is at the previous element relative to another iterator.
Definition forwardChain.h:544
std::string className() const override
Gets the class name of the iterator.
Definition forwardChain.h:556
Iterator * clone() const override
Clones the iterator.
Definition forwardChain.h:539
Iterator & operator=(const Iterator &other)
Assignment operator for Iterator.
Definition forwardChain.h:532
bool atNext(const iterator< TYPE > *other) const override
Checks if this iterator is at the next element relative to another iterator.
Definition forwardChain.h:550
A singly linked list implementation.
Definition forwardChain.h:33
std::string className() const override
Gets the class name of the forwardChain.
Definition forwardChain.h:816
void pushBegin(const TYPE &e) override
Inserts element at the beginning of the chain.
Definition forwardChain.h:698
void pushEnd(const TYPE &e) override
Inserts element at the end of the chain.
Definition forwardChain.h:731
void push(integer index, const TYPE &e) override
Pushes an element at the specified index in the forwardChain.
Definition forwardChain.h:711
TYPE & operator[](integer index) override
Gets a reference to the element at the specified index.
Definition forwardChain.h:668
TYPE popBegin() override
Removes and returns the first element.
Definition forwardChain.h:743
void set(integer index, const TYPE &e) override
Sets the element at the specified index.
Definition forwardChain.h:677
forwardChain(ALLOC alloc=ALLOC{})
Constructs an empty forwardChain with specified allocator.
Definition forwardChain.h:561
Iterator * ends() const override
Gets an iterator to the end of the forwardChain.
Definition forwardChain.h:811
~forwardChain() override
Destructor for the forwardChain.
Definition forwardChain.h:821
u_integer indexOf(const TYPE &e) const override
Finds the index of the first occurrence of the specified element.
Definition forwardChain.h:686
TYPE pop(integer index) override
Pops an element at the specified index in the forwardChain.
Definition forwardChain.h:763
TYPE popEnd() override
Removes and returns the last element.
Definition forwardChain.h:786
Iterator * begins() const override
Gets an iterator to the beginning of the forwardChain.
Definition forwardChain.h:806
forwardChain & operator=(const forwardChain &other)
Assignment operator for forwardChain.
Definition forwardChain.h:608
TYPE get(integer index) const override
Gets the element at the specified index.
Definition forwardChain.h:659
u_integer size() const override
Gets the size of the forwardChain.
Definition forwardChain.h:653
iterAdaptor end()
Returns an iterator adapter pointing to the end sentinel of the container.
Definition iterable.h:631
iterAdaptor last()
Returns an iterator adapter pointing to the last element.
Definition iterable.h:656
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
Abstract base class for unique element containers.
Definition set.h:44
Abstract base class for single-direction iterators.
Definition singleDirectionIterator.h:25
singleDirectionIterator & operator=(const singleDirectionIterator &other)
Copy assignment operator for singleDirectionIterator.
Definition singleDirectionIterator.h:65
Base class for linked value containers with formatted output.
Definition wrapper.h:28
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
Single-direction iterator base class.