Main Page   Class Hierarchy   Compound List   File List   Compound Members  

glcirclelist.h

00001 /*
00002 Copyright (c) 2000-2003 Lee Thomason (www.grinninglizard.com)
00003 
00004 Grinning Lizard Utilities. Note that software that uses the 
00005 utility package (including Lilith3D and Kyra) have more restrictive
00006 licences which applies to code outside of the utility package.
00007 
00008 
00009 This software is provided 'as-is', without any express or implied 
00010 warranty. In no event will the authors be held liable for any 
00011 damages arising from the use of this software.
00012 
00013 Permission is granted to anyone to use this software for any 
00014 purpose, including commercial applications, and to alter it and 
00015 redistribute it freely, subject to the following restrictions:
00016 
00017 1. The origin of this software must not be misrepresented; you must 
00018 not claim that you wrote the original software. If you use this 
00019 software in a product, an acknowledgment in the product documentation 
00020 would be appreciated but is not required.
00021 
00022 2. Altered source versions must be plainly marked as such, and 
00023 must not be misrepresented as being the original software.
00024 
00025 3. This notice may not be removed or altered from any source 
00026 distribution.
00027 */
00028 
00029 
00030 #ifndef KYRA_CIRCLELIST_INCLUDED
00031 #define KYRA_CIRCLELIST_INCLUDED
00032 
00033 #include "../util/gldebug.h"
00034 
00035 // OPT improvements:
00036 // - add memory allocator
00037 // - remove the 'data' from circle node, so the overhead isn't in
00038 //       the sentinels.
00039 
00040 template <class T>
00041 struct GlCircleNode
00042 {
00043         T data;
00044 
00045         GlCircleNode<T>* next;
00046         GlCircleNode<T>* prev;
00047 };
00048 
00049 /*
00050         A circular, double linked list.
00051 */
00052 template <class T>
00053 class GlCircleList
00054 {
00055   public:
00056         GlCircleList()          { sentinel.next = &sentinel; sentinel.prev = &sentinel; }
00057         ~GlCircleList()         { Clear(); }
00058 
00059         bool    Empty() const   { return sentinel.next == &sentinel; }
00060         T&              Front() const   { return sentinel.next->data; }
00061         T&              Back()  const   { return sentinel.prev->data; }
00062         GlCircleNode<T>* FrontNode() const      { return sentinel.next; }
00063         GlCircleNode<T>* BackNode()  const      { return sentinel.prev; }
00064 
00065         void Clear()                    {       GlCircleNode<T>* temp;
00066                                                                 while( sentinel.next != &sentinel )
00067                                                                 {
00068                                                                         temp = sentinel.next;
00069                                                                         sentinel.next = sentinel.next->next;
00070                                                                         delete temp;
00071                                                                 }
00072                                                                 sentinel.prev = &sentinel;
00073                                                         }
00074         void PushFront( const T& insert ) {
00075                                                                 GlCircleNode<T>* node = new GlCircleNode<T>;
00076                                                                 node->data = insert;
00077 
00078                                                                 node->prev = &sentinel;
00079                                                                 node->next = sentinel.next;
00080                                                                 sentinel.next->prev = node;
00081                                                                 sentinel.next = node;
00082                                                         }
00083         void PushBack( const T& insert ) {
00084                                                                 GlCircleNode<T>* node = new GlCircleNode<T>;
00085                                                                 node->data = insert;
00086 
00087                                                                 node->prev = sentinel.prev;
00088                                                                 node->next = &sentinel;
00089                                                                 sentinel.prev->next = node;
00090                                                                 sentinel.prev = node;
00091                                                         }
00092         void PopFront()                 {
00093                                                                 GLASSERT( sentinel.next != &sentinel );
00094                                                                 GlCircleNode<T>* node = sentinel.next;
00095 //                                                              node->prev->next = node->next;
00096 //                                                              node->next->prev = node->prev;
00097 //                                                              delete node;
00098                                                                 Delete( node );
00099                                                         }
00100         void PopBack()                  {
00101                                                                 GLASSERT( sentinel.prev != &sentinel );
00102                                                                 GlCircleNode<T>* node = sentinel.prev;
00103 //                                                              node->prev->next = node->next;
00104 //                                                              node->next->prev = node->prev;
00105 //                                                              delete node;
00106                                                                 Delete( node );
00107                                                         }
00108 
00109         void Delete( GlCircleNode<T>* node )    {
00110                                                                                                 GLASSERT( node != &sentinel );
00111                                                                                                 node->prev->next = node->next;
00112                                                                                                 node->next->prev = node->prev;
00113                                                                                                 delete node;
00114                                                                                         }
00115         GlCircleNode<T>* Find( T value )                {
00116                                                                                                 GlCircleNode<T>* node = sentinel.next;
00117                                                                                                 while ( node != &sentinel )
00118                                                                                                 {
00119                                                                                                         if ( node->data == value )
00120                                                                                                                 return node;
00121                                                                                                         node = node->next;
00122                                                                                                 }
00123                                                                                                 return 0;
00124                                                                                         }
00125 
00126         // Scoping problems. Pretend this is private.
00127         GlCircleNode<T> sentinel;
00128 };
00129 
00130 
00131 template <class T>
00132 class GlCircleListIterator
00133 {
00134   public:
00135         GlCircleListIterator( GlCircleList<T>& _list ) : current( 0 ), list( &_list )   {}
00136 
00137         void Begin()            { current = list->sentinel.next; }
00138         void Next()                     { current = current->next; }
00139         void Prev()                     { current = current->prev; }
00140         bool Done()                     { return ( current == &(list->sentinel) ); }
00141 
00143         T& Current()                                    { return (current->data); }
00144 
00145         void InsertBefore( const T& addMe )
00146         {
00147                 GlCircleNode<T>* node = new GlCircleNode<T>;
00148                 node->data = addMe;
00149 
00150                 node->prev = current->prev;
00151                 node->next = current;
00152                 current->prev->next = node;
00153                 current->prev = node;
00154         }
00155 
00156         void InsertAfter( const T& addMe )
00157         {
00158                 GlCircleNode<T>* node = new GlCircleNode<T>;
00159                 node->data = addMe;
00160 
00161                 node->prev = current;
00162                 node->next = current->next;
00163                 current->next->prev = node;
00164                 current->next = node;
00165         }
00166 
00167         void Remove()
00168         {
00169                 GLASSERT( current != &(list->sentinel) );
00170 
00171                 GlCircleNode<T>* temp = current;
00172                 current = current->next;
00173 
00174                 temp->prev->next = temp->next;
00175                 temp->next->prev = temp->prev;
00176                 delete temp;
00177         }
00178 
00179   private:
00180         GlCircleNode<T>* current;       
00181         GlCircleList<T>* list;
00182 };
00183 
00184 
00185 #endif

Generated on Mon Sep 15 12:01:10 2003 for Kyra by doxygen1.2.11.1 written by Dimitri van Heesch, © 1997-2001