5#include "doubleDirectionIterator.h"
8#include "iterationStream.h"
12 template <
typename TYPE>
14 class chainNode final :
public wrapper<TYPE>{
23 explicit chainNode(
const TYPE& data = TYPE{}, chainNode* prev =
nullptr, chainNode* next =
nullptr);
24 chainNode(
const chainNode& other);
25 chainNode& operator=(
const chainNode& other);
26 TYPE& getVal()
override;
27 const TYPE& getVal()
const override;
28 void setVal(TYPE data)
override;
29 chainNode* getPPrev()
const override;
30 chainNode* getPNext()
const override;
31 void setPPrev(chainNode* new_prev);
32 void setPNext(chainNode* new_next);
33 static void connect(chainNode* prev, chainNode* next);
40 chainNode* findNode(int64_t index)
const;
42 void firstAdd(chainNode* node);
43 chainNode* lastDelete();
44 void chainDestruction();
46 class Iterator final :
public doubleDirectionIterator<TYPE>
48 explicit Iterator(chainNode* ptr);
51 Iterator(
const Iterator& other);
52 Iterator& operator=(
const Iterator& other);
53 Iterator* clone()
const override;
56 [[nodiscard]] std::string className()
const override;
60 chain(
const chain& other);
61 chain(
const std::initializer_list<TYPE>& list);
63 chain& operator=(
const chain& other);
64 chain(chain&& other)
noexcept;
65 chain& operator=(chain&& other)
noexcept;
66 void operator+=(chain& other);
67 [[nodiscard]] uint32_t size()
const override;
68 TYPE get(int64_t index)
const override;
69 TYPE& operator[](int64_t index)
override;
70 void set(int64_t index,
const TYPE &e)
override;
71 uint32_t indexOf(
const TYPE &e)
const override;
72 void pushBegin(
const TYPE &e)
override;
73 void push(int64_t index,
const TYPE &e)
override;
74 void pushEnd(
const TYPE &e)
override;
75 TYPE popBegin()
override;
76 TYPE pop(int64_t index)
override;
77 TYPE popEnd()
override;
80 [[nodiscard]] std::string className()
const override;
85 template <
typename TYPE>
86 original::chain<TYPE>::chainNode::chainNode(
const TYPE& data, chainNode* prev, chainNode* next)
87 : data_(data), prev(prev), next(next) {}
89 template<
typename TYPE>
90 original::chain<TYPE>::chainNode::chainNode(
const chainNode& other)
91 : data_(other.data_), prev(other.prev), next(other.next) {}
93 template<
typename TYPE>
94 auto original::chain<TYPE>::chainNode::operator=(
const chainNode& other) -> chainNode& {
103 template <
typename TYPE>
104 auto original::chain<TYPE>::chainNode::getVal() -> TYPE&
109 template <
typename TYPE>
110 auto original::chain<TYPE>::chainNode::getVal() const -> const TYPE&
115 template <
typename TYPE>
116 auto original::chain<TYPE>::chainNode::setVal(TYPE data) ->
void
121 template <
typename TYPE>
122 auto original::chain<TYPE>::chainNode::getPPrev() const -> chainNode* {
126 template <
typename TYPE>
127 auto original::chain<TYPE>::chainNode::getPNext() const -> chainNode* {
131 template <
typename TYPE>
132 auto original::chain<TYPE>::chainNode::setPPrev(chainNode* new_prev) ->
void {
133 this->prev = new_prev;
136 template <
typename TYPE>
137 auto original::chain<TYPE>::chainNode::setPNext(chainNode* new_next) ->
void {
138 this->next = new_next;
141 template <
typename TYPE>
142 auto original::chain<TYPE>::chainNode::connect(chainNode* prev, chainNode* next) ->
void
144 if (prev !=
nullptr) prev->setPNext(next);
145 if (next !=
nullptr) next->setPPrev(prev);
148 template<
typename TYPE>
149 auto original::chain<TYPE>::findNode(int64_t index)
const -> chainNode* {
150 const bool reverse_visit = index <= this->size() / 2 ? 0 : 1;
154 for(uint32_t i = 0; i < index; i++)
156 cur = cur->getPNext();
160 for(uint32_t i = this->size() - 1; i > index; i -= 1)
162 cur = cur->getPPrev();
168 template <
typename TYPE>
169 auto original::chain<TYPE>::chainInit() ->
void
171 auto* pivot =
new chainNode();
173 this->begin_ = pivot->getPNext();
177 template <
typename TYPE>
178 auto original::chain<TYPE>::firstAdd(chainNode* node) ->
void
180 chainNode::connect(this->end_, node);
186 template <
typename TYPE>
187 auto original::chain<TYPE>::lastDelete() -> chainNode*
189 auto* last = this->end_;
190 delete last->getPPrev();
195 template <
typename TYPE>
196 auto original::chain<TYPE>::chainDestruction() ->
void
198 auto* current = this->end_;
200 auto* prev = current->getPPrev();
206 template<
typename TYPE>
207 original::chain<TYPE>::Iterator::Iterator(chainNode* ptr)
208 : doubleDirectionIterator<TYPE>::doubleDirectionIterator(ptr) {}
210 template<
typename TYPE>
211 original::chain<TYPE>::Iterator::Iterator(
const Iterator& other)
212 : doubleDirectionIterator<TYPE>::doubleDirectionIterator(nullptr) {
213 this->operator=(other);
216 template<
typename TYPE>
217 auto original::chain<TYPE>::Iterator::operator=(
const Iterator& other) ->
Iterator& {
218 if (
this == &other)
return *
this;
219 doubleDirectionIterator<TYPE>::operator=(other);
223 template<
typename TYPE>
224 auto original::chain<TYPE>::Iterator::clone() const ->
Iterator* {
228 template<
typename TYPE>
229 auto original::chain<TYPE>::Iterator::atPrev(
const iterator<TYPE> *other)
const ->
bool {
230 auto other_it =
dynamic_cast<const Iterator*
>(other);
231 return other_it !=
nullptr && this->_ptr->getPNext() == other_it->_ptr;
234 template<
typename TYPE>
235 auto original::chain<TYPE>::Iterator::atNext(
const iterator<TYPE> *other)
const ->
bool {
236 auto other_it =
dynamic_cast<const Iterator*
>(other);
237 return other_it !=
nullptr && other_it->_ptr->getPNext() == this->_ptr;
240 template<
typename TYPE>
241 auto original::chain<TYPE>::Iterator::className() const -> std::
string {
242 return "chain::Iterator";
245 template <
typename TYPE>
246 original::chain<TYPE>::chain() : size_(0)
251 template<
typename TYPE>
252 original::chain<TYPE>::chain(
const chain& other) : chain(){
253 this->operator=(other);
256 template <
typename TYPE>
257 original::chain<TYPE>::chain(
const std::initializer_list<TYPE>& list)
259 for (
const auto& e : list) {
260 auto* cur_node =
new chainNode(e);
261 if (this->size() == 0)
263 this->firstAdd(cur_node);
266 chainNode::connect(this->end_, cur_node);
267 this->end_ = cur_node;
273 template <
typename TYPE>
274 original::chain<TYPE>::chain(
const array<TYPE>& arr)
276 for (uint32_t i = 0; i < arr.size(); i++) {
277 auto* cur_node =
new chainNode(arr.get(i));
278 if (this->size() == 0)
280 this->firstAdd(cur_node);
283 chainNode::connect(this->end_, cur_node);
284 this->end_ = cur_node;
290 template<
typename TYPE>
291 original::chain<TYPE>& original::chain<TYPE>::operator=(
const chain& other){
292 if (
this == &other)
return *
this;
293 this->chainDestruction();
294 this->size_ = other.size_;
295 if (this->size() != 0){
296 auto* other_ = other.begin_->getPPrev();
297 auto* pivot =
new chainNode(other_->getVal());
298 other_ = other_->getPNext();
299 chainNode::connect(pivot,
new chainNode(other_->getVal()));
300 this->begin_ = pivot->getPNext();
301 auto* this_ = this->begin_;
302 while (other_ != other.end_){
303 other_ = other_->getPNext();
304 chainNode::connect(this_,
new chainNode(other_->getVal()));
305 this_ = this_->getPNext();
314 template <
typename TYPE>
315 original::chain<TYPE>::chain(chain&& other) noexcept : chain()
317 this->operator=(std::move(other));
320 template <
typename TYPE>
321 auto original::chain<TYPE>::operator=(chain&& other)
noexcept -> chain&
326 this->chainDestruction();
327 this->begin_ = other.begin_;
328 this->end_ = other.end_;
329 this->size_ = other.size_;
334 template <
typename TYPE>
335 auto original::chain<TYPE>::operator+=(chain& other) ->
void
337 if (other.empty())
return;
339 this->size_ += other.size_;
340 delete other.begin_->getPPrev();
341 chainNode::connect(this->end_, other.begin_);
342 this->end_ = other.end_;
346 template <
typename TYPE>
347 auto original::chain<TYPE>::size() const -> uint32_t
352 template <
typename TYPE>
353 auto original::chain<TYPE>::className() const -> std::
string
358 template <
typename TYPE>
359 auto original::chain<TYPE>::get(int64_t index)
const -> TYPE
361 if (this->indexOutOfBound(index)){
362 throw outOfBoundError();
364 chainNode* cur = this->findNode(this->parseNegIndex(index));
365 return cur->getVal();
368 template <
typename TYPE>
369 auto original::chain<TYPE>::operator[](
const int64_t index) -> TYPE&
371 if (this->indexOutOfBound(index)){
372 throw outOfBoundError();
374 chainNode* cur = this->findNode(this->parseNegIndex(index));
375 return cur->getVal();
378 template <
typename TYPE>
379 auto original::chain<TYPE>::set(int64_t index,
const TYPE &e) ->
void
381 if (this->indexOutOfBound(index)){
382 throw outOfBoundError();
384 auto* cur = this->findNode(this->parseNegIndex(index));
388 template <
typename TYPE>
389 auto original::chain<TYPE>::indexOf(
const TYPE &e)
const -> uint32_t {
391 for (chainNode* current = this->begin_; current !=
nullptr; current = current->getPNext()) {
392 if (current->getVal() == e) {
400 template <
typename TYPE>
401 auto original::chain<TYPE>::pushBegin(
const TYPE &e) ->
void
403 auto* new_node =
new chainNode(e);
404 if (this->size() == 0){
405 this->firstAdd(new_node);
407 auto* pivot = this->begin_->getPPrev();
408 chainNode::connect(new_node, this->begin_);
409 chainNode::connect(pivot, new_node);
410 this->begin_ = new_node;
415 template <
typename TYPE>
416 auto original::chain<TYPE>::push(int64_t index,
const TYPE &e) ->
void
418 index = this->parseNegIndex(index);
421 }
else if (index == this->size()){
424 if (this->indexOutOfBound(index)){
425 throw outOfBoundError();
427 auto* new_node =
new chainNode(e);
428 chainNode* cur = this->findNode(index);
429 auto* prev = cur->getPPrev();
430 chainNode::connect(prev, new_node);
431 chainNode::connect(new_node, cur);
436 template <
typename TYPE>
437 auto original::chain<TYPE>::pushEnd(
const TYPE &e) ->
void
439 auto* new_node =
new chainNode(e);
440 if (this->size() == 0){
441 this->firstAdd(new_node);
443 chainNode::connect(this->end_, new_node);
444 this->end_ = new_node;
449 template <
typename TYPE>
450 auto original::chain<TYPE>::popBegin() -> TYPE
453 if (this->size() == 0){
454 throw noElementError();
456 if (this->size() == 1){
457 auto* del = this->lastDelete();
462 res = this->begin_->getVal();
463 auto* new_begin = this->begin_->getPNext();
464 auto* pivot = this->begin_->getPPrev();
466 this->begin_ = new_begin;
467 chainNode::connect(pivot, this->begin_);
473 template <
typename TYPE>
474 auto original::chain<TYPE>::pop(int64_t index) -> TYPE
476 index = this->parseNegIndex(index);
478 return this->popBegin();
480 if (index == this->size() - 1){
481 return this->popEnd();
483 if (this->indexOutOfBound(index)){
484 throw outOfBoundError();
487 chainNode* cur = this->findNode(index);
489 auto* prev = cur->getPPrev();
490 auto* next = cur->getPNext();
491 chainNode::connect(prev, next);
497 template <
typename TYPE>
498 auto original::chain<TYPE>::popEnd() -> TYPE
501 if (this->size() == 0){
502 throw noElementError();
504 if (this->size() == 1){
505 auto* del = this->lastDelete();
510 res = this->end_->getVal();
511 auto* new_end = this->end_->getPPrev();
513 this->end_ = new_end;
514 chainNode::connect(this->end_,
nullptr);
520 template<
typename TYPE>
521 auto original::chain<TYPE>::begins() const ->
Iterator* {
525 template<
typename TYPE>
526 auto original::chain<TYPE>::ends() const ->
Iterator* {
530 template <
typename TYPE>
531 original::chain<TYPE>::~chain() {
532 this->chainDestruction();
Definition iterationStream.h:12