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
|
#ifndef ARRAY_CC
#define ARRAY_CC
#include "memory.cc"
#define ARRAY_INIT 4
#define ARRAY_GROWTH 2
template <typename T>
struct Array {
usize capacity, size;
u8* data;
const Allocator* allocator;
};
#define array_init(T, allocator) \
Array<T> { 0, 0, nullptr, allocator }
template<typename T>
static inline usize array_nbytes(usize size) {
return size * sizeof(T);
}
template<typename T>
static inline usize array_next_capacity(const Array<T>* array) {
assert(array != nullptr);
return array->capacity == 0 ? ARRAY_INIT : array->capacity * ARRAY_GROWTH;
}
template<typename T>
bool array_resize(Array<T>* array, usize new_capacity) {
assert(array != nullptr);
assert(array->size < new_capacity);
u8* new_data = allocate(array->allocator, array_nbytes<T>(new_capacity), alignof(T));
if(new_data == nullptr) return false;
memcpy(new_data, array->data, array_nbytes<T>(new_capacity));
deallocate(array->allocator, array->data);
array->data = new_data;
array->capacity = new_capacity;
return true;
}
template<typename T>
static inline bool array_grow_if_needed(Array<T>* array) {
assert(array != nullptr);
assert(array->size <= array->capacity);
if(array->size < array->capacity) return true;
usize new_capacity = array_next_capacity(array);
return array_resize(array, new_capacity);
}
template<typename T>
static inline T* array_at(const Array<T>* array, usize index) {
assert(array != NULL);
assert(index < array->capacity);
return array->data + index;
}
template<typename T>
bool array_push(Array<T>* array, T* item) {
assert(array != nullptr);
assert(item != nullptr);
bool ret = array_grow_if_needed(array);
if(!ret) return false;
T* loc = array_at(array, array->size);
memcpy(loc, item, sizeof(T));
array->size += 1;
return true;
}
template <typename T>
void array_deinit(Array<T>* array) {
assert(array != nullptr);
if (unlikely(array->data == nullptr)) return;
deallocate(array->allocator, array->data);
memset(array, 0, sizeof(*array));
}
#endif
|