Nebula
Loading...
Searching...
No Matches
trivialarray.h
Go to the documentation of this file.
1#pragma once
2//------------------------------------------------------------------------------
12#include "core/types.h"
13#include "util/array.h"
14
15//------------------------------------------------------------------------------
16namespace Util
17{
18template<class TYPE> class TrivialArray : public Array<TYPE>
19{
20public:
22 typedef TYPE* Iterator;
23
27 TrivialArray(SizeT initialCapacity, SizeT initialGrow);
29 TrivialArray(SizeT initialSize, SizeT initialGrow, const TYPE& initialValue);
33 TrivialArray(const Array<TYPE>& rhs);
35 TrivialArray(std::initializer_list<TYPE> list);
38
40 void operator=(const TrivialArray<TYPE>& rhs);
42 void operator=(const Array<TYPE>& rhs);
43
45 void EraseIndex(IndexT index);
47 void EraseIndexSwap(IndexT index);
48
50 void Clear();
51
52private:
54 void Destroy(TYPE* elm);
56 void Copy(const TrivialArray<TYPE>& src);
58 void Copy(const Array<TYPE>& src);
60 void GrowTo(SizeT newCapacity);
62 void Move(IndexT fromIndex, IndexT toIndex);
63};
64
65//------------------------------------------------------------------------------
68template<class TYPE>
70{
71 static_assert(std::is_trivial<TYPE>::value, "Non trivial type used, try Util::Array instead");
72}
73
74//------------------------------------------------------------------------------
77template<class TYPE>
79 Array<TYPE>(_capacity, _grow)
80
81{
82 static_assert(std::is_trivial<TYPE>::value, "Non trivial type used, try Util::Array instead");
83}
84
85//------------------------------------------------------------------------------
88template<class TYPE>
89TrivialArray<TYPE>::TrivialArray(SizeT initialSize, SizeT _grow, const TYPE& initialValue) :
90 Array<TYPE>(initialSize, _grow, initialValue)
91{
92 static_assert(std::is_trivial<TYPE>::value, "Non trivial type used, try Util::Array instead");
93}
94
95//------------------------------------------------------------------------------
98template<class TYPE>
99TrivialArray<TYPE>::TrivialArray(std::initializer_list<TYPE> list) :
100 Array<TYPE>(list)
101{
102 static_assert(std::is_trivial<TYPE>::value, "Non trivial type used, try Util::Array instead");
103
104}
105
106//------------------------------------------------------------------------------
109template<class TYPE>
111{
112 this->elements = 0;
113 this->Copy(rhs);
114}
115
116//------------------------------------------------------------------------------
119template<class TYPE>
121{
122 this->elements = 0;
123 this->Copy(rhs);
124}
125
126//------------------------------------------------------------------------------
129template<class TYPE> void
131{
132 #if NEBULA_BOUNDSCHECKS
133 n_assert(0 == this->elements);
134 #endif
135
136 this->grow = src.grow;
137 this->capacity = src.capacity;
138 this->size = src.size;
139 if (this->capacity > 0)
140 {
141 this->elements = new TYPE[this->capacity];
142 Memory::Copy(src.elements, this->elements, this->size * sizeof(TYPE));
143 }
144}
145
146//------------------------------------------------------------------------------
149template<class TYPE> void
151{
152#if NEBULA_BOUNDSCHECKS
153 n_assert(0 == this->elements);
154#endif
155 this->grow = src.grow;
156 this->capacity = src.capacity;
157 this->size = src.size;
158 if (this->capacity > 0)
159 {
160 this->elements = new TYPE[this->capacity];
161 Memory::Copy(src.elements, this->elements, this->size * sizeof(TYPE));
162 }
163}
164
165//------------------------------------------------------------------------------
168template<class TYPE> void
170{
171 // empty
172}
173
174//------------------------------------------------------------------------------
177template<class TYPE>
179{
180 this->Delete();
181}
182
183//------------------------------------------------------------------------------
186template<class TYPE> void
188{
189 if (this != &rhs)
190 {
191 if ((this->capacity > 0) && (rhs.size <= this->capacity))
192 {
193 // source array fits into our capacity, copy in place
194 n_assert(0 != this->elements);
195 Memory::Copy(rhs.elements, this->elements, rhs.size * sizeof(TYPE));
196
197 this->grow = rhs.grow;
198 this->size = rhs.size;
199 }
200 else
201 {
202 // source array doesn't fit into our capacity, need to reallocate
203 this->Delete();
204 this->Copy(rhs);
205 }
206 }
207}
208
209//------------------------------------------------------------------------------
212template<class TYPE> void
214{
215 if (this != &rhs)
216 {
217 if ((this->capacity > 0) && (rhs.size <= this->capacity))
218 {
219 // source array fits into our capacity, copy in place
220 n_assert(0 != this->elements);
221 Memory::Copy(rhs.elements, this->elements, rhs.size * sizeof(TYPE));
222
223 this->grow = rhs.grow;
224 this->size = rhs.size;
225 }
226 else
227 {
228 // source array doesn't fit into our capacity, need to reallocate
229 this->Delete();
230 this->Copy(rhs);
231 }
232 }
233}
234//------------------------------------------------------------------------------
237template<class TYPE> void
239{
240 TYPE* newArray = new TYPE[newCapacity];
241 if (this->elements)
242 {
243 Memory::Copy(this->elements, newArray, this->size * sizeof(TYPE));
244 // discard old array
245 delete[] this->elements;
246 }
247 this->elements = newArray;
248 this->capacity = newCapacity;
249}
250
251//------------------------------------------------------------------------------
256template<class TYPE> void
258{
259 #if NEBULA_BOUNDSCHECKS
260 n_assert(this->elements);
261 n_assert(fromIndex < this->size);
262 #endif
263
264 // nothing to move?
265 if (fromIndex == toIndex)
266 {
267 return;
268 }
269
270 // compute number of elements to move
271 SizeT num = this->size - fromIndex;
272
273 // check if array needs to grow
274 SizeT neededSize = toIndex + num;
275 while (neededSize > this->capacity)
276 {
277 this->Grow();
278 }
279
280 //TODO: check if memory move is faster than this
281 if (fromIndex > toIndex)
282 {
283 // this is a backward move
284 IndexT i;
285 for (i = 0; i < num; i++)
286 {
287 this->elements[toIndex + i] = this->elements[fromIndex + i];
288 }
289 }
290 else
291 {
292 // this is a forward move
293 int i; // NOTE: this must remain signed for the following loop to work!!!
294 for (i = num - 1; i >= 0; --i)
295 {
296 this->elements[toIndex + i] = this->elements[fromIndex + i];
297 }
298 }
299
300 // adjust array size
301 this->size = toIndex + num;
302}
303
304//------------------------------------------------------------------------------
307template<class TYPE> void
309{
310 #if NEBULA_BOUNDSCHECKS
311 n_assert(this->elements && (index < this->size));
312 #endif
313 if (index == (this->size - 1))
314 {
315 // special case: last element
316 this->size--;
317 }
318 else
319 {
320 this->Move(index + 1, index);
321 }
322}
323
324//------------------------------------------------------------------------------
328template<class TYPE> void
330{
331 #if NEBULA_BOUNDSCHECKS
332 n_assert(this->elements && (index < this->size));
333 #endif
334
335 // swap with last element, and destroy last element
336 IndexT lastElementIndex = this->size - 1;
337 if (index < lastElementIndex)
338 {
339 this->elements[index] = this->elements[lastElementIndex];
340 }
341 this->size--;
342}
343
344//------------------------------------------------------------------------------
349template<class TYPE> void
351{
352 this->size = 0;
353}
354
355} // namespace Util
356//------------------------------------------------------------------------------
Nebula's dynamic array class.
Definition array.h:60
SizeT capacity
Definition array.h:248
TYPE * elements
Definition array.h:250
SizeT grow
Definition array.h:247
size_t size() const
Definition array.h:1699
Array class based on Util::Array for trivial and POD types that avoids any per element copying and co...
Definition trivialarray.h:19
void Copy(const TrivialArray< TYPE > &src)
copy content
Definition trivialarray.h:130
~TrivialArray()
destructor
Definition trivialarray.h:178
void Move(IndexT fromIndex, IndexT toIndex)
move elements, grows array if needed
Definition trivialarray.h:257
void EraseIndexSwap(IndexT index)
erase element at index, fill gap by swapping in last element, destroys sorting!
Definition trivialarray.h:329
void Clear()
clear array (calls destructors)
Definition trivialarray.h:350
void EraseIndex(IndexT index)
erase element at index, keep sorting intact
Definition trivialarray.h:308
TrivialArray()
constructor with default parameters
Definition trivialarray.h:69
TYPE * Iterator
define iterator
Definition trivialarray.h:22
void GrowTo(SizeT newCapacity)
grow array to target size
Definition trivialarray.h:238
void operator=(const TrivialArray< TYPE > &rhs)
assignment operator
Definition trivialarray.h:187
void Destroy(TYPE *elm)
does nothing
Definition trivialarray.h:169
#define n_assert(exp)
Definition debug.h:50
void Copy(const void *from, void *to, size_t numBytes)
Copy a chunk of memory (note the argument order is different from memcpy()!!!)
Definition osxmemory.cc:213
A pinned array is an array which manages its own virtual memory.
Definition String.cs:6
int SizeT
Definition types.h:49
int IndexT
Definition types.h:48