summaryrefslogtreecommitdiff
path: root/src/stable/array.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/stable/array.h')
-rw-r--r--src/stable/array.h1382
1 files changed, 691 insertions, 691 deletions
diff --git a/src/stable/array.h b/src/stable/array.h
index f765e75..324c9ac 100644
--- a/src/stable/array.h
+++ b/src/stable/array.h
@@ -15,697 +15,697 @@
15 15
16namespace Bu 16namespace Bu
17{ 17{
18 subExceptionDecl( ArrayException ) 18 subExceptionDecl( ArrayException )
19 19
20 template<typename value, int inc, typename valuealloc> 20 template<typename value, int inc, typename valuealloc>
21 class Array; 21 class Array;
22 22
23 /** @cond DEVEL */ 23 /** @cond DEVEL */
24 template<typename value, int inc, typename valuealloc> 24 template<typename value, int inc, typename valuealloc>
25 class ArrayCore 25 class ArrayCore
26 { 26 {
27 friend class Array<value, inc, valuealloc>; 27 friend class Array<value, inc, valuealloc>;
28 friend class SharedCore< 28 friend class SharedCore<
29 Array<value, inc, valuealloc>, 29 Array<value, inc, valuealloc>,
30 ArrayCore<value, inc, valuealloc> 30 ArrayCore<value, inc, valuealloc>
31 >; 31 >;
32 private: 32 private:
33 ArrayCore() : 33 ArrayCore() :
34 pData( NULL ), 34 pData( NULL ),
35 iSize( 0 ), 35 iSize( 0 ),
36 iCapacity( 0 ) 36 iCapacity( 0 )
37 { } 37 { }
38 38
39 void setCapacity( int iNewLen ) 39 void setCapacity( int iNewLen )
40 { 40 {
41 //clear(); 41 //clear();
42 //iCapacity = iCapacity; 42 //iCapacity = iCapacity;
43 //pData = va.allocate( iCapacity ); 43 //pData = va.allocate( iCapacity );
44 if( iNewLen <= iCapacity ) return; 44 if( iNewLen <= iCapacity ) return;
45 value *pNewData = va.allocate( iNewLen ); 45 value *pNewData = va.allocate( iNewLen );
46 if( pData ) 46 if( pData )
47 { 47 {
48 for( int j = 0; j < iSize; j++ ) 48 for( int j = 0; j < iSize; j++ )
49 { 49 {
50 va.construct( &pNewData[j], pData[j] ); 50 va.construct( &pNewData[j], pData[j] );
51 va.destroy( &pData[j] ); 51 va.destroy( &pData[j] );
52 } 52 }
53 va.deallocate( pData, iCapacity ); 53 va.deallocate( pData, iCapacity );
54 } 54 }
55 pData = pNewData; 55 pData = pNewData;
56 iCapacity = iNewLen; 56 iCapacity = iNewLen;
57 } 57 }
58 58
59 virtual ~ArrayCore() 59 virtual ~ArrayCore()
60 { 60 {
61 clear(); 61 clear();
62 } 62 }
63 63
64 void clear() 64 void clear()
65 { 65 {
66 if( pData ) 66 if( pData )
67 { 67 {
68 for( int j = 0; j < iSize; j++ ) 68 for( int j = 0; j < iSize; j++ )
69 { 69 {
70 va.destroy( &pData[j] ); 70 va.destroy( &pData[j] );
71 } 71 }
72 va.deallocate( pData, iCapacity ); 72 va.deallocate( pData, iCapacity );
73 pData = NULL; 73 pData = NULL;
74 } 74 }
75 iSize = 0; 75 iSize = 0;
76 iCapacity = 0; 76 iCapacity = 0;
77 } 77 }
78 78
79 void erase( int iPos ) 79 void erase( int iPos )
80 { 80 {
81 for( int j = iPos; j < iSize; j++ ) 81 for( int j = iPos; j < iSize; j++ )
82 { 82 {
83 va.destroy( &pData[j] ); 83 va.destroy( &pData[j] );
84 if( j == iSize-1 ) 84 if( j == iSize-1 )
85 { 85 {
86 iSize--; 86 iSize--;
87 return; 87 return;
88 } 88 }
89 va.construct( &pData[j], pData[j+1] ); 89 va.construct( &pData[j], pData[j+1] );
90 } 90 }
91 } 91 }
92 92
93 void swapErase( int iPos ) 93 void swapErase( int iPos )
94 { 94 {
95 if( iPos == iSize-1 ) 95 if( iPos == iSize-1 )
96 { 96 {
97 erase( iPos ); 97 erase( iPos );
98 return; 98 return;
99 } 99 }
100 va.destroy( &pData[iPos] ); 100 va.destroy( &pData[iPos] );
101 va.construct( &pData[iPos], pData[iSize-1] ); 101 va.construct( &pData[iPos], pData[iSize-1] );
102 va.destroy( &pData[iSize-1] ); 102 va.destroy( &pData[iSize-1] );
103 iSize--; 103 iSize--;
104 } 104 }
105 105
106 valuealloc va; 106 valuealloc va;
107 value *pData; 107 value *pData;
108 long iSize; 108 long iSize;
109 long iCapacity; 109 long iCapacity;
110 }; 110 };
111 /** @endcond */ 111 /** @endcond */
112 112
113 /** 113 /**
114 * Array type container, just like a normal array only flexible and keeps 114 * Array type container, just like a normal array only flexible and keeps
115 * track of your memory for you. 115 * track of your memory for you.
116 * 116 *
117 *@param value (typename) The type of data to store in your list 117 *@param value (typename) The type of data to store in your list
118 *@param valuealloc (typename) Memory Allocator for your value type 118 *@param valuealloc (typename) Memory Allocator for your value type
119 *@param linkalloc (typename) Memory Allocator for the list links. 119 *@param linkalloc (typename) Memory Allocator for the list links.
120 *@ingroup Containers 120 *@ingroup Containers
121 */ 121 */
122 template<typename value, int inc=10, typename valuealloc=std::allocator<value> > 122 template<typename value, int inc=10, typename valuealloc=std::allocator<value> >
123 class Array : public SharedCore< 123 class Array : public SharedCore<
124 Array<value, inc, valuealloc>, 124 Array<value, inc, valuealloc>,
125 ArrayCore<value, inc, valuealloc> 125 ArrayCore<value, inc, valuealloc>
126 > 126 >
127 { 127 {
128 private: 128 private:
129 typedef class Array<value, inc, valuealloc> MyType; 129 typedef class Array<value, inc, valuealloc> MyType;
130 typedef class ArrayCore<value, inc, valuealloc> Core; 130 typedef class ArrayCore<value, inc, valuealloc> Core;
131 131
132 protected: 132 protected:
133 using SharedCore<MyType, Core>::core; 133 using SharedCore<MyType, Core>::core;
134 using SharedCore<MyType, Core>::_hardCopy; 134 using SharedCore<MyType, Core>::_hardCopy;
135 using SharedCore<MyType, Core>::_resetCore; 135 using SharedCore<MyType, Core>::_resetCore;
136 using SharedCore<MyType, Core>::_allocateCore; 136 using SharedCore<MyType, Core>::_allocateCore;
137 137
138 public: 138 public:
139 struct const_iterator; 139 struct const_iterator;
140 struct iterator; 140 struct iterator;
141 141
142 Array() 142 Array()
143 { 143 {
144 } 144 }
145 145
146 Array( const MyType &src ) : 146 Array( const MyType &src ) :
147 SharedCore<MyType, Core >( src ) 147 SharedCore<MyType, Core >( src )
148 { 148 {
149 } 149 }
150 150
151 Array( long iSetCap ) 151 Array( long iSetCap )
152 { 152 {
153 setCapacity( iSetCap ); 153 setCapacity( iSetCap );
154 } 154 }
155 155
156 ~Array() 156 ~Array()
157 { 157 {
158 } 158 }
159 159
160 bool operator==( const MyType &src ) const 160 bool operator==( const MyType &src ) const
161 { 161 {
162 if( core == src.core ) 162 if( core == src.core )
163 return true; 163 return true;
164 if( core->iSize != src.core->iSize ) 164 if( core->iSize != src.core->iSize )
165 return false; 165 return false;
166 166
167 for( int j = 0; j < core->iSize; j++ ) 167 for( int j = 0; j < core->iSize; j++ )
168 { 168 {
169 if( core->pData[j] != src.core->pData[j] ) 169 if( core->pData[j] != src.core->pData[j] )
170 return false; 170 return false;
171 } 171 }
172 return true; 172 return true;
173 } 173 }
174 174
175 bool operator!=( const MyType &src ) const 175 bool operator!=( const MyType &src ) const
176 { 176 {
177 return !(*this == src); 177 return !(*this == src);
178 } 178 }
179 179
180 /** 180 /**
181 * Clear the array. 181 * Clear the array.
182 */ 182 */
183 void clear() 183 void clear()
184 { 184 {
185 _resetCore(); 185 _resetCore();
186 } 186 }
187 187
188 MyType &append( const value &rVal ) 188 MyType &append( const value &rVal )
189 { 189 {
190 _hardCopy(); 190 _hardCopy();
191 if( core->iSize == core->iCapacity ) 191 if( core->iSize == core->iCapacity )
192 { 192 {
193 core->setCapacity( core->iCapacity + inc ); 193 core->setCapacity( core->iCapacity + inc );
194 } 194 }
195 195
196 core->va.construct( &core->pData[core->iSize++], rVal ); 196 core->va.construct( &core->pData[core->iSize++], rVal );
197 197
198 return *this; 198 return *this;
199 } 199 }
200 200
201 MyType &append( const MyType &rVal ) 201 MyType &append( const MyType &rVal )
202 { 202 {
203 _hardCopy(); 203 _hardCopy();
204 204
205 if( core->iSize + rVal.core->iSize > core->iCapacity ) 205 if( core->iSize + rVal.core->iSize > core->iCapacity )
206 { 206 {
207 core->setCapacity( core->iSize + rVal.core->iSize + inc ); 207 core->setCapacity( core->iSize + rVal.core->iSize + inc );
208 } 208 }
209 209
210 for( int j = 0; j < rVal.core->iSize; j++ ) 210 for( int j = 0; j < rVal.core->iSize; j++ )
211 { 211 {
212 core->va.construct( 212 core->va.construct(
213 &core->pData[core->iSize++], 213 &core->pData[core->iSize++],
214 rVal.core->pData[j] 214 rVal.core->pData[j]
215 ); 215 );
216 } 216 }
217 217
218 return *this; 218 return *this;
219 } 219 }
220 220
221 //operator 221 //operator
222 value &operator[]( long iIndex ) 222 value &operator[]( long iIndex )
223 { 223 {
224 _hardCopy(); 224 _hardCopy();
225 if( iIndex < 0 || iIndex >= core->iSize ) 225 if( iIndex < 0 || iIndex >= core->iSize )
226 throw ArrayException( 226 throw ArrayException(
227 "Index %d out of range 0:%d", iIndex, core->iSize ); 227 "Index %d out of range 0:%d", iIndex, core->iSize );
228 228
229 return core->pData[iIndex]; 229 return core->pData[iIndex];
230 } 230 }
231 231
232 const value &operator[]( long iIndex ) const 232 const value &operator[]( long iIndex ) const
233 { 233 {
234 if( iIndex < 0 || iIndex >= core->iSize ) 234 if( iIndex < 0 || iIndex >= core->iSize )
235 throw ArrayException( 235 throw ArrayException(
236 "Index %d out of range 0:%d", iIndex, core->iSize ); 236 "Index %d out of range 0:%d", iIndex, core->iSize );
237 237
238 return core->pData[iIndex]; 238 return core->pData[iIndex];
239 } 239 }
240 240
241 value &get( long iIndex ) 241 value &get( long iIndex )
242 { 242 {
243 _hardCopy(); 243 _hardCopy();
244 if( iIndex < 0 || iIndex >= core->iSize ) 244 if( iIndex < 0 || iIndex >= core->iSize )
245 throw ArrayException( 245 throw ArrayException(
246 "Index %d out of range 0:%d", iIndex, core->iSize ); 246 "Index %d out of range 0:%d", iIndex, core->iSize );
247 247
248 return core->pData[iIndex]; 248 return core->pData[iIndex];
249 } 249 }
250 250
251 const value &get( long iIndex ) const 251 const value &get( long iIndex ) const
252 { 252 {
253 if( iIndex < 0 || iIndex >= core->iSize ) 253 if( iIndex < 0 || iIndex >= core->iSize )
254 throw ArrayException( 254 throw ArrayException(
255 "Index %d out of range 0:%d", iIndex, core->iSize ); 255 "Index %d out of range 0:%d", iIndex, core->iSize );
256 256
257 return core->pData[iIndex]; 257 return core->pData[iIndex];
258 } 258 }
259 259
260 value &first() 260 value &first()
261 { 261 {
262 _hardCopy(); 262 _hardCopy();
263 return core->pData[0]; 263 return core->pData[0];
264 } 264 }
265 265
266 const value &first() const 266 const value &first() const
267 { 267 {
268 return core->pData[0]; 268 return core->pData[0];
269 } 269 }
270 270
271 value &last() 271 value &last()
272 { 272 {
273 _hardCopy(); 273 _hardCopy();
274 return core->pData[core->iSize-1]; 274 return core->pData[core->iSize-1];
275 } 275 }
276 276
277 const value &last() const 277 const value &last() const
278 { 278 {
279 return core->pData[core->iSize-1]; 279 return core->pData[core->iSize-1];
280 } 280 }
281 281
282 /** 282 /**
283 * Returns true if the array is empty. The capacity has no bearing on 283 * Returns true if the array is empty. The capacity has no bearing on
284 * this, only the size. 284 * this, only the size.
285 */ 285 */
286 bool isEmpty() const 286 bool isEmpty() const
287 { 287 {
288 return core->iSize==0; 288 return core->iSize==0;
289 } 289 }
290 290
291 /** 291 /**
292 * Get the current size of the array. 292 * Get the current size of the array.
293 *@returns The current size of the array. 293 *@returns The current size of the array.
294 */ 294 */
295 long getSize() const 295 long getSize() const
296 { 296 {
297 return core->iSize; 297 return core->iSize;
298 } 298 }
299 299
300 /** 300 /**
301 * Get the capacity of the array. This number will grow as data is 301 * Get the capacity of the array. This number will grow as data is
302 * added, and is mainly for the curious, it doesn't really determine 302 * added, and is mainly for the curious, it doesn't really determine
303 * much for the end user. 303 * much for the end user.
304 *@returns The current capacity of the array. 304 *@returns The current capacity of the array.
305 */ 305 */
306 long getCapacity() const 306 long getCapacity() const
307 { 307 {
308 return core->iCapacity; 308 return core->iCapacity;
309 } 309 }
310 310
311 /** 311 /**
312 * Change the capacity of the array, very useful if you know you'll be 312 * Change the capacity of the array, very useful if you know you'll be
313 * adding a large amount of already counted items to the array, makes 313 * adding a large amount of already counted items to the array, makes
314 * the appending much faster afterwords. 314 * the appending much faster afterwords.
315 *@param iNewLen The new capacity of the array. 315 *@param iNewLen The new capacity of the array.
316 *@todo Set this up so it can reduce the size of the array as well as 316 *@todo Set this up so it can reduce the size of the array as well as
317 * make it bigger. 317 * make it bigger.
318 */ 318 */
319 void setCapacity( long iNewLen ) 319 void setCapacity( long iNewLen )
320 { 320 {
321 _hardCopy(); 321 _hardCopy();
322 core->setCapacity( iNewLen ); 322 core->setCapacity( iNewLen );
323 } 323 }
324 324
325 typedef struct iterator 325 typedef struct iterator
326 { 326 {
327 friend class Array<value, inc, valuealloc>; 327 friend class Array<value, inc, valuealloc>;
328 private: 328 private:
329 iterator( MyType &src, long iPos=0 ) : 329 iterator( MyType &src, long iPos=0 ) :
330 src( src ), 330 src( src ),
331 iPos( iPos ) 331 iPos( iPos )
332 { 332 {
333 if( this->iPos >= src.getSize() ) 333 if( this->iPos >= src.getSize() )
334 this->iPos = -1; 334 this->iPos = -1;
335 } 335 }
336 336
337 MyType &src; 337 MyType &src;
338 long iPos; 338 long iPos;
339 339
340 public: 340 public:
341 iterator operator++( int ) 341 iterator operator++( int )
342 { 342 {
343 if( iPos < 0 ) 343 if( iPos < 0 )
344 throw ArrayException( 344 throw ArrayException(
345 "Cannot increment iterator past end of array."); 345 "Cannot increment iterator past end of array.");
346 iPos++; 346 iPos++;
347 if( iPos >= src.getSize() ) 347 if( iPos >= src.getSize() )
348 iPos = -1; 348 iPos = -1;
349 return *this; 349 return *this;
350 } 350 }
351 351
352 iterator operator++() 352 iterator operator++()
353 { 353 {
354 if( iPos >= 0 ) 354 if( iPos >= 0 )
355 iPos++; 355 iPos++;
356 if( iPos >= src.getSize() ) 356 if( iPos >= src.getSize() )
357 iPos = -1; 357 iPos = -1;
358 return *this; 358 return *this;
359 } 359 }
360 360
361 iterator operator+( int iAmnt ) 361 iterator operator+( int iAmnt )
362 { 362 {
363 if( iPos < 0 ) 363 if( iPos < 0 )
364 throw ArrayException( 364 throw ArrayException(
365 "Cannot increment iterator past end of array."); 365 "Cannot increment iterator past end of array.");
366 iPos += iAmnt; 366 iPos += iAmnt;
367 if( iPos >= src.getSize() ) 367 if( iPos >= src.getSize() )
368 iPos = -1; 368 iPos = -1;
369 return *this; 369 return *this;
370 } 370 }
371 371
372 iterator operator--( int ) 372 iterator operator--( int )
373 { 373 {
374 if( iPos < 0 ) 374 if( iPos < 0 )
375 throw ArrayException( 375 throw ArrayException(
376 "Cannot increment iterator past end of array."); 376 "Cannot increment iterator past end of array.");
377 iPos--; 377 iPos--;
378 if( iPos < 0 ) 378 if( iPos < 0 )
379 iPos = -1; 379 iPos = -1;
380 return *this; 380 return *this;
381 } 381 }
382 382
383 iterator operator--() 383 iterator operator--()
384 { 384 {
385 if( iPos < src.getSize() ) 385 if( iPos < src.getSize() )
386 iPos--; 386 iPos--;
387 if( iPos <= 0 ) 387 if( iPos <= 0 )
388 iPos = -1; 388 iPos = -1;
389 return *this; 389 return *this;
390 } 390 }
391 391
392 iterator operator-( int iAmnt ) 392 iterator operator-( int iAmnt )
393 { 393 {
394 if( iPos < src.getSize() ) 394 if( iPos < src.getSize() )
395 iPos -= iAmnt; 395 iPos -= iAmnt;
396 if( iPos <= 0 ) 396 if( iPos <= 0 )
397 iPos = -1; 397 iPos = -1;
398 return *this; 398 return *this;
399 } 399 }
400 400
401 bool operator==( const iterator &oth ) const 401 bool operator==( const iterator &oth ) const
402 { 402 {
403 return iPos == oth.iPos; 403 return iPos == oth.iPos;
404 } 404 }
405 405
406 bool operator!=( const iterator &oth ) const 406 bool operator!=( const iterator &oth ) const
407 { 407 {
408 return iPos != oth.iPos; 408 return iPos != oth.iPos;
409 } 409 }
410 410
411 iterator operator=( const iterator &oth ) 411 iterator operator=( const iterator &oth )
412 { 412 {
413 if( &src != &oth.src ) 413 if( &src != &oth.src )
414 throw ArrayException( 414 throw ArrayException(
415 "Cannot mix iterators from different array objects."); 415 "Cannot mix iterators from different array objects.");
416 iPos = oth.iPos; 416 iPos = oth.iPos;
417 } 417 }
418 418
419 value &operator*() 419 value &operator*()
420 { 420 {
421 if( iPos < 0 ) 421 if( iPos < 0 )
422 throw ArrayException( 422 throw ArrayException(
423 "Cannot dereference finished iterator."); 423 "Cannot dereference finished iterator.");
424 return src[iPos]; 424 return src[iPos];
425 } 425 }
426 426
427 long getIndex() const 427 long getIndex() const
428 { 428 {
429 return iPos; 429 return iPos;
430 } 430 }
431 431
432 operator bool() const 432 operator bool() const
433 { 433 {
434 return iPos >= 0; 434 return iPos >= 0;
435 } 435 }
436 436
437 bool isValid() const 437 bool isValid() const
438 { 438 {
439 return iPos >= 0; 439 return iPos >= 0;
440 } 440 }
441 } iterator; 441 } iterator;
442 442
443 typedef struct const_iterator 443 typedef struct const_iterator
444 { 444 {
445 friend class Array<value, inc, valuealloc>; 445 friend class Array<value, inc, valuealloc>;
446 private: 446 private:
447 const_iterator( const MyType &src, long iPos=0 ) : 447 const_iterator( const MyType &src, long iPos=0 ) :
448 src( src ), 448 src( src ),
449 iPos( iPos ) 449 iPos( iPos )
450 { 450 {
451 if( this->iPos >= src.getSize() ) 451 if( this->iPos >= src.getSize() )
452 this->iPos = -1; 452 this->iPos = -1;
453 } 453 }
454 454
455 const MyType &src; 455 const MyType &src;
456 long iPos; 456 long iPos;
457 457
458 public: 458 public:
459 const_iterator( iterator &rSrc ) : 459 const_iterator( iterator &rSrc ) :
460 src( rSrc.src ), 460 src( rSrc.src ),
461 iPos( rSrc.iPos ) 461 iPos( rSrc.iPos )
462 { 462 {
463 } 463 }
464 const_iterator operator++( int ) 464 const_iterator operator++( int )
465 { 465 {
466 if( iPos < 0 ) 466 if( iPos < 0 )
467 throw ArrayException( 467 throw ArrayException(
468 "Cannot increment iterator past end of array."); 468 "Cannot increment iterator past end of array.");
469 iPos++; 469 iPos++;
470 if( iPos >= src.getSize() ) 470 if( iPos >= src.getSize() )
471 iPos = -1; 471 iPos = -1;
472 return *this; 472 return *this;
473 } 473 }
474 474
475 const_iterator operator++() 475 const_iterator operator++()
476 { 476 {
477 if( iPos >= 0 ) 477 if( iPos >= 0 )
478 iPos++; 478 iPos++;
479 if( iPos >= src.getSize() ) 479 if( iPos >= src.getSize() )
480 iPos = -1; 480 iPos = -1;
481 return *this; 481 return *this;
482 } 482 }
483 483
484 const_iterator operator--( int ) 484 const_iterator operator--( int )
485 { 485 {
486 if( iPos < 0 ) 486 if( iPos < 0 )
487 throw ArrayException( 487 throw ArrayException(
488 "Cannot increment iterator past end of array."); 488 "Cannot increment iterator past end of array.");
489 iPos--; 489 iPos--;
490 if( iPos < 0 ) 490 if( iPos < 0 )
491 iPos = -1; 491 iPos = -1;
492 return *this; 492 return *this;
493 } 493 }
494 494
495 const_iterator operator--() 495 const_iterator operator--()
496 { 496 {
497 if( iPos < src.getSize() ) 497 if( iPos < src.getSize() )
498 iPos--; 498 iPos--;
499 if( iPos <= 0 ) 499 if( iPos <= 0 )
500 iPos = -1; 500 iPos = -1;
501 return *this; 501 return *this;
502 } 502 }
503 503
504 bool operator==( const const_iterator &oth ) const 504 bool operator==( const const_iterator &oth ) const
505 { 505 {
506 return iPos == oth.iPos; 506 return iPos == oth.iPos;
507 } 507 }
508 508
509 bool operator!=( const const_iterator &oth ) const 509 bool operator!=( const const_iterator &oth ) const
510 { 510 {
511 return iPos != oth.iPos; 511 return iPos != oth.iPos;
512 } 512 }
513 513
514 const_iterator operator=( const const_iterator &oth ) 514 const_iterator operator=( const const_iterator &oth )
515 { 515 {
516 if( &src != &oth.src ) 516 if( &src != &oth.src )
517 throw ArrayException( 517 throw ArrayException(
518 "Cannot mix iterators from different array objects."); 518 "Cannot mix iterators from different array objects.");
519 iPos = oth.iPos; 519 iPos = oth.iPos;
520 } 520 }
521 521
522 const value &operator*() const 522 const value &operator*() const
523 { 523 {
524 if( iPos < 0 ) 524 if( iPos < 0 )
525 throw ArrayException( 525 throw ArrayException(
526 "Cannot dereference finished iterator."); 526 "Cannot dereference finished iterator.");
527 return src[iPos]; 527 return src[iPos];
528 } 528 }
529 529
530 long getIndex() const 530 long getIndex() const
531 { 531 {
532 return iPos; 532 return iPos;
533 } 533 }
534 534
535 operator bool() const 535 operator bool() const
536 { 536 {
537 return iPos >= 0; 537 return iPos >= 0;
538 } 538 }
539 539
540 bool isValid() const 540 bool isValid() const
541 { 541 {
542 return iPos >= 0; 542 return iPos >= 0;
543 } 543 }
544 } const_iterator; 544 } const_iterator;
545 545
546 iterator begin() 546 iterator begin()
547 { 547 {
548 return iterator( *this ); 548 return iterator( *this );
549 } 549 }
550 550
551 const_iterator begin() const 551 const_iterator begin() const
552 { 552 {
553 return const_iterator( *this ); 553 return const_iterator( *this );
554 } 554 }
555 555
556 iterator end() 556 iterator end()
557 { 557 {
558 return iterator( *this, -1 ); 558 return iterator( *this, -1 );
559 } 559 }
560 560
561 const_iterator end() const 561 const_iterator end() const
562 { 562 {
563 return const_iterator( *this, -1 ); 563 return const_iterator( *this, -1 );
564 } 564 }
565 565
566 MyType &insert( iterator i, const value &rVal ) 566 MyType &insert( iterator i, const value &rVal )
567 { 567 {
568 if( i.iPos == -1 ) 568 if( i.iPos == -1 )
569 { 569 {
570 append( rVal ); 570 append( rVal );
571 return *this; 571 return *this;
572 } 572 }
573 573
574 _hardCopy(); 574 _hardCopy();
575 if( core->iSize == core->iCapacity ) 575 if( core->iSize == core->iCapacity )
576 { 576 {
577 core->setCapacity( core->iCapacity + inc ); 577 core->setCapacity( core->iCapacity + inc );
578 } 578 }
579 core->iSize++; 579 core->iSize++;
580 580
581 core->va.construct( 581 core->va.construct(
582 &core->pData[core->iSize-1], 582 &core->pData[core->iSize-1],
583 core->pData[core->iSize-2] 583 core->pData[core->iSize-2]
584 ); 584 );
585 for( int iPos = core->iSize-2; iPos > i.iPos; iPos-- ) 585 for( int iPos = core->iSize-2; iPos > i.iPos; iPos-- )
586 { 586 {
587 core->va.destroy( &core->pData[iPos] ); 587 core->va.destroy( &core->pData[iPos] );
588 core->va.construct( &core->pData[iPos], core->pData[iPos-1] ); 588 core->va.construct( &core->pData[iPos], core->pData[iPos-1] );
589 } 589 }
590 core->va.destroy( &core->pData[i.iPos] ); 590 core->va.destroy( &core->pData[i.iPos] );
591 core->va.construct( &core->pData[i.iPos], rVal ); 591 core->va.construct( &core->pData[i.iPos], rVal );
592 592
593 return *this; 593 return *this;
594 } 594 }
595 595
596 /** 596 /**
597 * If order is important, use this. It will delete the suggested item 597 * If order is important, use this. It will delete the suggested item
598 * and move the rest of the data up a spot. This is a time O(n) 598 * and move the rest of the data up a spot. This is a time O(n)
599 * operation. If the order isn't important, check swapErase 599 * operation. If the order isn't important, check swapErase
600 */ 600 */
601 void erase( iterator i ) 601 void erase( iterator i )
602 { 602 {
603 _hardCopy(); 603 _hardCopy();
604 core->erase( i.iPos ); 604 core->erase( i.iPos );
605 } 605 }
606 606
607 void erase( const value &v ) 607 void erase( const value &v )
608 { 608 {
609 _hardCopy(); 609 _hardCopy();
610 for( int j = 0; j < core->iSize; j++ ) 610 for( int j = 0; j < core->iSize; j++ )
611 { 611 {
612 if( core->pData[j] == v ) 612 if( core->pData[j] == v )
613 { 613 {
614 core->erase( j ); 614 core->erase( j );
615 return; 615 return;
616 } 616 }
617 } 617 }
618 } 618 }
619 619
620 void eraseLast() 620 void eraseLast()
621 { 621 {
622 _hardCopy(); 622 _hardCopy();
623 core->erase( core->iSize-1 ); 623 core->erase( core->iSize-1 );
624 } 624 }
625 625
626 void eraseFirst() 626 void eraseFirst()
627 { 627 {
628 _hardCopy(); 628 _hardCopy();
629 core->erase( 0 ); 629 core->erase( 0 );
630 } 630 }
631 631
632 /** 632 /**
633 * In order to make swapErase faster, what it does is swap the given 633 * In order to make swapErase faster, what it does is swap the given
634 * item in the array with the last item, then make the array shorter 634 * item in the array with the last item, then make the array shorter
635 * by one. It changes the order of the elements in the array, so it 635 * by one. It changes the order of the elements in the array, so it
636 * should be used carefully, but it is time O(1) instead of O(n) like 636 * should be used carefully, but it is time O(1) instead of O(n) like
637 * erase. 637 * erase.
638 */ 638 */
639 void swapErase( iterator i ) 639 void swapErase( iterator i )
640 { 640 {
641 _hardCopy(); 641 _hardCopy();
642 core->swapErase( i.iPos ); 642 core->swapErase( i.iPos );
643 } 643 }
644 644
645 protected: 645 protected:
646 virtual Core *_copyCore( Core *src ) 646 virtual Core *_copyCore( Core *src )
647 { 647 {
648 Core *pRet = _allocateCore(); 648 Core *pRet = _allocateCore();
649 pRet->setCapacity( src->iCapacity ); 649 pRet->setCapacity( src->iCapacity );
650 pRet->iSize = src->iSize; 650 pRet->iSize = src->iSize;
651 for( int j = 0; j < src->iSize; j++ ) 651 for( int j = 0; j < src->iSize; j++ )
652 { 652 {
653 pRet->va.construct( &pRet->pData[j], src->pData[j] ); 653 pRet->va.construct( &pRet->pData[j], src->pData[j] );
654 } 654 }
655 return pRet; 655 return pRet;
656 } 656 }
657 657
658 private: 658 private:
659 }; 659 };
660 660
661 class Formatter; 661 class Formatter;
662 Formatter &operator<<( Formatter &rOut, char *sStr ); 662 Formatter &operator<<( Formatter &rOut, char *sStr );
663 Formatter &operator<<( Formatter &rOut, signed char c ); 663 Formatter &operator<<( Formatter &rOut, signed char c );
664 template<typename value> 664 template<typename value>
665 Formatter &operator<<( Formatter &f, const Bu::Array<value> &a ) 665 Formatter &operator<<( Formatter &f, const Bu::Array<value> &a )
666 { 666 {
667 f << '['; 667 f << '[';
668 for( typename Bu::Array<value>::const_iterator i = a.begin(); i; i++ ) 668 for( typename Bu::Array<value>::const_iterator i = a.begin(); i; i++ )
669 { 669 {
670 if( i != a.begin() ) 670 if( i != a.begin() )
671 f << ", "; 671 f << ", ";
672 f << *i; 672 f << *i;
673 } 673 }
674 f << ']'; 674 f << ']';
675 675
676 return f; 676 return f;
677 } 677 }
678 678
679 template<typename value, int inc, typename valuealloc> 679 template<typename value, int inc, typename valuealloc>
680 ArchiveBase &operator<<( ArchiveBase &ar, 680 ArchiveBase &operator<<( ArchiveBase &ar,
681 const Array<value, inc, valuealloc> &h ) 681 const Array<value, inc, valuealloc> &h )
682 { 682 {
683 ar << h.getSize(); 683 ar << h.getSize();
684 for( typename Array<value, inc, valuealloc>::const_iterator i = 684 for( typename Array<value, inc, valuealloc>::const_iterator i =
685 h.begin(); i != h.end(); i++ ) 685 h.begin(); i != h.end(); i++ )
686 { 686 {
687 ar << (*i); 687 ar << (*i);
688 } 688 }
689 689
690 return ar; 690 return ar;
691 } 691 }
692 692
693 template<typename value, int inc, typename valuealloc> 693 template<typename value, int inc, typename valuealloc>
694 ArchiveBase &operator>>(ArchiveBase &ar, Array<value, inc, valuealloc> &h ) 694 ArchiveBase &operator>>(ArchiveBase &ar, Array<value, inc, valuealloc> &h )
695 { 695 {
696 h.clear(); 696 h.clear();
697 long nSize; 697 long nSize;
698 ar >> nSize; 698 ar >> nSize;
699 699
700 h.setCapacity( nSize ); 700 h.setCapacity( nSize );
701 for( long j = 0; j < nSize; j++ ) 701 for( long j = 0; j < nSize; j++ )
702 { 702 {
703 value v; 703 value v;
704 ar >> v; 704 ar >> v;
705 h.append( v ); 705 h.append( v );
706 } 706 }
707 return ar; 707 return ar;
708 } 708 }
709 709
710} 710}
711 711