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 110 111 112 113
|
#pragma once
#include "GcArray.h"
namespace storm {
STORM_PKG(core);
namespace pod {
// Get the GcType for the type.
template <class T>
struct Gc {
static const GcType type;
};
template <class T>
struct Gc<T *> {
static const GcType type;
};
template <class T>
const GcType Gc<T>::type = {
GcType::tArray,
null,
null,
sizeof(T),
0, {}
};
template <class T>
const GcType Gc<T *>::type = {
GcType::tArray,
null,
null,
sizeof(T *),
1, { 0 }
};
}
/**
* Array that can store POD types without pointers or an array of pure pointers. This array
* starts preallocated with a number of elements so that no allocations have to be made until
* the preallocation is filled.
*/
template <class T, nat alloc>
class PODArray {
public:
PODArray(Engine &e) : e(e) {
data = pre;
data->filled = 0;
}
// Add an element.
void push(const T &e) {
if (data->filled == data->count)
grow();
data->v[data->filled++] = e;
}
// Pop an element (does not clear storage).
void pop() {
if (data->filled > 0)
data->filled--;
}
// Access elements.
T &operator[] (nat id) {
return data->v[id];
}
// Count.
nat count() const {
return Nat(data->filled);
}
// Clear (does not clear storage)
void clear() {
data->filled = 0;
}
// Reverse the data.
void reverse() {
nat first = 0;
nat last = count();
while ((first != last) && (first != --last)) {
std::swap(data->v[first], data->v[last]);
++first;
}
}
private:
PODArray(const PODArray &o);
PODArray &operator =(const PODArray &o);
// Engine.
Engine &e;
// Pre-allocated array.
GcPreArray<T, alloc> pre;
// Pointer to the current data.
GcArray<T> *data;
// Grow storage.
void grow() {
nat newCount = Nat(data->count) * 2;
GcArray<T> *d = runtime::allocArray<T>(e, &pod::Gc<T>::type, newCount);
d->filled = data->filled;
memcpy(d->v, data->v, sizeof(T) * data->filled);
data = d;
}
};
}
|