diff options
author | Mike Buland <eichlan@xagasoft.com> | 2012-11-05 22:41:51 +0000 |
---|---|---|
committer | Mike Buland <eichlan@xagasoft.com> | 2012-11-05 22:41:51 +0000 |
commit | ec05778d5718a7912e506764d443a78d6a6179e3 (patch) | |
tree | 78a9a01532180030c095acefc45763f07c14edb8 /src/stable/array.h | |
parent | b20414ac1fe80a71a90601f4cd1767fa7014a9ba (diff) | |
download | libbu++-ec05778d5718a7912e506764d443a78d6a6179e3.tar.gz libbu++-ec05778d5718a7912e506764d443a78d6a6179e3.tar.bz2 libbu++-ec05778d5718a7912e506764d443a78d6a6179e3.tar.xz libbu++-ec05778d5718a7912e506764d443a78d6a6179e3.zip |
Converted tabs to spaces with tabconv.
Diffstat (limited to '')
-rw-r--r-- | src/stable/array.h | 1382 |
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 | ||
16 | namespace Bu | 16 | namespace 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 | ||