1
2 /*
3 * Vector - A template vector-class
4 * Copyright (c) 2005 by Mattias Hultgren <mattias_hultgren@tele2.se>
5 *
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; version 2 of the License.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public
17 * License along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20
21 /*
22 v3 2005-09-29 & 2005-11-14
23 --
24
25 Added swap, set_size_filled
26
27 v0.1.1 2005-07-21 - 2005-07-28
28 ------
29
30 Added insert & insert_this.
31 Changed so that append & append_this is implemented through insert & insert_this.
32 Changed so that operator[] preform boundary checking.
33
34 v0.1.0 2005-02-18 - 2005-02-19
35 ------
36
37 Basic vector-functionality works...
38
39 */
40
41 #ifndef VECTOR_H_
42 #define VECTOR_H_
43
44 #include "vartypes.h"
45 #include "keyfile.h"
46
47 #define VECTOR_H_VERSION "v3"
48 #define VECTOR_H_DATE "2005-02 - 2005-11"
49
50
51 template <typename Type>
52 class Vector
53 {
54 private:
55
56 int size;
57 Type **data;
58
59 public:
60 Vector();
61 Vector(const Vector<Type> &src) throw(error_obj);
62 ~Vector();
63
64 void clear(void);
65
66 void set_size(int new_size) throw(error_obj);
67 void set_size_filled(int new_size) throw(error_obj);
get_size(void)68 inline int get_size(void) const { return size; }
69
append(const Type & new_obj)70 inline void append(const Type &new_obj) throw(error_obj) { insert( new_obj, size ); }
append_this(Type * new_obj)71 inline void append_this(Type *new_obj) throw(error_obj) { insert_this( new_obj, size ); }
72
73 // illegal values of at_pos will be truncated to at_pos = size,
74 // which will be the same as append'ing
75 void insert(const Type &new_obj, int at_pos) throw(error_obj);
76 void insert_this( Type *new_obj, int at_pos) throw(error_obj);
77
78 void remove(int index);
79
80 void swap(int i1, int i2);
81
82 void operator=(const Vector<Type> &src) throw(error_obj);
83
84 Type * operator[](int index) throw(error_obj);
85 const Type * operator[](int index) const throw(error_obj);
86 };
87
88
89
90
91
92 template <typename Type>
Vector(void)93 Vector<Type>::Vector(void)
94 {
95 data = 0;
96 size = 0;
97 }
98
99 template <typename Type>
Vector(const Vector<Type> & src)100 Vector<Type>::Vector(const Vector<Type> &src) throw(error_obj)
101 {
102 data = 0;
103 size = 0;
104 *this = src;
105 }
106
107 template <typename Type>
~Vector()108 Vector<Type>::~Vector()
109 {
110 clear();
111 }
112
113 template <typename Type>
throw(error_obj)114 Type * Vector<Type>::operator[](int index) throw(error_obj)
115 {
116 if( index < 0 || index >= size )
117 THROW_ERROR( ErrorType_Memory, _("Index out-of-range in Vector::operator[]") );
118
119 return data[index];
120 }
121
122 template <typename Type>
throw(error_obj)123 const Type * Vector<Type>::operator[](int index) const throw(error_obj)
124 {
125 if( index < 0 || index >= size )
126 THROW_ERROR( ErrorType_General, _("Index out-of-range in Vector::operator[]") );
127
128 return data[index];
129 }
130
131 template <typename Type>
throw(error_obj)132 void Vector<Type>::operator=(const Vector &src) throw(error_obj)
133 {
134 set_size( src.size );
135
136 try
137 {
138 for( int i=0; i<size; i++ )
139 {
140 if( src.data[i] != 0 )
141 {
142 data[i] = new Type;
143 *(data[i]) = *(src.data[i]);
144 }
145 }
146 }
147 catch(error_obj error)
148 {
149 clear();
150 throw;
151 }
152 catch(...)
153 {
154 clear();
155 THROW_ERROR( ErrorType_Memory, _("Couldn't get memory.") );
156 }
157 }
158
159 template <typename Type>
set_size_filled(int new_size)160 void Vector<Type>::set_size_filled(int new_size) throw(error_obj)
161 {
162 set_size( new_size );
163
164 try
165 {
166 for( int i=0; i<size; i++ )
167 data[i] = new Type;
168 }
169 catch(...) { THROW_ERROR( ErrorType_Memory, _("Couldn't get memory.") ); }
170 }
171
172 template <typename Type>
set_size(int new_size)173 void Vector<Type>::set_size(int new_size) throw(error_obj)
174 {
175 clear();
176
177 if( new_size <= 0 )
178 return;
179
180 try
181 {
182 data = new Type * [new_size];
183 size = new_size;
184 }
185 catch(...) { THROW_ERROR( ErrorType_Memory, _("Couldn't get memory.") ); }
186
187 for( int i=0; i<size; i++ )
188 data[i] = 0;
189 }
190
191 template <typename Type>
clear(void)192 void Vector<Type>::clear(void)
193 {
194 for( int i=0; i<size; i++ )
195 delete data[i];
196
197 delete [] data;
198
199 data = 0;
200 size = 0;
201 }
202
203 template <typename Type>
remove(int index)204 void Vector<Type>::remove(int index)
205 {
206 if( index < 0 || index >= size )
207 return;
208
209 delete data[index];
210
211 size--;
212
213 for( int i=index; i<size; i++ )
214 data[i] = data[i+1];
215 }
216
217 template <typename Type>
swap(int i1,int i2)218 void Vector<Type>::swap(int i1, int i2)
219 {
220 if( i1 < 0 || i1 >= size || i2 < 0 || i2 >= size || i1 == i2 )
221 return;
222
223 Type *tmp;
224
225 tmp = data[i1];
226 data[i1] = data[i2];
227 data[i2] = tmp;
228 }
229
230 template <typename Type>
insert(const Type & new_obj,int at_pos)231 void Vector<Type>::insert(const Type &new_obj, int at_pos) throw(error_obj)
232 {
233 Type *tmp;
234
235 if( at_pos < 0 || at_pos > size )
236 at_pos = size;
237
238 try{ tmp = new Type; }
239 catch(...) { THROW_ERROR( ErrorType_Memory, _("Couldn't get memory.") ); }
240
241 try
242 {
243 *tmp = new_obj;
244 insert_this( tmp, at_pos );
245 }
246 catch(...)
247 {
248 delete tmp;
249 throw;
250 }
251 }
252
253 template <typename Type>
insert_this(Type * new_obj,int at_pos)254 void Vector<Type>::insert_this( Type *new_obj, int at_pos) throw(error_obj)
255 {
256 if( at_pos < 0 || at_pos > size )
257 at_pos = size;
258
259 Type **old_data = data;
260 int old_size = size, i;
261
262 data = 0;
263 size = 0;
264
265 try
266 {
267 set_size( old_size+1 );
268 }
269 catch(...)
270 {
271 data = old_data;
272 size = old_size;
273 throw;
274 }
275
276 for( i=0; i<at_pos; i++ )
277 data[i] = old_data[i];
278
279 data[at_pos] = new_obj;
280
281 for( i++; i<size; i++ )
282 data[i] = old_data[i-1];
283
284 delete [] old_data;
285 }
286
287 #endif // VECTOR_H_
288