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