From e76b4cd255949c9a5f73f89fcb78ec76c59a831c Mon Sep 17 00:00:00 2001 From: David Anderson <dvander@alliedmods.net> Date: Sat, 12 May 2007 22:52:25 +0000 Subject: [PATCH] whoa, added a new template function --HG-- extra : convert_revision : svn%3A39bc706e-5318-0410-9160-8a85361fbb7c/trunk%40773 --- core/sm_fastlink.h | 192 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 192 insertions(+) create mode 100644 core/sm_fastlink.h diff --git a/core/sm_fastlink.h b/core/sm_fastlink.h new file mode 100644 index 00000000..507a9926 --- /dev/null +++ b/core/sm_fastlink.h @@ -0,0 +1,192 @@ +/** + * vim: set ts=4 : + * =============================================================== + * SourceMod (C)2004-2007 AlliedModders LLC. All rights reserved. + * =============================================================== + * + * This file is not open source and may not be copied without explicit + * written permission of AlliedModders LLC. This file may not be redistributed + * in whole or significant part. + * For information, see LICENSE.txt or http://www.sourcemod.net/license.php + * + * Version: $Id$ + */ + + +#ifndef _INCLUDE_SOURCEMOD_FASTLINK_H_ +#define _INCLUDE_SOURCEMOD_FASTLINK_H_ + +template <typename T> +class FastLink +{ + friend class iterator; +public: + struct FastLinkNode + { + unsigned int prev; + unsigned int next; + unsigned int freeNode; + T obj; + }; +public: + FastLink(unsigned int maxsize) : m_Size(0), m_FirstLink(0), m_FreeNodes(0), m_LastLink(0) + { + m_MaxSize = maxsize; + m_Nodes = new FastLinkNode[m_MaxSize+1]; + } +public: + bool push_back(const T & obj) + { + unsigned int new_node = GetFreeIndex(); + if (!new_node) + { + return false; + } + m_Nodes[new_node].obj = obj; + m_Nodes[new_node].next = 0; + if (!m_FirstLink) + { + m_Nodes[new_node].prev = 0; + m_FirstLink = new_node; + m_LastLink = new_node; + } else { + m_Nodes[new_node].prev = m_LastLink; + m_Nodes[m_LastLink].next = new_node; + m_LastLink = new_node; + } + m_Size++; + return true; + } + size_t size() const + { + return m_Size; + } +private: + unsigned int GetFreeIndex() + { + if (m_FreeNodes) + { + return m_Nodes[m_FreeNodes--].freeNode; + } else { + if (m_LastLink >= m_MaxSize) + { + return 0; + } + return m_LastLink + 1; + } + } +public: + class iterator + { + friend class FastLink; + public: + iterator() + { + link = NULL; + position = 0; + } + iterator(const FastLink *_link, unsigned int _position) + { + link = _link; + position = _position; + } + public: + bool operator ==(const iterator &where) const + { + return (link == link && position == position); + } + bool operator !=(const iterator &where) const + { + return (link != link || position != position); + } + T & operator *() + { + return link->m_Nodes[position].obj; + } + const T & operator *() const + { + return link->m_Nodes[position].obj; + } + iterator & operator++() + { + position = link->m_Nodes[position].next; + return *this; + } + private: + const FastLink *link; + unsigned int position; + }; +public: + iterator begin() const + { + return iterator(this, m_FirstLink); + } + iterator end() const + { + return iterator(this, 0); + } + void remove(const T & obj) + { + for (iterator iter=begin(); iter!=end(); ++iter) + { + if ((*iter) == obj) + { + erase(iter); + return; + } + } + } + iterator erase(const iterator &where) + { + /* Whoa, this better be right! */ + assert(where.link == this); + + iterator iter(where.link, where.position); + ++iter; + + unsigned int index = where.position; + + /* Each case is different, we have no sentinel. + * CASE: We're the HEAD AND the TAIL */ + if (index == m_FirstLink + && index == m_LastLink) + { + m_FirstLink = 0; + m_LastLink = 0; + } + /* We're the HEAD */ + else if (index == m_FirstLink) + { + m_FirstLink = m_Nodes[index].next; + m_Nodes[index].prev = 0; + } + /* We're the TAIL */ + else if (index == m_LastLink) + { + m_LastLink = m_Nodes[index].prev; + m_Nodes[index].next = 0; + } + /* We're in the middle! */ + else + { + /* Patch forward reference */ + m_Nodes[m_Nodes[index].next].prev = m_Nodes[index].prev; + /* Patch backward reference */ + m_Nodes[m_Nodes[index].prev].next = m_Nodes[index].next; + } + + /* Add us to the free list */ + m_Nodes[++m_FreeNodes].freeNode = index; + + return iter; + } +private: + size_t m_Size; + unsigned int m_FirstLink; + unsigned int m_LastLink; + unsigned int m_FreeNodes; + unsigned int m_MaxSize; + FastLinkNode *m_Nodes; +}; + +#endif //_INCLUDE_SOURCEMOD_FASTLINK_H_