summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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