summaryrefslogtreecommitdiff
path: root/src/array.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/array.h')
-rw-r--r--src/array.h245
1 files changed, 167 insertions, 78 deletions
diff --git a/src/array.h b/src/array.h
index 6279382..af41c33 100644
--- a/src/array.h
+++ b/src/array.h
@@ -11,10 +11,95 @@
11#include <memory> 11#include <memory>
12#include "bu/exceptionbase.h" 12#include "bu/exceptionbase.h"
13#include "bu/archivebase.h" 13#include "bu/archivebase.h"
14#include "bu/sharedcore.h"
14 15
15namespace Bu 16namespace Bu
16{ 17{
17 subExceptionDecl( ArrayException ) 18 subExceptionDecl( ArrayException )
19
20 template<typename value, int inc, typename valuealloc>
21 class ArrayCore
22 {
23 public:
24 ArrayCore() :
25 pData( NULL ),
26 iSize( 0 ),
27 iCapacity( 0 )
28 { }
29
30 void setCapacity( int iNewLen )
31 {
32 //clear();
33 //iCapacity = iCapacity;
34 //pData = va.allocate( iCapacity );
35 if( iNewLen <= iCapacity ) return;
36 value *pNewData = va.allocate( iNewLen );
37 if( pData )
38 {
39 for( int j = 0; j < iSize; j++ )
40 {
41 va.construct( &pNewData[j], pData[j] );
42 va.destroy( &pData[j] );
43 }
44 va.deallocate( pData, iCapacity );
45 }
46 pData = pNewData;
47 iCapacity = iNewLen;
48 }
49
50 virtual ~ArrayCore()
51 {
52 clear();
53 }
54
55 void clear()
56 {
57 if( pData )
58 {
59 for( int j = 0; j < iSize; j++ )
60 {
61 va.destroy( &pData[j] );
62 }
63 va.deallocate( pData, iCapacity );
64 pData = NULL;
65 }
66 iSize = 0;
67 iCapacity = 0;
68 }
69
70 void erase( int iPos )
71 {
72 for( int j = iPos; j < iSize; j++ )
73 {
74 va.destroy( &pData[j] );
75 if( j == iSize-1 )
76 {
77 iSize--;
78 return;
79 }
80 va.construct( &pData[j], pData[j+1] );
81 }
82 }
83
84 void swapErase( int iPos )
85 {
86 if( iPos == iSize-1 )
87 {
88 erase( iPos );
89 return;
90 }
91 va.destroy( &pData[iPos] );
92 va.construct( &pData[iPos], pData[iSize-1] );
93 va.destroy( &pData[iSize-1] );
94 iSize--;
95 }
96
97 valuealloc va;
98 value *pData;
99 long iSize;
100 long iCapacity;
101 };
102
18 /** 103 /**
19 * Array type container, just like a normal array only flexible and keeps 104 * Array type container, just like a normal array only flexible and keeps
20 * track of your memory for you. 105 * track of your memory for you.
@@ -25,51 +110,57 @@ namespace Bu
25 *@ingroup Containers 110 *@ingroup Containers
26 */ 111 */
27 template<typename value, int inc=10, typename valuealloc=std::allocator<value> > 112 template<typename value, int inc=10, typename valuealloc=std::allocator<value> >
28 class Array 113 class Array : public SharedCore<ArrayCore<value, inc, valuealloc> >
29 { 114 {
30 private: 115 private:
31 typedef class Array<value, inc, valuealloc> MyType; 116 typedef class Array<value, inc, valuealloc> MyType;
117 typedef class ArrayCore<value, inc, valuealloc> Core;
118
119 protected:
120 using SharedCore< Core >::core;
121 using SharedCore< Core >::_hardCopy;
122 using SharedCore< Core >::_allocateCore;
32 123
33 public: 124 public:
34 Array() : 125 struct const_iterator;
35 pData( NULL ), 126 struct iterator;
36 iSize( 0 ), 127
37 iCapacity( 0 ) 128 Array()
38 { 129 {
39 } 130 }
40 131
41 Array( const MyType &src ) : 132 Array( const MyType &src ) :
42 pData( NULL ), 133 SharedCore< Core >( src )
43 iSize( 0 ),
44 iCapacity( 0 )
45 { 134 {
46 *this = src;
47 } 135 }
48 136
49 Array( long iSetCap ) : 137 Array( long iSetCap )
50 pData( NULL ),
51 iSize( 0 ),
52 iCapacity( 0 )
53 { 138 {
54 setCapacity( iSetCap ); 139 setCapacity( iSetCap );
55 } 140 }
56 141
57 ~Array() 142 ~Array()
58 { 143 {
59 clear();
60 } 144 }
61 145
62 MyType &operator=( const MyType &src ) 146 bool operator==( const MyType &src ) const
63 { 147 {
64 clear(); 148 if( core == src.core )
65 setCapacity( src.iCapacity ); 149 return true;
150 if( core->iSize != src.core->iSize )
151 return false;
66 152
67 long iTop = src.getSize(); 153 for( int j = 0; j < core->iSize; j++ )
68 for( long i = 0; i < iTop; ++i )
69 { 154 {
70 append( src[i] ); 155 if( core->pData[j] != src.core->pData[j] )
156 return false;
71 } 157 }
72 return *this; 158 return true;
159 }
160
161 bool operator!=( const MyType &src ) const
162 {
163 return !(*this == src);
73 } 164 }
74 165
75 /** 166 /**
@@ -77,46 +168,61 @@ namespace Bu
77 */ 168 */
78 void clear() 169 void clear()
79 { 170 {
80 if( pData ) 171 _hardCopy();
81 { 172 core->clear();
82 for( int j = 0; j < iSize; j++ )
83 {
84 va.destroy( &pData[j] );
85 }
86 va.deallocate( pData, iCapacity );
87 pData = NULL;
88 }
89 iSize = 0;
90 iCapacity = 0;
91 } 173 }
92 174
93 void append( const value &rVal ) 175 void append( const value &rVal )
94 { 176 {
95 if( iSize == iCapacity ) 177 _hardCopy();
178 if( core->iSize == core->iCapacity )
96 { 179 {
97 setCapacity( iCapacity + inc ); 180 core->setCapacity( core->iCapacity + inc );
98 } 181 }
99 182
100 va.construct( &pData[iSize++], rVal ); 183 core->va.construct( &core->pData[core->iSize++], rVal );
101 } 184 }
102 185
103 //operator 186 //operator
104 value &operator[]( long iIndex ) 187 value &operator[]( long iIndex )
105 { 188 {
106 if( iIndex < 0 || iIndex >= iSize ) 189 _hardCopy();
190 if( iIndex < 0 || iIndex >= core->iSize )
107 throw ArrayException( 191 throw ArrayException(
108 "Index %d out of range 0:%d", iIndex, iSize ); 192 "Index %d out of range 0:%d", iIndex, core->iSize );
109 193
110 return pData[iIndex]; 194 return core->pData[iIndex];
111 } 195 }
112 196
113 const value &operator[]( long iIndex ) const 197 const value &operator[]( long iIndex ) const
114 { 198 {
115 if( iIndex < 0 || iIndex >= iSize ) 199 if( iIndex < 0 || iIndex >= core->iSize )
116 throw ArrayException( 200 throw ArrayException(
117 "Index %d out of range 0:%d", iIndex, iSize ); 201 "Index %d out of range 0:%d", iIndex, core->iSize );
202
203 return core->pData[iIndex];
204 }
205
206 value &first()
207 {
208 _hardCopy();
209 return core->pData[0];
210 }
211
212 const value &first() const
213 {
214 return core->pData[0];
215 }
216
217 value &last()
218 {
219 _hardCopy();
220 return core->pData[core->iSize-1];
221 }
118 222
119 return pData[iIndex]; 223 const value &last() const
224 {
225 return core->pData[core->iSize-1];
120 } 226 }
121 227
122 /** 228 /**
@@ -125,7 +231,7 @@ namespace Bu
125 */ 231 */
126 long getSize() const 232 long getSize() const
127 { 233 {
128 return iSize; 234 return core->iSize;
129 } 235 }
130 236
131 /** 237 /**
@@ -136,7 +242,7 @@ namespace Bu
136 */ 242 */
137 long getCapacity() const 243 long getCapacity() const
138 { 244 {
139 return iCapacity; 245 return core->iCapacity;
140 } 246 }
141 247
142 /** 248 /**
@@ -149,19 +255,8 @@ namespace Bu
149 */ 255 */
150 void setCapacity( long iNewLen ) 256 void setCapacity( long iNewLen )
151 { 257 {
152 if( iNewLen <= iCapacity ) return; 258 _hardCopy();
153 value *pNewData = va.allocate( iNewLen ); 259 core->setCapacity( iNewLen );
154 if( pData )
155 {
156 for( int j = 0; j < iSize; j++ )
157 {
158 va.construct( &pNewData[j], pData[j] );
159 va.destroy( &pData[j] );
160 }
161 va.deallocate( pData, iCapacity );
162 }
163 pData = pNewData;
164 iCapacity = iNewLen;
165 } 260 }
166 261
167 typedef struct iterator 262 typedef struct iterator
@@ -387,16 +482,8 @@ namespace Bu
387 */ 482 */
388 void erase( iterator i ) 483 void erase( iterator i )
389 { 484 {
390 for( int j = i.iPos; j < iSize; j++ ) 485 _hardCopy();
391 { 486 core->erase( i.iPos );
392 va.destroy( &pData[j] );
393 if( j == iSize-1 )
394 {
395 iSize--;
396 return;
397 }
398 va.construct( &pData[j], pData[j+1] );
399 }
400 } 487 }
401 488
402 /** 489 /**
@@ -408,22 +495,24 @@ namespace Bu
408 */ 495 */
409 void swapErase( iterator i ) 496 void swapErase( iterator i )
410 { 497 {
411 if( i.iPos == iSize-1 ) 498 _hardCopy();
412 { 499 swapErase( i.iPos );
413 erase( i ); 500 }
414 return; 501
502 protected:
503 virtual Core *_copyCore( Core *src )
504 {
505 Core *pRet = _allocateCore();
506 pRet->setCapacity( src->iCapacity );
507 pRet->iSize = src->iSize;
508 for( int j = 0; j < src->iSize; j++ )
509 {
510 pRet->va.construct( &pRet->pData[j], src->pData[j] );
415 } 511 }
416 va.destroy( &pData[i.iPos] ); 512 return pRet;
417 va.construct( &pData[i.iPos], pData[iSize-1] );
418 va.destroy( &pData[iSize-1] );
419 iSize--;
420 } 513 }
421 514
422 private: 515 private:
423 valuealloc va;
424 value *pData;
425 long iSize;
426 long iCapacity;
427 }; 516 };
428 517
429 class Formatter; 518 class Formatter;