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
169 array(const array& other);
170
178 array& operator=(const array& other);
179
187 array(array&& other) noexcept;
188
197 array& operator=(array&& other) noexcept;
198
203 [[nodiscard]] u_integer size() const override;
204
210 TYPE& data() const;
211
218 TYPE get(integer index) const override;
219
226 TYPE& operator[](integer index) override;
227
234 using serial<TYPE, ALLOC>::operator[];
235
242 void set(integer index, const TYPE& e) override;
243
250 u_integer indexOf(const TYPE& e) const override;
251
256 Iterator* begins() const override;
257
262 Iterator* ends() const override;
263
268 [[nodiscard]] std::string className() const override;
269
274 ~array() override;
275 };
276
277} // namespace original
278
279 template<typename TYPE, typename ALLOC>
280 void original::array<TYPE, ALLOC>::arrInit(const u_integer size) {
281 this->size_ = size;
282 this->body = this->allocate(this->size_);
283 for (u_integer i = 0; i < this->size(); ++i) {
284 this->construct(&this->body[i]);
285 }
286 }
287
288 template<typename TYPE, typename ALLOC>
290 {
291 if (this->body){
292 for (u_integer i = 0; i < this->size_; ++i) {
293 this->destroy(&this->body[i]);
294 }
295 this->deallocate(this->body, this->size_);
296 this->body = nullptr;
297 }
298 }
299
300 template <typename TYPE, typename ALLOC>
301 TYPE original::array<TYPE, ALLOC>::getElem(integer pos) const
302 {
303 if constexpr (std::is_copy_constructible_v<TYPE>) {
304 return this->body[pos];
305 } else if constexpr (std::is_move_constructible_v<TYPE>) {
306 return std::move(this->body[pos]);
307 } else {
308 staticError<unSupportedMethodError, !std::is_copy_constructible_v<TYPE> && !std::is_move_constructible_v<TYPE>>::asserts();
309 return TYPE{};
310 }
311 }
312
313 template <typename TYPE, typename ALLOC>
314 void original::array<TYPE, ALLOC>::setElem(integer pos, const TYPE& e)
315 {
316 if constexpr (std::is_copy_assignable_v<TYPE>) {
317 this->body[pos] = e;
318 } else if constexpr (std::is_move_assignable_v<TYPE>) {
319 this->body[pos] = std::move(const_cast<TYPE&>(e));
320 } else {
321 staticError<unSupportedMethodError, !std::is_copy_constructible_v<TYPE> && !std::is_move_constructible_v<TYPE>>::asserts();
322 }
323 }
324
325 template<typename TYPE, typename ALLOC>
326 original::array<TYPE, ALLOC>::Iterator::Iterator(TYPE* ptr, const array* container, integer pos)
327 : randomAccessIterator<TYPE, ALLOC>(ptr, container, pos) {}
328
329 template<typename TYPE, typename ALLOC>
331 : randomAccessIterator<TYPE, ALLOC>(nullptr, nullptr, 0)
332 {
333 this->operator=(other);
334 }
335
336 template<typename TYPE, typename ALLOC>
338 {
339 if (this == &other) {
340 return *this;
341 }
343 return *this;
344 }
345
346 template<typename TYPE, typename ALLOC>
348 return new Iterator(*this);
349 }
350
351 template<typename TYPE, typename ALLOC>
353 auto other_it = dynamic_cast<const Iterator*>(other);
354 return this->_ptr + 1 == other_it->_ptr;
355 }
356
357 template<typename TYPE, typename ALLOC>
359 auto other_it = dynamic_cast<const Iterator*>(other);
360 return other_it->_ptr + 1 == this->_ptr;
361 }
362
363 template<typename TYPE, typename ALLOC>
365 return "array::Iterator";
366 }
367
368 template<typename TYPE, typename ALLOC>
370 : baseArray<TYPE, ALLOC>(std::move(alloc)), size_(), body(nullptr) {
371 this->arrInit(size);
372 }
373
374 template<typename TYPE, typename ALLOC>
375 original::array<TYPE, ALLOC>::array(const std::initializer_list<TYPE>& lst)
376 : array(lst.size()) {
377 u_integer i = 0;
378 for (const auto& e : lst) {
379 this->setElem(i, e);
380 i += 1;
381 }
382 }
383
384 template<typename TYPE, typename ALLOC>
386 : array(other.size()) {
387 this->operator=(other);
388 }
389
390 template<typename TYPE, typename ALLOC>
392 {
393 if (this == &other)
394 return *this;
395
396 this->arrDestroy();
397
398 this->arrInit(other.size());
399 for (u_integer i = 0; i < this->size_; i++) {
400 this->setElem(i, other.getElem(i));
401 }
402 if constexpr (ALLOC::propagate_on_container_copy_assignment::value){
403 this->allocator = other.allocator;
404 }
405 return *this;
406 }
407
408 template<typename TYPE, typename ALLOC>
410 this->operator=(std::move(other));
411 }
412
413 template<typename TYPE, typename ALLOC>
415 if (this == &other)
416 return *this;
417
418 this->arrDestroy();
419
420 this->body = other.body;
421 this->size_ = other.size_;
422 if constexpr (ALLOC::propagate_on_container_move_assignment::value){
423 this->allocator = std::move(other.allocator);
424 }
425 other.arrInit(0);
426 return *this;
427 }
428
429 template<typename TYPE, typename ALLOC>
431 this->arrDestroy();
432 }
433
434 template<typename TYPE, typename ALLOC>
436 {
437 return this->size_;
438 }
439
440 template<typename TYPE, typename ALLOC>
442 return this->body[0];
443 }
444
445 template<typename TYPE, typename ALLOC>
447 {
448 if (this->indexOutOfBound(index)){
449 throw outOfBoundError("Index " + std::to_string(this->parseNegIndex(index)) +
450 " out of bound max index " + std::to_string(this->size() - 1) + ".");
451 }
452 return this->getElem(this->parseNegIndex(index));
453 }
454
455 template<typename TYPE, typename ALLOC>
457 {
458 if (this->indexOutOfBound(index)){
459 throw outOfBoundError("Index " + std::to_string(this->parseNegIndex(index)) +
460 " out of bound max index " + std::to_string(this->size() - 1) + ".");
461 }
462 return this->body[this->parseNegIndex(index)];
463 }
464
465 template<typename TYPE, typename ALLOC>
466 auto original::array<TYPE, ALLOC>::set(integer index, const TYPE &e) -> void
467 {
468 if (this->indexOutOfBound(index)){
469 throw outOfBoundError("Index " + std::to_string(this->parseNegIndex(index)) +
470 " out of bound max index " + std::to_string(this->size() - 1) + ".");
471 }
472 this->setElem(this->parseNegIndex(index), e);
473 }
474
475 template<typename TYPE, typename ALLOC>
477 {
478 if constexpr (Comparable<TYPE>)
479 {
480 for (u_integer i = 0; i < this->size(); i += 1)
481 {
482 if (this->get(i) == e)
483 {
484 return i;
485 }
486 }
487 return this->size();
488 } else {
489 throw unSupportedMethodError("Comparison unsupported type");
490 }
491 }
492
493 template<typename TYPE, typename ALLOC>
495 return new Iterator(&this->body[0], this, 0);
496 }
497
498 template<typename TYPE, typename ALLOC>
500 return new Iterator(&this->body[this->size() - 1], this, this->size() - 1);
501 }
502
503 template<typename TYPE, typename ALLOC>
505 {
506 return "array";
507 }
508
509#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:154
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:364
Iterator & operator=(const Iterator &other)
Copy assignment operator for the iterator.
Definition array.h:337
bool atNext(const iterator< TYPE > *other) const override
Checks if this iterator is positioned just after the given iterator.
Definition array.h:358
Iterator * clone() const override
Clones the iterator.
Definition array.h:347
bool atPrev(const iterator< TYPE > *other) const override
Checks if this iterator is positioned just before the given iterator.
Definition array.h:352
A fixed-size array container with random access.
Definition array.h:41
array & operator=(array &&other) noexcept
Move assignment operator.
Definition array.h:414
std::string className() const override
Returns the class name.
Definition array.h:504
void set(integer index, const TYPE &e) override
Sets the value of an element at the specified index.
Definition array.h:466
Iterator * ends() const override
Returns an iterator to the last element of the array.
Definition array.h:499
TYPE get(integer index) const override
Retrieves an element at a specified index.
Definition array.h:446
array(array &&other) noexcept
Move constructor.
Definition array.h:409
array(const std::initializer_list< TYPE > &lst)
Constructs an array from an initializer list.
Definition array.h:375
array(u_integer size=0, ALLOC alloc=ALLOC{})
Constructs an empty array.
Definition array.h:369
TYPE & data() const
Returns a reference to the first element of the array.
Definition array.h:441
~array() override
Destroys the array and releases its memory.
Definition array.h:430
array(const array &other)
Copy constructor.
Definition array.h:385
array & operator=(const array &other)
Copy assignment operator.
Definition array.h:391
u_integer indexOf(const TYPE &e) const override
Finds the index of the specified element in the array.
Definition array.h:476
TYPE & operator[](integer index) override
Access an element at a specified index for modification.
Definition array.h:456
u_integer size() const override
Returns the size of the array.
Definition array.h:435
Iterator * begins() const override
Returns an iterator to the first element of the array.
Definition array.h:494
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, and printing.
Definition iterationStream.h:32
Base iterator interface that supports common operations for iteration.
Definition iterator.h:37
Exception for container index out-of-range errors.
Definition error.h:129
Abstract base class for random-access iterators.
Definition randomAccessIterator.h:39
randomAccessIterator & operator=(const randomAccessIterator &other)
Copy assignment operator.
Definition randomAccessIterator.h:197
TYPE * _ptr
Pointer to the current element.
Definition randomAccessIterator.h:41
Abstract base class for sequential containers with index-based access.
Definition serial.h:34
Exception for unimplemented method calls.
Definition error.h:192
Definition types.h:157
Platform-independent type definitions and compiler/platform detection.
Custom exception classes and callback validation utilities.
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
Provides functionality for an iteration stream.
Main namespace for the project Original.
Definition algorithms.h:21
Base class for random-access iterators.