mirror of
https://github.com/nillerusr/source-engine.git
synced 2026-08-15 05:06:57 +00:00
1
This commit is contained in:
+352
@@ -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__ */
|
||||
Reference in New Issue
Block a user