1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
|
#ifndef PKE_DYNAMIC_ARRAY_HPP
#define PKE_DYNAMIC_ARRAY_HPP
#include "memory.hpp"
#include "macros.hpp"
#include <cstdint>
#include <cstring>
#include <cassert>
#define BAKE_DYN_ARRAY(T) template struct DynArray<T>;
struct DynArrayBase {
char *ptr = nullptr;
int64_t elementSize = 0;
int64_t elementCount = 0;
int64_t reservedCount = 0;
};
template <typename T>
struct DynArray: DynArrayBase {
DynArray();
explicit DynArray(int64_t reserveCount);
~DynArray();
T &operator[](std::size_t index);
T *GetPtr();
const int64_t Count();
bool Has(const T &val);
void Push(const T &val);
T Pop();
void Remove(std::size_t index);
void Reserve(int64_t count);
void Resize(int64_t count);
protected:
using DynArrayBase::ptr;
using DynArrayBase::elementSize;
using DynArrayBase::elementCount;
using DynArrayBase::reservedCount;
};
void DynArrayReserve(DynArrayBase *arr, int64_t count);
void DynArrayDestroy(DynArrayBase *arr);
template <typename T> inline DynArray<T>::DynArray(int64_t count) {
this->elementSize = sizeof(T);
if (count > 0) DynArrayReserve(this, count);
}
template <typename T> inline DynArray<T>::DynArray() {
this->elementSize = sizeof(T);
}
template <typename T> inline DynArray<T>::~DynArray() {
DynArrayDestroy(this);
}
template <typename T> inline T &DynArray<T>::operator[](std::size_t index) {
assert(index < this->elementCount && "Invalid DynArray<T>[] index - out of bounds");
assert(index < this->reservedCount && "Invalid DynArray<T>[] index - out of reserved bounds");
assert(index < 0xF000000000000000 && "Invalid DynArray<T>[] index - unlikely value");
return *reinterpret_cast<T *>((this->ptr + (sizeof(T) * index)));
}
template <typename T> inline T *DynArray<T>::GetPtr() {
return reinterpret_cast<T *>(reinterpret_cast<void *>(this->ptr));
}
template <typename T> inline const int64_t DynArray<T>::Count() {
return this->elementCount;
}
template <typename T> inline bool DynArray<T>::Has(const T &val) {
for (long i = 0; i < this->elementCount; ++i) {
if ((*this)[i] == val) return true;
}
return false;
}
template <typename T> inline void DynArray<T>::Push(const T &val) {
if (this->elementCount + 1 > this->reservedCount) {
auto safeReserveCount = this->reservedCount == 0 ? 1 : this->reservedCount;
DynArrayReserve(this, int64_t(safeReserveCount * 1.5));
}
std::memcpy(this->ptr + (sizeof(T) * this->elementCount), &val, sizeof(T));
this->elementCount += 1;
}
template <typename T> inline T DynArray<T>::Pop() {
assert(this->elementCount == 0 && "Invalid DynArray<T>::Pop() - Contains no elements");
this->elementCount -= 1;
return *reinterpret_cast<T *>((this->ptr + (sizeof(T) * this->elementCount)));
}
template <typename T> inline void DynArray<T>::Remove(std::size_t index) {
assert(this->elementCount == 0 && "Invalid DynArray<T>::Remove() - Contains no elements");
assert(index >= this->elementCount && "Invalid DynArray<T>::Remove() - Out of bounds");
uint64_t moveCount = (this->elementCount - index - 1);
auto *tmp = Pke_New(this->elementSize * moveCount);
memcpy(tmp, this->ptr + (this->elementSize * (index + 1)), this->elementSize * moveCount);
memcpy(this->ptr + (this->elementSize * index), tmp, this->elementSize * moveCount);
Pke_Delete(tmp, moveCount * this->elementSize);
this->elementCount -= 1;
}
template <typename T> inline void DynArray<T>::Reserve(int64_t count) {
if (count > 0) {
return DynArrayReserve(this, count);
}
this->elementCount = this->elementCount > count ? count : this->elementCount;
}
template <typename T> inline void DynArray<T>::Resize(int64_t count) {
if (count > 0) {
DynArrayReserve(this, count);
}
this->elementCount = count;
}
#endif /* PKE_DYNAMIC_ARRAY_HPP */
|