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 {
25
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 arrDestruct() noexcept;
59
60 public:
61
72 class Iterator final : public randomAccessIterator<TYPE, ALLOC> {
79 explicit Iterator(TYPE* ptr, const array* container, integer pos);
80
81 public:
82 friend array;
83
89 Iterator(const Iterator& other);
90
97 Iterator& operator=(const Iterator& other);
98
104 Iterator* clone() const override;
105
112 bool atPrev(const iterator<TYPE> *other) const override;
113
120 bool atNext(const iterator<TYPE> *other) const override;
121
126 [[nodiscard]] std::string className() const override;
127 };
128
136 explicit array(u_integer size = 0, ALLOC alloc = ALLOC{});
137
144 array(const std::initializer_list<TYPE>& lst);
145
152 array(const array& other);
153
161 array& operator=(const array& other);
162
170 array(array&& other) noexcept;
171
180 array& operator=(array&& other) noexcept;
181
186 [[nodiscard]] u_integer size() const override;
187
192 TYPE& data() const;
193
200 TYPE get(integer index) const override;
201
208 TYPE& operator[](integer index) override;
209
210 // const version
211 using serial<TYPE, ALLOC>::operator[];
212
219 void set(integer index, const TYPE& e) override;
220
226 u_integer indexOf(const TYPE& e) const override;
227
232 Iterator* begins() const override;
233
238 Iterator* ends() const override;
239
244 [[nodiscard]] std::string className() const override;
245
250 ~array() override;
251 };
252
253} // namespace original
254
255 template<typename TYPE, typename ALLOC>
256 void original::array<TYPE, ALLOC>::arrInit(const u_integer size) {
257 this->size_ = size;
258 this->body = this->allocate(this->size_);
259 for (u_integer i = 0; i < this->size(); ++i) {
260 this->construct(&this->body[i]);
261 }
262 }
263
264 template<typename TYPE, typename ALLOC>
265 void original::array<TYPE, ALLOC>::arrDestruct() noexcept
266 {
267 if (this->body){
268 for (u_integer i = 0; i < this->size_; ++i) {
269 this->destroy(&this->body[i]);
270 }
271 this->deallocate(this->body, this->size_);
272 this->body = nullptr;
273 }
274 }
275
276 template<typename TYPE, typename ALLOC>
277 original::array<TYPE, ALLOC>::Iterator::Iterator(TYPE* ptr, const array* container, integer pos)
278 : randomAccessIterator<TYPE, ALLOC>(ptr, container, pos) {}
279
280 template<typename TYPE, typename ALLOC>
281 original::array<TYPE, ALLOC>::Iterator::Iterator(const Iterator& other)
282 : randomAccessIterator<TYPE, ALLOC>(nullptr, nullptr, 0)
283 {
284 this->operator=(other);
285 }
286
287 template<typename TYPE, typename ALLOC>
288 auto original::array<TYPE, ALLOC>::Iterator::operator=(const Iterator& other) -> Iterator&
289 {
290 if (this == &other) {
291 return *this;
292 }
294 return *this;
295 }
296
297 template<typename TYPE, typename ALLOC>
299 return new Iterator(*this);
300 }
301
302 template<typename TYPE, typename ALLOC>
304 auto other_it = dynamic_cast<const Iterator*>(other);
305 return this->_ptr + 1 == other_it->_ptr;
306 }
307
308 template<typename TYPE, typename ALLOC>
310 auto other_it = dynamic_cast<const Iterator*>(other);
311 return other_it->_ptr + 1 == this->_ptr;
312 }
313
314 template<typename TYPE, typename ALLOC>
316 return "array::Iterator";
317 }
318
319 template<typename TYPE, typename ALLOC>
321 : baseArray<TYPE, ALLOC>(std::move(alloc)), size_(), body(nullptr) {
322 this->arrInit(size);
323 }
324
325 template<typename TYPE, typename ALLOC>
326 original::array<TYPE, ALLOC>::array(const std::initializer_list<TYPE>& lst)
327 : array(lst.size()) {
328 u_integer i = 0;
329 for (const auto& e : lst) {
330 this->body[i] = e;
331 i += 1;
332 }
333 }
334
335 template<typename TYPE, typename ALLOC>
337 : array(other.size()) {
338 this->operator=(other);
339 }
340
341 template<typename TYPE, typename ALLOC>
343 {
344 if (this == &other)
345 return *this;
346
347 this->arrDestruct();
348
349 this->arrInit(other.size());
350 for (u_integer i = 0; i < this->size_; i++) {
351 this->body[i] = other.body[i];
352 }
353 if constexpr (ALLOC::propagate_on_container_copy_assignment::value){
354 this->allocator = other.allocator;
355 }
356 return *this;
357 }
358
359 template<typename TYPE, typename ALLOC>
361 this->operator=(std::move(other));
362 }
363
364 template<typename TYPE, typename ALLOC>
366 if (this == &other)
367 return *this;
368
369 this->arrDestruct();
370
371 this->body = other.body;
372 this->size_ = other.size_;
373 if constexpr (ALLOC::propagate_on_container_move_assignment::value){
374 this->allocator = std::move(other.allocator);
375 }
376 other.arrInit(0);
377 return *this;
378 }
379
380 template<typename TYPE, typename ALLOC>
382 this->arrDestruct();
383 }
384
385 template<typename TYPE, typename ALLOC>
387 {
388 return this->size_;
389 }
390
391 template<typename TYPE, typename ALLOC>
393 return this->body[0];
394 }
395
396 template<typename TYPE, typename ALLOC>
398 {
399 if (this->indexOutOfBound(index)){
400 throw outOfBoundError();
401 }
402 return this->body[this->parseNegIndex(index)];
403 }
404
405 template<typename TYPE, typename ALLOC>
407 {
408 if (this->indexOutOfBound(index)){
409 throw outOfBoundError();
410 }
411 return this->body[this->parseNegIndex(index)];
412 }
413
414 template<typename TYPE, typename ALLOC>
415 auto original::array<TYPE, ALLOC>::set(integer index, const TYPE &e) -> void
416 {
417 if (this->indexOutOfBound(index)){
418 throw outOfBoundError();
419 }
420 this->body[this->parseNegIndex(index)] = e;
421 }
422
423 template<typename TYPE, typename ALLOC>
425 {
426 for (u_integer i = 0; i < this->size(); i += 1)
427 {
428 if (this->get(i) == e)
429 {
430 return i;
431 }
432 }
433 return this->size();
434 }
435
436 template<typename TYPE, typename ALLOC>
438 return new Iterator(&this->body[0], this, 0);
439 }
440
441 template<typename TYPE, typename ALLOC>
443 return new Iterator(&this->body[this->size() - 1], this, this->size() - 1);
444 }
445
446 template<typename TYPE, typename ALLOC>
448 {
449 return "array";
450 }
451
452#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:72
std::string className() const override
Returns the class name of this iterator.
Definition array.h:315
Iterator & operator=(const Iterator &other)
Copy assignment operator for the iterator.
Definition array.h:288
bool atNext(const iterator< TYPE > *other) const override
Checks if this iterator is positioned just after the given iterator.
Definition array.h:309
Iterator * clone() const override
Clones the iterator.
Definition array.h:298
bool atPrev(const iterator< TYPE > *other) const override
Checks if this iterator is positioned just before the given iterator.
Definition array.h:303
A fixed-size array container with random access.
Definition array.h:41
array & operator=(array &&other) noexcept
Move assignment operator.
Definition array.h:365
std::string className() const override
Returns the class name.
Definition array.h:447
void set(integer index, const TYPE &e) override
Sets the value of an element at the specified index.
Definition array.h:415
Iterator * ends() const override
Returns an iterator to the last element of the array.
Definition array.h:442
TYPE get(integer index) const override
Retrieves an element at a specified index.
Definition array.h:397
array(array &&other) noexcept
Move constructor.
Definition array.h:360
array(const std::initializer_list< TYPE > &lst)
Constructs an array from an initializer list.
Definition array.h:326
array(u_integer size=0, ALLOC alloc=ALLOC{})
Constructs an empty array.
Definition array.h:320
TYPE & data() const
Returns a reference to the first element of the array.
Definition array.h:392
~array() override
Destroys the array and releases its memory.
Definition array.h:381
array(const array &other)
Copy constructor.
Definition array.h:336
array & operator=(const array &other)
Copy assignment operator.
Definition array.h:342
u_integer indexOf(const TYPE &e) const override
Finds the index of the specified element in the array.
Definition array.h:424
TYPE & operator[](integer index) override
Access an element at a specified index for modification.
Definition array.h:406
u_integer size() const override
Returns the size of the array.
Definition array.h:386
Iterator * begins() const override
Returns an iterator to the first element of the array.
Definition array.h:437
Base class for fixed-size serial containers.
Definition baseArray.h:43
Abstract base class for containers.
Definition container.h:28
A stream class that allows iteration, comparison, and printing.
Definition iterationStream.h:33
Base iterator interface that supports common operations for iteration.
Definition iterator.h:37
Exception for container index out-of-range errors.
Definition error.h:84
randomAccessIterator(TYPE *ptr, const container< TYPE, ALLOC > *container, integer pos)
Protected constructor for derived classes.
Definition randomAccessIterator.h:181
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
bool indexOutOfBound(integer index) const
Checks if the provided index is out of bounds.
Definition serial.h:133
integer parseNegIndex(integer index) const
Converts negative indices into valid positive indices.
Definition serial.h:140
Platform-independent integer and floating-point type definitions.
Custom exception classes and callback validation utilities.
Provides functionality for an iteration stream.
Main namespace for the project Original.
Definition algorithms.h:21
std::uint32_t u_integer
32-bit unsigned integer type for sizes and indexes
Definition config.h:43
std::int64_t integer
64-bit signed integer type for arithmetic operations
Definition config.h:35
Base class for random-access iterators.