summaryrefslogtreecommitdiff
path: root/src/array.hpp
blob: db8c564f5a27e8944b51d558047bfd589dc273f2 (plain)
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
#ifndef PKE_ARRAY_HPP
#define PKE_ARRAY_HPP

#include "macros.hpp"
#include "memory-type-defs.hpp"

#include <cstdint>

struct PkeArray_Base {
	uint32_t next = 0;
	uint32_t reserved = 0;
};

template<typename D>
struct PkeArray : PkeArray_Base {
	using PkeArray_Base::next;
	using PkeArray_Base::reserved;
	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);
}

template<typename D>
inline void PkeArray_Add(PkeArray_Base *arrIn, const D &val, MemBucket *bkt = nullptr) {
	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 = Pke_New<D>(arr->reserved, bkt);
		memset(newData + (sizeof(D) * originalCount), 0xFF, sizeof(D) * diff);
		if (arr->data != nullptr && arr->data != CAFE_BABE(D)) {
			memcpy(newData, arr->data, sizeof(D) * originalCount);
			Pke_Delete<D>(arr->data, originalCount, bkt);
		}
		arr->data = newData;
	}
	arr->data[arr->next++] = val;
}

template<typename D, typename F = bool(const D&)>
inline uint32_t PkeArray_FindFirstIndex(PkeArray_Base *arrIn, F fn) {
	auto *arr = static_cast<PkeArray<D> *>(arrIn);
	for (uint32_t i = 0; i < arr->next; ++i) {
		if (fn(arr->data[i])) {
			return i;
		}
	}
	return -1;
}

#endif /* PKE_ARRAY_HPP */