00001 #ifndef MERCURYVECTOR_H
00002 #define MERCURYVECTOR_H
00003
00004 #include "global.h"
00005 #include <malloc.h>
00006 #include <string.h>
00007
00008
00009 template<typename T>
00010 class MVector
00011 {
00012 public:
00013 MVector()
00014 :m_reserved(0), m_size(0), m_data(0)
00015 { }
00016 ~MVector()
00017 {
00018 clear();
00019 }
00020 MVector(const MVector<T>& v)
00021 :m_reserved(v.m_reserved), m_size(v.m_size)
00022 {
00023 m_data = (T*)malloc(sizeof(T)*m_reserved);
00024 for (unsigned int i = 0; i < m_size; ++i)
00025 {
00026 new( &m_data[i] ) T (v.m_data[i]);
00027 #if defined( _DEBUG_MEMORY )
00028 MercuryAFree( &m_data[i] );
00029 #endif
00030 }
00031 }
00032 void push_back(const T& element);
00033 inline unsigned int size() const { return m_size; }
00034 inline bool empty() const { return m_size == 0; }
00035 void resize(unsigned int newSize);
00036 void reserve(unsigned int newSize);
00037 inline T& operator[](unsigned int x) { return m_data[x]; }
00038 inline const T& operator[](unsigned int x) const { return m_data[x]; }
00039 inline T& at( unsigned int x ) { return m_data[x]; }
00040 inline const T& at( unsigned int x ) const { return m_data[x]; }
00041 const MVector<T>& operator=(const MVector<T>& v);
00042 void clear();
00043 void remove( int iPlace );
00044 void insert( int iPlace, const T & data );
00045 private:
00046 unsigned int m_reserved;
00047 unsigned int m_size;
00048 T * m_data;
00049 };
00050
00051 #include "MercuryUtil.h"
00052
00053 template<typename T>
00054 void MVector<T>::push_back(const T& element)
00055 {
00056 if (m_size >= m_reserved)
00057 {
00058 if (m_reserved <= 0)
00059 {
00060 SAFE_FREE( m_data );
00061 m_data = (T*)malloc(sizeof(T));
00062 m_reserved = 1;
00063 }
00064 else
00065 {
00066 int tsize = nextPow2(m_reserved);
00067 int size = m_size;
00068 reserve(tsize);
00069 m_size = size;
00070 }
00071 }
00072
00073 new( &m_data[m_size] ) T ( element );
00074 #if defined( _DEBUG_MEMORY )
00075 MercuryAFree( &m_data[m_size] );
00076 #endif
00077
00078 ++m_size;
00079 }
00080
00081 template<typename T>
00082 void MVector<T>::resize(unsigned int newSize)
00083 {
00084 if (newSize == 0)
00085 {
00086 clear();
00087 return;
00088 }
00089
00090
00091 if (newSize == m_size)
00092 {
00093 return;
00094 }
00095 else if(newSize > m_size)
00096 {
00097 if (newSize > m_reserved)
00098 {
00099 m_reserved = newSize;
00100 m_data = (T*)realloc(m_data, sizeof(T)*m_reserved);
00101 }
00102
00103 for (unsigned int i = m_size; i < newSize; ++i)
00104 {
00105 new (&m_data[i]) (T);
00106 #if defined( _DEBUG_MEMORY )
00107 MercuryAFree( &m_data[i] );
00108 #endif
00109
00110 }
00111 }
00112 else
00113 {
00114
00115 m_reserved = newSize;
00116
00117
00118 for (unsigned int i = m_reserved; i < m_size; ++i)
00119 (&m_data[i])->~T();
00120
00121 m_data = (T*)realloc(m_data, sizeof(T)*m_reserved);
00122 }
00123 m_size = newSize;
00124 }
00125
00126 template<typename T>
00127 void MVector<T>::reserve(unsigned int newSize)
00128 {
00129 if (newSize == 0)
00130 {
00131 clear();
00132 return;
00133 }
00134 if (newSize == m_reserved)
00135 {
00136 return;
00137 }
00138 else if (newSize > m_reserved)
00139 {
00140 m_reserved = newSize;
00141 m_data = (T*)realloc(m_data, sizeof(T)*m_reserved);
00142 }
00143 else
00144 {
00145 m_reserved = newSize;
00146
00147
00148 for (unsigned int i = m_reserved; i < m_size; ++i)
00149 (&m_data[i])->~T();
00150
00151 m_data = (T*)realloc(m_data, sizeof(T)*m_reserved);
00152 m_size = newSize;
00153 }
00154 }
00155
00156 template<typename T>
00157 void MVector<T>::remove( int iPlace )
00158 {
00159 m_size--;
00160 (&m_data[iPlace])->~T();
00161 memcpy( &m_data[iPlace], &m_data[iPlace+1], sizeof(T) * ( m_size - iPlace ) );
00162 }
00163
00164 #include <stdio.h>
00165 template<typename T>
00166 void MVector<T>::insert( int iPlace, const T & data )
00167 {
00168 int i;
00169 resize( m_size + 1 );
00170
00171 (&m_data[m_size-1])->~T();
00172 for( i = m_size - 1; i > iPlace; i-- )
00173 memcpy( &m_data[i], &m_data[i-1], sizeof (T) );
00174
00175 new ( &m_data[iPlace] ) T( data );
00176 #if defined( _DEBUG_MEMORY )
00177 MercuryAFree( &m_data[iPlace] );
00178 #endif
00179
00180 }
00181
00182 template<typename T>
00183 void MVector<T>::clear()
00184 {
00185 for (unsigned int i = 0; i < m_size; ++i)
00186 (&m_data[i])->~T();
00187
00188 SAFE_FREE(m_data);
00189 m_size = m_reserved = 0;
00190 }
00191 template<typename T>
00192 const MVector<T>& MVector<T>::operator=(const MVector<T>& v)
00193 {
00194 clear();
00195 m_reserved = v.m_reserved;
00196 m_size = v.m_size;
00197 m_data = (T*)malloc(sizeof(T)*m_reserved);
00198 for (unsigned int i = 0; i < m_size; ++i)
00199 {
00200 new( &m_data[i]) T( v.m_data[i] );
00201 #if defined( _DEBUG_MEMORY )
00202 MercuryAFree( &m_data[i] );
00203 #endif
00204 }
00205 return *this;
00206 }
00207
00208
00209 template<typename T>
00210 class MDequeNode
00211 {
00212 public:
00213 MDequeNode(): Next(0),Prev(0) { }
00214 MDequeNode( const T & tIn ): Data(tIn), Next(0), Prev(0) { }
00215 T Data;
00216 MDequeNode<T> * Next;
00217 MDequeNode<T> * Prev;
00218 };
00219
00221 template<typename T>
00222 class MDequeIterator
00223 {
00224 public:
00225 MDequeIterator() : ThisNode( 0 ) { }
00226 ~MDequeIterator() { ThisNode = 0; }
00227
00229 inline T & Data() { return ThisNode->Data; }
00231 inline T * operator -> () { return &ThisNode->Data; }
00233 inline T & operator * () { return ThisNode->Data; }
00234
00236 inline MDequeIterator<T> & operator ++ () { if( ThisNode ) ThisNode = ThisNode->Next; return *this; }
00238 inline MDequeIterator<T> & operator -- () { if( ThisNode ) ThisNode = ThisNode->Prev; return *this; }
00239
00240
00241 inline MDequeIterator<T> operator ++ ( int dummy ) { MDequeNode< T > * pS = ThisNode; ThisNode = ThisNode->Next; return MDequeIterator( pS ); }
00242
00243 inline MDequeIterator<T> operator -- ( int dummy ) { MDequeNode< T > * pS = ThisNode; ThisNode = ThisNode->Prev; return MDequeIterator( pS); }
00244
00245 inline bool operator == ( const MDequeIterator & rhs ) { return (ThisNode == rhs.ThisNode ); }
00246 inline bool operator != ( const MDequeIterator & rhs ) { return (ThisNode != rhs.ThisNode ); }
00247
00248
00249 MDequeIterator( MDequeNode<T> * pBootNode ) { ThisNode = pBootNode; }
00250 MDequeNode<T> * ThisNode;
00251 };
00252
00253
00254 template<typename T>
00255
00256 class MDeque
00257 {
00258 public:
00259 MDeque() : iSize(0), Head(0), Tail(0){ }
00260 ~MDeque() { while( Head ) { Temp = Head; Head=Head->Next; delete Temp; } }
00261
00262 MDeque( const MDeque & rhs ) : iSize(0), Head(0), Tail(0)
00263 {
00264 MDequeIterator< T > t = rhs.begin();
00265 while( t != rhs.end() )
00266 {
00267 push_back( *t );
00268 ++t;
00269 }
00270 }
00271
00272 MDeque & operator = ( const MDeque & rhs )
00273 {
00274 MDequeIterator< T > t = rhs.begin();
00275 while( t != rhs.end() )
00276 {
00277 push_back( *t );
00278 ++t;
00279 }
00280 return *this;
00281 }
00282
00284 inline void swap( MDequeIterator<T> & p1, MDequeIterator<T> & p2 ) {
00285
00286 if( p1.ThisNode->Next == p2.ThisNode )
00287 {
00288 p2.ThisNode->Prev = p1.ThisNode->Prev;
00289 p1.ThisNode->Prev = p2.ThisNode;
00290 p1.ThisNode->Next = p2.ThisNode->Next;
00291 p2.ThisNode->Next = p1.ThisNode;
00292 if( p2.ThisNode->Prev )
00293 p2.ThisNode->Prev->Next = p2.ThisNode;
00294 else
00295 Head = p2.ThisNode;
00296 if( p1.ThisNode->Next )
00297 p1.ThisNode->Next->Prev = p1.ThisNode;
00298 else
00299 Tail = p1.ThisNode;
00300 }
00301 else if( p2.ThisNode->Next == p1.ThisNode )
00302 {
00303 p1.ThisNode->Prev = p2.ThisNode->Prev;
00304 p2.ThisNode->Prev = p1.ThisNode;
00305 p2.ThisNode->Next = p1.ThisNode->Next;
00306 p1.ThisNode->Next = p2.ThisNode;
00307
00308 if( p1.ThisNode->Prev )
00309 p1.ThisNode->Prev->Next = p1.ThisNode;
00310 else
00311 Head = p1.ThisNode;
00312 if( p2.ThisNode->Next )
00313 p2.ThisNode->Next->Prev = p2.ThisNode;
00314 else
00315 Tail = p2.ThisNode;
00316 }
00317 else {
00318 Temp = p1.ThisNode->Prev;
00319 p1.ThisNode->Prev = p2.ThisNode->Prev;
00320 p2.ThisNode->Prev = Temp;
00321
00322 Temp = p1.ThisNode->Next;
00323 p1.ThisNode->Next = p2.ThisNode->Next;
00324 p2.ThisNode->Next = Temp;
00325
00326 if( p1.ThisNode->Prev )
00327 p1.ThisNode->Prev->Next = p1.ThisNode;
00328 else
00329 Head = p1.ThisNode;
00330 if( p1.ThisNode->Next )
00331 p1.ThisNode->Next->Prev = p1.ThisNode;
00332 else
00333 Tail = p1.ThisNode;
00334
00335
00336
00337 if( p2.ThisNode->Prev )
00338 p2.ThisNode->Prev->Next = p2.ThisNode;
00339 else
00340 Head = p2.ThisNode;
00341 if( p2.ThisNode->Next )
00342 p2.ThisNode->Next->Prev = p2.ThisNode;
00343 else
00344 Tail = p2.ThisNode;
00345
00346 }
00347 }
00348
00350 inline void push_front( const T & pData ) { iSize++; Temp = Head; Head = new MDequeNode<T>( pData ); Head->Next = Temp; if( Temp ) Temp->Prev = Head; if( !Tail ) Tail = Head; }
00352 inline void push_back( const T & pData ) { iSize++; Temp = Tail; Tail = new MDequeNode<T>( pData ); Tail->Prev = Temp; if( Temp ) Temp->Next = Tail; if( !Head ) Head = Tail; }
00354 inline void pop_front() { Temp = Head->Next; delete Head; iSize--; Head = Temp; if ( !Temp ) Tail = 0; }
00356 inline void pop_back() { Temp = Tail->Prev; delete Tail; iSize--; Tail = Temp; if ( !Temp ) Head = 0; }
00358 inline T & front() const { return Head->Data; }
00360 inline T & back() const { return Tail->Data; }
00362 inline unsigned int size() const { return iSize; }
00364 inline bool empty() const { return iSize==0; }
00365
00367 inline MDequeIterator<T> begin() { return MDequeIterator<T>(Head); }
00369 inline MDequeIterator<T> & end() { return Nil; }
00370
00372 inline const MDequeIterator<T> begin() const { return MDequeIterator<T>(Head); }
00374 inline const MDequeIterator<T> & end() const { return Nil; }
00375
00377 inline MDequeIterator<T> find( const T & fCmp )
00378 {
00379 Temp = Head;
00380 while( Temp )
00381 if( Temp->Data == fCmp )
00382 return MDequeIterator<T>( Temp );
00383 else
00384 Temp = Temp->Next;
00385 return MDequeIterator<T>( Tail );
00386 }
00387
00389 inline void erase( MDequeIterator<T> & p ) {
00390 if( !p.ThisNode || iSize <= 0 )
00391 ASSERT_M( false, "DELETING NULL!!!" );
00392 iSize--;
00393 if( p.ThisNode == Tail )
00394 {
00395
00396 if( p.ThisNode == Head )
00397 {
00398 delete Tail;
00399 Tail = 0;
00400 Head = 0;
00401 return;
00402 }
00403 Temp = Tail;
00404 Tail = Tail->Prev;
00405 Tail->Next = 0;
00406 delete Temp;
00407 return;
00408 }
00409 else if( p.ThisNode == Head )
00410 {
00411 Temp = Head;
00412 Head = Head->Next;
00413 Head->Prev = 0;
00414 delete Temp;
00415 return;
00416 } else {
00417 Temp = p.ThisNode;
00418 p.ThisNode->Prev->Next = p.ThisNode->Next;
00419 p.ThisNode->Next->Prev = p.ThisNode->Prev;
00420 delete Temp;
00421 }
00422 }
00423 private:
00424 unsigned int iSize;
00425 MDequeIterator <T> Nil;
00426 MDequeNode <T> * Temp;
00427 MDequeNode <T> * Head;
00428 MDequeNode <T> * Tail;
00429 };
00430
00432 int GetAPrime( int ith );
00433
00435 template<typename T>
00436 class MHash
00437 {
00438 public:
00439 MHash( ) : m_iSize( GetAPrime( m_iPrimest = 1 ) )
00440 {
00441 m_pTable = new MHashNode<T> * [m_iSize];
00442 memset( m_pTable, 0, m_iSize * sizeof( MHashNode<T>* ) );
00443 m_iCount = 0;
00444 }
00445
00446 MHash( const MHash & rhs )
00447 {
00448 m_iPrimest = rhs.m_iPrimest;
00449 m_iCount = rhs.m_iCount;
00450 m_pTable = new MHashNode<T> * [rhs.m_iSize];
00451 m_iSize = rhs.m_iSize;
00452
00453 memset( m_pTable, 0, m_iSize * sizeof( MHashNode<T>* ) );
00454
00455 for( unsigned i = 0; i < m_iSize; ++i )
00456 {
00457 MHashNode <T> * TMP = rhs.m_pTable[i];
00458 while (TMP)
00459 {
00460 m_pTable[i] = new MHashNode<T>( m_pTable[i], TMP->Index, TMP->Data );
00461 TMP = TMP->Next;
00462 }
00463 }
00464 }
00465
00466 MHash & operator = ( const MHash & rhs )
00467 {
00468 m_iPrimest = rhs.m_iPrimest;
00469 m_iCount = rhs.m_iCount;
00470 m_pTable = new MHashNode<T> * [rhs.m_iSize];
00471 m_iSize = rhs.m_iSize;
00472
00473 memset( m_pTable, 0, m_iSize * sizeof( MHashNode<T>* ) );
00474
00475 for( unsigned i = 0; i < m_iSize; ++i )
00476 {
00477 MHashNode <T> * TMP = rhs.m_pTable[i];
00478 while (TMP)
00479 {
00480 m_pTable[i] = new MHashNode<T>( m_pTable[i], TMP->Index, TMP->Data );
00481 TMP = TMP->Next;
00482 }
00483 }
00484 return *this;
00485 }
00486
00487 void resize( int iNewSize )
00488 {
00489 MHashNode <T> ** pOldTable = m_pTable;
00490 int iOldSize = m_iSize;
00491
00492 m_pTable = new MHashNode<T> * [iNewSize];
00493 m_iSize = iNewSize;
00494 memset( m_pTable, 0, iNewSize * sizeof( MHashNode<T>* ) );
00495
00496 for( int i = 0; i < iOldSize; ++i )
00497 {
00498 while (pOldTable[i])
00499 {
00500 MHashNode <T> * TMP = pOldTable[i];
00501 pOldTable[i] = TMP->Next;
00502
00503 int iNewHash = TMP->Index.hash();
00504 MHashNode <T> * TMP2 = m_pTable[iNewHash%m_iSize];
00505 m_pTable[iNewHash%m_iSize] = TMP;
00506 TMP->Next = TMP2;
00507 }
00508 }
00509
00510 free( pOldTable );
00511 }
00512
00513 ~MHash()
00514 {
00515 for( unsigned i = 0; i < m_iSize; ++i )
00516 while (m_pTable[i])
00517 {
00518 MHashNode <T> * TMP = m_pTable[i];
00519 m_pTable[i] = TMP->Next;
00520 SAFE_DELETE( TMP );
00521 }
00522 SAFE_DELETE( m_pTable );
00523 }
00524
00525 void clear()
00526 {
00527 for( unsigned i = 0; i < m_iSize; ++i )
00528 {
00529 while (m_pTable[i])
00530 {
00531 MHashNode <T> * TMP = m_pTable[i];
00532 m_pTable[i] = TMP->Next;
00533 SAFE_DELETE( TMP );
00534 }
00535 m_pTable[i] = 0;
00536 }
00537 m_iCount = 0;
00538 }
00539
00541 T & operator[]( const MString & pIndex )
00542 {
00543 unsigned int iHash = pIndex.hash();
00544 MHashNode<T> * m_pTmp = m_pTable[iHash%m_iSize];
00545
00546 while( m_pTmp )
00547 if( m_pTmp->Index == pIndex )
00548 return m_pTmp->Data;
00549 else
00550 m_pTmp = m_pTmp->Next;
00551
00552 insert( pIndex, T() );
00553
00554 m_pTmp = m_pTable[iHash%m_iSize];
00555
00556 while( m_pTmp )
00557 if( m_pTmp->Index == pIndex )
00558 return m_pTmp->Data;
00559 else
00560 m_pTmp = m_pTmp->Next;
00561
00562
00563 FAIL( "FAIL! Hash insertion failed!" );
00564 return m_pNil;
00565 }
00566
00568 void insert( const MString & pIndex, const T & pData )
00569 {
00570 unsigned int iHash = pIndex.hash();
00571 m_pTable[iHash%m_iSize] = new MHashNode<T>( m_pTable[iHash%m_iSize], pIndex, pData );
00572
00573 if( ++m_iCount > m_iSize + 5 )
00574 resize( GetAPrime( ++m_iPrimest ) );
00575 }
00576
00578 T * get( const MString & pIndex )
00579 {
00580 unsigned int iHash = pIndex.hash();
00581 MHashNode<T> * m_pTmp = m_pTable[iHash%m_iSize];
00582
00583 while( m_pTmp )
00584 if( m_pTmp->Index == pIndex )
00585 return &m_pTmp->Data;
00586 else
00587 m_pTmp = m_pTmp->Next;
00588
00589 return 0;
00590 }
00591
00592 bool remove( const MString & pIndex )
00593 {
00594 unsigned int iHash = pIndex.hash();
00595 MHashNode<T> * m_pPrev = 0;
00596 MHashNode<T> * m_pTmp = m_pTable[iHash%m_iSize];
00597
00598 while( m_pTmp )
00599 if( m_pTmp->Index == pIndex )
00600 {
00601 if( m_pPrev )
00602 m_pPrev->Next = m_pTmp->Next;
00603 else
00604 m_pTable[iHash%m_iSize] = m_pTable[iHash%m_iSize]->Next;
00605 SAFE_DELETE( m_pTmp );
00606 m_iCount--;
00607 return true;
00608 }
00609 else
00610 {
00611 m_pPrev = m_pTmp;
00612 m_pTmp = m_pTmp->Next;
00613 }
00614
00615 return false;
00616 }
00617
00618 void VectorIndicies( MVector < MString > & vOut )
00619 {
00620 unsigned int i;
00621 MHashNode<T> * m_pTmp;
00622 for( i = 0; i < m_iSize; i++ )
00623 {
00624 m_pTmp = m_pTable[i];
00625 while( m_pTmp )
00626 {
00627 vOut.push_back( m_pTmp->Index );
00628 m_pTmp = m_pTmp->Next;
00629 }
00630 }
00631 }
00632
00633 private:
00634 template<typename TC>
00635 struct MHashNode
00636 {
00637 MHashNode() : Next(0) { }
00638 MHashNode( MHashNode<TC> * pA, const MString & pIn, const TC & pD ) : Next( pA ), Index( pIn ), Data( pD ) { }
00639
00640 MHashNode <TC> * Next;
00641 MString Index;
00642 TC Data;
00643 };
00644
00645 MHashNode <T> ** m_pTable;
00646 T m_pNil;
00647 unsigned int m_iSize;
00648 unsigned int m_iPrimest;
00649 unsigned int m_iCount;
00650 };
00651
00652 #endif
00653
00654
00655
00656
00657
00658
00659
00660
00661
00662
00663
00664
00665
00666
00667
00668
00669
00670
00671
00672
00673
00674
00675
00676
00677
00678
00679
00680