File: PrePODArray.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 (105 lines) | stat: -rw-r--r-- 2,057 bytes parent folder | download | duplicates (4)
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
#pragma once

/**
 * Array with a preallocated part and a dynamic part. This is
 * to accommodate cases where there is a common case where the
 * number of elements required is small, and a rare case where
 * the number of elements is larger. Using this array, the common
 * case can use automatic storage (eg. the stack), while we can
 * still gracefully handle the rare cases by dynamically allocate
 * memory.
 * This version is intended for POD:s, ie types where it is fine
 * to not call constructors and destructors. For the generic case,
 * please use PreArray in PreArray.h.
 */
template <class T, nat n>
class PrePODArray {
public:
	// Create.
	PrePODArray() : dyn(null), size(0), capacity(n) {}

	// Copy.
	PrePODArray(const PrePODArray &o) : dyn(null), size(0), capacity(n) {
		ensure(o.size());
		size = o.size;
		copyArray(pre, o.pre, size);
		if (size > n)
			copyArray(dyn, o.dyn, size - n);
	}

	// Assign.
	PrePODArray<T, n> &operator =(const PrePODArray<T, n> &o) {
		clear();
		ensure(o.size);
		for (nat i = 0; i < o.size; i++)
			push(o[i]);
		return *this;
	}

	// Destroy.
	~PrePODArray() {
		clear();
	}

	// Clear.
	void clear() {
		delete []dyn;
		dyn = null;
		capacity = n;
		size = 0;
	}

	// Element access.
	T &operator [](nat id) {
		return *ptr(id);
	}

	const T &operator [](nat id) const {
		return *ptr(id);
	}

	// Push new elements.
	void push(const T &v) {
		ensure(size + 1);
		*ptr(size++) = v;
	}

	// # of elements
	inline nat count() const {
		return size;
	}

private:
	// Preallocated storage.
	T pre[n];

	// Dynamic storage.
	T *dyn;

	// Used until.
	nat size;

	// Allocated size (all storage).
	nat capacity;

	// Ensure capacity.
	void ensure(nat elems) {
		if (elems <= capacity)
			return;

		capacity = max(elems, capacity * 2);
		T *z = new T[capacity - n];
		if (dyn != null && size > n)
			copyArray(z, dyn, size - n);
		swap(dyn, z);
		delete []z;
	}

	// Get a pointer to an element.
	inline T *ptr(nat id) const {
		if (id >= n)
			return (T *)&dyn[id - n];
		else
			return (T *)&pre[id];
	}
};