File: PODArray.h

package info (click to toggle)
storm-lang 0.7.4-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 52,004 kB
  • sloc: ansic: 261,462; cpp: 140,405; sh: 14,891; perl: 9,846; python: 2,525; lisp: 2,504; asm: 860; makefile: 678; pascal: 70; java: 52; xml: 37; awk: 12
file content (113 lines) | stat: -rw-r--r-- 2,022 bytes parent folder | download | duplicates (2)
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;
		}
	};

}