Programming - cpueblo.com

wTemplateList - 템플릿으로 구성된 List 클래스 라이브러리


글쓴이 : 유광희 날짜 : 2007-09-14 (금) 14:00 조회 : 10596
#ifndef __WTEMPLATELIST_H__
#define __WTEMPLATELIST_H__

/*******************************************************************

    wTemplateList : List 처리 관련 템플릿 클래스

    by : cpueblo@cpueblo.com, 유광희

    help : debugx

    History : 2007.09.14 1차 등록

ex)
    typedef wTemplateList    TIntegerList;
    TIntegerList a;

    a.Add(5);
    a.Add(10);

    // Items[] 를 이용시
    for (int i = 0; i < a.Count; i++)
    {
        TRACE("%d = %d\\n", i, a.Items[i]);
    }

    // Node 를 이용시
    int *p;
    for (a.MoveHead(); p = a.GetNode(); a.MoveNext())
    {
        TRACE("- %d\\n", *p);

        // 10이라는 숫자를 만나면 해당 Node 를 리스트에서 지운다
        if (*p == 10)
            a.DeleteNode();
    }

    // 값 가져오기
    int A0 = a.Items[0];

    // 값 수정
    int *pA0 = a.ItemsPtr[0];
    *pA0 = 10;
*******************************************************************/


<FONT COLOR=#0000FF>template <<FONT COLOR=#0000FF>class Type>
class wTemplateList
{
private:
    Type extractData;

    class CNode
    {
    public:
        Type  tData;
        CNode * pPrev;
        CNode * pNext;
        CNode()
        {
            pPrev = NULL;
            pNext = NULL;
        }
    };

    CNode *    m_pHead;
    CNode *    m_pTail;

    // MoveHead, MoveTail, MoveNext, MovePrev 에서만 사용
    CNode *    m_pCrnt;
    int        m_nCount;

public:
    wTemplateList (void);
    ~wTemplateList (void);

    void    Add     (Type tData);            // 새로운 값을 마지막에 추가한 후 추가된 인덱스 번호를 리턴한다. 시작은 0 이다.
    void    Clear   (void);                    // 모든 인덱스를 삭제하며, 총 개수를 0 으로 초기화한다
    BOOL    delete  (int Index);            // 특정 인덱스를 삭제한다. 삭제후에는 Index 배열의 변화가 생기므로 유의해야 한다
    Type     Extract (int Index);            // 리스트에서 인덱스에 해당하는 아이템을 추출한다
                                            // 아이템의 추출과 함께 삭제를 처리하며, 총 개수를 감소시킨다

    // [] 를 이용한 처리 관련
    __declspec(property(get=PGetCount))        int        Count;
    __declspec(property(get=PGetItems))        Type    Items[];
    __declspec(property(get=PGetItemsPtr))    Type*    ItemsPtr[];

    // Node 직접 처리 관련
    Type *    MoveHead (void);
    Type *    MoveTail (void);
    Type *    MoveNext (void);
    Type *    MovePrev (void);
    Type *    GetNode     (void);
    void    DeleteNode(void);

private:
    // FMoveIndex 사용시 인덱스 이동 속도를 효율적으로 하기 위해
    int        LastMoveIndex;
    CNode *    LastMoveNode;

public:
    Type    PGetItems(int Index);
    Type *    PGetItemsPtr(int Index);
    int        PGetCount (void);

private:
    void *    FMoveIndex (int i);
    void    FResetLastMoveIndex();
    void    FDeleteNode(CNode *Node);
};


//-----------------------------------------------------------------------------
// Construction
//-----------------------------------------------------------------------------
template <<FONT COLOR=#0000FF>class Type>
inline wTemplateList::wTemplateList (void) : m_pHead(0), m_pTail(0), m_pCrnt(0), m_nCount(0)
{
    FResetLastMoveIndex();
}


//-----------------------------------------------------------------------------
// Destruction
//-----------------------------------------------------------------------------
template <<FONT COLOR=#0000FF>class Type>
inline wTemplateList::~wTemplateList (void)
{
    Clear();
}


//-----------------------------------------------------------------------------
// Add()
//-----------------------------------------------------------------------------
template <<FONT COLOR=#0000FF>class Type>
inline void wTemplateList::Add (Type tData)
{
    CNode * pNode = new CNode;
    pNode->tData = tData;
    m_nCount++;

    if (m_pHead)
    {
        m_pTail->pNext = pNode;
        pNode->pPrev   = m_pTail;
        m_pTail           = pNode;
    }
    else
    {
        m_pHead = pNode;
        m_pTail = pNode;
    }
}




//-----------------------------------------------------------------------------
// Extract() - 해당 인덱스를 삭제함과 동시에 값을 리턴
//-----------------------------------------------------------------------------
template <<FONT COLOR=#0000FF>class Type>
inline Type wTemplateList::Extract (int i)
{
    CNode *pNode = (CNode *)FMoveIndex(i);

    extractData = pNode->tData;

    FDeleteNode(pNode);
    FResetLastMoveIndex();

    return extractData;
}


//-----------------------------------------------------------------------------
// Delete() - 해당 인덱스를 삭제
//-----------------------------------------------------------------------------
template <<FONT COLOR=#0000FF>class Type>
inline BOOL wTemplateList::Delete (int i)
{
    CNode *pNode = (CNode *)FMoveIndex(i);

    if (!pNode)
        return FALSE;

    FDeleteNode(pNode);

    FResetLastMoveIndex();
    return TRUE;
}


//-----------------------------------------------------------------------------
// FResetLastMoveIndex() - 마지막 검색 인덱스를 초기화 한다
//-----------------------------------------------------------------------------
template <<FONT COLOR=#0000FF>class Type>
inline void wTemplateList::FResetLastMoveIndex()
{
    LastMoveIndex = -2;
    LastMoveNode = NULL;
}


//-----------------------------------------------------------------------------
// FDeleteNode() - 특정 노드의 삭제
//-----------------------------------------------------------------------------
template <<FONT COLOR=#0000FF>class Type>
inline void wTemplateList::FDeleteNode (CNode *pNode)
{
    CNode * pPrev = pNode->pPrev;
    CNode * pNext = pNode->pNext;

    // 이전의 다음은 다음꺼
    if (pPrev)
        pPrev->pNext = pNext;

    // 다음의 이전은 이전꺼
    if (pNext)
        pNext->pPrev = pPrev;

    // 이전이 없다면 헤드는 다음꺼
    if (!pPrev)
        m_pHead = pNext;

    // 다음이 없다면 꼬리는 이전꺼
    if (!pNext)
        m_pTail = pPrev;

    delete pNode;
    m_nCount--;
}


//-----------------------------------------------------------------------------
// FMoveIndex() - 인덱스 이동
//-----------------------------------------------------------------------------
template <<FONT COLOR=#0000FF>class Type>
inline void * wTemplateList::FMoveIndex (int i)
{
    int Count = 0;

    // 가장 많이 쓰이는 다음 인덱스를 요청시
    if (LastMoveIndex + 1 == i)
    {
        LastMoveIndex++;
        LastMoveNode = LastMoveNode->pNext;
        return LastMoveNode;
    }

    // 이전 인덱스를 요청시
    if (LastMoveIndex - 1 == i)
    {
        LastMoveIndex--;
        LastMoveNode = LastMoveNode->pPrev;
        return LastMoveNode;
    }

    // 같은 인덱스를 요청시
    if (LastMoveIndex == i)
        return LastMoveNode;


    for (CNode * pNode = m_pHead; pNode;)
    {
        if (Count == i)
        {
            LastMoveNode = pNode;
            LastMoveIndex = i;
            return pNode;
        }

        Count++;
        pNode = pNode->pNext;
    }

    return NULL;
}


//-----------------------------------------------------------------------------
// Clear()
//-----------------------------------------------------------------------------
template <<FONT COLOR=#0000FF>class Type>
inline void wTemplateList::Clear (void)
{
    CNode * pTemp;

    for (CNode * pNode = m_pHead ; pNode; pNode = pTemp)
    {
        pTemp = pNode->pNext;
        if (pNode)
        {
            delete pNode;
            pNode = 0;
        }
    }

    m_nCount = 0;
    m_pHead = 0;
    m_pTail = 0;
}


//-----------------------------------------------------------------------------
// DeleteNode() - MoveHead. MoveNext 등에서 이동 후 현재의 노드를 삭제시 사용
//-----------------------------------------------------------------------------
template <<FONT COLOR=#0000FF>class Type>
inline void wTemplateList::DeleteNode()
{
    CNode *Node = m_pCrnt->pPrev;

    FDeleteNode(m_pCrnt);

    m_pCrnt = Node;
}


//-----------------------------------------------------------------------------
// MoveHead()
//-----------------------------------------------------------------------------
template <<FONT COLOR=#0000FF>class Type>
inline Type *wTemplateList::MoveHead (void)
{
    m_pCrnt = m_pHead;

    return (Type *)m_pCrnt;
}


//-----------------------------------------------------------------------------
// MoveTail()
//-----------------------------------------------------------------------------
template <<FONT COLOR=#0000FF>class Type>
inline Type *wTemplateList::MoveTail (void)
{
    m_pCrnt = m_pTail;
    return (Type *)m_pCrnt;
}


//-----------------------------------------------------------------------------
// MoveNext()
//-----------------------------------------------------------------------------
template <<FONT COLOR=#0000FF>class Type>
inline Type *wTemplateList::MoveNext (void)
{
    if (m_pCrnt)
    {
        m_pCrnt = m_pCrnt->pNext;
        return (Type *)m_pCrnt;
    }

    return NULL;
}


//-----------------------------------------------------------------------------
// MovePrev()
//-----------------------------------------------------------------------------
template <<FONT COLOR=#0000FF>class Type>
inline Type *wTemplateList::MovePrev (void)
{
    if (m_pCrnt)
    {
        m_pCrnt = m_pCrnt->pPrev;
        return (Type *)m_pCrnt;
    }

    return NULL;
}


//-----------------------------------------------------------------------------
// GetNode()
//-----------------------------------------------------------------------------
template <<FONT COLOR=#0000FF>class Type>
inline Type *wTemplateList::GetNode (void)
{
    return (Type *)m_pCrnt;
}


//-----------------------------------------------------------------------------
// PGetItems - Items[] 프로퍼티에 의해 호출되는 함수
//-----------------------------------------------------------------------------
template <<FONT COLOR=#0000FF>class Type>
inline Type  wTemplateList::PGetItems(int Index)
{
    CNode *pNode = (CNode *)FMoveIndex(Index);

    if (!pNode)
        return FALSE;

    return pNode->tData;
}


//-----------------------------------------------------------------------------
// PGetItemsPtr - ItemsPtr[] 프로퍼티에 의해 호출되는 함수
//-----------------------------------------------------------------------------
template <<FONT COLOR=#0000FF>class Type>
inline Type * wTemplateList::PGetItemsPtr(int Index)
{
    CNode *pNode = (CNode *)FMoveIndex(Index);

    if (!pNode)
        return FALSE;

    return (Type *)pNode; //->tData;
}


//-----------------------------------------------------------------------------
// PGetCount() - Count 프로퍼티에 의 해 호출
//-----------------------------------------------------------------------------
template <<FONT COLOR=#0000FF>class Type>
inline int wTemplateList::PGetCount (void)
{
    return m_nCount;
}



#endif