ORIGINAL
Loading...
Searching...
No Matches
chain.h
1#ifndef CHAIN_H
2#define CHAIN_H
3#pragma once
4
5#include "doubleDirectionIterator.h"
6#include "array.h"
7#include "baseList.h"
8#include "iterationStream.h"
9
10
11namespace original {
12 template <typename TYPE>
13 class chain final : public baseList<TYPE>, public iterationStream<TYPE, chain<TYPE>>{
14 class chainNode final : public wrapper<TYPE>{
15 public:
16 friend class iterator<TYPE>;
17 friend class chain;
18 private:
19 TYPE data_;
20 chainNode* prev;
21 chainNode* next;
22 protected:
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);
34 };
35
36 uint32_t size_;
37 chainNode* begin_;
38 chainNode* end_;
39
40 chainNode* findNode(int64_t index) const;
41 void chainInit();
42 void firstAdd(chainNode* node);
43 chainNode* lastDelete();
44 void chainDestruction();
45 public:
46 class Iterator final : public doubleDirectionIterator<TYPE>
47 {
48 explicit Iterator(chainNode* ptr);
49 public:
50 friend chain;
51 Iterator(const Iterator& other);
52 Iterator& operator=(const Iterator& other);
53 Iterator* clone() const override;
54 bool atPrev(const iterator<TYPE> *other) const override;
55 bool atNext(const iterator<TYPE> *other) const override;
56 [[nodiscard]] std::string className() const override;
57 };
58
59 explicit chain();
60 chain(const chain& other);
61 chain(const std::initializer_list<TYPE>& list);
62 explicit chain(const array<TYPE>& arr);
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;
78 Iterator* begins() const override;
79 Iterator* ends() const override;
80 [[nodiscard]] std::string className() const override;
81 ~chain() override;
82 };
83}
84
85 template <typename TYPE>
86 original::chain<TYPE>::chainNode::chainNode(const TYPE& data, chainNode* prev, chainNode* next)
87 : data_(data), prev(prev), next(next) {}
88
89 template<typename TYPE>
90 original::chain<TYPE>::chainNode::chainNode(const chainNode& other)
91 : data_(other.data_), prev(other.prev), next(other.next) {}
92
93 template<typename TYPE>
94 auto original::chain<TYPE>::chainNode::operator=(const chainNode& other) -> chainNode& {
95 if (this != &other) {
96 data_ = other.data_;
97 prev = other.prev;
98 next = other.next;
99 }
100 return *this;
101 }
102
103 template <typename TYPE>
104 auto original::chain<TYPE>::chainNode::getVal() -> TYPE&
105 {
106 return this->data_;
107 }
108
109 template <typename TYPE>
110 auto original::chain<TYPE>::chainNode::getVal() const -> const TYPE&
111 {
112 return this->data_;
113 }
114
115 template <typename TYPE>
116 auto original::chain<TYPE>::chainNode::setVal(TYPE data) -> void
117 {
118 this->data_ = data;
119 }
120
121 template <typename TYPE>
122 auto original::chain<TYPE>::chainNode::getPPrev() const -> chainNode* {
123 return this->prev;
124 }
125
126 template <typename TYPE>
127 auto original::chain<TYPE>::chainNode::getPNext() const -> chainNode* {
128 return this->next;
129 }
130
131 template <typename TYPE>
132 auto original::chain<TYPE>::chainNode::setPPrev(chainNode* new_prev) -> void {
133 this->prev = new_prev;
134 }
135
136 template <typename TYPE>
137 auto original::chain<TYPE>::chainNode::setPNext(chainNode* new_next) -> void {
138 this->next = new_next;
139 }
140
141 template <typename TYPE>
142 auto original::chain<TYPE>::chainNode::connect(chainNode* prev, chainNode* next) -> void
143 {
144 if (prev != nullptr) prev->setPNext(next);
145 if (next != nullptr) next->setPPrev(prev);
146 }
147
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;
151 chainNode* cur;
152 if (!reverse_visit){
153 cur = this->begin_;
154 for(uint32_t i = 0; i < index; i++)
155 {
156 cur = cur->getPNext();
157 }
158 } else{
159 cur = this->end_;
160 for(uint32_t i = this->size() - 1; i > index; i -= 1)
161 {
162 cur = cur->getPPrev();
163 }
164 }
165 return cur;
166 }
167
168 template <typename TYPE>
169 auto original::chain<TYPE>::chainInit() -> void
170 {
171 auto* pivot = new chainNode();
172 this->size_ = 0;
173 this->begin_ = pivot->getPNext();
174 this->end_ = pivot;
175 }
176
177 template <typename TYPE>
178 auto original::chain<TYPE>::firstAdd(chainNode* node) -> void
179 {
180 chainNode::connect(this->end_, node);
181 this->begin_ = node;
182 this->end_ = node;
183 this->size_ += 1;
184 }
185
186 template <typename TYPE>
187 auto original::chain<TYPE>::lastDelete() -> chainNode*
188 {
189 auto* last = this->end_;
190 delete last->getPPrev();
191 this->chainInit();
192 return last;
193 }
194
195 template <typename TYPE>
196 auto original::chain<TYPE>::chainDestruction() -> void
197 {
198 auto* current = this->end_;
199 while (current) {
200 auto* prev = current->getPPrev();
201 delete current;
202 current = prev;
203 }
204 }
205
206 template<typename TYPE>
207 original::chain<TYPE>::Iterator::Iterator(chainNode* ptr)
208 : doubleDirectionIterator<TYPE>::doubleDirectionIterator(ptr) {}
209
210 template<typename TYPE>
211 original::chain<TYPE>::Iterator::Iterator(const Iterator& other)
212 : doubleDirectionIterator<TYPE>::doubleDirectionIterator(nullptr) {
213 this->operator=(other);
214 }
215
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);
220 return *this;
221 }
222
223 template<typename TYPE>
224 auto original::chain<TYPE>::Iterator::clone() const -> Iterator* {
225 return new Iterator(*this);
226 }
227
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;
232 }
233
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;
238 }
239
240 template<typename TYPE>
241 auto original::chain<TYPE>::Iterator::className() const -> std::string {
242 return "chain::Iterator";
243 }
244
245 template <typename TYPE>
246 original::chain<TYPE>::chain() : size_(0)
247 {
248 chainInit();
249 }
250
251 template<typename TYPE>
252 original::chain<TYPE>::chain(const chain& other) : chain(){
253 this->operator=(other);
254 }
255
256 template <typename TYPE>
257 original::chain<TYPE>::chain(const std::initializer_list<TYPE>& list)
258 : chain() {
259 for (const auto& e : list) {
260 auto* cur_node = new chainNode(e);
261 if (this->size() == 0)
262 {
263 this->firstAdd(cur_node);
264 }else
265 {
266 chainNode::connect(this->end_, cur_node);
267 this->end_ = cur_node;
268 size_ += 1;
269 }
270 }
271 }
272
273 template <typename TYPE>
274 original::chain<TYPE>::chain(const array<TYPE>& arr)
275 : chain() {
276 for (uint32_t i = 0; i < arr.size(); i++) {
277 auto* cur_node = new chainNode(arr.get(i));
278 if (this->size() == 0)
279 {
280 this->firstAdd(cur_node);
281 }else
282 {
283 chainNode::connect(this->end_, cur_node);
284 this->end_ = cur_node;
285 size_ += 1;
286 }
287 }
288 }
289
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();
306 }
307 this->end_ = this_;
308 } else{
309 this->chainInit();
310 }
311 return *this;
312 }
313
314 template <typename TYPE>
315 original::chain<TYPE>::chain(chain&& other) noexcept : chain()
316 {
317 this->operator=(std::move(other));
318 }
319
320 template <typename TYPE>
321 auto original::chain<TYPE>::operator=(chain&& other) noexcept -> chain&
322 {
323 if (this == &other)
324 return *this;
325
326 this->chainDestruction();
327 this->begin_ = other.begin_;
328 this->end_ = other.end_;
329 this->size_ = other.size_;
330 other.chainInit();
331 return *this;
332 }
333
334 template <typename TYPE>
335 auto original::chain<TYPE>::operator+=(chain& other) -> void
336 {
337 if (other.empty()) return;
338
339 this->size_ += other.size_;
340 delete other.begin_->getPPrev();
341 chainNode::connect(this->end_, other.begin_);
342 this->end_ = other.end_;
343 other.chainInit();
344 }
345
346 template <typename TYPE>
347 auto original::chain<TYPE>::size() const -> uint32_t
348 {
349 return this->size_;
350 }
351
352 template <typename TYPE>
353 auto original::chain<TYPE>::className() const -> std::string
354 {
355 return "chain";
356 }
357
358 template <typename TYPE>
359 auto original::chain<TYPE>::get(int64_t index) const -> TYPE
360 {
361 if (this->indexOutOfBound(index)){
362 throw outOfBoundError();
363 }
364 chainNode* cur = this->findNode(this->parseNegIndex(index));
365 return cur->getVal();
366 }
367
368 template <typename TYPE>
369 auto original::chain<TYPE>::operator[](const int64_t index) -> TYPE&
370 {
371 if (this->indexOutOfBound(index)){
372 throw outOfBoundError();
373 }
374 chainNode* cur = this->findNode(this->parseNegIndex(index));
375 return cur->getVal();
376 }
377
378 template <typename TYPE>
379 auto original::chain<TYPE>::set(int64_t index, const TYPE &e) -> void
380 {
381 if (this->indexOutOfBound(index)){
382 throw outOfBoundError();
383 }
384 auto* cur = this->findNode(this->parseNegIndex(index));
385 cur->setVal(e);
386 }
387
388 template <typename TYPE>
389 auto original::chain<TYPE>::indexOf(const TYPE &e) const -> uint32_t {
390 uint32_t i = 0;
391 for (chainNode* current = this->begin_; current != nullptr; current = current->getPNext()) {
392 if (current->getVal() == e) {
393 return i;
394 }
395 i += 1;
396 }
397 return this->size();
398 }
399
400 template <typename TYPE>
401 auto original::chain<TYPE>::pushBegin(const TYPE &e) -> void
402 {
403 auto* new_node = new chainNode(e);
404 if (this->size() == 0){
405 this->firstAdd(new_node);
406 } else{
407 auto* pivot = this->begin_->getPPrev();
408 chainNode::connect(new_node, this->begin_);
409 chainNode::connect(pivot, new_node);
410 this->begin_ = new_node;
411 this->size_ += 1;
412 }
413 }
414
415 template <typename TYPE>
416 auto original::chain<TYPE>::push(int64_t index, const TYPE &e) -> void
417 {
418 index = this->parseNegIndex(index);
419 if (index == 0){
420 this->pushBegin(e);
421 } else if (index == this->size()){
422 this->pushEnd(e);
423 } else{
424 if (this->indexOutOfBound(index)){
425 throw outOfBoundError();
426 }
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);
432 this->size_ += 1;
433 }
434 }
435
436 template <typename TYPE>
437 auto original::chain<TYPE>::pushEnd(const TYPE &e) -> void
438 {
439 auto* new_node = new chainNode(e);
440 if (this->size() == 0){
441 this->firstAdd(new_node);
442 } else{
443 chainNode::connect(this->end_, new_node);
444 this->end_ = new_node;
445 this->size_ += 1;
446 }
447 }
448
449 template <typename TYPE>
450 auto original::chain<TYPE>::popBegin() -> TYPE
451 {
452 TYPE res;
453 if (this->size() == 0){
454 throw noElementError();
455 }
456 if (this->size() == 1){
457 auto* del = this->lastDelete();
458 res = del->getVal();
459 delete del;
460 this->chainInit();
461 } else{
462 res = this->begin_->getVal();
463 auto* new_begin = this->begin_->getPNext();
464 auto* pivot = this->begin_->getPPrev();
465 delete this->begin_;
466 this->begin_ = new_begin;
467 chainNode::connect(pivot, this->begin_);
468 this->size_ -= 1;
469 }
470 return res;
471 }
472
473 template <typename TYPE>
474 auto original::chain<TYPE>::pop(int64_t index) -> TYPE
475 {
476 index = this->parseNegIndex(index);
477 if (index == 0){
478 return this->popBegin();
479 }
480 if (index == this->size() - 1){
481 return this->popEnd();
482 }
483 if (this->indexOutOfBound(index)){
484 throw outOfBoundError();
485 }
486 TYPE res;
487 chainNode* cur = this->findNode(index);
488 res = cur->getVal();
489 auto* prev = cur->getPPrev();
490 auto* next = cur->getPNext();
491 chainNode::connect(prev, next);
492 delete cur;
493 this->size_ -= 1;
494 return res;
495 }
496
497 template <typename TYPE>
498 auto original::chain<TYPE>::popEnd() -> TYPE
499 {
500 TYPE res;
501 if (this->size() == 0){
502 throw noElementError();
503 }
504 if (this->size() == 1){
505 auto* del = this->lastDelete();
506 res = del->getVal();
507 delete del;
508 this->chainInit();
509 } else{
510 res = this->end_->getVal();
511 auto* new_end = this->end_->getPPrev();
512 delete this->end_;
513 this->end_ = new_end;
514 chainNode::connect(this->end_, nullptr);
515 this->size_ -= 1;
516 }
517 return res;
518 }
519
520 template<typename TYPE>
521 auto original::chain<TYPE>::begins() const -> Iterator* {
522 return new Iterator(this->begin_);
523 }
524
525 template<typename TYPE>
526 auto original::chain<TYPE>::ends() const -> Iterator* {
527 return new Iterator(this->end_);
528 }
529
530 template <typename TYPE>
531 original::chain<TYPE>::~chain() {
532 this->chainDestruction();
533 }
534
535#endif //CHAIN_H
Definition array.h:15
Definition baseList.h:7
Definition chain.h:47
Definition iterationStream.h:12
Definition iterator.h:11
Definition wrapper.h:12