diff options
author | Mike Buland <eichlan@xagasoft.com> | 2008-09-24 05:52:36 +0000 |
---|---|---|
committer | Mike Buland <eichlan@xagasoft.com> | 2008-09-24 05:52:36 +0000 |
commit | 6119b465b19e9be095971a33c63b0fa9a0e8a224 (patch) | |
tree | 3dafeb91d18290790417477939179526a27de38b | |
parent | 5aec71241c874a2249c14025a7df1eddc1c14654 (diff) | |
download | libbu++-6119b465b19e9be095971a33c63b0fa9a0e8a224.tar.gz libbu++-6119b465b19e9be095971a33c63b0fa9a0e8a224.tar.bz2 libbu++-6119b465b19e9be095971a33c63b0fa9a0e8a224.tar.xz libbu++-6119b465b19e9be095971a33c63b0fa9a0e8a224.zip |
Wow, I realized that the Bu::Array class wasn't finished, and went ahead and
wrote it, it's pretty feature complete, index, append, iterators. You can't
delete anything yet, exactly, but that's tricky in an array anyway, basically
you just want to be able to remove elements from the end, and that's halfway
there.
Also, fixed some documentation and minor issues in Bu::Set, and made the
Bu::Archive include fewer other classes while still defining archive oprators
for them. I think I may yet move those into the headers for the classes that
are being stored instead, makes a little more sense.
I also would like to move the Exception classes out of the exceptions.h file
and into the appropriate class' files'. There still should probably be a
couple of general ones in there, or maybe just in exceptionbase.h, we'll see.
-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 | |||