From c068f22329d5cc722622a2183bbb22eef2093df7 Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Mon, 24 Aug 2026 11:16:07 +0200 Subject: initial import --- src/libparsec/include/utl_list.h | 254 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 254 insertions(+) create mode 100644 src/libparsec/include/utl_list.h (limited to 'src/libparsec/include/utl_list.h') diff --git a/src/libparsec/include/utl_list.h b/src/libparsec/include/utl_list.h new file mode 100644 index 0000000..7bbb3a0 --- /dev/null +++ b/src/libparsec/include/utl_list.h @@ -0,0 +1,254 @@ +/* +* PARSEC HEADER: UTL_List.h +*/ + +#ifndef _UTL_LIST_H_ +#define _UTL_LIST_H_ + +#include + + +// type for data in the list -------------------------------------------------- +// +typedef void* UTL_listdata; + +// struct defining one entry in the UTL_List ---------------------------------- +// +template +class UTL_listentry_s +{ +public: + T m_data; + UTL_listentry_s* m_pPrev; + UTL_listentry_s* m_pNext; +}; + +// class for holding a single linked list ------------------------------------- +// +template +class UTL_List { +protected: + UTL_listentry_s* m_pHead; + UTL_listentry_s* m_pTail; + int m_nNumEntries; + + // unlinkg an entry from the list + void _Unlink( UTL_listentry_s* node ) + { + ASSERT( node != NULL ); + + // unlink from list + if ( node->m_pNext != NULL ) { + node->m_pNext->m_pPrev = node->m_pPrev; + } + if ( node->m_pPrev != NULL ) { + node->m_pPrev->m_pNext = node->m_pNext; + } + + // correct head/tail pointers + if ( node->m_pPrev == NULL ) { + ASSERT( node == m_pHead ); + m_pHead = node->m_pNext; + } + if ( node->m_pNext == NULL ) { + ASSERT( node == m_pTail ); + m_pTail = node->m_pPrev; + } + + m_nNumEntries--; + } + +public: + UTL_List() + { + m_pHead = NULL; + m_pTail = NULL; + m_nNumEntries = 0; + } + + ~UTL_List() + { + Clear(); + } + + // clear all entries in the list + void Clear() + { + UTL_listentry_s* next; + for( UTL_listentry_s* node = m_pHead; node != NULL; ) { + next = node->m_pNext; + delete node; + node = next; + } + m_nNumEntries = 0; + m_pHead = NULL; + m_pTail = NULL; + } + void RemoveAll() { Clear(); } + + // append an entry at the tail of the list + UTL_listentry_s* AppendTail( T _data ) + { + UTL_listentry_s* newentry = new UTL_listentry_s; + newentry->m_data = _data; + newentry->m_pPrev = m_pTail; + newentry->m_pNext = NULL; + if ( m_pTail != NULL ) { + m_pTail->m_pNext = newentry; + m_pTail = newentry; + } else { + ASSERT( m_pHead == NULL ); + m_pHead = newentry; + m_pTail = newentry; + } + + m_nNumEntries++; + + return newentry; + } + + // append an entry at the head of the list + UTL_listentry_s* AppendHead( T _data ) + { + UTL_listentry_s* newentry = new UTL_listentry_s; + newentry->m_data = _data; + newentry->m_pPrev = NULL; + newentry->m_pNext = m_pHead; + if ( m_pHead != NULL ) { + m_pHead->m_pPrev = newentry; + m_pHead = newentry; + } else { + ASSERT( m_pTail == NULL ); + m_pHead = newentry; + m_pTail = newentry; + } + + m_nNumEntries++; + + return newentry; + } + + // return the head entry of the list + UTL_listentry_s* GetHead() const { return m_pHead; } + + // return the tail entry of the list + UTL_listentry_s* GetTail() const { return m_pTail; } + + // find an entry with a specific data + UTL_listentry_s* Find( T& data ) const + { + for( UTL_listentry_s* node = m_pHead; node != NULL; ) { + if ( node->m_data == data ) { + return node; + } + node = node->m_pNext; + } + return NULL; + } + + + + // remove an entry specified by its data + //FIXME: evt. introduce key into UTL_listentry_s + bool_t Remove( T& _data ) + { + UTL_listentry_s* node = Find( _data ); + if ( node != NULL ) { + _Unlink( node ); + delete node; + return true; + } + + return false; + } + + // dump contents + void Dump() const + { + int nEntry = 0; + printf( "# of entries: %d", m_nNumEntries ); + for( UTL_listentry_s* node = m_pHead; node != NULL; ) { + printf( "%03d: adress: %8x, data: %8x prev: %8x next: %8x\n", nEntry, (int)node, (int)node->m_data, (int)node->m_pPrev, (int)node->m_pNext ); + node = node->m_pNext; + nEntry++; + } + } + + // return the # of entries + int GetNumEntries() const + { + return m_nNumEntries; + } + + // return the entry at a specified index + UTL_listentry_s* GetEntryAtIndex( int nIndex ) const + { + // TODO: MINGW32 fails on this for some reason... might have to look into why... + //ASSERT( ( nIndex >= 0 ) && ( nIndex < m_nNumEntries ) ); + int nEntry = 0; + for( UTL_listentry_s* node = m_pHead; node != NULL; ) { + + if ( nEntry == nIndex ) { + return node; + } + + node = node->m_pNext; + nEntry++; + } + + return NULL; + } + + // remove entry from list, returns data in entry + T RemoveHead() + { + ASSERT( GetHead() != NULL ); + return RemoveEntry( GetHead() ); + } + + // remove tail entry from list, returns data in entry + T RemoveTail() + { + ASSERT( GetTail() != NULL ); + return RemoveEntry( GetTail() ); + } + + // remove entry from list, returns data in entry + T RemoveEntry( UTL_listentry_s* entry ) + { + ASSERT( entry != NULL ); + _Unlink( entry ); + T data = entry->m_data; + delete entry; + return data; + } + + // call a function for each entry in the list, stop iteration upon fuction failing + void ForEach( int (*procfunc)( UTL_listentry_s* node, void* param ), void* param ) + { + for( UTL_listentry_s* node = m_pHead; node != NULL; ) { + + // call the processing function + if ( (*procfunc) (node, param ) == FALSE ) { + break; + } + + node = node->m_pNext; + } + } +}; + +/* +template +class UTL_ListWalker +{ +protected: + void* m_pData; +public: + UTL_ListWalker( ) + virtual void Callback( UTL_listentry_s* entry ) = 0; +}; + +*/ +#endif // _UTL_LIST_H_ + -- cgit v1.2.3