diff options
| author | Joe Ludwig <[email protected]> | 2013-06-26 15:22:04 -0700 |
|---|---|---|
| committer | Joe Ludwig <[email protected]> | 2013-06-26 15:22:04 -0700 |
| commit | 39ed87570bdb2f86969d4be821c94b722dc71179 (patch) | |
| tree | abc53757f75f40c80278e87650ea92808274aa59 /mp/src/public/list.h | |
| download | source-sdk-2013-39ed87570bdb2f86969d4be821c94b722dc71179.tar.xz source-sdk-2013-39ed87570bdb2f86969d4be821c94b722dc71179.zip | |
First version of the SOurce SDK 2013
Diffstat (limited to 'mp/src/public/list.h')
| -rw-r--r-- | mp/src/public/list.h | 352 |
1 files changed, 352 insertions, 0 deletions
diff --git a/mp/src/public/list.h b/mp/src/public/list.h new file mode 100644 index 00000000..07fe9995 --- /dev/null +++ b/mp/src/public/list.h @@ -0,0 +1,352 @@ +//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+// $NoKeywords: $
+//
+//=============================================================================//
+#ifndef __LIST_H__
+#define __LIST_H__
+
+// TODO:
+// GetPositionAtIndex needs to keep a cache of the previous call so
+// that it doesn't do a linear search every time.
+
+#include <stdlib.h>
+
+// FIXME: change the name of this to something more specific.
+typedef struct
+{
+} _Position;
+typedef _Position *Position;
+
+template <class T> class GList;
+template <class T> class GListIterator;
+
+// GListNode: Class decleration and definition
+template <class T> class GListNode
+{
+private:
+ T data;
+ GListNode<T> *next;
+ GListNode<T> *prev;
+ GListNode();
+ GListNode( T item );
+ friend class GList<T>;
+ friend class GListIterator<T>;
+};
+
+template <class T>
+GListNode<T>::GListNode()
+{
+ next = NULL;
+ prev = NULL;
+}
+
+template <class T>
+GListNode<T>::GListNode( T item )
+{
+ data = item;
+ next = NULL;
+ prev = NULL;
+}
+
+// GList: Class decleration and definition
+template <class T> class GList
+{
+public:
+ // Contructors/destructors
+ GList();
+
+ //
+ Position InsertAtHead( T );
+ Position InsertAtTail( T );
+ T Remove( Position position );
+ void RemoveAll( void (*DeleteItem)( T ) );
+ void RemoveSelectedItems( bool (*NeedsRemovalFunc)( T ), void (*DeleteItemFunc)( T ) );
+ Position InsertAfter( T item, Position position );
+ Position InsertBefore( T item, Position position );
+ bool IsEmpty();
+ int GetNumItems();
+ T GetItemAtPosition( Position position );
+ Position GetPositionAtIndex( int index );
+ T GetItemAtIndex( int index );
+
+protected:
+ GListNode<T> *head;
+ GListNode<T> *tail;
+ int numItems;
+ friend class GListIterator<T>;
+};
+
+template<class T>
+GList<T>::GList()
+{
+ // Set up a dummy head node and a dummy tail node.
+ head = new GListNode<T>;
+ tail = new GListNode<T>;
+ head->next = tail;
+ head->prev = head;
+ tail->next = tail;
+ tail->prev = head;
+ numItems = 0;
+}
+
+template<class T>
+Position GList<T>::InsertAtHead( T item )
+{
+ GListNode<T> *newNode = new GListNode<T>( item );
+ head->next->prev = newNode;
+ newNode->next = head->next;
+ newNode->prev = head;
+ head->next = newNode;
+ numItems++;
+ return ( Position )( void * )newNode;
+}
+
+template<class T>
+Position GList<T>::InsertAtTail( T item )
+{
+ GListNode<T> *newNode = new GListNode<T>( item );
+ tail->prev->next = newNode;
+ newNode->prev = tail->prev;
+ tail->prev = newNode;
+ newNode->next = tail;
+ numItems++;
+ return ( Position )( void * )newNode;
+}
+
+template<class T>
+T GList<T>::Remove( Position position )
+{
+ GListNode<T> *node = ( GListNode<T> * )( void * )position;
+ node->prev->next = node->next;
+ node->next->prev = node->prev;
+ T data = node->data;
+ numItems--;
+ delete node;
+ return data;
+}
+
+template<class T>
+void GList<T>::RemoveAll( void (*DeleteItemFunc)( T ) )
+{
+ GListNode<T> *tmpNode;
+ GListNode<T> *node = head->next;
+ while( node != tail )
+ {
+ if( DeleteItemFunc )
+ {
+ DeleteItemFunc( node->data );
+ }
+ tmpNode = node->next;
+ delete node;
+ node = tmpNode;
+ }
+ head->next = tail;
+ head->prev = head;
+ tail->next = tail;
+ tail->prev = head;
+ numItems = 0;
+}
+
+template<class T>
+void GList<T>::RemoveSelectedItems( bool (*NeedsRemovalFunc)( T ), void (*DeleteItemFunc)( T ) )
+{
+ GListNode<T> *tmpNode;
+ GListNode<T> *node = head->next;
+ while( node != tail )
+ {
+ if( NeedsRemovalFunc( node->data ) )
+ {
+ DeleteItemFunc( node->data );
+ node->prev->next = node->next;
+ node->next->prev = node->prev;
+ tmpNode = node;
+ node = node->next;
+ delete tmpNode;
+ numItems--;
+ }
+ else
+ {
+ node = node->next;
+ }
+ }
+}
+
+template<class T>
+Position GList<T>::InsertAfter( T item, Position position )
+{
+ GListNode<T> *node = ( GListNode<T> * )( void * )position;
+ GListNode<T> *newNode = new GListNode<T>( item );
+ newNode->prev = node;
+ newNode->next = node->next;
+ node->next->prev = newNode;
+ node->next = newNode;
+ numItems++;
+ return ( Position )( void * )newNode;
+}
+
+template<class T>
+Position GList<T>::InsertBefore( T item, Position position )
+{
+ GListNode<T> *node = ( GListNode<T> * )( void * )position;
+ GListNode<T> *newNode = new GListNode<T>( item );
+ newNode->prev = node->prev;
+ newNode->next = node;
+ node->prev->next = newNode;
+ node->prev = newNode;
+ numItems++;
+ return ( Position )( void * )newNode;
+}
+
+template<class T>
+bool GList<T>::IsEmpty()
+{
+ return ( numItems == 0 );
+}
+
+template <class T>
+int GList<T>::GetNumItems()
+{
+ return numItems;
+}
+
+template<class T>
+T GList<T>::GetItemAtPosition( Position position )
+{
+ return ( ( GListNode<T> * )( void * )position )->data;
+}
+
+template<class T>
+Position GList<T>::GetPositionAtIndex( int index )
+{
+ int i;
+ GListNode<T> *node = head->next;
+ for( i = 0; i < index; i++ )
+ {
+ node = node->next;
+ }
+ return ( Position )( void * )node;
+}
+
+template<class T>
+T GList<T>::GetItemAtIndex( int index )
+{
+ return GetItemAtPosition( GetPositionAtIndex( index ) );
+}
+
+// GListIterator: Class decleration and definition
+template<class T> class GListIterator
+{
+public:
+ GListIterator( GList<T> *GList );
+ void GotoHead( void );
+ void GotoTail( void );
+ void Goto( int index );
+ void Increment();
+ void Decrement();
+ T GetCurrentAndIncrement();
+ T GetCurrentAndDecrement();
+ T IncrementAndGetCurrent();
+ T DecrementAndGetCurrent();
+ // postfix
+ T operator++( int ) { return GetCurrentAndIncrement(); }
+ T operator--( int ) { return GetCurrentAndDecrement(); }
+ // prefix
+ T operator++() { return IncrementAndGetCurrent(); }
+ T operator--() { return DecrementAndGetCurrent(); }
+ T GetCurrent();
+ bool AtEnd( void );
+ bool AtBeginning( void );
+protected:
+ GList<T> *list;
+ GListNode<T> *currentNode;
+};
+
+template<class T>
+GListIterator<T>::GListIterator( GList<T> *list )
+{
+ this->list = list;
+ GotoHead();
+}
+
+template<class T>
+void GListIterator<T>::GotoHead()
+{
+ this->currentNode = list->head->next;
+}
+
+template<class T>
+void GListIterator<T>::GotoTail()
+{
+ this->currentNode = list->tail->prev;
+}
+
+template<class T>
+void GListIterator<T>::Goto( int index )
+{
+ currentNode = ( GListNode<T> * )( void * )list->GetPositionAtIndex( index );
+}
+
+template<class T>
+void GListIterator<T>::Increment()
+{
+ currentNode = currentNode->next;
+}
+
+template<class T>
+void GListIterator<T>::Decrement()
+{
+ currentNode = currentNode->prev;
+}
+
+template<class T>
+T GListIterator<T>::GetCurrentAndIncrement()
+{
+ T retval = currentNode->data;
+ Increment();
+ return retval;
+}
+
+template<class T>
+T GListIterator<T>::GetCurrentAndDecrement()
+{
+ T retval = currentNode->data;
+ Decrement();
+ return retval;
+}
+
+template<class T>
+T GListIterator<T>::IncrementAndGetCurrent()
+{
+ Increment();
+ return GetCurrent();
+}
+
+template<class T>
+T GListIterator<T>::DecrementAndGetCurrent()
+{
+ Decrement();
+ return GetCurrent();
+}
+
+template<class T>
+T GListIterator<T>::GetCurrent()
+{
+ return currentNode->data;
+}
+
+template<class T>
+bool GListIterator<T>::AtEnd( void )
+{
+ return currentNode->next == currentNode;
+}
+
+template<class T>
+bool GListIterator<T>::AtBeginning( void )
+{
+ return currentNode->prev == currentNode;
+}
+
+#endif /* __LIST_H__ */
|