"L. Spiro Engine"
|
00001 00016 #ifndef __LSTL_SINGLELINKEDLIST_H__ 00017 #define __LSTL_SINGLELINKEDLIST_H__ 00018 00019 #include "../LSTLib.h" 00020 #include "LSTLLinkedListBase.h" 00021 00022 namespace lstl { 00023 00030 template <typename _tType> 00031 class CSingleLinkedList : protected CLinkedListBase { 00032 public : 00033 // == Various constructors. 00034 LSE_CALL CSingleLinkedList() : 00035 m_lpllnHead( NULL ), 00036 m_paOurAllocator( &Parent::m_aAllocator ) { 00037 } 00038 LSE_CALL ~CSingleLinkedList() { 00039 Reset(); 00040 } 00041 00042 00043 // == Types. 00047 typedef struct LSTL_LINKED_LIST_NODE { 00051 _tType tLinkedListObject; 00052 00056 LSTL_LINKED_LIST_NODE * pllnLinkedListNext; 00057 } * LPLSTL_LINKED_LIST_NODE, * const LPCLSTL_LINKED_LIST_NODE; 00058 00059 00060 // == Functions. 00067 LSVOID LSE_CALL SetAllocator( CAllocator * _paAllocator ) { 00068 Reset(); 00069 m_paOurAllocator = _paAllocator; 00070 if ( !m_paOurAllocator ) { 00071 m_paOurAllocator = &Parent::m_aAllocator; 00072 } 00073 } 00074 00080 CAllocator * LSE_CALL GetAllocator() { 00081 return m_paOurAllocator; 00082 } 00083 00087 LSVOID LSE_CALL Reset() { 00088 LPLSTL_LINKED_LIST_NODE lpllnNext = NULL; 00089 for ( LPLSTL_LINKED_LIST_NODE lpllnThis = m_lpllnHead; 00090 lpllnThis; lpllnThis = lpllnNext ) { 00091 lpllnNext = lpllnThis->pllnLinkedListNext; 00092 Destroy( (*lpllnThis) ); 00093 m_paOurAllocator->Free( lpllnThis ); 00094 } 00095 00096 m_lpllnHead = NULL; 00097 } 00098 00107 LPLSTL_LINKED_LIST_NODE LSE_CALL InsertAfter( const _tType &_tNew, LPLSTL_LINKED_LIST_NODE _lpllnNode ) { 00108 LPLSTL_LINKED_LIST_NODE lpllnNew = NewNode(); 00109 if ( !lpllnNew ) { return NULL; } 00110 Construct( (*lpllnNew) ); 00111 lpllnNew->tLinkedListObject = _tNew; 00112 00113 if ( !_lpllnNode ) { 00114 // Insert at the head. 00115 lpllnNew->pllnLinkedListNext = m_lpllnHead; 00116 m_lpllnHead = lpllnNew; 00117 } 00118 else { 00119 // Otherwise it goes after some item or another. 00120 lpllnNew->pllnLinkedListNext = _lpllnNode->pllnLinkedListNext; 00121 _lpllnNode->pllnLinkedListNext = lpllnNew; 00122 } 00123 00124 return lpllnNew; 00125 } 00126 00133 LSVOID LSE_CALL RemoveItem( LPLSTL_LINKED_LIST_NODE _lpllnNode ) { 00134 if ( !_lpllnNode ) { return; } 00135 // Unlink the object. 00136 if ( m_lpllnHead == _lpllnNode ) { 00137 // At the head. 00138 m_lpllnHead = _lpllnNode->pllnLinkedListNext; 00139 } 00140 else { 00141 // Find the node before it. 00142 for ( LPLSTL_LINKED_LIST_NODE pllnThis = m_lpllnHead; pllnThis; pllnThis = pllnThis->pllnLinkedListNext ) { 00143 if ( pllnThis->pllnLinkedListNext == _lpllnNode ) { 00144 pllnThis->pllnLinkedListNext = _lpllnNode->pllnLinkedListNext; 00145 break; 00146 } 00147 } 00148 } 00149 00150 Destroy( (*_lpllnNode) ); 00151 m_paOurAllocator->Free( _lpllnNode ); 00152 } 00153 00159 LPLSTL_LINKED_LIST_NODE LSE_CALL Head() { 00160 return m_lpllnHead; 00161 } 00162 00168 const LPLSTL_LINKED_LIST_NODE LSE_CALL Head() const { 00169 return m_lpllnHead; 00170 } 00171 00178 LPLSTL_LINKED_LIST_NODE LSE_CALL PushFront( const _tType &_tNew ) { 00179 return InsertAfter( _tNew, NULL ); 00180 } 00181 00187 LSUINT32 LSE_CALL Length() { 00188 LSUINT32 ui32Len = 0UL; 00189 for ( LPLSTL_LINKED_LIST_NODE lpllnThis = m_lpllnHead; 00190 lpllnThis; lpllnThis = lpllnThis->pllnLinkedListNext ) { 00191 ++ui32Len; 00192 } 00193 return ui32Len; 00194 } 00195 00202 LPLSTL_LINKED_LIST_NODE LSE_CALL Find( const _tType &_tValue ) { 00203 for ( LPLSTL_LINKED_LIST_NODE lpllnThis = m_lpllnHead; 00204 lpllnThis; lpllnThis = lpllnThis->pllnLinkedListNext ) { 00205 if ( lpllnThis->tLinkedListObject == _tValue ) { 00206 return lpllnThis; 00207 } 00208 } 00209 return NULL; 00210 } 00211 00212 00213 protected : 00214 // == Members. 00218 LPLSTL_LINKED_LIST_NODE m_lpllnHead; 00219 00223 CAllocator * m_paOurAllocator; 00224 00225 00226 // == Functions. 00232 LSVOID LSE_CALL Construct( LSTL_LINKED_LIST_NODE &_llnNode ) { 00233 _llnNode.pllnLinkedListNext = NULL; 00234 new( &_llnNode.tLinkedListObject ) _tType; 00235 } 00241 LSVOID LSE_CALL Destroy( const LSTL_LINKED_LIST_NODE &_llnNode ) { 00242 // This gives warning C4100 when this class is created with types that have no destructor, 00243 // claiming _llnNode is unreferenced. 00244 // Erase this warning with some do-nothing code. 00245 #ifdef LSE_VISUALSTUDIO 00246 static_cast<LSTL_LINKED_LIST_NODE>(_llnNode); 00247 #endif // #ifdef LSE_VISUALSTUDIO 00248 _llnNode.tLinkedListObject.~_tType(); 00249 } 00250 00256 LPLSTL_LINKED_LIST_NODE LSE_CALL NewNode() { 00257 return static_cast<LPLSTL_LINKED_LIST_NODE>(m_paOurAllocator->Alloc( sizeof( LSTL_LINKED_LIST_NODE ) )); 00258 } 00259 00260 private : 00261 typedef CLinkedListBase Parent; 00262 }; 00263 00264 } // namespace lstl 00265 00266 #endif // __LSTL_SINGLELINKEDLIST_H__