DotNetDupe 4.0.6
C++17/20 Implementation of the .NET Base Class Library (BCL)
Loading...
Searching...
No Matches
List.h
Go to the documentation of this file.
1
5
6#pragma once
7
8#include "Common.h"
9#include "System/Object.h"
10#include "System/Array.h"
11#include <new>
12#include <utility>
13#include <initializer_list>
14
15namespace DotNetDupe {
16 namespace System {
17 namespace Collections {
18 namespace Generic {
19
28 template <typename T>
29 class List : public Object {
30 public:
32 List() { }
33
36 List(int iCapacity) { SetCapacity(iCapacity); }
37
40 List(const std::initializer_list<T>& vCollection) {
41 SetCapacity((int)vCollection.size());
42 for (const auto& item : vCollection) {
43 Add(item);
44 }
45 }
46
49 List(const List& lstOther) {
50 SetCapacity(lstOther.m_iCapacity);
51 for (int i = 0; i < lstOther.m_iCount; ++i) {
52 Add(lstOther.m_pData[i]);
53 }
54 }
55
58 List& operator=(const List& lstOther) {
59 if (this != &lstOther) {
60 Clear();
61 SetCapacity(lstOther.m_iCapacity);
62 for (int i = 0; i < lstOther.m_iCount; ++i) {
63 Add(lstOther.m_pData[i]);
64 }
65 }
66 return *this;
67 }
68
71 List(List&& lstOther) noexcept : m_pData(lstOther.m_pData), m_iCount(lstOther.m_iCount), m_iCapacity(lstOther.m_iCapacity) {
72 lstOther.m_pData = nullptr;
73 lstOther.m_iCount = 0;
74 lstOther.m_iCapacity = 0;
75 }
76
80 List& operator=(List&& lstOther) noexcept {
81 if (this != &lstOther) {
82 FreeBuffer();
83 m_pData = lstOther.m_pData;
84 m_iCount = lstOther.m_iCount;
85 m_iCapacity = lstOther.m_iCapacity;
86 lstOther.m_pData = nullptr;
87 lstOther.m_iCount = 0;
88 lstOther.m_iCapacity = 0;
89 }
90 return *this;
91 }
92
94 ~List() override {
95 FreeBuffer();
96 }
97
100 int GetCount() const { return m_iCount; }
101
104 int GetCapacity() const { return m_iCapacity; }
105
109 void SetCapacity(int iValue) {
110 if (iValue > m_iCapacity) {
111 T* pNewData = static_cast<T*>(AllocateCollectionBuffer(sizeof(T) * iValue));
112 for (int i = 0; i < m_iCount; ++i) {
113 ::new ((void*)&pNewData[i]) T(std::move(m_pData[i]));
114 }
115 FreeBuffer();
116 m_pData = pNewData;
117 m_iCapacity = iValue;
118 }
119 }
120
124 T& operator[](int iIndex) {
125 return m_pData[iIndex];
126 }
127
131 const T& operator[](int iIndex) const {
132 return m_pData[iIndex];
133 }
134
138 void Add(const T& item) {
139 if (m_iCount == m_iCapacity) {
140 SetCapacity(m_iCapacity == 0 ? 4 : m_iCapacity * 2);
141 }
142 ::new ((void*)&m_pData[m_iCount]) T(item);
143 m_iCount++;
144 }
145
148 void AddRange(const Array<T>& arrCollection) {
149 int iNewCount = m_iCount + arrCollection.GetLength();
150 if (iNewCount > m_iCapacity) {
151 SetCapacity(iNewCount);
152 }
153 for (int iIdx = 0; iIdx < arrCollection.GetLength(); iIdx++) {
154 ::new ((void*)&m_pData[m_iCount]) T(arrCollection[iIdx]);
155 m_iCount++;
156 }
157 }
158
160 void Clear() {
161 for (int i = 0; i < m_iCount; ++i) {
162 m_pData[i].~T();
163 }
164 m_iCount = 0;
165 }
166
170 bool Contains(const T& item) const {
171 return IndexOf(item) != -1;
172 }
173
177 int IndexOf(const T& item) const {
178 for (int i = 0; i < m_iCount; ++i) {
179 if (m_pData[i] == item) return i;
180 }
181 return -1;
182 }
183
188 int BinarySearch(const T& item) const {
189 int low = 0;
190 int high = m_iCount - 1;
191 while (low <= high) {
192 int mid = low + (high - low) / 2;
193 if (m_pData[mid] == item) return mid;
194 if (m_pData[mid] < item) {
195 low = mid + 1;
196 } else {
197 high = mid - 1;
198 }
199 }
200 return ~low;
201 }
202
206 void Insert(int iIndex, const T& item) {
207 if (m_iCount == m_iCapacity) {
208 SetCapacity(m_iCapacity == 0 ? 4 : m_iCapacity * 2);
209 }
210 if (iIndex < m_iCount) {
211 ::new ((void*)&m_pData[m_iCount]) T(std::move(m_pData[m_iCount - 1]));
212 for (int i = m_iCount - 1; i > iIndex; --i) {
213 m_pData[i] = std::move(m_pData[i - 1]);
214 }
215 m_pData[iIndex] = item;
216 } else {
217 ::new ((void*)&m_pData[m_iCount]) T(item);
218 }
219 m_iCount++;
220 }
221
225 bool Remove(const T& item) {
226 int idx = IndexOf(item);
227 if (idx != -1) {
228 RemoveAt(idx);
229 return true;
230 }
231 return false;
232 }
233
236 void RemoveAt(int iIndex) {
237 if (iIndex >= 0 && iIndex < m_iCount) {
238 for (int i = iIndex; i < m_iCount - 1; ++i) {
239 m_pData[i] = std::move(m_pData[i + 1]);
240 }
241 m_pData[m_iCount - 1].~T();
242 m_iCount--;
243 }
244 }
245
246 void SwapElements(T& a, T& b) {
247 T temp = std::move(a);
248 a = std::move(b);
249 b = std::move(temp);
250 }
251
253 void Sort() {
254 for (int i = 0; i < m_iCount - 1; ++i) {
255 for (int j = 0; j < m_iCount - i - 1; ++j) {
256 if (m_pData[j] > m_pData[j + 1]) {
257 SwapElements(m_pData[j], m_pData[j + 1]);
258 }
259 }
260 }
261 }
262
267 template <typename Predicate>
268 bool Exists(Predicate fnMatch) const {
269 for (int i = 0; i < m_iCount; ++i) {
270 if (fnMatch(m_pData[i])) return true;
271 }
272 return false;
273 }
274
279 template <typename Predicate>
280 T Find(Predicate fnMatch) const {
281 for (int i = 0; i < m_iCount; ++i) {
282 if (fnMatch(m_pData[i])) return m_pData[i];
283 }
284 return T();
285 }
286
291 template <typename Predicate>
292 List<T> FindAll(Predicate fnMatch) const {
293 List<T> lstResult;
294 for (int i = 0; i < m_iCount; ++i) {
295 if (fnMatch(m_pData[i])) lstResult.Add(m_pData[i]);
296 }
297 return lstResult;
298 }
299
304 template <typename Predicate>
305 bool TrueForAll(Predicate fnMatch) const {
306 for (int i = 0; i < m_iCount; ++i) {
307 if (!fnMatch(m_pData[i])) return false;
308 }
309 return true;
310 }
311
315 Array<T> arrResult(m_iCount);
316 for (int iIdx = 0; iIdx < m_iCount; iIdx++) {
317 arrResult[iIdx] = m_pData[iIdx];
318 }
319 return arrResult;
320 }
321
323 T* begin() { return m_pData; }
324
326 T* end() { return m_pData + m_iCount; }
327
329 const T* begin() const { return m_pData; }
330
332 const T* end() const { return m_pData + m_iCount; }
333
334 private:
335 T* m_pData = nullptr;
336 int m_iCount = 0;
337 int m_iCapacity = 0;
338
339 void FreeBuffer() {
340 if (m_pData) {
341 for (int i = 0; i < m_iCount; ++i) {
342 m_pData[i].~T();
343 }
344 FreeCollectionBuffer(m_pData);
345 m_pData = nullptr;
346 }
347 }
348 };
349 }
350 }
351 }
352}
Provides methods for creating, manipulating, searching, and sorting arrays.
Defines common cross-platform macros, export decorators, and fundamental types.
Base object class for DotNetDupe mirroring .NET System.Object.
Provides methods for creating, manipulating, searching, and sorting arrays, thereby serving as the ba...
Definition Array.h:29
int GetLength() const
Gets the total number of elements in all dimensions of the Array.
Definition Array.h:142
bool Remove(const T &item)
Removes the first occurrence of a specific object from the List.
Definition List.h:225
List & operator=(List &&lstOther) noexcept
Move assignment operator.
Definition List.h:80
const T & operator[](int iIndex) const
Gets a const reference to the element at the specified index.
Definition List.h:131
List(const List &lstOther)
Copy constructor.
Definition List.h:49
void Sort()
Sorts the elements in the entire List using the default comparer.
Definition List.h:253
T & operator[](int iIndex)
Gets a reference to the element at the specified index.
Definition List.h:124
List(int iCapacity)
Initializes a new instance of the List class with specified initial capacity.
Definition List.h:36
bool TrueForAll(Predicate fnMatch) const
Determines whether every element in the List matches the conditions defined by the specified predicat...
Definition List.h:305
T * end()
Returns a pointer to one past the last element for range-based for loops.
Definition List.h:326
void RemoveAt(int iIndex)
Removes the element at the specified index of the List.
Definition List.h:236
void Insert(int iIndex, const T &item)
Inserts an element into the List at the specified index.
Definition List.h:206
int BinarySearch(const T &item) const
Searches the entire sorted List for an element using the default comparer.
Definition List.h:188
bool Contains(const T &item) const
Determines whether an element is in the List.
Definition List.h:170
List(const std::initializer_list< T > &vCollection)
Initializes a new instance of the List class containing elements from an initializer list.
Definition List.h:40
List & operator=(const List &lstOther)
Copy assignment operator.
Definition List.h:58
int IndexOf(const T &item) const
Searches for the specified object and returns the zero-based index of the first occurrence within the...
Definition List.h:177
bool Exists(Predicate fnMatch) const
Determines whether the List contains elements that match the conditions defined by the specified pred...
Definition List.h:268
List()
Initializes a new instance of the List class that is empty.
Definition List.h:32
int GetCount() const
Gets the number of elements contained in the List.
Definition List.h:100
const T * begin() const
Returns a const pointer to the first element for range-based for loops.
Definition List.h:329
T Find(Predicate fnMatch) const
Searches for an element that matches the conditions defined by the specified predicate,...
Definition List.h:280
~List() override
Destructor releasing internal buffer resources.
Definition List.h:94
void Add(const T &item)
Adds an object to the end of the List.
Definition List.h:138
int GetCapacity() const
Gets the total number of elements the internal data structure can hold without resizing.
Definition List.h:104
void AddRange(const Array< T > &arrCollection)
Adds the elements of the specified array to the end of the List.
Definition List.h:148
T * begin()
Returns a pointer to the first element for range-based for loops.
Definition List.h:323
List(List &&lstOther) noexcept
Move constructor.
Definition List.h:71
void SetCapacity(int iValue)
Sets the capacity of the internal buffer to a specified value.
Definition List.h:109
Array< T > ToArray() const
Copies the elements of the List to a new Array.
Definition List.h:314
void Clear()
Removes all elements from the List.
Definition List.h:160
List< T > FindAll(Predicate fnMatch) const
Retrieves all the elements that match the conditions defined by the specified predicate.
Definition List.h:292
const T * end() const
Returns a const pointer to one past the last element for range-based for loops.
Definition List.h:332
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