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
|
#ifndef PKE_ARRAY_HPP
#define PKE_ARRAY_HPP
#include "pk.h"
#include <cstdint>
#include <cstring>
#include <type_traits>
typedef uint32_t PkeArray_Count_T;
struct PkeArray_Base {
PkeArray_Count_T next = 0;
PkeArray_Count_T reserved = 0;
struct pk_membucket *bkt;
};
template<typename D>
struct PkeArray : PkeArray_Base {
using PkeArray_Base::next;
using PkeArray_Base::reserved;
using PkeArray_Base::bkt;
D *data = nullptr;
};
template<typename D>
void PkeArray_HardReset(PkeArray_Base *arrIn) {
auto *arr = static_cast<PkeArray<D> *>(arrIn);
arr->next = 0;
arr->reserved = 0;
arr->data = CAFE_BABE(D);
}
inline void PkeArray_SoftReset(PkeArray_Base *arrIn) {
arrIn->next = 0;
}
template<typename D>
inline void PkeArray_Add(PkeArray_Base *arrIn, const D &val) {
auto *arr = static_cast<PkeArray<D> *>(arrIn);
if (arr->reserved == arr->next) {
long originalCount = arr->reserved;
long diff = 0;
if (arr->reserved == 0) {
diff = 16;
arr->reserved = 16;
} else {
arr->reserved *= 2.5;
diff = arr->reserved - originalCount;
}
auto *newData = pk_new<D>(arr->reserved, arr->bkt);
if constexpr (std::is_trivial<D>::value) {
memset(newData + (sizeof(D) * originalCount), 0x00, sizeof(D) * diff);
} else {
for (int64_t i = originalCount; i < arr->reserved; ++i) {
newData[i] = {};
}
}
if (arr->data != nullptr && arr->data != CAFE_BABE(D)) {
if constexpr (std::is_trivial<D>::value) {
memcpy(newData, arr->data, sizeof(D) * originalCount);
} else {
for (int64_t i = 0; i < diff; ++i) {
newData[i] = arr->data[i];
}
}
pk_delete<D>(arr->data, originalCount, arr->bkt);
}
arr->data = newData;
}
if constexpr (std::is_assignable<D&, const D&>::value) {
arr->data[arr->next++] = val;
} else {
memcpy(arr->data[arr->next++], val, sizeof(D));
}
}
template<typename D, typename D2, typename F = bool(const D&, const D2&)>
inline int64_t PkeArray_FindFirstIndex(PkeArray_Base *arrIn, F fn, const D2 &d2) {
auto *arr = static_cast<PkeArray<D> *>(arrIn);
for (int64_t i = 0; i < arr->next; ++i) {
if (fn(arr->data[i], d2)) {
return i;
}
}
return -1;
}
#endif /* PKE_ARRAY_HPP */
|