ORIGINAL
Loading...
Searching...
No Matches
array.h
Go to the documentation of this file.
1#ifndef ARRAY_H
2#define ARRAY_H
3#pragma once
4
5#include <initializer_list>
6#include "allocator.h"
7#include "config.h"
8#include "baseArray.h"
9#include "iterationStream.h"
11#include "error.h"
12
13namespace original {
40 template<typename TYPE, typename ALLOC = allocator<TYPE>>
41 class array final : public iterationStream<TYPE, array<TYPE, ALLOC>>, public baseArray<TYPE, ALLOC> {
42 u_integer size_;
43 TYPE* body;
44
51 void arrInit(u_integer size);
52
58 void arrDestroy() noexcept;
59
67 TYPE getElem(integer pos) const;
68
76 void setElem(integer pos, const TYPE &e);
77 public:
78
89 class Iterator final : public randomAccessIterator<TYPE, ALLOC> {
96 explicit Iterator(TYPE* ptr, const array* container, integer pos);
97
98 public:
99 friend array;
100
106 Iterator(const Iterator& other);
107
114 Iterator& operator=(const Iterator& other);
115
121 Iterator* clone() const override;
122
129 bool atPrev(const iterator<TYPE> *other) const override;
130
137 bool atNext(const iterator<TYPE> *other) const override;
138
143 [[nodiscard]] std::string className() const override;
144 };
145
153 explicit array(u_integer size = 0, ALLOC alloc = ALLOC{});
154
161 array(const std::initializer_list<TYPE>& lst);
162
170
179
187 array(array&& other) noexcept;
188
198
204 void swap(array& other) noexcept;
205
210 [[nodiscard]] u_integer size() const override;
211
217 TYPE& data() const;
218
225 TYPE get(integer index) const override;
226
233 TYPE& operator[](integer index) override;
234
241 using serial<TYPE, ALLOC>::operator[];
242
249 void set(integer index, const TYPE& e) override;
250
257 u_integer indexOf(const TYPE& e) const override;
258
263 Iterator* begins() const override;
264
269 Iterator* ends() const override;
270
275 [[nodiscard]] std::string className() const override;
276
281 ~array() override;
282 };
283} // namespace original
284
285namespace std {
293 template<typename TYPE, typename ALLOC>
294 void swap(original::array<TYPE, ALLOC>& lhs, original::array<TYPE, ALLOC>& rhs) noexcept; // NOLINT
295}
296
297 template<typename TYPE, typename ALLOC>
298 void original::array<TYPE, ALLOC>::arrInit(const u_integer size) {
299 this->size_ = size;
300 this->body = this->allocate(this->size_);
301 for (u_integer i = 0; i < this->size(); ++i) {
302 this->construct(&this->body[i]);
303 }
304 }
305
306 template<typename TYPE, typename ALLOC>
308 {
309 if (this->body){
310 for (u_integer i = 0; i < this->size_; ++i) {
311 this->destroy(&this->body[i]);
312 }
313 this->deallocate(this->body, this->size_);
314 this->body = nullptr;
315 }
316 }
317
318 template <typename TYPE, typename ALLOC>
319 TYPE original::array<TYPE, ALLOC>::getElem(integer pos) const
320 {
321 if constexpr (std::is_copy_constructible_v<TYPE>) {
322 return this->body[pos];
323 } else if constexpr (std::is_move_constructible_v<TYPE>) {
324 return std::move(this->body[pos]);
325 } else {
326 staticError<unSupportedMethodError, !std::is_copy_constructible_v<TYPE> && !std::is_move_constructible_v<TYPE>>::asserts();
327 return TYPE{};
328 }
329 }
330
331 template <typename TYPE, typename ALLOC>
332 void original::array<TYPE, ALLOC>::setElem(integer pos, const TYPE& e)
333 {
334 if constexpr (std::is_copy_assignable_v<TYPE>) {
335 this->body[pos] = e;
336 } else if constexpr (std::is_move_assignable_v<TYPE>) {
337 this->body[pos] = std::move(const_cast<TYPE&>(e));
338 } else {
339 staticError<unSupportedMethodError, !std::is_copy_constructible_v<TYPE> && !std::is_move_constructible_v<TYPE>>::asserts();
340 }
341 }
342
343 template<typename TYPE, typename ALLOC>
344 original::array<TYPE, ALLOC>::Iterator::Iterator(TYPE* ptr, const array* container, integer pos)
345 : randomAccessIterator<TYPE, ALLOC>(ptr, container, pos) {}
346
347 template<typename TYPE, typename ALLOC>
353
354 template<typename TYPE, typename ALLOC>
356 {
357 if (this == &other) {
358 return *this;
359 }
361 return *this;
362 }
363
364 template<typename TYPE, typename ALLOC>
366 return new Iterator(*this);
367 }
368
369 template<typename TYPE, typename ALLOC>
371 auto other_it = dynamic_cast<const Iterator*>(other);
372 return this->_ptr + 1 == other_it->_ptr;
373 }
374
375 template<typename TYPE, typename ALLOC>
377 auto other_it = dynamic_cast<const Iterator*>(other);
378 return other_it->_ptr + 1 == this->_ptr;
379 }
380
381 template<typename TYPE, typename ALLOC>
383 return "array::Iterator";
384 }
385
386 template<typename TYPE, typename ALLOC>
388 : baseArray<TYPE, ALLOC>(std::move(alloc)), size_(), body(nullptr) {
389 this->arrInit(size);
390 }
391
392 template<typename TYPE, typename ALLOC>
393 original::array<TYPE, ALLOC>::array(const std::initializer_list<TYPE>& lst)
394 : array(lst.size()) {
395 u_integer i = 0;
396 for (const auto& e : lst) {
397 this->setElem(i, e);
398 i += 1;
399 }
400 }
401
402 template<typename TYPE, typename ALLOC>
404 : array(other.size()) {
405 this->operator=(other);
406 }
407
408 template<typename TYPE, typename ALLOC>
410 {
411 if (this == &other)
412 return *this;
413
414 this->arrDestroy();
415
416 this->arrInit(other.size());
417 for (u_integer i = 0; i < this->size_; i++) {
418 this->setElem(i, other.getElem(i));
419 }
420 if constexpr (ALLOC::propagate_on_container_copy_assignment::value){
421 this->allocator = other.allocator;
422 }
423 return *this;
424 }
425
426 template<typename TYPE, typename ALLOC>
428 this->operator=(std::move(other));
429 }
430
431 template<typename TYPE, typename ALLOC>
433 if (this == &other)
434 return *this;
435
436 this->arrDestroy();
437
438 this->body = other.body;
439 this->size_ = other.size_;
440 if constexpr (ALLOC::propagate_on_container_move_assignment::value){
441 this->allocator = std::move(other.allocator);
442 }
443 other.arrInit(0);
444 return *this;
445 }
446
447 template <typename TYPE, typename ALLOC>
449 if (this == &other)
450 return;
451
452 std::swap(this->size_, other.size_);
453 std::swap(this->body, other.body);
454 if constexpr (ALLOC::propagate_on_container_swap::value) {
455 std::swap(this->allocator, other.allocator);
456 }
457 }
458
459 template<typename TYPE, typename ALLOC>
461 this->arrDestroy();
462 }
463
464 template<typename TYPE, typename ALLOC>
466 {
467 return this->size_;
468 }
469
470 template<typename TYPE, typename ALLOC>
472 return this->body[0];
473 }
474
475 template<typename TYPE, typename ALLOC>
477 {
478 if (this->indexOutOfBound(index)){
479 throw outOfBoundError("Index " + std::to_string(this->parseNegIndex(index)) +
480 " out of bound max index " + std::to_string(this->size() - 1) + ".");
481 }
482 return this->getElem(this->parseNegIndex(index));
483 }
484
485 template<typename TYPE, typename ALLOC>
487 {
488 if (this->indexOutOfBound(index)){
489 throw outOfBoundError("Index " + std::to_string(this->parseNegIndex(index)) +
490 " out of bound max index " + std::to_string(this->size() - 1) + ".");
491 }
492 return this->body[this->parseNegIndex(index)];
493 }
494
495 template<typename TYPE, typename ALLOC>
497 {
498 if (this->indexOutOfBound(index)){
499 throw outOfBoundError("Index " + std::to_string(this->parseNegIndex(index)) +
500 " out of bound max index " + std::to_string(this->size() - 1) + ".");
501 }
502 this->setElem(this->parseNegIndex(index), e);
503 }
504
505 template<typename TYPE, typename ALLOC>
507 {
508 if constexpr (Comparable<TYPE>)
509 {
510 for (u_integer i = 0; i < this->size(); i += 1)
511 {
512 if (this->get(i) == e)
513 {
514 return i;
515 }
516 }
517 return this->size();
518 } else {
519 throw unSupportedMethodError("Comparison unsupported type");
520 }
521 }
522
523 template<typename TYPE, typename ALLOC>
525 return new Iterator(&this->body[0], this, 0);
526 }
527
528 template<typename TYPE, typename ALLOC>
530 return new Iterator(&this->body[this->size() - 1], this, this->size() - 1);
531 }
532
533 template<typename TYPE, typename ALLOC>
535 {
536 return "array";
537 }
538
539 template <typename TYPE, typename ALLOC>
541 {
542 lhs.swap(rhs);
543 }
544
545#endif //ARRAY_H
Memory allocation interface and implementations.
Provides a base class for fixed-size serial containers.
Default memory allocator using allocators utilities.
Definition allocator.h:153
Iterator for the array class that supports random access.
Definition array.h:89
std::string className() const override
Returns the class name of this iterator.
Definition array.h:382
Iterator & operator=(const Iterator &other)
Copy assignment operator for the iterator.
Definition array.h:355
bool atNext(const iterator< TYPE > *other) const override
Checks if this iterator is positioned just after the given iterator.
Definition array.h:376
Iterator * clone() const override
Clones the iterator.
Definition array.h:365
bool atPrev(const iterator< TYPE > *other) const override
Checks if this iterator is positioned just before the given iterator.
Definition array.h:370
A fixed-size array container with random access.
Definition array.h:41
void swap(array &other) noexcept
Swaps the contents of two arrays.
Definition array.h:448
array & operator=(array &&other) noexcept
Move assignment operator.
Definition array.h:432
std::string className() const override
Returns the class name.
Definition array.h:534
void set(integer index, const TYPE &e) override
Sets the value of an element at the specified index.
Definition array.h:496
Iterator * ends() const override
Returns an iterator to the last element of the array.
Definition array.h:529
TYPE get(integer index) const override
Retrieves an element at a specified index.
Definition array.h:476
array(array &&other) noexcept
Move constructor.
Definition array.h:427
array(const std::initializer_list< TYPE > &lst)
Constructs an array from an initializer list.
Definition array.h:393
array(u_integer size=0, ALLOC alloc=ALLOC{})
Constructs an empty array.
Definition array.h:387
TYPE & data() const
Returns a reference to the first element of the array.
Definition array.h:471
~array() override
Destroys the array and releases its memory.
Definition array.h:460
array(const array &other)
Copy constructor.
Definition array.h:403
array & operator=(const array &other)
Copy assignment operator.
Definition array.h:409
u_integer indexOf(const TYPE &e) const override
Finds the index of the specified element in the array.
Definition array.h:506
TYPE & operator[](integer index) override
Access an element at a specified index for modification.
Definition array.h:486
u_integer size() const override
Returns the size of the array.
Definition array.h:465
Iterator * begins() const override
Returns an iterator to the first element of the array.
Definition array.h:524
void swap(autoPtr &other) noexcept
Swaps the reference counters between two autoPtr instances.
Definition autoPtr.h:703
Base class for fixed-size serial containers.
Definition baseArray.h:43
Abstract base class for containers.
Definition container.h:26
A stream class that allows iteration, comparison, hashing and printing.
Definition iterationStream.h:60
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 random-access iterators.
Definition randomAccessIterator.h:39
randomAccessIterator & operator=(const randomAccessIterator &other)
Copy assignment operator.
Definition randomAccessIterator.h:197
Abstract base class for sequential containers with index-based access.
Definition serial.h:34
Exception for unimplemented method calls.
Definition error.h:271
Definition types.h:157
Platform-independent type definitions and compiler/platform detection.
Custom exception classes and callback validation utilities.
Provides functionality for an iteration stream with comparison, hashing and printing.
Main namespace for the project Original.
Definition algorithms.h:21
Standard namespace extensions for original::alternative.
Definition allocator.h:351
std::string to_string(const T &t)
std::to_string overload for printable-derived types
Definition printable.h:415
void swap(original::objPoolAllocator< TYPE > &lhs, original::objPoolAllocator< TYPE > &rhs) noexcept
Specialization of std::swap for objPoolAllocator.
Definition allocator.h:635
Base class for random-access iterators.