// wzlist.h #ifndef _PROGRAMCOMMON_WZLIST_H_ #define _PROGRAMCOMMON_WZLIST_H_ #include "wztypedef.h" template class CWzList; //------------------------------------------------------------------------------ /** @class CWzNode */ template class CWzNode { public: // »ý¼ºÀÚ CWzNode( void ) : m_prev( NULL ) , m_next( NULL ) { // empty } // º¹»ç »ý¼ºÀÚ CWzNode( const T& data ) : m_prev( NULL ) , m_next( NULL ) { m_data = data; } // ¼Ò¸êÀÚ ~CWzNode( void ) { // empty } // µ¥ÀÌŸ ¼³Á¤ void SetData( const T& data ) { m_data = data; } // µ¥ÀÌŸ ¾ò±â T& GetData( void ) { return m_data; } private: // ÀÌÀü ³ëµå ¼³Á¤ void SetPrev( CWzNode* prev ) { m_prev = prev; } // ÀÌÀü ³ëµå ¾ò±â CWzNode* GetPrev( void ) const { return m_prev; } // ´ÙÀ½ ³ëµå ¼³Á¤ void SetNext( CWzNode* next ) { m_next = next; } // ´ÙÀ½ ³ëµå ¾ò±â CWzNode* GetNext( void ) const { return m_next; } private: friend class CWzList; CWzNode* m_prev; CWzNode* m_next; T m_data; }; //------------------------------------------------------------------------------ /** @class CWzList */ template class CWzList { public: // »ý¼ºÀÚ/¼Ò¸êÀÚ CWzList( void ); virtual ~CWzList( void ); // ¾Õ¿¡ µ¥ÀÌŸ Ãß°¡ CWzNode* AddHead( const T& data ); // µÚ¿¡ µ¥ÀÌŸ Ãß°¡ CWzNode* AddTail( const T& data ); // ÇØ´ç ³ëµå Àü¿¡ µ¥ÀÌŸ Ãß°¡ CWzNode* InsertBefore( CWzNode* node, const T& data ); // ÇØ´ç ³ëµå ÈÄ¿¡ µ¥ÀÌŸ Ãß°¡ CWzNode* InsertAfter( CWzNode* node, const T& data ); // ¸Ç ¾Õ ³ëµå Á¦°Å T RemoveHead( void ); // ¸Ç ³¡ ³ëµå Á¦°Å T RemoveTail( void ); // ÇØ´ç ³ëµå Á¦°Å T RemoveNode( CWzNode* &node ); // Àüü ³ëµå Á¦°Å void RemoveAll( void ); // ¸Ç ¾Õ ³ëµå ã±â CWzNode* FindHead( void ) const; // ¸Ç ³¡ ³ëµå ã±â CWzNode* FindTail( void ) const; // µ¥ÀÌŸ¸¦ ÅëÇØ ³ëµå ã±â CWzNode* FindNode( const T& findData ) const; // ÇØ´ç ³ëµå ÀÌÀü ³ëµå ¾ò±â CWzNode* GetPrev( CWzNode* node ) const; // ÇØ´ç ³ëµå ÀÌÈÄ ³ëµå ¾ò±â CWzNode* GetNext( CWzNode* node ) const; // Àüü ³ëµå ¼ö ¾ò±â int GetCount( void ) const; // ºñ¾ú´Â°¡? BOOL IsEmpty( void ) const; // ÇØ´ç ³ëµå µ¥ÀÌŸ ¼³Á¤ void SetData( CWzNode* node, const T& data ); // ÇØ´ç ³ëµå µ¥ÀÌŸ ¾ò±â T& GetData( CWzNode* node ) const; protected: // xxx: ±¸Â÷ÇÏ°Ô ÀÌ·± º¯¼ö¸¦ ¸¸µé°í ½ÍÁø ¾ÊÁö¸¸ // ±âÁ¸¿¡ ÀÌ¹Ì ¾²·¹±â °ªÀ» ¸®ÅÏÇØ¾ß ÇÏ´Â °æ¿ì°¡ Àֱ⠶§¹®¿¡ // Â÷¶ó¸® ÀÌ ¹æ¹ýÀÌ ÁÁÀº °Í °°¾Æ ÀÌ·¸°Ô °£´Ù. static T m_dummyData; protected: CWzNode* m_head; CWzNode* m_tail; int m_numNodes; }; template T CWzList::m_dummyData; //------------------------------------------------------------------------------ /** »ý¼ºÀÚ¿¡¼­ ¹º°¡¸¦ »ý¼ºÇÑ´Ù´Â °ÍÀÌ ÁÁ¾Æ º¸ÀÌÁö´Â ¾ÊÁö¸¸ ±âÁ¸¿¡ ÀÌ¹Ì ±×·¸°Ô ½á ¿Ô±â ¶§¹®¿¡ ±×³É °£´Ù. */ template CWzList::CWzList( void ) : m_numNodes( 0 ) { m_head = new CWzNode; WzAssert( m_head ); m_tail = new CWzNode; WzAssert( m_tail ); m_head->SetNext( m_tail ); m_tail->SetPrev( m_head ); } //------------------------------------------------------------------------------ /** */ template CWzList::~CWzList( void ) { RemoveAll(); if( m_tail ) { delete m_tail; m_tail = NULL; } if( m_head ) { delete m_head; m_head = NULL; } } //------------------------------------------------------------------------------ /** */ template CWzNode* CWzList::AddHead( const T& data ) { WzAssert( m_head ); CWzNode* newNode = new CWzNode; WzAssert( newNode ); if( !newNode ) { WZLOG( WZWAR, "CWzList::AddHead() - »õ ³ëµå »ý¼º ½ÇÆÐ" ); return NULL; } newNode->SetData( data ); // »õ·Î¿î ³ëµå¿Í ÀÌÀü ù ³ëµå°£ ¸µÅ© ¼³Á¤ newNode->SetNext( m_head->GetNext() ); (m_head->GetNext())->SetPrev( newNode ); // »õ·Î¿î ³ëµå¿Í head°£ ¸µÅ© ¼³Á¤ newNode->SetPrev( m_head ); m_head->SetNext( newNode ); ++m_numNodes; return newNode; } //------------------------------------------------------------------------------ /** */ template CWzNode* CWzList::AddTail( const T& data ) { WzAssert( m_tail ); CWzNode* newNode = new CWzNode; WzAssert( newNode ); if( !newNode ) { WZLOG( WZWAR, "CWzList::AddTail() - »õ ³ëµå »ý¼º ½ÇÆÐ" ); return NULL; } newNode->SetData( data ) ; // »õ·Î¿î ³ëµå¿Í ÀÌÀü ¸¶Áö¸· ³ëµå°£ ¸µÅ© ¼³Á¤ newNode->SetPrev( m_tail->GetPrev() ); (m_tail->GetPrev())->SetNext( newNode ); // »õ·Î¿î ³ëµå¿Í tail°£ ¸µÅ© ¼³Á¤ newNode->SetNext( m_tail ); m_tail->SetPrev( newNode ); ++m_numNodes; return newNode; } //------------------------------------------------------------------------------ /** */ template CWzNode* CWzList::InsertBefore( CWzNode* node, const T& data ) { WzAssert( node ); if( !node ) { WZLOG( WZWAR, "CWzList::InsertBefore() - NULL ³ëµå" ); return NULL; } CWzNode* newNode = new CWzNode; WzAssert( newNode ); if( !newNode ) { WZLOG( WZWAR, "CWzList::InsertBefore() - »õ ³ëµå »ý¼º ½ÇÆÐ" ); return NULL; } newNode->SetData( data ); // »õ·Î¿î ³ëµå¿Í ÁÖ¾îÁø ³ëµå ÀÌÀü ³ëµå°£ ¸µÅ© ¼³Á¤ newNode->SetPrev( node->GetPrev() ); (node->GetPrev())->SetNext( newNode ); // »õ·Î¿î ³ëµå¿Í ÁÖ¾îÁø ³ëµå°£ ¸µÅ© ¼³Á¤ newNode->SetNext( node ); node->SetPrev( newNode ); ++m_numNodes; return newNode; } //------------------------------------------------------------------------------ /** */ template CWzNode* CWzList::InsertAfter( CWzNode* node, const T& data ) { WzAssert( node ); if( !node ) { WZLOG( WZWAR, "CWzList::InsertAfter() - NULL ³ëµå" ); return NULL; } CWzNode* newNode = new CWzNode; WzAssert( newNode ); if( !newNode ) { WZLOG( WZWAR, "CWzList::InsertAfter() - »õ ³ëµå »ý¼º ½ÇÆÐ" ); return NULL; } newNode->SetData( data ); // »õ·Î¿î ³ëµå¿Í ÁÖ¾îÁø ³ëµå ´ÙÀ½ ³ëµå°£ ¸µÅ© ¼³Á¤ newNode->SetNext( node->GetNext() ); (node->GetNext())->SetPrev( newNode ); // »õ·Î¿î ³ëµå¿Í ÁÖ¾îÁø ³ëµå°£ ¸µÅ© ¼³Á¤ newNode->SetPrev( node ); node->SetNext( newNode ); ++m_numNodes; return newNode; } //------------------------------------------------------------------------------ /** */ template T CWzList::RemoveHead( void ) { WzAssert( m_head ); WzAssert( m_tail ); // ù ³ëµå¸¦ ±¸Çϰí CWzNode* headNode = m_head->GetNext(); WzAssert( headNode ); // ¸®½ºÆ®°¡ ºñ¾î ÀÖ´Â °æ¿ì WzAssert( headNode != m_tail ); if( headNode == m_tail ) { WZLOG( WZWAR, "CWzList::RemoveHead() - ¸®½ºÆ®°¡ ºñ¾î ÀÖÀ½(¾²·¹±â°ª ¹Ýȯ)" ); return m_dummyData; } // ³ëµå°ª ÀúÀå T data = headNode->GetData(); // head¿Í ù ³ëµå ´ÙÀ½ ³ëµå°£ ¸µÅ© ¼³Á¤ (headNode->GetNext())->SetPrev( m_head ); m_head->SetNext( headNode->GetNext() ); // ³ëµå Á¦°Å delete headNode; --m_numNodes; return data; } //------------------------------------------------------------------------------ /** */ template T CWzList::RemoveTail( void ) { WzAssert( m_head ); WzAssert( m_tail ); // ¸¶Áö¸· ³ëµå¸¦ ±¸Çϰí CWzNode* tailNode = m_tail->GetPrev(); WzAssert( tailNode ); // ¸®½ºÆ®°¡ ºñ¾î ÀÖ´Â °æ¿ì WzAssert( tailNode != m_head ); if( tailNode == m_head ) { WZLOG( WZWAR, "CWzList::RemoveTail() - ¸®½ºÆ®°¡ ºñ¾î ÀÖÀ½(¾²·¹±â°ª ¹Ýȯ)" ); return m_dummyData; } // ³ëµå°ª ÀúÀå T data = tailNode->GetData(); // tail°ú ¸¶Áö¸· ³ëµå ÀÌÀü ³ëµå°£ ¸µÅ© ¼³Á¤ (tailNode->GetPrev())->SetNext( m_tail ); m_tail->SetPrev( tailNode->GetPrev() ); // ³ëµå Á¦°Å delete tailNode; --m_numNodes; return data; } //------------------------------------------------------------------------------ /** */ template T CWzList::RemoveNode( CWzNode* &node ) { WzAssert( node ); if( !node ) { WZLOG( WZWAR, "CWzList::RemoveNode() - NULL ³ëµå(¾²·¹±â°ª ¹Ýȯ)" ); return m_dummyData; } T data = node->GetData(); CWzNode* nextNode = node->GetNext(); WzAssert( nextNode ); // nodeÀÇ ¾Õ µÚ ³ëµå ¸µÅ© ¼³Á¤ (node->GetPrev())->SetNext( nextNode ); nextNode->SetPrev( node->GetPrev() ); // node Á¦°Å delete node; // node¸¦ ´ÙÀ½ ³ëµå·Î ¼³Á¤ ÈÄ ¹Ýȯ node = ( nextNode != m_tail ? nextNode : NULL ); --m_numNodes; return data; } //------------------------------------------------------------------------------ /** */ template void CWzList::RemoveAll( void ) { WzAssert( m_head ); WzAssert( m_tail ); // Àüü ³ëµå »èÁ¦ CWzNode* curNode = m_head->GetNext(); while( curNode != m_tail ) { CWzNode* delNode = curNode; curNode = curNode->GetNext(); delete delNode; } // head¿Í tail ¿¬°á m_head->SetNext( m_tail ); m_tail->SetPrev( m_head ); m_numNodes = 0; } //------------------------------------------------------------------------------ /** */ template CWzNode* CWzList::FindHead( void ) const { WzAssert( m_head ); WzAssert( m_tail ); CWzNode* headNode = m_head->GetNext(); return ( headNode != m_tail ? headNode : NULL ); } //------------------------------------------------------------------------------ /** */ template CWzNode* CWzList::FindTail( void ) const { WzAssert( m_head ); WzAssert( m_tail ); CWzNode* tailNode = m_tail->GetPrev(); return ( tailNode != m_head ? tailNode : NULL ); } //------------------------------------------------------------------------------ /** */ template CWzNode* CWzList::FindNode( const T& findData ) const { WzAssert( m_head ); WzAssert( m_tail ); CWzNode* curNode = m_head->GetNext(); while( curNode != m_tail ) { if( curNode->GetData() == findData ) { return curNode; } curNode = curNode->GetNext(); } return NULL; } //------------------------------------------------------------------------------ /** */ template CWzNode* CWzList::GetPrev( CWzNode* node ) const { WzAssert( node ); WzAssert( m_head ); if( node && node->GetPrev() != m_head ) { return node->GetPrev(); } return NULL; } //------------------------------------------------------------------------------ /** */ template CWzNode* CWzList::GetNext( CWzNode* node ) const { WzAssert( node ); WzAssert( m_tail ); if( node && node->GetNext() != m_tail ) { return node->GetNext(); } return NULL; } //------------------------------------------------------------------------------ /** */ template int CWzList::GetCount( void ) const { return m_numNodes; } //------------------------------------------------------------------------------ /** */ template BOOL CWzList::IsEmpty( void ) const { WzAssert( m_head ); WzAssert( m_tail ); return ( m_head->GetNext() == m_tail ); } //------------------------------------------------------------------------------ /** */ template void CWzList::SetData( CWzNode* node, const T& data ) { WzAssert( node ); if( node ) { node->SetData( data ); } } //------------------------------------------------------------------------------ /** */ template T& CWzList::GetData( CWzNode* node ) const { WzAssert( node ); WzAssert( m_head ); WzAssert( m_tail ); if( node && node != m_head && node != m_tail ) { return node->GetData(); } WZLOG( WZWAR, "CWzList::GetData() - À߸øµÈ ³ëµå(¾²·¹±â°ª ¹Ýȯ)" ); return m_dummyData; } #endif // _PROGRAMCOMMON_WZLIST_H_