O2 2.0
A communication protocol for interactive music and media applications.
vec.h
1// vec.h -- O2 vector implementation
2//
3// Roger B. Dannenberg
4// November 2020
5
6template <typename T> class Vec : public O2obj {
7 protected:
8 int allocated;
9 int length;
10 T *array;
11 public:
12 Vec(int siz) { array = NULL; init(siz); }
13
14 // initialization with optional fill with zeros
15 Vec(int siz, bool z) { init(siz, z); }
16
17 // move vector to new one, initialize src vector to empty
18 Vec(Vec &v) { allocated = v.allocated;
19 length = v.length; array = v.array;
20 v.array = NULL; v.allocated = 0; v.length = 0; }
21
22 // default constructor does not allocate any memory
23 Vec() { array = NULL; init(0); }
24
25 ~Vec() { finish(); }
26
27 // explicitly (re)initialize the vector and array storage
28 void init(int siz) { init(siz, false); }
29
30 // explicitly (re)initialize the vector and array storage
31 // with option to zero fill all the entries
32 void init(int siz, bool z) {
33 if (array) finish();
34 array = (siz > 0 ? O2_MALLOCNT(siz, T) : NULL);
35 allocated = siz;
36 length = 0;
37 if (z) zero();
38 }
39
40 // explicitly free the associated storage. No destructors called
41 // on elements.
42 void finish() {
43 length = 0;
44 allocated = 0;
45 // note that delete would call system delete, so call O2_FREE.
46 if (array) O2_FREE(array);
47 array = NULL;
48 }
49
50 // clear all allocated space
51 void zero() { memset((void *) array, 0, sizeof(T) * allocated); }
52
53 T &operator[](int index) { return array[index]; }
54
55 // return the last element
56 T &last() { return array[length - 1]; }
57
58 // remove all elements. No destructors are called.
59 void clear() { length = 0; }
60
61 // remove an element quickly: fill the "hole" with the last element,
62 // which reorders the array but leaves no holes.
63 void remove(int index) {
64 length--;
65 if (length > index) {
66 array[index] = array[length];
67 }
68 }
69
70 // push one element to the end of the array.
71 void push_back(T data) { *append_space(1) = data; }
72
73 // append a C array of count elements to the end of the array.
74 void append(const T *data, int count) {
75 memcpy(append_space(count), data, count * sizeof(T));
76 }
77
78 // make room for an additional count of elements, return address of first
79 // the new elements are uninitialized
80 T *append_space(int count) {
81 if (length + count > allocated) {
82 expand_array(length + count);
83 }
84 length += count;
85 return &array[length - count];
86 }
87
88 // remove elements from index first to index last, [first, last)
89 // No destructors are callled. Element order is maintained.
90 void erase(int first, int last) {
91 if (first >= 0 && first <= last && last <= length) {
92 int n = last - first;
93 memmove(array + first, array + last, (length - last) * sizeof(T));
94 length -= n;
95 }
96 }
97
98 // remove one element. Element order is maintained.
99 void erase(int i) { erase(i, i + 1); }
100
101 // remove n elements from beginning if size is at least n.
102 // No destructors are callled.
103 void drop_front(int n) { erase(0, n); }
104
105 void insert(int i, T data) {
106 if (i >= 0 && i <= length) {
107 append_space(1);
108 memmove(array + i, array + i + 1, (length - i) * sizeof(T));
109 array[i] = data;
110 }
111 }
112
113 // copy all size() elements to C array:
114 void retrieve(T *data) { memcpy(data, array, length * sizeof(T)); }
115
116 // remove the last element
117 T pop_back() { return array[length-- - 1]; }
118
119 // check if index i is in-bounds
120 bool bounds_check(int i) { return i >= 0 && i < length; }
121
122 // return the number of elements in use
123 int size() { return length; }
124
125 // return the maximum count of elements that could be stored
126 // without reallocating the array. Use
127 // v.init(n, true); v.append_space(v.get_allocated()) to
128 // create an array of at least n zero-filled elements
129 // e.g. for a hash table that uses all allocated entries.
130 int get_allocated() { return allocated; }
131
132private:
133 void expand_array(int new_size);
134};
135
136
137template <typename T>
138void Vec<T>::expand_array(int newsize)
139{
140 if (allocated > 0) allocated *= 2;
141 else allocated = 1;
142 if (allocated < newsize) allocated = newsize;
143 T *bigger = O2_MALLOCNT(allocated, T);
144 memcpy(bigger, array, length * sizeof(T));
145 if (array) O2_FREE(array);
146 array = bigger;
147}
148
Definition: o2obj.h:9
Definition: vec.h:6