EHS
Vector.h
Go to the documentation of this file.
1#pragma once
2
3#include "BaseObj.h"
4#include "Types.h"
5#include "Util.h"
6
7#include <initializer_list>
8#include <utility>
9
10namespace ehs
11{
16 template<typename T, typename N = UInt_64>
17 class Vector
18 {
19 protected:
23 T* data;
24
25 public:
28 {
29 delete[] data;
30 }
31
34 : rawSize(0), size(0), stride(5), data(nullptr)
35 {
36 }
37
41 Vector(const N size, const N stride)
43 {
44 }
45
49 Vector(std::initializer_list<T> list, const N stride = 5)
50 : rawSize(0), size(list.size()), stride(stride), data(nullptr)
51 {
52 if (stride)
53 {
54 rawSize = list.size() / stride * stride;
55 if (list.size() % stride)
56 rawSize += stride;
57 }
58 else
59 {
60 rawSize = list.size();
61 }
62
63 data = new T[rawSize];
64
65 N i = 0;
66 for (auto v = list.begin(); v != list.end(); ++v)
67 data[i++] = std::move(*v);
68 }
69
74 Vector(const T* data, const N size, const N stride)
75 : rawSize(0), size(size), stride(stride), data(nullptr)
76 {
77 if (stride)
78 {
80 if (size % stride)
81 rawSize += stride;
82 }
83 else
84 {
85 rawSize = size;
86 }
87
88 data = new T[rawSize];
89
90 for (N i = 0; i < size; ++i)
91 this->data[i] = data[i];
92 }
93
96 Vector(const Vector& vec)
97 : rawSize(vec.rawSize), size(vec.size), stride(vec.stride), data(new T[rawSize])
98 {
99 for (N i = 0; i < size; ++i)
100 data[i] = vec.data[i];
101 }
102
103 Vector(Vector&& vec) noexcept
104 : rawSize(vec.rawSize), size(vec.size), stride(vec.stride), data(vec.data)
105 {
106 vec.rawSize = 0;
107 vec.size = 0;
108 vec.stride = 0;
109 vec.data = nullptr;
110 }
111
116 {
117 if (this == &vec)
118 return *this;
119
120 rawSize = vec.rawSize;
121 size = vec.size;
122 stride = vec.stride;
123
124 delete[] data;
125 data = new T[rawSize];
126
127 for (N i = 0; i < size; ++i)
128 data[i] = vec.data[i];
129
130 return *this;
131 }
132
133 Vector& operator=(Vector&& vec) noexcept
134 {
135 if (this == &vec)
136 return *this;
137
138 rawSize = vec.rawSize;
139 size = vec.size;
140 stride = vec.stride;
141 delete[] data;
142 data = vec.data;
143
144 vec.rawSize = 0;
145 vec.size = 0;
146 vec.stride = 0;
147 vec.data = nullptr;
148
149 return *this;
150 }
151
152 bool operator==(const Vector& in) const
153 {
154 if (size != in.size)
155 return false;
156
157 return Util::Compare(data, in.data, size);
158 }
159
160 bool operator!=(const Vector& in) const
161 {
162 if (size != in.size)
163 return true;
164
165 return !Util::Compare(data, in.data, size);
166 }
167
170 Vector& operator+=(std::initializer_list<T> value)
171 {
172 if (size + value.size() >= rawSize)
173 {
174 if (stride)
175 {
176 rawSize = (size + value.size()) / stride * stride;
177 if ((size + value.size()) % stride)
178 rawSize += stride;
179 }
180 else
181 {
182 rawSize = size + value.size();
183 }
184
185 T* result = new T[rawSize];
186
187 for (N i = 0; i < size; ++i)
188 result[i] = std::move(std::move(data[i]));
189
190 delete[] data;
191 data = result;
192 }
193
194 for (auto v = value.begin(); v != value.end(); ++v)
195 data[size++] = std::move(*v);
196
197 return *this;
198 }
199
202 Vector& operator+=(const T value)
203 {
204 if (size + 1 >= rawSize)
205 {
206 if (stride)
207 rawSize = size + stride;
208 else
209 rawSize = size + 1;
210
211 T* result = new T[rawSize];
212
213 for (N i = 0; i < size; ++i)
214 result[i] = std::move(data[i]);
215
216 delete[] data;
217 data = result;
218 }
219
220 data[size++] = std::move(value);
221
222 return *this;
223 }
224
226 operator T* () const
227 {
228 return data;
229 }
230
233 N RawSize() const
234 {
235 return rawSize;
236 }
237
240 N Size() const
241 {
242 return size;
243 }
244
247 N Stride() const
248 {
249 return stride;
250 }
251
254 N End() const
255 {
256 return size ? size - 1 : size;
257 }
258
263 void Copy(const N dstOffset, Vector<T, N> src, const N srcOffset = 0)
264 {
265 for (N i = 0; i < src.Size() - srcOffset; ++i)
266 data[i + dstOffset] = std::move(src[i + srcOffset]);
267 }
268
273 void Copy(const N dstOffset, const T* src, const N inSize)
274 {
275 if (dstOffset + inSize > size)
276 return;
277
278 for (N i = 0; i < inSize; ++i)
279 data[i + dstOffset] = src[i];
280 }
281
285 void Swap(N a, N b)
286 {
287 T tmp = std::move(data[a]);
288
289 data[a] = std::move(data[b]);
290 data[b] = std::move(tmp);
291 }
292
296 void Insert(const N index, const T value)
297 {
298 N newSize = 0;
299 if (index > size - 1)
300 newSize = size + ((index + 1) - size);
301 else
302 newSize = size + 1;
303
304 if (newSize >= rawSize)
305 {
306 if (stride)
307 rawSize += newSize + stride;
308 else
309 rawSize = newSize;
310
311 T* result = new T[rawSize];
312
313 for (N i = 0; i < index; ++i)
314 result[i] = std::move(data[i]);
315
316 result[index] = std::move(value);
317
318 for (N i = index; i < size; ++i)
319 result[i + 1] = std::move(data[i]);
320
321 delete[] data;
322 data = result;
323 }
324 else
325 {
326 for (N i = index; i < size; ++i)
327 data[i + 1] = std::move(data[i]);
328
329 data[index] = std::move(value);
330 }
331
332 size = newSize;
333 }
334
338 T Remove(const N index)
339 {
340 T popped = {};
341
342 if (!size || index >= size)
343 return popped;
344
345 popped = std::move(data[index]);
346
347 if (!stride)
348 {
349 rawSize = size - 1;
350 T* result = new T[rawSize];
351
352 for (N i = 0; i < index; ++i)
353 result[i] = std::move(data[i]);
354
355 for (N i = index + 1; i < size; ++i)
356 result[i - 1] = std::move(data[i]);
357
358 delete[] data;
359 data = result;
360 }
361 else if (rawSize - stride && size - 1 <= rawSize - stride)
362 {
363 rawSize -= stride;
364 T* result = new T[rawSize];
365
366 for (N i = 0; i < index; ++i)
367 result[i] = std::move(data[i]);
368
369 for (N i = index + 1; i < size; ++i)
370 result[i - 1] = std::move(data[i]);
371
372 delete[] data;
373 data = result;
374 }
375 else
376 {
377 for (N i = index + 1; i < size; ++i)
378 data[i - 1] = std::move(data[i]);
379 }
380
381 --size;
382
383 return popped;
384 }
385
389 void Push(const T* const value, const N size)
390 {
391 if (this->size + size >= rawSize)
392 {
393 if (stride)
394 {
395 rawSize = (this->size + size) / stride * stride;
396 if ((this->size + size) % stride)
397 rawSize += stride;
398 }
399 else
400 {
401 rawSize = this->size + size;
402 }
403
404 T* result = new T[rawSize];
405
406 for (N i = 0; i < this->size; ++i)
407 result[i] = std::move(data[i]);
408
409 delete[] data;
410 data = result;
411 }
412
413 for (N i = 0; i < size; ++i)
414 data[this->size + i] = value[i];
415
416 this->size += size;
417 }
418
421 void Push(Vector<T> value)
422 {
423 if (size + value.size >= rawSize)
424 {
425 if (stride)
426 {
427 rawSize = (size + value.size) / stride * stride;
428 if ((size + value.size) % stride)
429 rawSize += stride;
430 }
431 else
432 {
433 rawSize = size + value.size;
434 }
435
436 T* result = new T[rawSize];
437
438 for (N i = 0; i < size; ++i)
439 result[i] = std::move(data[i]);
440
441 delete[] data;
442 data = result;
443 }
444
445 for (N i = 0; i < value.size; ++i)
446 data[size + i] = std::move(value.data[i]);
447
448 size += value.size;
449 }
450
453 void Push(std::initializer_list<T> value)
454 {
455 if (size + value.size() >= rawSize)
456 {
457 if (stride)
458 {
459 rawSize = (size + value.size()) / stride * stride;
460 if ((size + value.size()) % stride)
461 rawSize += stride;
462 }
463 else
464 {
465 rawSize = size + value.size();
466 }
467
468 T* result = new T[rawSize];
469
470 for (N i = 0; i < size; ++i)
471 result[i] = std::move(data[i]);
472
473 delete[] data;
474 data = result;
475 }
476
477 for (auto v = value.begin(); v != value.end(); ++v)
478 data[size++] = std::move(*v);
479 }
480
483 void Push(T value)
484 {
485 if (size + 1 >= rawSize)
486 {
487 if (stride)
488 rawSize += stride;
489 else
490 rawSize = size + 1;
491
492 T* result = new T[rawSize];
493
494 for (N i = 0; i < size; ++i)
495 result[i] = std::move(data[i]);
496
497 delete[] data;
498 data = result;
499 }
500
501 data[size++] = std::move(value);
502 }
503
506 T Pop()
507 {
508 T popped = {};
509
510 if (!size)
511 return popped;
512
513 popped = std::move(data[--size]);
514
515 if (!stride)
516 {
517 rawSize = size;
518 T* result = new T[rawSize];
519
520 for (N i = 0; i < size; ++i)
521 result[i] = std::move(data[i]);
522
523 delete[] data;
524 data = result;
525 }
526 else if (rawSize - stride && size < rawSize - stride)
527 {
528 rawSize -= stride;
529 T* result = new T[rawSize];
530
531 for (N i = 0; i < size; ++i)
532 result[i] = std::move(data[i]);
533
534 delete[] data;
535 data = result;
536 }
537
538 return popped;
539 }
540
544 T Pop(const N index)
545 {
546 if (!size)
547 return {};
548
549 N lastIndex = size - 1;
550
551 if (index < lastIndex)
552 Swap(index, lastIndex);
553
554 return Pop();
555 }
556
559 void Resize(const N newSize)
560 {
561 if (newSize == size)
562 return;
563
564 if (stride)
565 {
566 rawSize = newSize / stride * stride;
567 if (newSize % stride)
568 rawSize += stride;
569 }
570 else
571 {
572 rawSize = newSize;
573 }
574
575 T* result = new T[rawSize];
576
577 for (N i = 0; i < size && i < newSize; ++i)
578 result[i] = std::move(data[i]);
579
580 delete[] data;
581 data = result;
582 size = newSize;
583 }
584
587 {
588 if (!stride)
589 return;
590
591 stride = 0;
592
593 if (size)
594 {
595 rawSize = size;
596 T* result = new T[rawSize];
597
598 for (N i = 0; i < size; ++i)
599 result[i] = std::move(data[i]);
600
601 delete[] data;
602 data = result;
603 }
604 else
605 {
606 rawSize = 0;
607 delete[] data;
608 data = nullptr;
609 }
610 }
611
613 void Clear()
614 {
615 if (!size)
616 return;
617
618 rawSize = stride;
619 size = 0;
620
621 delete[] data;
622
623 if (rawSize)
624 data = new T[rawSize];
625 else
626 data = nullptr;
627 }
628 };
629}
static bool Compare(const void *a, const void *b, UInt_64 size)
Definition: Util.cpp:9
Definition: Vector.h:18
~Vector()
Frees any data created on the heap.
Definition: Vector.h:27
Vector(const T *data, const N size, const N stride)
Definition: Vector.h:74
N End() const
Definition: Vector.h:254
Vector()
Default members initialization.
Definition: Vector.h:33
Vector(const Vector &vec)
Definition: Vector.h:96
T Pop(const N index)
Definition: Vector.h:544
T * data
Definition: Vector.h:23
void Insert(const N index, const T value)
Definition: Vector.h:296
Vector & operator=(const Vector &vec)
Definition: Vector.h:115
Vector(Vector &&vec) noexcept
Definition: Vector.h:103
void Copy(const N dstOffset, Vector< T, N > src, const N srcOffset=0)
Definition: Vector.h:263
Vector(const N size, const N stride)
Definition: Vector.h:41
Vector & operator=(Vector &&vec) noexcept
Definition: Vector.h:133
bool operator==(const Vector &in) const
Definition: Vector.h:152
T Pop()
Definition: Vector.h:506
N RawSize() const
Definition: Vector.h:233
void Swap(N a, N b)
Definition: Vector.h:285
void Clear()
Releases the resources of the vector.
Definition: Vector.h:613
Vector & operator+=(std::initializer_list< T > value)
Definition: Vector.h:170
bool operator!=(const Vector &in) const
Definition: Vector.h:160
void Push(std::initializer_list< T > value)
Definition: Vector.h:453
Vector & operator+=(const T value)
Definition: Vector.h:202
N stride
Definition: Vector.h:22
void Push(Vector< T > value)
Definition: Vector.h:421
N size
Definition: Vector.h:21
void Push(T value)
Definition: Vector.h:483
N rawSize
Definition: Vector.h:20
void Copy(const N dstOffset, const T *src, const N inSize)
Definition: Vector.h:273
void Push(const T *const value, const N size)
Definition: Vector.h:389
N Size() const
Definition: Vector.h:240
Vector(std::initializer_list< T > list, const N stride=5)
Definition: Vector.h:49
void Resize(const N newSize)
Definition: Vector.h:559
T Remove(const N index)
Definition: Vector.h:338
N Stride() const
Definition: Vector.h:247
void ExactSize()
Removes any extra allocated memory.
Definition: Vector.h:586
Definition: Anchor.h:6