Sync with 5.3.0
[deliverable/titan.core.git] / core / Vector.hh
CommitLineData
970ed795
EL
1///////////////////////////////////////////////////////////////////////////////
2// Copyright (c) 2000-2014 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#include "Error.hh"
15
16// Not invented here
17template<typename T>
18class Vector {
19private:
20 size_t cap;
21 size_t nof_elem;
22 T* data;
23
24 void copy(const Vector<T>&);
25public:
26 explicit Vector(size_t p_capacity = 4);
27
28 explicit Vector(const Vector<T>& other);
29 ~Vector();
30
31 Vector<T>& operator=(const Vector<T>& rhs);
32
33 // Capacity
34 size_t size() const { return nof_elem; }
35 void resize(size_t new_size, T element = T());
36 size_t capacity() const { return cap; }
37 bool empty() const { return nof_elem == 0; }
38 void reserve(size_t n);
39 void shrink_to_fit();
40
41 // Element access
42 T& operator[](size_t idx);
43 const T& operator[](size_t idx) const;
44 T& at(size_t idx);
45 const T& at(size_t idx) const;
46 T& front() { return at(0); }
47 const T& front() const { return at(0); }
48 T& back() { return at(nof_elem - 1); }
49 const T& back() const { return at(nof_elem - 1); }
50 // This could be used better with iterators
51 void erase_at(size_t idx);
52
53 // Modifiers
54 void push_back(const T& element);
55 void pop_back();
56 void clear();
57};
58
59template<typename T>
60Vector<T>::Vector(size_t p_capacity)
61 : cap(p_capacity), nof_elem(0) {
62
63 data = new T[cap];
64 if (!data) {
65 TTCN_error("Internal error: new returned NULL");
66 }
67}
68
69template<typename T>
70Vector<T>::Vector(const Vector<T>& other) {
71 copy(other);
72}
73
74template<typename T>
75Vector<T>& Vector<T>::operator=(const Vector<T>& rhs) {
76 if (this == &rhs) {
77 return *this;
78 }
79
80 clear();
81 delete[] data;
82
83 copy(rhs);
84
85 return *this;
86}
87
88template<typename T>
89void Vector<T>::copy(const Vector<T>& other) {
90 cap = other.cap;
91 data = new T[cap];
92 if (!data) {
93 TTCN_error("Internal error: new returned NULL");
94 }
95
96 for (size_t i = 0; i < other.nof_elem; ++i) {
97 data[i] = other.data[i];
98 }
99
100 nof_elem = other.nof_elem;
101}
102
103template<typename T>
104Vector<T>::~Vector() {
105 clear();
106 delete[] data;
107}
108
109template<typename T>
110void Vector<T>::resize(size_t new_size, T element) {
111 if (new_size > nof_elem) {
112 reserve(new_size);
113 while (nof_elem < new_size) {
114 data[nof_elem++] = element;
115 }
116 return;
117 }
118
119 nof_elem = new_size;
120}
121
122template<typename T>
123void Vector<T>::reserve(size_t new_size) {
124 if (new_size <= cap) {
125 return;
126 }
127
128 cap = new_size;
129 T* data_tmp = new T[cap];
130 if (!data_tmp) {
131 TTCN_error("Internal error: new returned NULL");
132 }
133 for (size_t i = 0; i < nof_elem; ++i) {
134 data_tmp[i] = data[i];
135 }
136
137 delete[] data;
138 data = data_tmp;
139}
140
141// Modifiers
142template<typename T>
143void Vector<T>::push_back(const T& element) {
144 if (nof_elem == cap) {
145 size_t new_cap = (cap == 0 ? 4 : (cap * 2));
146 reserve(new_cap);
147 }
148
149 data[nof_elem++] = element;
150}
151
152template<typename T>
153const T& Vector<T>::at(size_t idx) const {
154 if (idx >= nof_elem) {
155 TTCN_error("Internal error: Vector over-indexing.");
156 }
157
158 return data[idx];
159}
160
161template<typename T>
162T& Vector<T>::at(size_t idx) {
163 if (idx >= nof_elem) {
164 TTCN_error("Internal error: Vector over-indexing.");
165 }
166
167 return data[idx];
168}
169
170template<typename T>
171const T& Vector<T>::operator[](size_t idx) const {
172 return at(idx);
173}
174
175template<typename T>
176T& Vector<T>::operator[](size_t idx) {
177 return at(idx);
178}
179
180template<typename T>
181void Vector<T>::erase_at(size_t idx) {
182 if (idx >= nof_elem) {
183 TTCN_error("Internal error: Vector over-indexing.");
184 }
185
186 while (idx < nof_elem - 1) {
187 data[idx] = data[idx + 1];
188 ++idx;
189 }
190
191 --nof_elem;
192}
193
194template<typename T>
195void Vector<T>::shrink_to_fit() {
196 if (nof_elem == cap) {
197 return;
198 }
199
200 cap = nof_elem;
201 T* data_tmp = new T[nof_elem];
202 if (!data_tmp) {
203 TTCN_error("Internal error: new returned NULL");
204 }
205 for (size_t i = 0; i < nof_elem; ++i) {
206 data_tmp[i] = data[i];
207 }
208 delete[] data;
209 data = data_tmp;
210}
211
212template<typename T>
213void Vector<T>::clear() {
214 nof_elem = 0;
215}
216
217#endif /* TITANVECTOR_H_ */
This page took 0.032201 seconds and 5 git commands to generate.