"L. Spiro Engine"

F:/My Projects/LSEngine/Modules/LSTL/Src/LinkedList/LSTLSingleLinkedList.h

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__
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator