Merge "implemented decmatch (artf724241)"
[deliverable/titan.core.git] / core / Vector.hh
CommitLineData
d44e3c4f 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 ******************************************************************************/
970ed795
EL
16
17#ifndef TITANVECTOR_H_
18#define TITANVECTOR_H_
19
20#include <stddef.h>
21
3abe9331 22#ifndef PROF_MERGE
970ed795 23#include "Error.hh"
3abe9331 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>
29void 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
970ed795
EL
39
40// Not invented here
41template<typename T>
42class Vector {
43private:
44 size_t cap;
45 size_t nof_elem;
46 T* data;
47
48 void copy(const Vector<T>&);
49public:
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
83template<typename T>
84Vector<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
93template<typename T>
94Vector<T>::Vector(const Vector<T>& other) {
95 copy(other);
96}
97
98template<typename T>
99Vector<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
112template<typename T>
113void 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
127template<typename T>
128Vector<T>::~Vector() {
129 clear();
130 delete[] data;
131}
132
133template<typename T>
134void 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
146template<typename T>
147void 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
166template<typename T>
167void 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
176template<typename T>
177const 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
185template<typename T>
186T& 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
194template<typename T>
195const T& Vector<T>::operator[](size_t idx) const {
196 return at(idx);
197}
198
199template<typename T>
200T& Vector<T>::operator[](size_t idx) {
201 return at(idx);
202}
203
204template<typename T>
205void 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
218template<typename T>
219void 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
236template<typename T>
237void Vector<T>::clear() {
238 nof_elem = 0;
239}
240
241#endif /* TITANVECTOR_H_ */
This page took 0.033207 seconds and 5 git commands to generate.