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