00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030 #ifndef KYRA_CIRCLELIST_INCLUDED
00031 #define KYRA_CIRCLELIST_INCLUDED
00032
00033 #include "../util/gldebug.h"
00034
00035
00036
00037
00038
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
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
00096
00097
00098 Delete( node );
00099 }
00100 void PopBack() {
00101 GLASSERT( sentinel.prev != &sentinel );
00102 GlCircleNode<T>* node = sentinel.prev;
00103
00104
00105
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
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