diff options
Diffstat (limited to '')
-rw-r--r-- | src/array.h | 245 |
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 | ||
15 | namespace Bu | 16 | namespace 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; |