Team Fortress 2 Source Code as on 22/4/2020
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
|
|
//========= 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__ */
|