00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #ifndef _tlist_h
00018 #define _tlist_h
00019
00020 #include <spl/types.h>
00021 #include <spl/Debug.h>
00022
00023 #include <spl/collection/Array.h>
00024 #include <spl/Compare.h>
00025 #include <spl/Exception.h>
00026 #include <spl/collection/IEnumerable.h>
00027 #include <spl/IIterator.h>
00028 #include <spl/math/Math.h>
00029 #include <spl/Memory.h>
00030 #include <spl/RefCountPtr.h>
00031
00037 template<typename T>
00038 class _listnode
00039 {
00040 public:
00041 _listnode *next;
00042 _listnode *prev;
00043 T data;
00044 };
00045
00047 template<typename T>
00048 class List : public IEnumerable<T>
00049 {
00050 private:
00051 inline void _Init()
00052 {
00053 m_head.data = T();
00054 m_head.next = &m_tail;
00055 m_head.prev = NULL;
00056 m_tail.data = T();
00057 m_tail.next = NULL;
00058 m_tail.prev = &m_head;
00059 m_count = 0;
00060 }
00061
00062 protected:
00063 _listnode<T> m_head;
00064 _listnode<T> m_tail;
00065 int m_count;
00066
00067 public:
00069 class Iterator : public IIterator<T>
00070 {
00071 friend class List<T>;
00072
00073 private:
00074 _listnode<T> *m_current;
00075
00076 public:
00077 Iterator()
00078 : m_current(NULL)
00079 {
00080 }
00081
00082 Iterator(_listnode<T> *head)
00083 : m_current(head)
00084 {
00085 }
00086
00087 Iterator(const Iterator& li)
00088 : m_current(li.m_current)
00089 {
00090 }
00091
00092 virtual bool Next( )
00093 {
00094 if (NULL == m_current || NULL == m_current->next)
00095 {
00096
00097 return false;
00098 }
00099 m_current = m_current->next;
00100 if (NULL == m_current->next)
00101 {
00102
00103 return false;
00104 }
00105
00106 ASSERT_MEM( m_current, sizeof( _listnode<T> ) );
00107 return true;
00108 }
00109
00110 virtual bool Prev( )
00111 {
00112 if (NULL == m_current || NULL == m_current->prev)
00113 {
00114
00115 return false;
00116 }
00117 m_current = m_current->prev;
00118 if (NULL == m_current->prev)
00119 {
00120
00121 return false;
00122 }
00123 return true;
00124 }
00125
00126 virtual T Current()
00127 {
00128 ASSERT_MEM( m_current, sizeof( _listnode<T> ) );
00129 return m_current->data;
00130 }
00131
00132 virtual T& CurrentRef()
00133 {
00134 ASSERT_MEM( m_current, sizeof( _listnode<T> ) );
00135 return m_current->data;
00136 }
00137 };
00138
00139 List()
00140 {
00141 _Init();
00142 }
00143
00144 List( const List<T>& list )
00145 {
00146 _Init();
00147
00148 _listnode<T> *node = list.m_head.next;
00149 while ( node != &list.m_tail )
00150 {
00151 ASSERT_MEM( node, sizeof( _listnode<T> ) );
00152 Add( node->data );
00153 node = node->next;
00154 }
00155 }
00156
00157 ~List()
00158 {
00159 Clear();
00160 }
00161
00162 List<T>& operator =( const List<T>& list )
00163 {
00164 Clear();
00165
00166 _listnode<T> *node = list.m_head.next;
00167 while ( node != &list.m_tail )
00168 {
00169 Add( node->data );
00170 node = node->next;
00171 }
00172 return *this;
00173 }
00174
00175 bool IsEmpty( ) const
00176 {
00177 return m_head.next == &m_tail;
00178 }
00179
00180 void Clear( )
00181 {
00182 _listnode<T> *np;
00183 _listnode<T> *npnext;
00184
00185 np = m_head.next;
00186
00187 while ( np != &m_tail )
00188 {
00189 ASSERT_MEM( np, sizeof( _listnode<T> ) );
00190 npnext = np->next;
00191 delete np;
00192 np = npnext;
00193 }
00194 m_head.next = &m_tail;
00195 m_count = 0;
00196 ASSERT( IsEmpty( ) );
00197 }
00198
00199 void Add( T data )
00200 {
00201 _listnode<T> *np;
00202 np = new _listnode<T>();
00203 np->data = data;
00204 np->next = m_head.next;
00205 np->prev = &m_head;
00206 m_head.next->prev = np;
00207 m_head.next = np;
00208 m_count++;
00209 }
00210
00211 inline Iterator Begin()
00212 {
00213 return Iterator(&m_head);
00214 }
00215
00216 T& ElementAt( const int index ) const
00217 {
00218 int count = 0;
00219 _listnode<T> *np;
00220
00221 np = m_head.next;
00222 while ( np != &m_tail && count < index )
00223 {
00224 np = np->next;
00225 count++;
00226 }
00227 if ( np == &m_tail )
00228 {
00229 throw IndexOutOfBoundsException();
00230 }
00231 return np->data;
00232 }
00233
00234 inline T& operator[] (const int idx) const
00235 {
00236 return ElementAt(idx);
00237 }
00238
00239 void RemoveCurrent( Iterator& iter )
00240 {
00241 _listnode<T> *newcur = iter.m_current->prev;
00242 ASSERT( iter.m_current != &m_head && iter.m_current != &m_tail && iter.m_current != NULL );
00243 iter.m_current->prev->next = iter.m_current->next;
00244 iter.m_current->next->prev = iter.m_current->prev;
00245 ASSERT_MEM( iter.m_current, sizeof( _listnode<T> ) );
00246 delete iter.m_current;
00247 iter.m_current = newcur;
00248 m_count--;
00249 }
00250
00251 T Pop()
00252 {
00253 _listnode<T> *cur = m_head.next;
00254 ASSERT( cur != &m_tail );
00255 m_head.next = cur->next;
00256 cur->next->prev = &m_head;
00257 T data = cur->data;
00258 m_count--;
00259 delete cur;
00260 return data;
00261 }
00262
00263 T Peek() const
00264 {
00265 _listnode<T> *cur = m_head.next;
00266 if( cur == &m_tail )
00267 {
00268 return NULL;
00269 }
00270 return cur->data;
00271 }
00272
00273 T& PeekRef() const
00274 {
00275 _listnode<T> *cur = m_head.next;
00276 if( cur == &m_tail )
00277 {
00278 return T();
00279 }
00280 return cur->data;
00281 }
00282
00283 T Tail() const
00284 {
00285 _listnode<T> *cur = m_tail.prev;
00286 if( cur == &m_head )
00287 {
00288 return T();
00289 }
00290 return cur->data;
00291 }
00292
00293 T& TailRef() const
00294 {
00295 _listnode<T> *cur = m_tail.prev;
00296 if( cur == &m_head )
00297 {
00298 return T();
00299 }
00300 return cur->data;
00301 }
00302
00303 void RemoveTail( )
00304 {
00305 _listnode<T> *cur = m_tail.prev;
00306 ASSERT( cur != &m_head && cur != &m_tail && cur != NULL );
00307 cur->prev->next = cur->next;
00308 cur->next->prev = cur->prev;
00309 ASSERT_MEM( cur, sizeof( _listnode<T> ) );
00310 delete cur;
00311 m_count--;
00312 }
00313
00314 void Remove( const T& data )
00315 {
00316 int count = 0;
00317 _listnode<T> *np;
00318
00319 np = m_head.next;
00320 while ( np != &m_tail )
00321 {
00322 if ( Compare::Equals(data, np->data) )
00323 {
00324 np->prev->next = np->next;
00325 np->next->prev = np->prev;
00326 ASSERT_MEM( np, sizeof( _listnode<T> ) );
00327 delete np;
00328 m_count--;
00329 return;
00330 }
00331 np = np->next;
00332 count++;
00333 }
00334 }
00335
00336 inline int Count( ) const
00337 {
00338 return m_count;
00339 }
00340
00341 RefCountPtr<Array<T> > ToArray() const
00342 {
00343 RefCountPtr<Array<T> > ap(new Array<T>(m_count));
00344
00345 Iterator iter = Begin();
00346 int pos = 0;
00347 while (iter.Next())
00348 {
00349 ap->SetElementAt(pos++, iter.Current());
00350 }
00351 return ap;
00352 }
00353
00354 #ifdef DEBUG
00355 void ValidateMem() const
00356 {
00357 _listnode<T> *np = m_head.next;
00358 while ( np != &m_tail )
00359 {
00360 ASSERT_MEM( np, sizeof(_listnode<T>) );
00361 ValidateType( np->data );
00362 np = np->next;
00363 }
00364 ValidateType(m_head.data);
00365 ValidateType(m_tail.data);
00366 }
00367
00368 void CheckMem() const
00369 {
00370 _listnode<T> *np = m_head.next;
00371 while ( np != &m_tail )
00372 {
00373 DEBUG_NOTE_MEM_ALLOCATION( np );
00374 ValidateType( np->data );
00375 np = np->next;
00376 }
00377 ValidateType(m_head.data);
00378 ValidateType(m_tail.data);
00379 }
00380 #else
00381 inline void ValidateMem() const {}
00382 inline void CheckMem() const {}
00383 #endif
00384
00385 protected:
00386 virtual RefCountPtr<IIterator<T> > IteratorPtr()
00387 {
00388 return RefCountPtr<IIterator<T> >(new Iterator(&m_head));
00389 }
00390 };
00391
00392 REGISTER_TYPEOF( 300, List<char> );
00393 REGISTER_TYPEOF( 301, List<byte> );
00394 REGISTER_TYPEOF( 302, List<int16> );
00395 REGISTER_TYPEOF( 303, List<uint16> );
00396 REGISTER_TYPEOF( 304, List<int32> );
00397 REGISTER_TYPEOF( 305, List<uint32> );
00398 REGISTER_TYPEOF( 306, List<int64> );
00399 REGISTER_TYPEOF( 307, List<uint64> );
00400 REGISTER_TYPEOF( 308, List<float32> );
00401 REGISTER_TYPEOF( 309, List<float64> );
00402
00403 REGISTER_TYPEOF( 310, List<BigInteger> );
00404 REGISTER_TYPEOF( 311, List<Char> );
00405 REGISTER_TYPEOF( 312, List<Date> );
00406 REGISTER_TYPEOF( 313, List<DateTime> );
00407 REGISTER_TYPEOF( 314, List<Decimal> );
00408 REGISTER_TYPEOF( 315, List<Double> );
00409 REGISTER_TYPEOF( 316, List<Int32> );
00410 REGISTER_TYPEOF( 317, List<Int64> );
00411 REGISTER_TYPEOF( 318, List<Null> );
00412 REGISTER_TYPEOF( 319, List<String> );
00413 REGISTER_TYPEOF( 320, List<StringPtr> );
00414 REGISTER_TYPEOF( 321, List<UInt32> );
00415 REGISTER_TYPEOF( 322, List<UInt64> );
00416 REGISTER_TYPEOF( 323, List<Undefined> );
00417
00420 #endif