Published in: C++
/* Epic Delusions Multimedia API v0.5 Cross platform libraries and utilities for multimedia software Copyright (C) 1993-2006 Orlando Llanes aka KodeApe This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA E-Mail: "Orlando Llanes" <ollanes@pobox.com> */ #ifndef edlist_h #define edlist_h #include "eddef.h" #include "edio.h" /* * Base key list object */ template <typename TEDKeyItem, typename TEDKeyID, int t_nGrowBy = 16> class TEDKeyList { public: TEDKeyList(); TEDKeyList( edu32 p_nItems ); virtual ~TEDKeyList(); bool Create( edu32 p_nItems = t_nGrowBy ); void Destroy(); virtual bool Sort(); edu32 ItemCount(); edu32 FindItem( const TEDKeyID p_Key ); bool GetItem( edu32 p_Index, TEDKeyItem& p_ResItem ); bool SetItem( edu32 p_Index, TEDKeyItem& p_ResItem ); bool Remove( const TEDKeyID p_Key ); bool RemoveItem( edu32 p_Index ); protected: bool Add( const TEDKeyItem& p_Item ); virtual int Compare( const TEDKeyItem& p_Left, const TEDKeyID p_Key ); virtual int Compare( const TEDKeyItem& p_Left, const TEDKeyItem& p_Right ); bool InsertItem( edu32 p_Index ); bool DeleteItem( edu32 p_Index ); bool SwapItem( edu32 p_Left, edu32 p_Right ); bool GrowList(); bool ShrinkList(); protected: TEDKeyItem* m_List; edu32 m_nItems; edu32 m_MaxItems; }; template <typename TEDKeyItem, typename TEDKeyID, int t_nGrowBy> TEDKeyList<TEDKeyItem, TEDKeyID>::TEDKeyList(): m_List(NULL), m_nItems(0), m_MaxItems(0) { } template <typename TEDKeyItem, typename TEDKeyID, int t_nGrowBy> TEDKeyList<TEDKeyItem, TEDKeyID>::TEDKeyList( edu32 p_nItems ): m_List(NULL), m_nItems(0), m_MaxItems(0) { Create( p_nItems ); } template <typename TEDKeyItem, typename TEDKeyID, int t_nGrowBy> TEDKeyList<TEDKeyItem, TEDKeyID>::~TEDKeyList() { Destroy(); } template <typename TEDKeyItem, typename TEDKeyID, int t_nGrowBy> bool TEDKeyList<TEDKeyItem, TEDKeyID>::Create( edu32 p_nItems ) { Destroy(); if( p_nItems == 0 ) p_nItems = t_nGrowBy; m_List = new TEDKeyItem[p_nItems]; if( m_List == NULL ) return false; m_nItems = 0; m_MaxItems = p_nItems; return true; } template <typename TEDKeyItem, typename TEDKeyID, int t_nGrowBy> void TEDKeyList<TEDKeyItem, TEDKeyID>::Destroy() { if( m_List ) delete[] m_List; m_List = NULL; m_nItems = 0; m_MaxItems = 0; } template <typename TEDKeyItem, typename TEDKeyID, int t_nGrowBy> bool TEDKeyList<TEDKeyItem, TEDKeyID>::Sort() { return false; } template <typename TEDKeyItem, typename TEDKeyID, int t_nGrowBy> edu32 TEDKeyList<TEDKeyItem, TEDKeyID>::ItemCount() { if( m_nItems <= m_MaxItems ) return m_nItems; return ED_INVALID; } template <typename TEDKeyItem, typename TEDKeyID, int t_nGrowBy> edu32 TEDKeyList<TEDKeyItem, TEDKeyID>::FindItem( const TEDKeyID p_Key ) { edu32 l_Left = 0; edu32 l_Mid = m_nItems >> 1; edu32 l_Right = m_nItems; int l_Code; if( m_List == NULL ) return ED_INVALID; if( m_nItems == 0 ) return ED_INVALID; while( l_Left < l_Right ) { l_Code = Compare(m_List[l_Mid], p_Key); if( l_Code == 0 ) return l_Mid; if( l_Code < 0 ) l_Left = l_Mid + 1; else l_Right = l_Mid; l_Mid = (l_Left + l_Right) >> 1; } return ED_INVALID; } template <typename TEDKeyItem, typename TEDKeyID, int t_nGrowBy> bool TEDKeyList<TEDKeyItem, TEDKeyID>::GetItem( edu32 p_Index, TEDKeyItem& p_ResItem ) { if( (p_Index >= m_nItems) || (&p_ResItem == NULL) ) return false; p_ResItem = m_List[p_Index]; return true; } template <typename TEDKeyItem, typename TEDKeyID, int t_nGrowBy> bool TEDKeyList<TEDKeyItem, TEDKeyID>::SetItem( edu32 p_Index, TEDKeyItem& p_ResItem ) { if( (p_Index >= m_nItems) || (&p_ResItem == NULL) ) return false; m_List[p_Index] = p_ResItem; return true; } template <typename TEDKeyItem, typename TEDKeyID, int t_nGrowBy> bool TEDKeyList<TEDKeyItem, TEDKeyID>::Remove( const TEDKeyID p_Key ) { edu32 l_Index; l_Index = FindItem(p_Key); if( !DeleteItem(l_Index) ) return false; if( m_nItems ) m_nItems--; return ShrinkList(); } template <typename TEDKeyItem, typename TEDKeyID, int t_nGrowBy> bool TEDKeyList<TEDKeyItem, TEDKeyID>::RemoveItem( edu32 p_Index ) { if( !DeleteItem(p_Index) ) return false; if( m_nItems ) m_nItems--; return ShrinkList(); } template <typename TEDKeyItem, typename TEDKeyID, int t_nGrowBy> bool TEDKeyList<TEDKeyItem, TEDKeyID>::Add( const TEDKeyItem& p_Item ) { edu32 l_Left; edu32 l_Mid = 0; edu32 l_Right; int l_Code; if( !GrowList() ) return false; if( m_nItems == 0 ) goto Add_SkipSearch; // Special case last item, no duplicates allowed l_Code = Compare(m_List[m_nItems - 1], p_Item); if( l_Code == 0 ) return false; // If insert position is at end, skip search if( l_Code < 0 ) { l_Mid = m_nItems; goto Add_SkipSearch; } l_Left = 0; l_Right = m_nItems; l_Mid = (l_Left + l_Right) >> 1; while( l_Left < l_Right ) { // No duplicates allowed l_Code = Compare(m_List[l_Mid], p_Item); if( l_Code == 0 ) return false; if( l_Code < 0 ) l_Left = l_Mid + 1; else l_Right = l_Mid; l_Mid = (l_Left + l_Right) >> 1; } if( !InsertItem(l_Mid) ) return false; Add_SkipSearch: m_List[l_Mid] = p_Item; m_nItems++; return true; } template <typename TEDKeyItem, typename TEDKeyID, int t_nGrowBy> int TEDKeyList<TEDKeyItem, TEDKeyID>::Compare( const TEDKeyItem& p_Left, const TEDKeyID p_Key ) { return -1; } template <typename TEDKeyItem, typename TEDKeyID, int t_nGrowBy> int TEDKeyList<TEDKeyItem, TEDKeyID>::Compare( const TEDKeyItem& p_Left, const TEDKeyItem& p_Right ) { return -1; } template <typename TEDKeyItem, typename TEDKeyID, int t_nGrowBy> bool TEDKeyList<TEDKeyItem, TEDKeyID>::InsertItem( edu32 p_Index ) { if( p_Index >= m_nItems ) return false; memmove( &m_List[p_Index + 1], &m_List[p_Index], (m_nItems - p_Index) * sizeof(TEDKeyItem) ); return true; } template <typename TEDKeyItem, typename TEDKeyID, int t_nGrowBy> bool TEDKeyList<TEDKeyItem, TEDKeyID>::DeleteItem( edu32 p_Index ) { if( p_Index > m_nItems ) return false; memmove( &m_List[p_Index], &m_List[p_Index + 1], (m_nItems - p_Index) * sizeof(TEDKeyItem) ); return true; } template <typename TEDKeyItem, typename TEDKeyID, int t_nGrowBy> bool TEDKeyList<TEDKeyItem, TEDKeyID>::SwapItem( edu32 p_Left, edu32 p_Right ) { TEDKeyItem l_Tmp; if( m_List == NULL ) return false; if( (p_Left >= m_nItems) || (p_Right >= m_nItems) ) return false; l_Tmp = m_List[p_Left]; m_List[p_Left] = m_List[p_Right]; m_List[p_Right] = l_Tmp; return true; } template <typename TEDKeyItem, typename TEDKeyID, int t_nGrowBy> bool TEDKeyList<TEDKeyItem, TEDKeyID>::GrowList() { TEDKeyItem* l_List; edu32 l_MaxItems; if( m_MaxItems < m_nItems ) return false; if( m_nItems == m_MaxItems ) { l_MaxItems = m_nItems + t_nGrowBy; l_List = new TEDKeyItem[l_MaxItems]; if( l_List == NULL ) return false; if( m_List ) { memcpy( l_List, m_List, m_nItems * sizeof(TEDKeyItem) ); delete[] m_List; } m_List = l_List; m_MaxItems = l_MaxItems; } return true; } template <typename TEDKeyItem, typename TEDKeyID, int t_nGrowBy> bool TEDKeyList<TEDKeyItem, TEDKeyID>::ShrinkList() { TEDKeyItem* l_List; edu32 l_MaxItems; if( m_MaxItems < m_nItems ) return false; if( (m_MaxItems - m_nItems) > t_nGrowBy ) { l_MaxItems = m_MaxItems - t_nGrowBy; l_List = new TEDKeyItem[l_MaxItems]; if( l_List == NULL ) return false; if( m_List ) { memcpy( l_List, m_List, m_nItems * sizeof(TEDKeyItem) ); delete[] m_List; } m_List = l_List; m_MaxItems = l_MaxItems; } return true; } #endif
You need to login to post a comment.
