Merge pull request #10 from egerpil/master
[deliverable/titan.core.git] / core / Vector.hh
1 ///////////////////////////////////////////////////////////////////////////////
2 // Copyright (c) 2000-2015 Ericsson Telecom AB
3 // All rights reserved. This program and the accompanying materials
4 // are made available under the terms of the Eclipse Public License v1.0
5 // which accompanies this distribution, and is available at
6 // http://www.eclipse.org/legal/epl-v10.html
7 ///////////////////////////////////////////////////////////////////////////////
8
9 #ifndef TITANVECTOR_H_
10 #define TITANVECTOR_H_
11
12 #include <stddef.h>
13
14 #ifndef PROF_MERGE
15 #include "Error.hh"
16 #else
17 // there's no point in including Error.hh and all the includes that come with it
18 // when building the profiler merge tool, just use this simple error function
19 #include <stdio.h>
20 #include <stdarg.h>
21 void TTCN_error(const char *fmt, ...)
22 {
23 va_list parameters;
24 va_start(parameters, fmt);
25 vfprintf(stderr, fmt, parameters);
26 va_end(parameters);
27 putc('\n', stderr);
28 fflush(stderr);
29 }
30 #endif
31
32 // Not invented here
33 template<typename T>
34 class Vector {
35 private:
36 size_t cap;
37 size_t nof_elem;
38 T* data;
39
40 void copy(const Vector<T>&);
41 public:
42 explicit Vector(size_t p_capacity = 4);
43
44 explicit Vector(const Vector<T>& other);
45 ~Vector();
46
47 Vector<T>& operator=(const Vector<T>& rhs);
48
49 // Capacity
50 size_t size() const { return nof_elem; }
51 void resize(size_t new_size, T element = T());
52 size_t capacity() const { return cap; }
53 bool empty() const { return nof_elem == 0; }
54 void reserve(size_t n);
55 void shrink_to_fit();
56
57 // Element access
58 T& operator[](size_t idx);
59 const T& operator[](size_t idx) const;
60 T& at(size_t idx);
61 const T& at(size_t idx) const;
62 T& front() { return at(0); }
63 const T& front() const { return at(0); }
64 T& back() { return at(nof_elem - 1); }
65 const T& back() const { return at(nof_elem - 1); }
66 // This could be used better with iterators
67 void erase_at(size_t idx);
68
69 // Modifiers
70 void push_back(const T& element);
71 void pop_back();
72 void clear();
73 };
74
75 template<typename T>
76 Vector<T>::Vector(size_t p_capacity)
77 : cap(p_capacity), nof_elem(0) {
78
79 data = new T[cap];
80 if (!data) {
81 TTCN_error("Internal error: new returned NULL");
82 }
83 }
84
85 template<typename T>
86 Vector<T>::Vector(const Vector<T>& other) {
87 copy(other);
88 }
89
90 template<typename T>
91 Vector<T>& Vector<T>::operator=(const Vector<T>& rhs) {
92 if (this == &rhs) {
93 return *this;
94 }
95
96 clear();
97 delete[] data;
98
99 copy(rhs);
100
101 return *this;
102 }
103
104 template<typename T>
105 void Vector<T>::copy(const Vector<T>& other) {
106 cap = other.cap;
107 data = new T[cap];
108 if (!data) {
109 TTCN_error("Internal error: new returned NULL");
110 }
111
112 for (size_t i = 0; i < other.nof_elem; ++i) {
113 data[i] = other.data[i];
114 }
115
116 nof_elem = other.nof_elem;
117 }
118
119 template<typename T>
120 Vector<T>::~Vector() {
121 clear();
122 delete[] data;
123 }
124
125 template<typename T>
126 void Vector<T>::resize(size_t new_size, T element) {
127 if (new_size > nof_elem) {
128 reserve(new_size);
129 while (nof_elem < new_size) {
130 data[nof_elem++] = element;
131 }
132 return;
133 }
134
135 nof_elem = new_size;
136 }
137
138 template<typename T>
139 void Vector<T>::reserve(size_t new_size) {
140 if (new_size <= cap) {
141 return;
142 }
143
144 cap = new_size;
145 T* data_tmp = new T[cap];
146 if (!data_tmp) {
147 TTCN_error("Internal error: new returned NULL");
148 }
149 for (size_t i = 0; i < nof_elem; ++i) {
150 data_tmp[i] = data[i];
151 }
152
153 delete[] data;
154 data = data_tmp;
155 }
156
157 // Modifiers
158 template<typename T>
159 void Vector<T>::push_back(const T& element) {
160 if (nof_elem == cap) {
161 size_t new_cap = (cap == 0 ? 4 : (cap * 2));
162 reserve(new_cap);
163 }
164
165 data[nof_elem++] = element;
166 }
167
168 template<typename T>
169 const T& Vector<T>::at(size_t idx) const {
170 if (idx >= nof_elem) {
171 TTCN_error("Internal error: Vector over-indexing.");
172 }
173
174 return data[idx];
175 }
176
177 template<typename T>
178 T& Vector<T>::at(size_t idx) {
179 if (idx >= nof_elem) {
180 TTCN_error("Internal error: Vector over-indexing.");
181 }
182
183 return data[idx];
184 }
185
186 template<typename T>
187 const T& Vector<T>::operator[](size_t idx) const {
188 return at(idx);
189 }
190
191 template<typename T>
192 T& Vector<T>::operator[](size_t idx) {
193 return at(idx);
194 }
195
196 template<typename T>
197 void Vector<T>::erase_at(size_t idx) {
198 if (idx >= nof_elem) {
199 TTCN_error("Internal error: Vector over-indexing.");
200 }
201
202 while (idx < nof_elem - 1) {
203 data[idx] = data[idx + 1];
204 ++idx;
205 }
206
207 --nof_elem;
208 }
209
210 template<typename T>
211 void Vector<T>::shrink_to_fit() {
212 if (nof_elem == cap) {
213 return;
214 }
215
216 cap = nof_elem;
217 T* data_tmp = new T[nof_elem];
218 if (!data_tmp) {
219 TTCN_error("Internal error: new returned NULL");
220 }
221 for (size_t i = 0; i < nof_elem; ++i) {
222 data_tmp[i] = data[i];
223 }
224 delete[] data;
225 data = data_tmp;
226 }
227
228 template<typename T>
229 void Vector<T>::clear() {
230 nof_elem = 0;
231 }
232
233 #endif /* TITANVECTOR_H_ */
This page took 0.035914 seconds and 5 git commands to generate.