diff options
Diffstat (limited to 'src/list.h')
-rw-r--r-- | src/list.h | 214 |
1 files changed, 195 insertions, 19 deletions
@@ -13,6 +13,15 @@ namespace Bu | |||
13 | ListLink *pNext; | 13 | ListLink *pNext; |
14 | ListLink *pPrev; | 14 | ListLink *pPrev; |
15 | }; | 15 | }; |
16 | |||
17 | /** | ||
18 | * Linked list template container. This class is similar to the stl list | ||
19 | * class except for a few minor changes. First, it doesn't mimic a stack or | ||
20 | * queue, use the Stack or Queue clasess for that. Second, when const, all | ||
21 | * members are only accessable const. Third, erasing a location does not | ||
22 | * invalidate the iterator, it simply points to the next valid location, or | ||
23 | * end() if there are no more. | ||
24 | */ | ||
16 | template<typename value, typename valuealloc=std::allocator<value>, typename linkalloc=std::allocator<struct ListLink<value> > > | 25 | template<typename value, typename valuealloc=std::allocator<value>, typename linkalloc=std::allocator<struct ListLink<value> > > |
17 | class List | 26 | class List |
18 | { | 27 | { |
@@ -23,15 +32,59 @@ namespace Bu | |||
23 | public: | 32 | public: |
24 | List() : | 33 | List() : |
25 | pFirst( NULL ), | 34 | pFirst( NULL ), |
26 | pLast( NULL ) | 35 | pLast( NULL ), |
36 | nSize( 0 ) | ||
37 | { | ||
38 | } | ||
39 | |||
40 | List( const MyType &src ) : | ||
41 | pFirst( NULL ), | ||
42 | pLast( NULL ), | ||
43 | nSize( 0 ) | ||
44 | { | ||
45 | for( Link *pCur = src.pFirst; pCur; pCur = pCur->pNext ) | ||
46 | { | ||
47 | append( *pCur->pValue ); | ||
48 | } | ||
49 | } | ||
50 | |||
51 | ~List() | ||
52 | { | ||
53 | clear(); | ||
54 | } | ||
55 | |||
56 | MyType &operator=( const MyType &src ) | ||
27 | { | 57 | { |
58 | clear(); | ||
59 | for( Link *pCur = src.pFirst; pCur; pCur = pCur->pNext ) | ||
60 | { | ||
61 | append( *pCur->pValue ); | ||
62 | } | ||
63 | } | ||
64 | |||
65 | void clear() | ||
66 | { | ||
67 | Link *pCur = pFirst; | ||
68 | for(;;) | ||
69 | { | ||
70 | if( pCur == NULL ) break; | ||
71 | va.destroy( pCur->pValue ); | ||
72 | va.deallocate( pCur->pValue, sizeof( value ) ); | ||
73 | Link *pTmp = pCur->pNext; | ||
74 | la.destroy( pCur ); | ||
75 | la.deallocate( pCur, sizeof( Link ) ); | ||
76 | pCur = pTmp; | ||
77 | } | ||
78 | pFirst = pLast = NULL; | ||
79 | nSize = 0; | ||
28 | } | 80 | } |
29 | 81 | ||
30 | void append( value v ) | 82 | void append( const value &v ) |
31 | { | 83 | { |
32 | Link *pNew = la.allocate( sizeof( Link ) ); | 84 | Link *pNew = la.allocate( sizeof( Link ) ); |
33 | pNew->pValue = va.allocate( sizeof( value ) ); | 85 | pNew->pValue = va.allocate( sizeof( value ) ); |
34 | va.construct( pNew->pValue, v ); | 86 | va.construct( pNew->pValue, v ); |
87 | nSize++; | ||
35 | if( pFirst == NULL ) | 88 | if( pFirst == NULL ) |
36 | { | 89 | { |
37 | // Empty list | 90 | // Empty list |
@@ -47,11 +100,12 @@ namespace Bu | |||
47 | } | 100 | } |
48 | } | 101 | } |
49 | 102 | ||
50 | void prepend( value v ) | 103 | void prepend( const value &v ) |
51 | { | 104 | { |
52 | Link *pNew = la.allocate( sizeof( Link ) ); | 105 | Link *pNew = la.allocate( sizeof( Link ) ); |
53 | pNew->pValue = va.allocate( sizeof( value ) ); | 106 | pNew->pValue = va.allocate( sizeof( value ) ); |
54 | va.construct( pNew->pValue, v ); | 107 | va.construct( pNew->pValue, v ); |
108 | nSize++; | ||
55 | if( pFirst == NULL ) | 109 | if( pFirst == NULL ) |
56 | { | 110 | { |
57 | // Empty list | 111 | // Empty list |
@@ -83,22 +137,22 @@ namespace Bu | |||
83 | } | 137 | } |
84 | 138 | ||
85 | public: | 139 | public: |
86 | bool operator==( const iterator &oth ) | 140 | bool operator==( const iterator &oth ) const |
87 | { | 141 | { |
88 | return ( pLink == oth.pLink ); | 142 | return ( pLink == oth.pLink ); |
89 | } | 143 | } |
90 | 144 | ||
91 | bool operator==( const Link *pOth ) | 145 | bool operator==( const Link *pOth ) const |
92 | { | 146 | { |
93 | return ( pLink == pOth ); | 147 | return ( pLink == pOth ); |
94 | } | 148 | } |
95 | 149 | ||
96 | bool operator!=( const iterator &oth ) | 150 | bool operator!=( const iterator &oth ) const |
97 | { | 151 | { |
98 | return ( pLink != oth.pLink ); | 152 | return ( pLink != oth.pLink ); |
99 | } | 153 | } |
100 | 154 | ||
101 | bool operator!=( const Link *pOth ) | 155 | bool operator!=( const Link *pOth ) const |
102 | { | 156 | { |
103 | return ( pLink != pOth ); | 157 | return ( pLink != pOth ); |
104 | } | 158 | } |
@@ -110,40 +164,128 @@ namespace Bu | |||
110 | 164 | ||
111 | value *operator->() | 165 | value *operator->() |
112 | { | 166 | { |
113 | return pLink->pValue(); | 167 | return pLink->pValue; |
114 | } | 168 | } |
115 | 169 | ||
116 | iterator operator++() | 170 | iterator &operator++() |
117 | { | 171 | { |
118 | if( pLink != NULL ) | 172 | if( pLink != NULL ) |
119 | pLink = pLink->pNext; | 173 | pLink = pLink->pNext; |
120 | return *this; | 174 | return *this; |
121 | } | 175 | } |
122 | 176 | ||
123 | iterator operator--() | 177 | iterator &operator--() |
124 | { | 178 | { |
125 | if( pLink != NULL ) | 179 | if( pLink != NULL ) |
126 | pLink = pLink->pPrev; | 180 | pLink = pLink->pPrev; |
127 | return *this; | 181 | return *this; |
128 | } | 182 | } |
129 | 183 | ||
130 | iterator operator++( int ) | 184 | iterator &operator++( int ) |
131 | { | 185 | { |
132 | if( pLink != NULL ) | 186 | if( pLink != NULL ) |
133 | pLink = pLink->pNext; | 187 | pLink = pLink->pNext; |
134 | return *this; | 188 | return *this; |
135 | } | 189 | } |
136 | 190 | ||
137 | iterator operator--( int ) | 191 | iterator &operator--( int ) |
138 | { | 192 | { |
139 | if( pLink != NULL ) | 193 | if( pLink != NULL ) |
140 | pLink = pLink->pPrev; | 194 | pLink = pLink->pPrev; |
141 | return *this; | 195 | return *this; |
142 | } | 196 | } |
143 | 197 | ||
144 | iterator operator=( const iterator &oth ) | 198 | iterator &operator=( const iterator &oth ) |
145 | { | 199 | { |
146 | pLink = oth.pLink; | 200 | pLink = oth.pLink; |
201 | return *this; | ||
202 | } | ||
203 | }; | ||
204 | |||
205 | typedef struct const_iterator | ||
206 | { | ||
207 | friend class List<value, valuealloc, linkalloc>; | ||
208 | private: | ||
209 | Link *pLink; | ||
210 | const_iterator() : | ||
211 | pLink( NULL ) | ||
212 | { | ||
213 | } | ||
214 | |||
215 | const_iterator( Link *pLink ) : | ||
216 | pLink( pLink ) | ||
217 | { | ||
218 | } | ||
219 | |||
220 | public: | ||
221 | bool operator==( const const_iterator &oth ) const | ||
222 | { | ||
223 | return ( pLink == oth.pLink ); | ||
224 | } | ||
225 | |||
226 | bool operator==( const Link *pOth ) const | ||
227 | { | ||
228 | return ( pLink == pOth ); | ||
229 | } | ||
230 | |||
231 | bool operator!=( const const_iterator &oth ) const | ||
232 | { | ||
233 | return ( pLink != oth.pLink ); | ||
234 | } | ||
235 | |||
236 | bool operator!=( const Link *pOth ) const | ||
237 | { | ||
238 | return ( pLink != pOth ); | ||
239 | } | ||
240 | |||
241 | const value &operator*() | ||
242 | { | ||
243 | return *(pLink->pValue); | ||
244 | } | ||
245 | |||
246 | const value *operator->() | ||
247 | { | ||
248 | return pLink->pValue; | ||
249 | } | ||
250 | |||
251 | const_iterator &operator++() | ||
252 | { | ||
253 | if( pLink != NULL ) | ||
254 | pLink = pLink->pNext; | ||
255 | return *this; | ||
256 | } | ||
257 | |||
258 | const_iterator &operator--() | ||
259 | { | ||
260 | if( pLink != NULL ) | ||
261 | pLink = pLink->pPrev; | ||
262 | return *this; | ||
263 | } | ||
264 | |||
265 | const_iterator &operator++( int ) | ||
266 | { | ||
267 | if( pLink != NULL ) | ||
268 | pLink = pLink->pNext; | ||
269 | return *this; | ||
270 | } | ||
271 | |||
272 | const_iterator &operator--( int ) | ||
273 | { | ||
274 | if( pLink != NULL ) | ||
275 | pLink = pLink->pPrev; | ||
276 | return *this; | ||
277 | } | ||
278 | |||
279 | const_iterator &operator=( const iterator &oth ) | ||
280 | { | ||
281 | pLink = oth.pLink; | ||
282 | return *this; | ||
283 | } | ||
284 | |||
285 | const_iterator &operator=( const const_iterator &oth ) | ||
286 | { | ||
287 | pLink = oth.pLink; | ||
288 | return *this; | ||
147 | } | 289 | } |
148 | }; | 290 | }; |
149 | 291 | ||
@@ -152,17 +294,50 @@ namespace Bu | |||
152 | return iterator( pFirst ); | 294 | return iterator( pFirst ); |
153 | } | 295 | } |
154 | 296 | ||
155 | const Link *end() | 297 | const const_iterator begin() const |
298 | { | ||
299 | return const_iterator( pFirst ); | ||
300 | } | ||
301 | |||
302 | const Link *end() const | ||
156 | { | 303 | { |
157 | return NULL; | 304 | return NULL; |
158 | } | 305 | } |
159 | 306 | ||
160 | int getSize() | 307 | void erase( iterator &i ) |
308 | { | ||
309 | Link *pCur = i.pLink; | ||
310 | Link *pPrev = pCur->pPrev; | ||
311 | if( pPrev == NULL ) | ||
312 | { | ||
313 | va.destroy( pCur->pValue ); | ||
314 | va.deallocate( pCur->pValue, sizeof( value ) ); | ||
315 | pFirst = pCur->pNext; | ||
316 | la.destroy( pCur ); | ||
317 | la.deallocate( pCur, sizeof( Link ) ); | ||
318 | if( pFirst == NULL ) | ||
319 | pLast = NULL; | ||
320 | nSize--; | ||
321 | i.pLink = pFirst; | ||
322 | } | ||
323 | else | ||
324 | { | ||
325 | va.destroy( pCur->pValue ); | ||
326 | va.deallocate( pCur->pValue, sizeof( value ) ); | ||
327 | Link *pTmp = pCur->pNext; | ||
328 | la.destroy( pCur ); | ||
329 | la.deallocate( pCur, sizeof( Link ) ); | ||
330 | pPrev->pNext = pTmp; | ||
331 | if( pTmp != NULL ) | ||
332 | pTmp->pPrev = pPrev; | ||
333 | nSize--; | ||
334 | i.pLink = pTmp; | ||
335 | } | ||
336 | } | ||
337 | |||
338 | int getSize() const | ||
161 | { | 339 | { |
162 | int j = 0; | 340 | return nSize; |
163 | for( Link *pCur = pFirst; pCur; pCur = pCur->pNext ) | ||
164 | j++; | ||
165 | return j; | ||
166 | } | 341 | } |
167 | 342 | ||
168 | private: | 343 | private: |
@@ -170,6 +345,7 @@ namespace Bu | |||
170 | Link *pLast; | 345 | Link *pLast; |
171 | linkalloc la; | 346 | linkalloc la; |
172 | valuealloc va; | 347 | valuealloc va; |
348 | int nSize; | ||
173 | }; | 349 | }; |
174 | } | 350 | } |
175 | 351 | ||