aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Buland <eichlan@xagasoft.com>2008-09-24 05:52:36 +0000
committerMike Buland <eichlan@xagasoft.com>2008-09-24 05:52:36 +0000
commit6119b465b19e9be095971a33c63b0fa9a0e8a224 (patch)
tree3dafeb91d18290790417477939179526a27de38b
parent5aec71241c874a2249c14025a7df1eddc1c14654 (diff)
downloadlibbu++-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.h45
-rw-r--r--src/array.cpp1
-rw-r--r--src/array.h240
-rw-r--r--src/set.h6
-rw-r--r--src/unit/array.cpp59
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
19namespace Bu 19namespace 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
10namespace 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
14namespace Bu 14namespace 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
diff --git a/src/set.h b/src/set.h
index 7dfa191..42f9eb8 100644
--- a/src/set.h
+++ b/src/set.h
@@ -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
11class Unit : public Bu::UnitSuite
12{
13public:
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
55int main( int argc, char *argv[] )
56{
57 return Unit().run( argc, argv );
58}
59