diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/archive.h | 45 | ||||
-rw-r--r-- | src/array.cpp | 1 | ||||
-rw-r--r-- | src/array.h | 240 | ||||
-rw-r--r-- | src/set.h | 6 | ||||
-rw-r--r-- | src/unit/array.cpp | 59 |
5 files changed, 328 insertions, 23 deletions
diff --git a/src/archive.h b/src/archive.h index 1d57724..519b2a7 100644 --- a/src/archive.h +++ b/src/archive.h | |||
@@ -13,7 +13,7 @@ | |||
13 | #include <list> | 13 | #include <list> |
14 | #include "bu/hash.h" | 14 | #include "bu/hash.h" |
15 | #include "bu/list.h" | 15 | #include "bu/list.h" |
16 | #include "bu/set.h" | 16 | //#include "bu/set.h" |
17 | #include "bu/util.h" | 17 | #include "bu/util.h" |
18 | 18 | ||
19 | namespace Bu | 19 | namespace Bu |
@@ -298,11 +298,12 @@ namespace Bu | |||
298 | return ar; | 298 | return ar; |
299 | } | 299 | } |
300 | 300 | ||
301 | template<typename value> | 301 | template<typename value, int inc, typename valuealloc> class Array; |
302 | Archive &operator<<( Archive &ar, Set<value> &h ) | 302 | template<typename value, int inc, typename valuealloc> |
303 | Archive &operator<<( Archive &ar, Array<value, inc, valuealloc> &h ) | ||
303 | { | 304 | { |
304 | ar << h.getSize(); | 305 | ar << h.getSize(); |
305 | for( typename Set<value>::iterator i = h.begin(); i != h.end(); i++ ) | 306 | for( typename Array<value, inc, valuealloc>::iterator i = h.begin(); i != h.end(); i++ ) |
306 | { | 307 | { |
307 | ar << (*i); | 308 | ar << (*i); |
308 | } | 309 | } |
@@ -310,17 +311,47 @@ namespace Bu | |||
310 | return ar; | 311 | return ar; |
311 | } | 312 | } |
312 | 313 | ||
313 | template<typename value> | 314 | template<typename value, int inc, typename valuealloc> |
314 | Archive &operator>>( Archive &ar, Set<value> &h ) | 315 | Archive &operator>>(Archive &ar, Array<value, inc, valuealloc> &h ) |
315 | { | 316 | { |
316 | h.clear(); | 317 | h.clear(); |
317 | long nSize; | 318 | long nSize; |
318 | ar >> nSize; | 319 | ar >> nSize; |
319 | 320 | ||
321 | h.setCapacity( nSize ); | ||
320 | for( long j = 0; j < nSize; j++ ) | 322 | for( long j = 0; j < nSize; j++ ) |
321 | { | 323 | { |
322 | value v; | 324 | value v; |
323 | ar >> v; | 325 | ar >> v; |
326 | h.append( v ); | ||
327 | } | ||
328 | return ar; | ||
329 | } | ||
330 | |||
331 | template<typename key, typename b, typename c, typename d> class Set; | ||
332 | template<typename key, typename b, typename c, typename d> | ||
333 | Archive &operator<<( Archive &ar, Set<key, b, c, d> &h ) | ||
334 | { | ||
335 | ar << h.getSize(); | ||
336 | for( typename Set<key, b, c, d>::iterator i = h.begin(); i != h.end(); i++ ) | ||
337 | { | ||
338 | ar << (*i); | ||
339 | } | ||
340 | |||
341 | return ar; | ||
342 | } | ||
343 | |||
344 | template<typename key, typename b, typename c, typename d> | ||
345 | Archive &operator>>( Archive &ar, Set<key, b, c, d> &h ) | ||
346 | { | ||
347 | h.clear(); | ||
348 | long nSize; | ||
349 | ar >> nSize; | ||
350 | |||
351 | for( long j = 0; j < nSize; j++ ) | ||
352 | { | ||
353 | key v; | ||
354 | ar >> v; | ||
324 | h.insert( v ); | 355 | h.insert( v ); |
325 | } | 356 | } |
326 | 357 | ||
diff --git a/src/array.cpp b/src/array.cpp index 8cb58ab..826425c 100644 --- a/src/array.cpp +++ b/src/array.cpp | |||
@@ -7,3 +7,4 @@ | |||
7 | 7 | ||
8 | #include "bu/array.h" | 8 | #include "bu/array.h" |
9 | 9 | ||
10 | namespace Bu { subExceptionDef( ArrayException ) } | ||
diff --git a/src/array.h b/src/array.h index 093ece2..9233875 100644 --- a/src/array.h +++ b/src/array.h | |||
@@ -13,6 +13,7 @@ | |||
13 | 13 | ||
14 | namespace Bu | 14 | namespace Bu |
15 | { | 15 | { |
16 | subExceptionDecl( ArrayException ) | ||
16 | /** | 17 | /** |
17 | * Array type container, just like a normal array only flexible and keeps | 18 | * Array type container, just like a normal array only flexible and keeps |
18 | * track of your memory for you. | 19 | * track of your memory for you. |
@@ -41,10 +42,14 @@ namespace Bu | |||
41 | iSize( 0 ), | 42 | iSize( 0 ), |
42 | iCapacity( 0 ) | 43 | iCapacity( 0 ) |
43 | { | 44 | { |
44 | // for( Link *pCur = src.pFirst; pCur; pCur = pCur->pNext ) | 45 | } |
45 | // { | 46 | |
46 | // append( *pCur->pValue ); | 47 | Array( long iSetCap ) : |
47 | // } | 48 | pData( NULL ), |
49 | iSize( 0 ), | ||
50 | iCapacity( 0 ) | ||
51 | { | ||
52 | setCapacity( iSetCap ); | ||
48 | } | 53 | } |
49 | 54 | ||
50 | ~Array() | 55 | ~Array() |
@@ -53,33 +58,244 @@ namespace Bu | |||
53 | } | 58 | } |
54 | 59 | ||
55 | /** | 60 | /** |
56 | * Clear the data from the list. | 61 | * Clear the array. |
57 | */ | 62 | */ |
58 | void clear() | 63 | void clear() |
59 | { | 64 | { |
65 | if( pData ) | ||
66 | { | ||
67 | for( int j = 0; j < iSize; j++ ) | ||
68 | { | ||
69 | va.destroy( &pData[j] ); | ||
70 | } | ||
71 | va.deallocate( pData, iCapacity ); | ||
72 | pData = NULL; | ||
73 | } | ||
74 | iSize = 0; | ||
75 | iCapacity = 0; | ||
60 | } | 76 | } |
61 | 77 | ||
62 | //operator | 78 | void append( const value &rVal ) |
79 | { | ||
80 | if( iSize == iCapacity ) | ||
81 | { | ||
82 | setCapacity( iCapacity + inc ); | ||
83 | } | ||
84 | |||
85 | va.construct( &pData[iSize++], rVal ); | ||
86 | } | ||
87 | |||
88 | //operator | ||
89 | value &operator[]( long iIndex ) | ||
90 | { | ||
91 | if( iIndex < 0 || iIndex >= iSize ) | ||
92 | throw ArrayException( | ||
93 | "Index %d out of range 0:%d", iIndex, iSize ); | ||
94 | |||
95 | return pData[iIndex]; | ||
96 | } | ||
97 | |||
98 | const value &operator[]( long iIndex ) const | ||
99 | { | ||
100 | if( iIndex < 0 || iIndex >= iSize ) | ||
101 | throw ArrayException( | ||
102 | "Index %d out of range 0:%d", iIndex, iSize ); | ||
103 | |||
104 | return pData[iIndex]; | ||
105 | } | ||
63 | 106 | ||
64 | /** | 107 | /** |
65 | * Get the current size of the list. | 108 | * Get the current size of the array. |
66 | *@returns (int) The current size of the list. | 109 | *@returns The current size of the array. |
67 | */ | 110 | */ |
68 | int getSize() const | 111 | long getSize() const |
69 | { | 112 | { |
70 | return iSize; | 113 | return iSize; |
71 | } | 114 | } |
72 | 115 | ||
73 | int getCapacity() const | 116 | /** |
117 | * Get the capacity of the array. This number will grow as data is | ||
118 | * added, and is mainly for the curious, it doesn't really determine | ||
119 | * much for the end user. | ||
120 | *@returns The current capacity of the array. | ||
121 | */ | ||
122 | long getCapacity() const | ||
74 | { | 123 | { |
75 | return iCapacity; | 124 | return iCapacity; |
76 | } | 125 | } |
77 | 126 | ||
127 | /** | ||
128 | * Change the capacity of the array, very useful if you know you'll be | ||
129 | * adding a large amount of already counted items to the array, makes | ||
130 | * the appending much faster afterwords. | ||
131 | *@param iNewLen The new capacity of the array. | ||
132 | *@todo Set this up so it can reduce the size of the array as well as | ||
133 | * make it bigger. | ||
134 | */ | ||
135 | void setCapacity( long iNewLen ) | ||
136 | { | ||
137 | if( iNewLen < iCapacity ) return; | ||
138 | value *pNewData = va.allocate( iNewLen ); | ||
139 | if( pData ) | ||
140 | { | ||
141 | for( int j = 0; j < iSize; j++ ) | ||
142 | { | ||
143 | va.construct( &pNewData[j], pData[j] ); | ||
144 | va.destroy( &pData[j] ); | ||
145 | } | ||
146 | va.deallocate( pData, iCapacity ); | ||
147 | } | ||
148 | pData = pNewData; | ||
149 | iCapacity = iNewLen; | ||
150 | } | ||
151 | |||
152 | typedef struct iterator | ||
153 | { | ||
154 | friend class Array<value, inc, valuealloc>; | ||
155 | private: | ||
156 | iterator( MyType &src, long iPos=0 ) : | ||
157 | src( src ), | ||
158 | iPos( iPos ) | ||
159 | { | ||
160 | } | ||
161 | |||
162 | MyType &src; | ||
163 | long iPos; | ||
164 | |||
165 | public: | ||
166 | iterator operator++( int ) | ||
167 | { | ||
168 | if( iPos < 0 ) | ||
169 | throw ArrayException( | ||
170 | "Cannot increment iterator past end of array."); | ||
171 | iPos++; | ||
172 | if( iPos >= src.getSize() ) | ||
173 | iPos = -1; | ||
174 | return *this; | ||
175 | } | ||
176 | |||
177 | iterator operator++() | ||
178 | { | ||
179 | if( iPos >= 0 ) | ||
180 | iPos++; | ||
181 | if( iPos >= src.getSize() ) | ||
182 | iPos = -1; | ||
183 | return *this; | ||
184 | } | ||
185 | |||
186 | bool operator==( const iterator &oth ) | ||
187 | { | ||
188 | return iPos == oth.iPos; | ||
189 | } | ||
190 | |||
191 | bool operator!=( const iterator &oth ) | ||
192 | { | ||
193 | return iPos != oth.iPos; | ||
194 | } | ||
195 | |||
196 | iterator operator=( const iterator &oth ) | ||
197 | { | ||
198 | if( &src != &oth.src ) | ||
199 | throw ArrayException( | ||
200 | "Cannot mix iterators from different array objects."); | ||
201 | iPos = oth.iPos; | ||
202 | } | ||
203 | |||
204 | value &operator*() | ||
205 | { | ||
206 | if( iPos < 0 ) | ||
207 | throw ArrayException( | ||
208 | "Cannot dereference finished iterator."); | ||
209 | return src[iPos]; | ||
210 | } | ||
211 | } iterator; | ||
212 | |||
213 | typedef struct const_iterator | ||
214 | { | ||
215 | friend class Array<value, inc, valuealloc>; | ||
216 | private: | ||
217 | const_iterator( const MyType &src, long iPos=0 ) : | ||
218 | src( src ), | ||
219 | iPos( iPos ) | ||
220 | { | ||
221 | } | ||
222 | |||
223 | const MyType &src; | ||
224 | long iPos; | ||
225 | |||
226 | public: | ||
227 | const_iterator operator++( int ) | ||
228 | { | ||
229 | if( iPos < 0 ) | ||
230 | throw ArrayException( | ||
231 | "Cannot increment iterator past end of array."); | ||
232 | iPos++; | ||
233 | if( iPos >= src.getSize() ) | ||
234 | iPos = -1; | ||
235 | return *this; | ||
236 | } | ||
237 | |||
238 | const_iterator operator++() | ||
239 | { | ||
240 | if( iPos >= 0 ) | ||
241 | iPos++; | ||
242 | if( iPos >= src.getSize() ) | ||
243 | iPos = -1; | ||
244 | return *this; | ||
245 | } | ||
246 | |||
247 | bool operator==( const const_iterator &oth ) | ||
248 | { | ||
249 | return iPos == oth.iPos; | ||
250 | } | ||
251 | |||
252 | bool operator!=( const const_iterator &oth ) | ||
253 | { | ||
254 | return iPos != oth.iPos; | ||
255 | } | ||
256 | |||
257 | const_iterator operator=( const const_iterator &oth ) | ||
258 | { | ||
259 | if( &src != &oth.src ) | ||
260 | throw ArrayException( | ||
261 | "Cannot mix iterators from different array objects."); | ||
262 | iPos = oth.iPos; | ||
263 | } | ||
264 | |||
265 | const value &operator*() const | ||
266 | { | ||
267 | if( iPos < 0 ) | ||
268 | throw ArrayException( | ||
269 | "Cannot dereference finished iterator."); | ||
270 | return src[iPos]; | ||
271 | } | ||
272 | } const_iterator; | ||
273 | |||
274 | iterator begin() | ||
275 | { | ||
276 | return iterator( *this ); | ||
277 | } | ||
278 | |||
279 | const_iterator begin() const | ||
280 | { | ||
281 | return const_iterator( *this ); | ||
282 | } | ||
283 | |||
284 | iterator end() | ||
285 | { | ||
286 | return iterator( *this, -1 ); | ||
287 | } | ||
288 | |||
289 | const_iterator end() const | ||
290 | { | ||
291 | return const_iterator( *this, -1 ); | ||
292 | } | ||
293 | |||
78 | private: | 294 | private: |
79 | valuealloc va; | 295 | valuealloc va; |
80 | value *pData; | 296 | value *pData; |
81 | int iSize; | 297 | long iSize; |
82 | int iCapacity; | 298 | long iCapacity; |
83 | }; | 299 | }; |
84 | } | 300 | } |
85 | 301 | ||
@@ -16,8 +16,6 @@ | |||
16 | #include <utility> | 16 | #include <utility> |
17 | #include "bu/exceptionbase.h" | 17 | #include "bu/exceptionbase.h" |
18 | #include "bu/list.h" | 18 | #include "bu/list.h" |
19 | ///#include "archival.h" | ||
20 | ///#include "archive.h" | ||
21 | 19 | ||
22 | #define bitsToBytes( n ) (n/32+(n%32>0 ? 1 : 0)) | 20 | #define bitsToBytes( n ) (n/32+(n%32>0 ? 1 : 0)) |
23 | 21 | ||
@@ -355,7 +353,7 @@ namespace Bu | |||
355 | { | 353 | { |
356 | if( &hsh != &oth.hsh ) | 354 | if( &hsh != &oth.hsh ) |
357 | throw SetException( | 355 | throw SetException( |
358 | "Cannot mix iterators from different hash objects."); | 356 | "Cannot mix iterators from different set objects."); |
359 | nPos = oth.nPos; | 357 | nPos = oth.nPos; |
360 | bFinished = oth.bFinished; | 358 | bFinished = oth.bFinished; |
361 | } | 359 | } |
@@ -371,7 +369,7 @@ namespace Bu | |||
371 | } iterator; | 369 | } iterator; |
372 | 370 | ||
373 | /** | 371 | /** |
374 | * Iteration structure for iterating through the hash (const). | 372 | * Iteration structure for iterating through the set (const). |
375 | */ | 373 | */ |
376 | typedef struct const_iterator | 374 | typedef struct const_iterator |
377 | { | 375 | { |
diff --git a/src/unit/array.cpp b/src/unit/array.cpp new file mode 100644 index 0000000..db29882 --- /dev/null +++ b/src/unit/array.cpp | |||
@@ -0,0 +1,59 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2007-2008 Xagasoft, All rights reserved. | ||
3 | * | ||
4 | * This file is part of the libbu++ library and is released under the | ||
5 | * terms of the license contained in the file LICENSE. | ||
6 | */ | ||
7 | |||
8 | #include "bu/unitsuite.h" | ||
9 | #include "bu/array.h" | ||
10 | |||
11 | class Unit : public Bu::UnitSuite | ||
12 | { | ||
13 | public: | ||
14 | Unit() | ||
15 | { | ||
16 | setName("Array"); | ||
17 | addTest( Unit::general ); | ||
18 | addTest( Unit::iterate ); | ||
19 | } | ||
20 | |||
21 | virtual ~Unit() | ||
22 | { | ||
23 | } | ||
24 | |||
25 | void general() | ||
26 | { | ||
27 | Bu::Array<int> ai; | ||
28 | |||
29 | ai.append( 5 ); | ||
30 | ai.append( 10 ); | ||
31 | unitTest( ai.getSize() == 2 ); | ||
32 | unitTest( ai.getCapacity() == 10 ); | ||
33 | unitTest( ai[0] == 5 ); | ||
34 | unitTest( ai[1] == 10 ); | ||
35 | } | ||
36 | |||
37 | void iterate() | ||
38 | { | ||
39 | Bu::Array<int> ai; | ||
40 | for( int j = 0; j < 10; j++ ) | ||
41 | ai.append( j ); | ||
42 | |||
43 | int j = 0; | ||
44 | for( Bu::Array<int>::iterator i = ai.begin(); i != ai.end(); i++ ) | ||
45 | unitTest( (*i) == j++ ); | ||
46 | |||
47 | const Bu::Array<int> &ci = ai; | ||
48 | j = 0; | ||
49 | for( Bu::Array<int>::const_iterator i = ci.begin(); i != ci.end(); i++ ) | ||
50 | unitTest( (*i) == j++ ); | ||
51 | } | ||
52 | |||
53 | }; | ||
54 | |||
55 | int main( int argc, char *argv[] ) | ||
56 | { | ||
57 | return Unit().run( argc, argv ); | ||
58 | } | ||
59 | |||