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>
562 : baseList<TYPE, ALLOC>(std::move(alloc)), size_(0) , rebind_alloc(std::move(rebind_alloc_node{}))
563 {
564 this->chainInit();
565 }
566
567 template <typename TYPE, typename ALLOC>
571
572 template <typename TYPE, typename ALLOC>
574 for (auto e: list) {
575 auto cur_node = this->createNode(e);
576 if (this->size() == 0)
577 {
578 this->firstAdd(cur_node);
579 }else
580 {
581 auto end = this->findNode(this->size() - 1);
582 forwardChainNode::connect(end, cur_node);
583 this->size_ += 1;
584 }
585 }
586 }
587
588 template <typename TYPE, typename ALLOC>
590 for (u_integer i = 0; i < arr.size(); i++) {
591 auto cur_node = this->createNode(arr.get(i));
592 if (this->size() == 0)
593 {
594 this->firstAdd(cur_node);
595 }else
596 {
597 auto end = this->findNode(this->size() - 1);
598 forwardChainNode::connect(end, cur_node);
599 this->size_ += 1;
600 }
601 }
602 }
603
604 template <typename TYPE, typename ALLOC>
606 if (this == &other) return *this;
607 this->chainDestroy();
608 this->size_ = other.size_;
609 if (this->size() != 0){
610 auto other_ = other.begin_;
611 this->begin_ = this->createNode(other_->getVal());
612 auto this_ = this->begin_;
613 while (other_->getPNext() != nullptr){
614 other_ = other_->getPNext();
615 forwardChainNode::connect(this_, this->createNode(other_->getVal()));
616 this_ = this_->getPNext();
617 }
618 } else{
619 this->chainInit();
620 }
621 if constexpr (ALLOC::propagate_on_container_copy_assignment::value){
622 this->allocator = other.allocator;
623 this->rebind_alloc = other.rebind_alloc;
624 }
625 return *this;
626 }
627
628 template <typename TYPE, typename ALLOC>
632
633 template <typename TYPE, typename ALLOC>
635 if (this == &other)
636 return *this;
637
638 this->chainDestroy();
639 this->begin_ = other.begin_;
640 this->size_ = other.size_;
641 if constexpr (ALLOC::propagate_on_container_move_assignment::value){
642 this->allocator = std::move(other.allocator);
643 this->rebind_alloc = std::move(other.rebind_alloc);
644 }
645 other.chainInit();
646 return *this;
647 }
648
649 template <typename TYPE, typename ALLOC>
651 {
652 return this->size_;
653 }
654
655 template <typename TYPE, typename ALLOC>
657 if (this->indexOutOfBound(index)){
658 throw outOfBoundError();
659 }
660 auto cur = this->findNode(this->parseNegIndex(index));
661 return cur->getVal();
662 }
663
664 template <typename TYPE, typename ALLOC>
666 if (this->indexOutOfBound(index)){
667 throw outOfBoundError();
668 }
669 auto cur = this->findNode(this->parseNegIndex(index));
670 return cur->getVal();
671 }
672
673 template <typename TYPE, typename ALLOC>
675 if (this->indexOutOfBound(index)){
676 throw outOfBoundError();
677 }
678 auto cur = this->findNode(this->parseNegIndex(index));
679 cur->setVal(e);
680 }
681
682 template <typename TYPE, typename ALLOC>
684 u_integer i = 0;
685 for (auto current = this->begin_; current != nullptr; current = current->getPNext()) {
686 if (current->getVal() == e) {
687 return i;
688 }
689 i += 1;
690 }
691 return this->size();
692 }
693
694 template <typename TYPE, typename ALLOC>
696 auto new_node = this->createNode(e);
697 if (this->size() == 0){
698 this->firstAdd(new_node);
699 } else{
700 auto next = this->beginNode();
701 forwardChainNode::connect(this->begin_, new_node);
702 forwardChainNode::connect(new_node, next);
703 this->size_ += 1;
704 }
705 }
706
707 template <typename TYPE, typename ALLOC>
709 index = this->parseNegIndex(index);
710 if (index == 0){
711 this->pushBegin(e);
712 } else if (index == this->size()){
713 this->pushEnd(e);
714 } else{
715 if (this->indexOutOfBound(index)){
716 throw outOfBoundError();
717 }
718 auto new_node = this->createNode(e);
719 auto prev = this->findNode(index - 1);
720 auto cur = prev->getPNext();
721 forwardChainNode::connect(prev, new_node);
722 forwardChainNode::connect(new_node, cur);
723 this->size_ += 1;
724 }
725 }
726
727 template <typename TYPE, typename ALLOC>
729 auto new_node = this->createNode(e);
730 if (this->size() == 0){
731 this->firstAdd(new_node);
732 } else{
733 auto end = this->findNode(this->size() - 1);
734 forwardChainNode::connect(end, new_node);
735 this->size_ += 1;
736 }
737 }
738
739 template <typename TYPE, typename ALLOC>
741 TYPE res;
742 if (this->size() == 0){
743 throw noElementError();
744 }
745
746 res = this->beginNode()->getVal();
747 if (this->size() == 1){
748 this->destroyNode(this->lastDelete());
749 } else{
750 auto del = this->beginNode();
751 auto new_begin = del->getPNext();
752 this->destroyNode(del);
753 forwardChainNode::connect(this->begin_, new_begin);
754 this->size_ -= 1;
755 }
756 return res;
757 }
758
759 template <typename TYPE, typename ALLOC>
761 index = this->parseNegIndex(index);
762 if (index == 0){
763 return this->popBegin();
764 }
765 if (index == this->size() - 1){
766 return this->popEnd();
767 }
768 if (this->indexOutOfBound(index)){
769 throw outOfBoundError();
770 }
771 TYPE res;
772 auto prev = this->findNode(index - 1);
773 auto cur = prev->getPNext();
774 res = cur->getVal();
775 auto next = cur->getPNext();
776 forwardChainNode::connect(prev, next);
777 this->destroyNode(cur);
778 this->size_ -= 1;
779 return res;
780 }
781
782 template <typename TYPE, typename ALLOC>
784 TYPE res;
785 if (this->size() == 0){
786 throw noElementError();
787 }
788 if (this->size() == 1){
789 res = this->beginNode()->getVal();
790 this->destroyNode(this->lastDelete());
791 } else{
792 auto new_end = this->findNode(this->size() - 2);
793 auto end = new_end->getPNext();
794 res = end->getVal();
795 this->destroyNode(end);
796 forwardChainNode::connect(new_end, nullptr);
797 this->size_ -= 1;
798 }
799 return res;
800 }
801
802 template <typename TYPE, typename ALLOC>
804 return new Iterator(this->beginNode());
805 }
806
807 template <typename TYPE, typename ALLOC>
809 return new Iterator(this->findNode(this->size() - 1));
810 }
811
812 template <typename TYPE, typename ALLOC>
814 return "forwardChain";
815 }
816
817 template <typename TYPE, typename ALLOC>
819 this->chainDestroy();
820 }
821
822#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:813
void pushBegin(const TYPE &e) override
Inserts element at the beginning of the chain.
Definition forwardChain.h:695
void pushEnd(const TYPE &e) override
Inserts element at the end of the chain.
Definition forwardChain.h:728
void push(integer index, const TYPE &e) override
Pushes an element at the specified index in the forwardChain.
Definition forwardChain.h:708
TYPE & operator[](integer index) override
Gets a reference to the element at the specified index.
Definition forwardChain.h:665
TYPE popBegin() override
Removes and returns the first element.
Definition forwardChain.h:740
void set(integer index, const TYPE &e) override
Sets the element at the specified index.
Definition forwardChain.h:674
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:808
~forwardChain() override
Destructor for the forwardChain.
Definition forwardChain.h:818
u_integer indexOf(const TYPE &e) const override
Finds the index of the first occurrence of the specified element.
Definition forwardChain.h:683
TYPE pop(integer index) override
Pops an element at the specified index in the forwardChain.
Definition forwardChain.h:760
TYPE popEnd() override
Removes and returns the last element.
Definition forwardChain.h:783
Iterator * begins() const override
Gets an iterator to the beginning of the forwardChain.
Definition forwardChain.h:803
forwardChain & operator=(const forwardChain &other)
Assignment operator for forwardChain.
Definition forwardChain.h:605
TYPE get(integer index) const override
Gets the element at the specified index.
Definition forwardChain.h:656
u_integer size() const override
Gets the size of the forwardChain.
Definition forwardChain.h:650
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
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
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
Single-direction iterator base class.