DotNetDupe 4.0.6
C++17/20 Implementation of the .NET Base Class Library (BCL)
Loading...
Searching...
No Matches
Array.h
Go to the documentation of this file.
1
5
6#pragma once
7
8#include "Common.h"
9#include "System/Object.h"
12#include "System/Predicate.h"
13#include "System/Action.h"
14#include "System/String.h"
15#include <new>
16#include <initializer_list>
17#include <utility>
18#include <cstddef>
19
20namespace DotNetDupe {
21 namespace System {
22
28 template <class T>
29 class Array : public Object {
30 private:
31 T* m_pData = nullptr;
32 int m_iLength = 0;
33
34 void Allocate(int iLength) {
35 if (iLength > 0) {
36 m_pData = static_cast<T*>(AllocateCollectionBuffer(sizeof(T) * iLength));
37 m_iLength = iLength;
38 }
39 }
40
41 void Free() {
42 if (m_pData) {
43 for (int i = 0; i < m_iLength; ++i) {
44 m_pData[i].~T();
45 }
46 FreeCollectionBuffer(m_pData);
47 m_pData = nullptr;
48 m_iLength = 0;
49 }
50 }
51
52 void SwapElements(T& a, T& b) {
53 T temp = std::move(a);
54 a = std::move(b);
55 b = std::move(temp);
56 }
57
58 public:
60 Array() = default;
61
64 Array(int iLength) {
65 Allocate(iLength);
66 for (int i = 0; i < m_iLength; ++i) {
67 ::new ((void*)&m_pData[i]) T();
68 }
69 }
70
74 Array(const T* pData, int iLength) {
75 Allocate(iLength);
76 if (pData) {
77 for (int i = 0; i < m_iLength; ++i) {
78 ::new ((void*)&m_pData[i]) T(pData[i]);
79 }
80 } else {
81 for (int i = 0; i < m_iLength; ++i) {
82 ::new ((void*)&m_pData[i]) T();
83 }
84 }
85 }
86
89 Array(const std::initializer_list<T>& vItems) {
90 Allocate(static_cast<int>(vItems.size()));
91 int iIdx = 0;
92 for (const auto& item : vItems) {
93 ::new ((void*)&m_pData[iIdx++]) T(item);
94 }
95 }
96
98 Array(const Array& other) {
99 Allocate(other.m_iLength);
100 for (int i = 0; i < m_iLength; ++i) {
101 ::new ((void*)&m_pData[i]) T(other.m_pData[i]);
102 }
103 }
104
106 Array& operator=(const Array& other) {
107 if (this != &other) {
108 Free();
109 Allocate(other.m_iLength);
110 for (int i = 0; i < m_iLength; ++i) {
111 ::new ((void*)&m_pData[i]) T(other.m_pData[i]);
112 }
113 }
114 return *this;
115 }
116
118 Array(Array&& other) noexcept : m_pData(other.m_pData), m_iLength(other.m_iLength) {
119 other.m_pData = nullptr;
120 other.m_iLength = 0;
121 }
122
124 Array& operator=(Array&& other) noexcept {
125 if (this != &other) {
126 Free();
127 m_pData = other.m_pData;
128 m_iLength = other.m_iLength;
129 other.m_pData = nullptr;
130 other.m_iLength = 0;
131 }
132 return *this;
133 }
134
136 ~Array() override {
137 Free();
138 }
139
142 int GetLength() const { return m_iLength; }
143
146 T* GetData() { return m_pData; }
147
150 const T* GetData() const { return m_pData; }
151
153 T* begin() { return m_pData; }
154
156 T* end() { return m_pData + m_iLength; }
157
159 const T* begin() const { return m_pData; }
160
162 const T* end() const { return m_pData + m_iLength; }
163
166 bool IsNull() const { return m_iLength == 0; }
167
169 T& operator[](int iIndex) { return m_pData[iIndex]; }
170
172 const T& operator[](int iIndex) const { return m_pData[iIndex]; }
173
177 int IndexOf(const T& value) const {
178 for (int iIdx = 0; iIdx < m_iLength; ++iIdx) {
179 if (m_pData[iIdx] == value) return iIdx;
180 }
181 return -1;
182 }
183
187 int LastIndexOf(const T& value) const {
188 for (int iIdx = m_iLength - 1; iIdx >= 0; --iIdx) {
189 if (m_pData[iIdx] == value) return iIdx;
190 }
191 return -1;
192 }
193
195 void Sort() {
196 for (int i = 0; i < m_iLength - 1; ++i) {
197 for (int j = 0; j < m_iLength - i - 1; ++j) {
198 if (m_pData[j] > m_pData[j + 1]) {
199 SwapElements(m_pData[j], m_pData[j + 1]);
200 }
201 }
202 }
203 }
204
206 void Reverse() {
207 int left = 0;
208 int right = m_iLength - 1;
209 while (left < right) {
210 SwapElements(m_pData[left], m_pData[right]);
211 left++;
212 right--;
213 }
214 }
215
217 void Clear() {
218 for (int i = 0; i < m_iLength; ++i) {
219 m_pData[i] = T();
220 }
221 }
222
224 void CopyTo(Array<T>& arrTarget, int iIndex);
225
227 static void Copy(Array<T>& arrSource, Array<T>& arrDestination, int iLength);
228
230 bool Exists(const Predicate<T>& fnPredicate) const {
231 for (int i = 0; i < m_iLength; ++i) {
232 if (fnPredicate(m_pData[i])) return true;
233 }
234 return false;
235 }
236
238 T Find(const Predicate<T>& fnPredicate) const {
239 for (int i = 0; i < m_iLength; ++i) {
240 if (fnPredicate(m_pData[i])) return m_pData[i];
241 }
242 return T();
243 }
244
246 Array<T> FindAll(const Predicate<T>& fnPredicate) const {
247 int count = 0;
248 for (int i = 0; i < m_iLength; ++i) {
249 if (fnPredicate(m_pData[i])) count++;
250 }
251 Array<T> arrNew(count);
252 int idx = 0;
253 for (int i = 0; i < m_iLength; ++i) {
254 if (fnPredicate(m_pData[i])) {
255 arrNew[idx++] = m_pData[i];
256 }
257 }
258 return arrNew;
259 }
260
262 int FindIndex(const Predicate<T>& fnPredicate) const {
263 for (int i = 0; i < m_iLength; ++i) {
264 if (fnPredicate(m_pData[i])) return i;
265 }
266 return -1;
267 }
268
270 T FindLast(const Predicate<T>& fnPredicate) const {
271 for (int i = m_iLength - 1; i >= 0; --i) {
272 if (fnPredicate(m_pData[i])) return m_pData[i];
273 }
274 return T();
275 }
276
278 int FindLastIndex(const Predicate<T>& fnPredicate) const {
279 for (int i = m_iLength - 1; i >= 0; --i) {
280 if (fnPredicate(m_pData[i])) return i;
281 }
282 return -1;
283 }
284
286 void ForEach(const Action<T>& fnAction) {
287 for (int i = 0; i < m_iLength; ++i) {
288 fnAction(m_pData[i]);
289 }
290 }
291
293 bool TrueForAll(const Predicate<T>& fnPredicate) const {
294 for (int i = 0; i < m_iLength; ++i) {
295 if (!fnPredicate(m_pData[i])) return false;
296 }
297 return true;
298 }
299 };
300 }
301}
302
303#include "System/String.h"
304
305namespace DotNetDupe {
306 namespace System {
307 template <class T>
308 inline void Array<T>::CopyTo(Array<T>& arrTarget, int iIndex) {
310 if (iIndex < 0) throw ArgumentOutOfRangeException("iIndex");
311 if (iIndex + GetLength() > arrTarget.GetLength()) throw ArgumentException("Destination array was not long enough.");
312
314 for (int iIdx = 0; iIdx < GetLength(); ++iIdx) {
315 arrTarget[iIndex + iIdx] = m_pData[iIdx];
316 }
317 }
318
319 template <class T>
320 inline void Array<T>::Copy(Array<T>& arrSource, Array<T>& arrDestination, int iLength) {
322 if (iLength < 0) throw ArgumentOutOfRangeException("iLength");
323 if (arrSource.GetLength() < iLength) throw ArgumentException("Source array was not long enough.");
324 if (arrDestination.GetLength() < iLength) throw ArgumentException("Destination array was not long enough.");
325
327 for (int iIdx = 0; iIdx < iLength; ++iIdx) {
328 arrDestination[iIdx] = arrSource[iIdx];
329 }
330 }
331 }
332}
Encapsulates a delegate method that has parameters and returns void.
Defines the exception thrown when an invalid argument is provided to a method.
Defines the exception thrown when an argument value is outside the acceptable range of values.
Defines common cross-platform macros, export decorators, and fundamental types.
Base object class for DotNetDupe mirroring .NET System.Object.
Represents the method that defines a set of criteria and determines whether the specified object meet...
High-performance UTF-8 / UTF-16 string manipulation class mirroring .NET System.String.
Encapsulates a method that has parameters and does not return a value.
Definition Action.h:46
ArgumentException(const String &sMessage)
Initializes a new instance of the ArgumentException class with a specified error message.
ArgumentOutOfRangeException(const String &sMessage)
Initializes a new instance of the ArgumentOutOfRangeException class with a specified error message.
Array(int iLength)
Initializes an Array of the specified length with default-constructed elements.
Definition Array.h:64
Array()=default
Initializes an empty Array instance.
Array & operator=(const Array &other)
Copy assignment operator.
Definition Array.h:106
const T * end() const
Returns a const iterator to the element following the last element of the array.
Definition Array.h:162
bool Exists(const Predicate< T > &fnPredicate) const
Determines whether the specified array contains elements that match the conditions defined by the spe...
Definition Array.h:230
int FindIndex(const Predicate< T > &fnPredicate) const
Searches for an element that matches the conditions defined by the specified predicate,...
Definition Array.h:262
void Sort()
Sorts the elements in an entire Array using the default comparison.
Definition Array.h:195
bool TrueForAll(const Predicate< T > &fnPredicate) const
Determines whether every element in the array matches the conditions defined by the specified predica...
Definition Array.h:293
Array< T > FindAll(const Predicate< T > &fnPredicate) const
Retrieves all the elements that match the conditions defined by the specified predicate.
Definition Array.h:246
static void Copy(Array< T > &arrSource, Array< T > &arrDestination, int iLength)
Copies a range of elements from an Array starting at the first element and pastes them to another Arr...
Definition Array.h:320
int LastIndexOf(const T &value) const
Searches for the specified object and returns the index of the last occurrence.
Definition Array.h:187
void Reverse()
Reverses the sequence of the elements in the entire Array.
Definition Array.h:206
T Find(const Predicate< T > &fnPredicate) const
Searches for an element that matches the conditions defined by the specified predicate,...
Definition Array.h:238
void Clear()
Sets a range of elements in the Array to the default value of each element type.
Definition Array.h:217
const T * GetData() const
Gets a const pointer to the contiguous internal element buffer.
Definition Array.h:150
int GetLength() const
Gets the total number of elements in all dimensions of the Array.
Definition Array.h:142
const T * begin() const
Returns a const iterator to the first element of the array.
Definition Array.h:159
Array(const T *pData, int iLength)
Initializes an Array by copying elements from a raw pointer buffer.
Definition Array.h:74
~Array() override
Destroys array elements and releases allocated storage.
Definition Array.h:136
T & operator[](int iIndex)
Accesses the element at the specified index.
Definition Array.h:169
Array & operator=(Array &&other) noexcept
Move assignment operator.
Definition Array.h:124
int FindLastIndex(const Predicate< T > &fnPredicate) const
Searches for an element that matches the conditions defined by the specified predicate,...
Definition Array.h:278
Array(const std::initializer_list< T > &vItems)
Initializes an Array from an initializer list of elements.
Definition Array.h:89
T * end()
Returns an iterator to the element following the last element of the array.
Definition Array.h:156
T * GetData()
Gets a pointer to the contiguous internal element buffer.
Definition Array.h:146
Array(const Array &other)
Copy constructor. Performs a deep copy of elements.
Definition Array.h:98
int IndexOf(const T &value) const
Searches for the specified object and returns the index of its first occurrence.
Definition Array.h:177
void CopyTo(Array< T > &arrTarget, int iIndex)
Copies all elements of the current Array to the specified destination Array starting at the specified...
Definition Array.h:308
T * begin()
Returns an iterator to the first element of the array.
Definition Array.h:153
Array(Array &&other) noexcept
Move constructor.
Definition Array.h:118
void ForEach(const Action< T > &fnAction)
Performs the specified action on each element of the specified array.
Definition Array.h:286
const T & operator[](int iIndex) const
Accesses the const element at the specified index.
Definition Array.h:172
T FindLast(const Predicate< T > &fnPredicate) const
Searches for an element that matches the conditions defined by the specified predicate,...
Definition Array.h:270
bool IsNull() const
Checks whether the array has zero length.
Definition Array.h:166
Supports all classes in the DotNetDupe class hierarchy.
Definition Object.h:18
Represents the method that defines a set of criteria and determines whether the specified object meet...
Definition Predicate.h:19
void * AllocateCollectionBuffer(size_t size)
Internal memory allocator for generic collections.
Definition Object.cpp:39
void FreeCollectionBuffer(void *p)
Frees collection buffer allocated with AllocateCollectionBuffer.
Definition Object.cpp:44