-
Notifications
You must be signed in to change notification settings - Fork 0
/
dynamic_array.h
109 lines (91 loc) · 2.21 KB
/
dynamic_array.h
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
#pragma once
struct Allocator;
template<typename T>
struct DynamicArray
{
Allocator* allocator;
T* data;
unsigned num;
unsigned capacity;
void grow()
{
T* old_data = data;
unsigned new_capacity = max(capacity * 2, num + 5);
data = (T*)allocator->alloc(new_capacity * sizeof(T));
memcpy(data, old_data, num * sizeof(T));
allocator->dealloc(old_data);
capacity = new_capacity;
}
void insert(const T&v, unsigned i)
{
while (data == nullptr || num == capacity || i + 1 > capacity)
grow();
*(data + i) = v;
}
void add(const T& v)
{
if (data == nullptr || num == capacity)
grow();
*(data + num) = v;
++num;
}
T* push()
{
if (data == nullptr || num == capacity)
grow();
T* p = data + num;
++num;
return p;
}
void remove(unsigned i)
{
if (num == 1 || (num > 1 && i == num - 1))
{
--num;
return;
}
memcpy(data + i, data + num - 1, sizeof(T));
--num;
}
DynamicArray<T> clone(Allocator* new_allocator = nullptr) const
{
Allocator* allocator_to_use = new_allocator == nullptr ? allocator : new_allocator;
DynamicArray<T> c = {};
c.allocator = allocator_to_use;
c.data = (T*)allocator_to_use->alloc(num * sizeof(T));
c.capacity = num;
c.num = num;
memcpy(c.data, data, num * sizeof(T));
return c;
}
T* clone_raw(Allocator* alloc = nullptr) const
{
T* p = (T*)(alloc == nullptr ? allocator : alloc)->alloc(num * sizeof(T));
memcpy(p, data, num * sizeof(T));
return p;
}
T& last()
{
return data[num - 1];
}
T& operator[](unsigned i)
{
return data[i];
}
const T& operator[](unsigned i) const
{
return data[i];
}
};
template<typename T>
inline DynamicArray<T> dynamic_array_create(Allocator* allocator)
{
DynamicArray<T> da = {};
da.allocator = allocator;
return da;
}
template<typename T>
inline void dynamic_array_destroy(DynamicArray<T>* da)
{
da->allocator->dealloc(da->data);
}