Uniot Core
0.8.1
Loading...
Searching...
No Matches
Array.h
Go to the documentation of this file.
1/*
2 * This is a part of the Uniot project.
3 * Copyright (C) 2016-2024 Uniot <contact@uniot.io>
4 *
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18
26
36
37#pragma once
38
39#include <Arduino.h>
40
41#include <new>
42#include <type_traits>
43#include <utility>
44
45namespace uniot {
65template <typename T>
66class Array {
67 public:
71 Array() : mData(nullptr), mSize(0), mCapacity(0) {}
72
78 Array(size_t capacity) : mData(nullptr), mSize(0), mCapacity(0) {
80 }
81
88 Array(size_t size, const T* values) : mData(nullptr), mSize(0), mCapacity(0) {
89 if (values && size > 0) {
90 mData = new (std::nothrow) T[size];
91 if (!mData) {
92 return;
93 }
94
95 if constexpr (std::is_trivially_copyable<T>::value) {
96 memcpy(reinterpret_cast<void*>(mData), values, sizeof(T) * size);
97 } else {
98 for (size_t i = 0; i < size; ++i) {
99 mData[i] = values[i];
100 }
101 }
102
103 mSize = size;
104 mCapacity = size;
105 }
106 }
107
111 Array(const Array& other) = delete;
112
118 Array(Array&& other) noexcept
119 : mData(other.mData), mSize(other.mSize), mCapacity(other.mCapacity) {
120 other.mData = nullptr;
121 other.mSize = 0;
122 other.mCapacity = 0;
123 }
124
128 Array& operator=(const Array& other) = delete;
129
136 Array& operator=(Array&& other) noexcept {
137 if (this != &other) {
138 delete[] mData;
139
140 mData = other.mData;
141 mSize = other.mSize;
142 mCapacity = other.mCapacity;
143
144 other.mData = nullptr;
145 other.mSize = 0;
146 other.mCapacity = 0;
147 }
148 return *this;
149 }
150
155 delete[] mData;
156 mData = nullptr;
157 mSize = 0;
158 mCapacity = 0;
159 }
160
167 T& operator[](size_t index) {
168 return mData[index];
169 }
170
177 const T& operator[](size_t index) const {
178 return mData[index];
179 }
180
189 bool get(size_t index, T& outValue) const {
190 if (index < mSize) {
191 outValue = mData[index];
192 return true;
193 }
194 return false;
195 }
196
205 bool set(size_t index, const T& value) {
206 if (index < mSize) {
207 mData[index] = value;
208 return true;
209 }
210 return false;
211 }
212
218 size_t size() const { return mSize; }
219
225 size_t capacity() const { return mCapacity; }
226
233 bool isEmpty() const { return mSize == 0; }
234
240 const T* raw() const { return mData; }
241
249 bool reserve(size_t newCapacity) {
250 if (newCapacity <= mCapacity) {
251 return true;
252 }
253
254 T* new_data = new (std::nothrow) T[newCapacity];
255 if (!new_data) {
256 return false;
257 }
258
259 // Move existing elements
260 for (size_t i = 0; i < mSize; ++i) {
261 new_data[i] = std::move(mData[i]);
262 }
263
264 // Initialize new elements
265 if constexpr (std::is_trivially_default_constructible<T>::value) {
266 memset(reinterpret_cast<void*>(new_data + mSize), 0, sizeof(T) * (newCapacity - mSize));
267 } else {
268 for (size_t i = mSize; i < newCapacity; ++i) {
269 new_data[i] = T();
270 }
271 }
272
273 delete[] mData;
274 mData = new_data;
275 mCapacity = newCapacity;
276 return true;
277 }
278
286 bool push(const T& value) {
287 if (mSize >= mCapacity) {
288 size_t newCapacity = (mCapacity == 0) ? 1 : mCapacity * 2;
289 if (!reserve(newCapacity)) {
290 return false;
291 }
292 }
293 mData[mSize++] = value;
294 return true;
295 }
296
304 bool push(T&& value) {
305 if (mSize >= mCapacity) {
306 size_t newCapacity = (mCapacity == 0) ? 1 : mCapacity * 2;
307 if (!reserve(newCapacity)) {
308 return false;
309 }
310 }
311 mData[mSize++] = std::move(value);
312 return true;
313 }
314
318 void clear() {
319 // if constexpr (!std::is_trivially_destructible<T>::value) {
320 // for (size_t i = 0; i < mSize; ++i) {
321 // mData[i].~T();
322 // }
323 // }
324 mSize = 0;
325 }
326
333 bool shrink() {
334 if (mCapacity == mSize) {
335 return true;
336 }
337
338 T* new_data = nullptr;
339 if (mSize > 0) {
340 new_data = new (std::nothrow) T[mSize];
341 if (!new_data) {
342 return false;
343 }
344
345 for (size_t i = 0; i < mSize; ++i) {
346 new_data[i] = std::move(mData[i]);
347 }
348 }
349
350 // if constexpr (!std::is_trivially_destructible<T>::value) {
351 // for (size_t i = mSize; i < mCapacity; ++i) {
352 // mData[i].~T();
353 // }
354 // }
355
356 delete[] mData;
357 mData = new_data;
358 mCapacity = mSize;
359 return true;
360 }
361
362 private:
363 T* mData;
364 size_t mSize;
365 size_t mCapacity;
366};
367
368} // namespace uniot
bool isEmpty() const
Checks if the array is empty.
Definition Array.h:233
const T & operator[](size_t index) const
Provides read-only access to the array elements without bounds checking.
Definition Array.h:177
Array()
Constructs an empty Array.
Definition Array.h:71
Array(size_t capacity)
Constructs an Array with the given capacity, allocating memory.
Definition Array.h:78
bool shrink()
Reduces the capacity to fit the current size.
Definition Array.h:333
bool push(const T &value)
Adds a new element to the end of the array using copy semantics.
Definition Array.h:286
Array & operator=(const Array &other)=delete
Copy assignment operator (deleted to prevent accidental copying).
const T * raw() const
Retrieves a const pointer to the underlying data.
Definition Array.h:240
bool get(size_t index, T &outValue) const
Provides access to the array elements with bounds checking.
Definition Array.h:189
Array(Array &&other) noexcept
Move constructor.
Definition Array.h:118
size_t capacity() const
Returns the capacity of the array.
Definition Array.h:225
bool push(T &&value)
Adds a new element to the end of the array using move semantics.
Definition Array.h:304
Array(const Array &other)=delete
Copy constructor (deleted to prevent accidental copying).
size_t size() const
Returns the size of the array.
Definition Array.h:218
Array(size_t size, const T *values)
Constructs an Array from an existing C-style array.
Definition Array.h:88
Array & operator=(Array &&other) noexcept
Move assignment operator.
Definition Array.h:136
T & operator[](size_t index)
Provides access to the array elements without bounds checking.
Definition Array.h:167
void clear()
Clears the array, setting its size to zero.
Definition Array.h:318
~Array()
Destructor that deallocates the array memory.
Definition Array.h:154
bool reserve(size_t newCapacity)
Reserves memory for at least the specified number of elements.
Definition Array.h:249
bool set(size_t index, const T &value)
Sets the value of an element in the array.
Definition Array.h:205
Contains all classes and functions related to the Uniot Core.