acme
Foundational cross-platform layer of the ca2 framework
Loading...
Searching...
No Matches
tiny_array.h
1#pragma once
2
3
4#define TINY_ARRAY_BUILTIN_SIZE 4
5
6
7template < typename TYPE >
8class tiny_array
9{
10public:
11
12
13 TYPE * m_p;
14 ::i32 m_iCount;
15 ::i32 m_iAllocation;
16 TYPE m_typea[TINY_ARRAY_BUILTIN_SIZE];
17
18
19
20 tiny_array() : m_iCount(0), m_iAllocation(0), m_p(nullptr) { }
21 ~tiny_array() { free(); }
22
23
24 void allocate(::i32 iCount);
25 void free();
26 void zero();
27 void set_at_grow(::i32 iIndex, const TYPE& t);
28 void erase_at(::i32 iIndex);
29 void push(const TYPE & t) { set_at_grow(count(), t);}
30 TYPE pop() { TYPE t = element_at(count() - 1); erase_at(count() -1); return t; }
31 ::i32 count() const {return m_iCount;}
32
33 TYPE& element_at_grow(::i32 iIndex);
34 TYPE& element_at(::i32 iIndex) { return m_p[iIndex];}
35
36
37};
38
39
40
41
42
43// Created by camilo on 2021-03-09 00:43 BRT <3ThomasBS_!!
44
45
46template < typename TYPE >
47void tiny_array < TYPE > ::allocate(::i32 iCount)
48{
49
50 if (iCount < 0)
51 {
52
53 throw_exception(error_bad_argument);
54
55 return;
56
57 }
58
59 if (iCount > TINY_ARRAY_BUILTIN_SIZE || m_iAllocation > 0)
60 {
61
62 if (m_iAllocation <= 0)
63 {
64
65 memsize sizeAllocated = 0;
66
67 auto p = (TYPE *) ::acme::get()->m_pheapmanagement->memory(::heap::e_memory_main)->allocate(sizeof(TYPE) * iCount, &sizeAllocated);
68
69 auto iAllocation = (::i32) (sizeAllocated / sizeof(TYPE));
70
71 ::zero(p, sizeof(TYPE) * iAllocation);
72
73 m_iAllocation = iAllocation;
74
75 m_p = p;
76
77 }
78
79 else if (iCount > m_iAllocation)
80 {
81
82 auto p = (TYPE *) ::acme::get()->m_pheapmanagement->memory(::heap::e_memory_main)->reallocate(m_p, sizeof(TYPE) * iCount);
83
84 ::zero(p + m_iCount, sizeof(TYPE) * (iCount - m_iAllocation));
85
86 m_iAllocation = iCount;
87
88 m_p = p;
89
90 }
91
92 }
93 else
94 {
95
96 m_p = m_typea;
97
98 }
99
100 m_iCount = iCount;
101
102}
103
104
105template < typename TYPE >
106void tiny_array < TYPE > ::free()
107{
108
109 if (m_iAllocation > 0)
110 {
111
112 ::acme::get()->m_pheapmanagement->memory(::heap::e_memory_main)->free(m_p);
113
114 }
115
116 m_iCount = 0;
117
118 m_iAllocation = 0;
119
120 m_p = nullptr;
121
122}
123
124
125template < typename TYPE >
126void tiny_array < TYPE > ::zero()
127{
128
129 ::zero(m_p, sizeof(TYPE) * m_iCount);
130
131}
132
133
134template < typename TYPE >
135void tiny_array < TYPE > ::set_at_grow(::i32 iIndex, const TYPE& t)
136{
137
138 element_at_grow(iIndex) = t;
139
140}
141
142
143template < typename TYPE >
144void tiny_array < TYPE > ::erase_at(::i32 iIndex)
145{
146
147 if(iIndex < 0 || iIndex >= m_iCount)
148 {
149
150 throw_exception(error_index_out_of_bounds);
151
152 }
153
154 auto iNext = iIndex + 1;
155
156 auto countMove = m_iCount - iNext;
157
158 if(countMove > 0)
159 {
160
161 ::memory_transfer(m_p + iIndex, m_p + iNext, countMove * sizeof(TYPE));
162
163 }
164
165 m_iCount--;
166
167}
168
169
170template < typename TYPE >
171TYPE & tiny_array < TYPE > ::element_at_grow(::i32 iIndex)
172{
173
174 if (iIndex < 0)
175 {
176
177 throw_exception(error_bad_argument);
178
179 }
180
181 if (iIndex >= m_iCount)
182 {
183
184 allocate(iIndex + 1);
185
186 }
187
188 return m_p[iIndex];
189
190}
191
192
193