//:Header:82, "queue", 3b93fb4c // // File: llqueue.h // // G A M E.O.N.E - LOW LEVEL LIB V1.0 // Copyright (C) 2001 LEVEL ONE ENTERTAINMENT, // Licensed under the terms of LGPL. //:--------------------------------------------------------------------------- //:Description // Fast all purpose queue template class // //:----------------------------------------------------------------------------- #if !defined(_LLQUEUE_H) #define _LLQUEUE_H //:Include #include <ctype.h> #include <stdlib.h> #include <stdio.h> #include <search.h> #include <memory.h> #include "llmem.h" //:Custom #define LLQUEUE_DEFAULT_SIZE (32) #define EXPANDFAILED(s) DebugOutLn("Expand queue failed"); #define INDEXFAILED(s) DebugOutLn("Invalid Queue index"); //:End Custom //:> +-------------------------------+ //:>---------------------| queue Class Declaration |---------------------- //:> +-------------------------------+ //:Class template< typename T > class queue { public: //::1 // +---------------+ // | Constructor | // +---------------+ queue(); //::2 // +--------------+ // | Destructor | // +--------------+ ~queue(); //::3 // +-----------+ // | Clear() | // +-----------+ //:Description // // Setzt die Anzahl der Elemente auf 0. Logisches L�schen. // inline void Clear(); //::6 // +---------+ // | Get() | // +---------+ //:Description // // Entfernt einen Elementpointer vom Ende der Queue. // inline T * Get(); //::4 // +----------+ // | Init() | // +----------+ //:Description // // Setzt Initialgr�sse des Arrays. // Aktuelles Array wird dabei zerst�rt und durch die neue gr�sse Ersetzt. // Alle Variablen werden Resetet. // void Init( int imax); //::10 // +-------------+ // | InQueue() | // +-------------+ //:Description // // Liefert Anzahl der Elemente. // inline int InQueue(); //::11 // +-------------+ // | IsEmpty() | // +-------------+ //:Description // // Liefert true wenn die Queue leer ist. // inline bool IsEmpty() const; //::14 // +----------+ // | Next() | // +----------+ //:Description // // Liefert ElementPtr an der aktuellen Iteration-Index Stelle. // Bei jedem Aufruf von Next() wird der Interations-Index um eins erh�ht. // Ist der Index ung�ltig, d.h. Ausserhalb des Arrays, dann wird 0 geliefert und // der Iterations-Index auf 0 gesetz. // inline T * Next(); //::15 // +-----------------+ // | NextNoReset() | // +-----------------+ //:Description // // Liefert ElementPtr an der aktuellen Iteration-Index Stelle. // Bei jedem Aufruf von Next() wird der Interations-Index um eins erh�ht. // Ist der Index ung�ltig, d.h. Ausserhalb des Arrays, dann wird 0 geliefert. // // Im Gegensatz zur Funktion Next(), wird der Iteration-Index nicht zur�ckgestellt. // Jeder weiterer Aufruf von NextNoReset() liefert eine 0. // inline T * NextNoReset(); //::16 // +-----------------+ // | operator []() | // +-----------------+ //:Description // // Direct Access // T * operator []( int i) const; //::5 // +---------+ // | Put() | // +---------+ //:Description // // H�ngt neuen Elementpointer an den NormalStack. // inline void Put( T *element); //::5 // +---------+ // | Put() | // +---------+ //:Description // // Insert Element an Stelle 0. // inline void PutFront( T *element); // Insert Element an Stelle idx inline void InsertAt(int idx, T *element); // Entfernt Element an Stelle idx inline T* RemoveAt(int idx); inline int Remove(T * element); //::13 // +-----------+ // | Reset() | // +-----------+ //:Description // // Setzt Inerations-Index auf 0. Entspricht Set(0). // inline void Reset(); //::12 // +---------+ // | Set() | // +---------+ //:Description // // Setzt den Iteration-Index. // inline void Set( int index); //::17 // +-----------+ // | SetAt() | // +-----------+ //:Description // // Direktzugriff auf das Stack Array. // Tauscht den Pointer an der Stelle 'i', // liefert vorherigen Wert. // T * SetAt( int i, T* newvalue); //::18 // +----------+ // | Sort() | // +----------+ //:Description // // QuickSort // void Sort( int (*compare)(const void *, const void *)); //:=6 // +----------+ // | m_Qptr | // +----------+ T * * m_Qptr; //:=8 // +------------+ // | m_array1 | // +------------+ T * * m_array1; //:=11 // +--------------------+ // | m_iterator_index | // +--------------------+ int m_iterator_index; //:=12 // +------------------+ // | m_num_elements | // +------------------+ int m_num_elements; //:=14 // +------------------+ // | m_max_elements | // +------------------+ int m_max_elements; //::19 // +-----------------+ // | ExpandQueue() | // +-----------------+ void ExpandQueue(); }; //:> +-------------------------------+ //:>---------------------| queue Iterator Class |---------------------- //:> +-------------------------------+ //:Class template< typename T > class queue_itr { public: //::1 // +---------------+ // | Constructor | // +---------------+ queue_itr<T>(queue<T> &queue_to_iterate ) : m_Q(queue_to_iterate) { m_local_iterator_index = m_Q.m_iterator_index; m_local_iterator_index = 0; }; T * Next() { if( m_local_iterator_index < m_Q.m_num_elements ) return m_Q.m_array1[m_local_iterator_index++]; // reset: m_local_iterator_index = 0; return 0; } T * NextNoReset() { if( m_local_iterator_index < m_Q.m_num_elements ) return m_Q.m_array1[m_local_iterator_index++]; // No reset: m_local_iterator_index = 0; return 0; } void Reset() { m_local_iterator_index = 0; } private: queue<T> & m_Q; int m_local_iterator_index; }; //:> +-----------------------------------+ //:>-------------------| Member Function Definitions |-------------------- //:> +-----------------------------------+ //::1 // +---------------+ // | Constructor | // +---------------+ template< typename T > queue<T>::queue() { m_array1=0; Clear(); m_max_elements=0; m_num_elements=0; } //::2 // +--------------+ // | Destructor | // +--------------+ template< typename T > queue<T>::~queue() { Clear(); if( m_array1 ) llmem_free(m_array1); m_array1=0; } //::3 // +-----------+ // | Clear() | // +-----------+ template< typename T > inline void queue<T>::Clear() { m_num_elements=0; m_iterator_index=0; m_Qptr=m_array1; } //::19 // +-----------------+ // | ExpandQueue() | // +-----------------+ template< typename T > void queue<T>::ExpandQueue() { int newsize = m_max_elements; newsize += (newsize>>1); if(!newsize) newsize=LLQUEUE_DEFAULT_SIZE; m_array1 = (T**)llmem_realloc(m_array1,newsize*sizeof(T*)); if(!m_array1) EXPANDFAILED(newsize*sizeof(T*)); m_Qptr = m_array1; m_Qptr += m_num_elements; m_max_elements = newsize; } //::6 // +---------+ // | Get() | // +---------+ template< typename T > inline T * queue<T>::Get() { if( m_num_elements > 0 ) { m_num_elements--; return *--m_Qptr; } return 0; } //::4 // +----------+ // | Init() | // +----------+ template< typename T > void queue<T>::Init( int imax) { Clear(); m_max_elements = imax>0?imax:LLQUEUE_DEFAULT_SIZE; ExpandQueue(); } //::10 // +-------------+ // | InQueue() | // +-------------+ template< typename T > inline int queue<T>::InQueue() { return m_num_elements; } //::11 // +-------------+ // | IsEmpty() | // +-------------+ template< typename T > inline bool queue<T>::IsEmpty() const { return m_num_elements == 0 ? true : false; } //::14 // +----------+ // | Next() | // +----------+ template< typename T > inline T * queue<T>::Next() { if( m_iterator_index < m_num_elements ) { return m_array1[m_iterator_index++]; } Reset(); return 0; } //::15 // +-----------------+ // | NextNoReset() | // +-----------------+ template< typename T > inline T * queue<T>::NextNoReset() { if( m_iterator_index < m_num_elements ) { return m_array1[m_iterator_index++]; } return 0; } //::16 // +-----------------+ // | operator []() | // +-----------------+ template< typename T > T * queue<T>::operator []( int i) const { if( i >= 0 && i < m_num_elements ) { return m_array1[i]; } return 0; } //::5 // +---------+ // | Put() | // +---------+ template< typename T > inline void queue<T>::Put( T *element) { if( m_num_elements < m_max_elements ) { m_num_elements++; *m_Qptr++=element; return; } ExpandQueue(); m_num_elements++; *m_Qptr++=element; return; } //::5 // +--------------+ // | InsertAt() | // +--------------+ template< typename T > inline void queue<T>::InsertAt(int idx, T *element) { if( idx > m_num_elements ) INDEXFAILED(idx); if( (m_num_elements + 1) < m_max_elements ) { memmove( &m_array1[idx+1], &m_array1[idx], (m_num_elements-idx)*sizeof(T*) ); m_array1[idx]=element; m_num_elements++; m_Qptr++; return; } ExpandQueue(); InsertAt(idx, element); } //::5 // +--------------+ // | RemoveAt() | // +--------------+ template< typename T > T* queue<T>::RemoveAt(int idx) { if( idx > m_num_elements ) INDEXFAILED(idx); T* rc; if( m_num_elements > 0 ) { rc = m_array1[idx]; memmove( &m_array1[idx], &m_array1[idx+1], (m_num_elements-idx-1)*sizeof(T*) ); if( m_iterator_index > 0 && m_iterator_index >= idx ) m_iterator_index --; m_num_elements--; m_Qptr--; return rc; } return NULL; } //::5 // +---------------------+ // | Remove(T *element) | // +---------------------+ template< typename T > int queue<T>::Remove(T * element) { int rc = 0; for( int idx = 0 ; idx < m_num_elements; idx ++ ) { if( m_array1[idx] == element ) { memmove( &m_array1[idx], &m_array1[idx+1], (m_num_elements-idx-1)*sizeof(T*) ); if( m_iterator_index > 0 && m_iterator_index >= idx ) m_iterator_index --; m_num_elements--; m_Qptr--; idx--; rc++; } } return rc; // remove count } //::5 // +--------------+ // | PutFront() | // +--------------+ template< typename T > inline void queue<T>::PutFront( T *element) { if( m_num_elements < m_max_elements ) { memmove( &m_array1[1], &m_array1[0], m_num_elements*sizeof(T*) ); m_array1[0]=element; m_num_elements++; m_Qptr++; return; } ExpandQueue(); PutFront(element); } //::13 // +-----------+ // | Reset() | // +-----------+ template< typename T > inline void queue<T>::Reset() { m_iterator_index=0; } //::12 // +---------+ // | Set() | // +---------+ template< typename T > inline void queue<T>::Set( int index) { m_iterator_index=index<0?0:index; } //::17 // +-----------+ // | SetAt() | // +-----------+ template< typename T > T * queue<T>::SetAt( int i, T* newvalue) { T* oldvalue; if( i < m_num_elements ) { oldvalue=m_array1[i]; m_array1[i]=newvalue; return oldvalue; } INDEXFAILED(i); return 0; } //::18 // +----------+ // | Sort() | // +----------+ template< typename T > void queue<T>::Sort( int(*compare)(const void *, const void *) ) { qsort(m_array1,m_num_elements,sizeof(T*),compare); } #endif // _LLQUEUE_H