Annotation of mstools/mfc/samples/templdef/list.ctt, revision 1.1

1.1     ! root        1: /////////////////////////////////////////////////////////////////////////////
        !             2: // class CList<TYPE, ARG_TYPE, IS_SERIAL, HAS_CREATE> - a list containing 'TYPE' elements
        !             3: // passed in parameters as ARG_TYPE
        !             4: //
        !             5: // This is a part of the Microsoft Foundation Classes C++ library.
        !             6: // Copyright (C) 1992 Microsoft Corporation
        !             7: // All rights reserved.
        !             8: //
        !             9: // This source code is only intended as a supplement to the
        !            10: // Microsoft Foundation Classes Reference and Microsoft
        !            11: // QuickHelp documentation provided with the library.
        !            12: // See these sources for detailed information regarding the
        !            13: // Microsoft Foundation Classes product.
        !            14: /////////////////////////////////////////////////////////////////////////////
        !            15: 
        !            16: //$DECLARE_TEMPLATE
        !            17: 
        !            18: /////////////////////////////////////////////////////////////////////////////
        !            19: 
        !            20: template <class TYPE, class ARG_TYPE, int IS_SERIAL, int HAS_CREATE>
        !            21: class CList : public CObject
        !            22: {
        !            23: #if IS_SERIAL
        !            24:        DECLARE_SERIAL(CList)
        !            25: #else
        !            26:        DECLARE_DYNAMIC(CList)
        !            27: #endif //!IS_SERIAL
        !            28: 
        !            29: protected:
        !            30:        struct CNode
        !            31:        {
        !            32:                CNode*  pNext;
        !            33:                CNode*  pPrev;
        !            34:                TYPE    data;
        !            35:        };
        !            36: public:
        !            37: 
        !            38: // Construction
        !            39:        CList(int nBlockSize=10);
        !            40: 
        !            41: // Attributes (head and tail)
        !            42:        // count of elements
        !            43:        int     GetCount() const
        !            44:                                { return m_nCount; }
        !            45:        BOOL    IsEmpty() const
        !            46:                                { return m_nCount == 0; }
        !            47: 
        !            48:        // peek at head or tail
        !            49:        TYPE&   GetHead()
        !            50:                                { ASSERT(m_pNodeHead != NULL);
        !            51:                                        return m_pNodeHead->data; }
        !            52:        TYPE    GetHead() const
        !            53:                                { ASSERT(m_pNodeHead != NULL);
        !            54:                                        return m_pNodeHead->data; }
        !            55:        TYPE&   GetTail()
        !            56:                                { ASSERT(m_pNodeTail != NULL);
        !            57:                                        return m_pNodeTail->data; }
        !            58:        TYPE    GetTail() const
        !            59:                                { ASSERT(m_pNodeTail != NULL);
        !            60:                                        return m_pNodeTail->data; }
        !            61: 
        !            62: // Operations
        !            63:        // get head or tail (and remove it) - don't call on empty list !
        !            64:        TYPE    RemoveHead();
        !            65:        TYPE    RemoveTail();
        !            66: 
        !            67:        // add before head or after tail
        !            68:        POSITION AddHead(ARG_TYPE newElement);
        !            69:        POSITION AddTail(ARG_TYPE newElement);
        !            70: 
        !            71:        // add another list of elements before head or after tail
        !            72:        void    AddHead(CList* pNewList);
        !            73:        void    AddTail(CList* pNewList);
        !            74: 
        !            75:        // remove all elements
        !            76:        void    RemoveAll();
        !            77: 
        !            78:        // iteration
        !            79:        POSITION GetHeadPosition() const
        !            80:                                { return (POSITION) m_pNodeHead; }
        !            81:        POSITION GetTailPosition() const
        !            82:                                { return (POSITION) m_pNodeTail; }
        !            83:        TYPE&   GetNext(POSITION& rPosition) // return *Position++
        !            84:                                { CNode* pNode = (CNode*) rPosition;
        !            85:                                        ASSERT(pNode != NULL);
        !            86:                                        rPosition = (POSITION) pNode->pNext;
        !            87:                                        return pNode->data; }
        !            88:        TYPE    GetNext(POSITION& rPosition) const // return *Position++
        !            89:                                { CNode* pNode = (CNode*) rPosition;
        !            90:                                        ASSERT(pNode != NULL);
        !            91:                                        rPosition = (POSITION) pNode->pNext;
        !            92:                                        return pNode->data; }
        !            93:        TYPE&   GetPrev(POSITION& rPosition) // return *Position--
        !            94:                                { CNode* pNode = (CNode*) rPosition;
        !            95:                                        ASSERT(pNode != NULL);
        !            96:                                        rPosition = (POSITION) pNode->pPrev;
        !            97:                                        return pNode->data; }
        !            98:        TYPE    GetPrev(POSITION& rPosition) const // return *Position--
        !            99:                                { CNode* pNode = (CNode*) rPosition;
        !           100:                                        ASSERT(pNode != NULL);
        !           101:                                        rPosition = (POSITION) pNode->pPrev;
        !           102:                                        return pNode->data; }
        !           103: 
        !           104:        // getting/modifying an element at a given position
        !           105:        TYPE&   GetAt(POSITION position)
        !           106:                                { CNode* pNode = (CNode*) position;
        !           107:                                        ASSERT(pNode != NULL);
        !           108:                                        return pNode->data; }
        !           109:        TYPE    GetAt(POSITION position) const
        !           110:                                { CNode* pNode = (CNode*) position;
        !           111:                                        ASSERT(pNode != NULL);
        !           112:                                        return pNode->data; }
        !           113:        void    SetAt(POSITION pos, ARG_TYPE newElement)
        !           114:                                { CNode* pNode = (CNode*) pos;
        !           115:                                        ASSERT(pNode != NULL);
        !           116:                                        pNode->data = newElement; }
        !           117:        void    RemoveAt(POSITION position);
        !           118: 
        !           119:        // inserting before or after a given position
        !           120:        POSITION InsertBefore(POSITION position, ARG_TYPE newElement);
        !           121:        POSITION InsertAfter(POSITION position, ARG_TYPE newElement);
        !           122: 
        !           123:        // helper functions (note: O(n) speed)
        !           124:        POSITION Find(ARG_TYPE searchValue, POSITION startAfter = NULL) const;
        !           125:                                                // defaults to starting at the HEAD
        !           126:                                                // return NULL if not found
        !           127:        POSITION FindIndex(int nIndex) const;
        !           128:                                                // get the 'nIndex'th element (may return NULL)
        !           129: 
        !           130: // Implementation
        !           131: protected:
        !           132:        CNode*  m_pNodeHead;
        !           133:        CNode*  m_pNodeTail;
        !           134:        int     m_nCount;
        !           135:        CNode*  m_pNodeFree;
        !           136:        struct CPlex* m_pBlocks;
        !           137:        int     m_nBlockSize;
        !           138: 
        !           139:        CNode*  NewNode(CNode*, CNode*);
        !           140:        void    FreeNode(CNode*);
        !           141: 
        !           142: public:
        !           143:        ~CList();
        !           144: #if IS_SERIAL
        !           145:        void    Serialize(CArchive&);
        !           146: #endif //IS_SERIAL
        !           147: #ifdef _DEBUG
        !           148:        void    Dump(CDumpContext&) const;
        !           149:        void    AssertValid() const;
        !           150: #endif
        !           151: };
        !           152: 
        !           153: //$IMPLEMENT_TEMPLATE
        !           154: 
        !           155: /////////////////////////////////////////////////////////////////////////////
        !           156: //
        !           157: // Implementation of List of TYPEs
        !           158: //
        !           159: /////////////////////////////////////////////////////////////////////////////
        !           160: 
        !           161: #include "afxcoll.h"
        !           162: #pragma hdrstop
        !           163: 
        !           164: #include "plex.h"
        !           165: 
        !           166: #ifdef AFX_COLL_SEG
        !           167: #pragma code_seg(AFX_COLL_SEG)
        !           168: #endif
        !           169: 
        !           170: #if IS_SERIAL
        !           171: IMPLEMENT_SERIAL(CList, CObject, 0);
        !           172: #else
        !           173: IMPLEMENT_DYNAMIC(CList, CObject);
        !           174: #endif //!IS_SERIAL
        !           175: 
        !           176: #ifdef _DEBUG
        !           177: #undef THIS_FILE
        !           178: static char BASED_CODE THIS_FILE[] = __FILE__;
        !           179: #endif
        !           180: 
        !           181: #if HAS_CREATE
        !           182: #include "elements.h"       // used for special creation
        !           183: #endif
        !           184: 
        !           185: /////////////////////////////////////////////////////////////////////////////
        !           186: 
        !           187: template <class TYPE, class ARG_TYPE, int IS_SERIAL, int HAS_CREATE>
        !           188: CList<TYPE, ARG_TYPE, IS_SERIAL, HAS_CREATE>::CList(int nBlockSize)
        !           189: {
        !           190:        ASSERT(nBlockSize > 0);
        !           191: 
        !           192:        m_nCount = 0;
        !           193:        m_pNodeHead = m_pNodeTail = m_pNodeFree = NULL;
        !           194:        m_pBlocks = NULL;
        !           195:        m_nBlockSize = nBlockSize;
        !           196: }
        !           197: 
        !           198: template <class TYPE, class ARG_TYPE, int IS_SERIAL, int HAS_CREATE>
        !           199: void CList<TYPE, ARG_TYPE, IS_SERIAL, HAS_CREATE>::RemoveAll()
        !           200: {
        !           201:        ASSERT_VALID(this);
        !           202: 
        !           203:        // destroy elements
        !           204: #if HAS_CREATE
        !           205:        register CNode* pNode;
        !           206:        for (pNode = m_pNodeHead; pNode != NULL; pNode = pNode->pNext)
        !           207:                DestructElement(&pNode->data);
        !           208: #endif
        !           209: 
        !           210:        m_nCount = 0;
        !           211:        m_pNodeHead = m_pNodeTail = m_pNodeFree = NULL;
        !           212:        m_pBlocks->FreeDataChain();
        !           213:        m_pBlocks = NULL;
        !           214: }
        !           215: 
        !           216: template <class TYPE, class ARG_TYPE, int IS_SERIAL, int HAS_CREATE>
        !           217: CList<TYPE, ARG_TYPE, IS_SERIAL, HAS_CREATE>::~CList()
        !           218: {
        !           219:        RemoveAll();
        !           220:        ASSERT(m_nCount == 0);
        !           221: }
        !           222: 
        !           223: /////////////////////////////////////////////////////////////////////////////
        !           224: // Node helpers
        !           225: /*
        !           226:  * Implementation note: CNode's are stored in CPlex blocks and
        !           227:  *  chained together. Free blocks are maintained in a singly linked list
        !           228:  *  using the 'pNext' member of CNode with 'm_pNodeFree' as the head.
        !           229:  *  Used blocks are maintained in a doubly linked list using both 'pNext'
        !           230:  *  and 'pPrev' as links and 'm_pNodeHead' and 'm_pNodeTail'
        !           231:  *   as the head/tail.
        !           232:  *
        !           233:  * We never free a CPlex block unless the List is destroyed or RemoveAll()
        !           234:  *  is used - so the total number of CPlex blocks may grow large depending
        !           235:  *  on the maximum past size of the list.
        !           236:  */
        !           237: 
        !           238: template <class TYPE, class ARG_TYPE, int IS_SERIAL, int HAS_CREATE>
        !           239: CList<TYPE, ARG_TYPE, IS_SERIAL, HAS_CREATE>::CNode*
        !           240: CList<TYPE, ARG_TYPE, IS_SERIAL, HAS_CREATE>::NewNode(CList::CNode* pPrev, CList::CNode* pNext)
        !           241: {
        !           242:        if (m_pNodeFree == NULL)
        !           243:        {
        !           244:                // add another block
        !           245:                CPlex* pNewBlock = CPlex::Create(m_pBlocks, m_nBlockSize,
        !           246:                                 sizeof(CNode));
        !           247: 
        !           248:                // chain them into free list
        !           249:                CNode* pNode = (CNode*) pNewBlock->data();
        !           250:                // free in reverse order to make it easier to debug
        !           251:                pNode += m_nBlockSize - 1;
        !           252:                for (int i = m_nBlockSize-1; i >= 0; i--, pNode--)
        !           253:                {
        !           254:                        pNode->pNext = m_pNodeFree;
        !           255:                        m_pNodeFree = pNode;
        !           256:                }
        !           257:        }
        !           258:        ASSERT(m_pNodeFree != NULL); // we must have something
        !           259: 
        !           260:        register CList::CNode* pNode = m_pNodeFree;
        !           261:        m_pNodeFree = m_pNodeFree->pNext;
        !           262:        pNode->pPrev = pPrev;
        !           263:        pNode->pNext = pNext;
        !           264:        m_nCount++;
        !           265:        ASSERT(m_nCount > 0);       // make sure we don't overflow
        !           266: 
        !           267: #if HAS_CREATE
        !           268:        ConstructElement(&pNode->data);
        !           269: #else
        !           270:        memset(&pNode->data, 0, sizeof(TYPE));          // zero fill
        !           271: #endif
        !           272:        return pNode;
        !           273: }
        !           274: 
        !           275: template <class TYPE, class ARG_TYPE, int IS_SERIAL, int HAS_CREATE>
        !           276: void CList<TYPE, ARG_TYPE, IS_SERIAL, HAS_CREATE>::FreeNode(CList::CNode* pNode)
        !           277: {
        !           278: #if HAS_CREATE
        !           279:        DestructElement(&pNode->data);
        !           280: #endif
        !           281:        pNode->pNext = m_pNodeFree;
        !           282:        m_pNodeFree = pNode;
        !           283:        m_nCount--;
        !           284:        ASSERT(m_nCount >= 0);      // make sure we don't underflow
        !           285: }
        !           286: 
        !           287: /////////////////////////////////////////////////////////////////////////////
        !           288: 
        !           289: template <class TYPE, class ARG_TYPE, int IS_SERIAL, int HAS_CREATE>
        !           290: POSITION CList<TYPE, ARG_TYPE, IS_SERIAL, HAS_CREATE>::AddHead(ARG_TYPE newElement)
        !           291: {
        !           292:        ASSERT_VALID(this);
        !           293: 
        !           294:        CNode* pNewNode = NewNode(NULL, m_pNodeHead);
        !           295:        pNewNode->data = newElement;
        !           296:        if (m_pNodeHead != NULL)
        !           297:                m_pNodeHead->pPrev = pNewNode;
        !           298:        else
        !           299:                m_pNodeTail = pNewNode;
        !           300:        m_pNodeHead = pNewNode;
        !           301:        return (POSITION) pNewNode;
        !           302: }
        !           303: 
        !           304: template <class TYPE, class ARG_TYPE, int IS_SERIAL, int HAS_CREATE>
        !           305: POSITION CList<TYPE, ARG_TYPE, IS_SERIAL, HAS_CREATE>::AddTail(ARG_TYPE newElement)
        !           306: {
        !           307:        ASSERT_VALID(this);
        !           308: 
        !           309:        CNode* pNewNode = NewNode(m_pNodeTail, NULL);
        !           310:        pNewNode->data = newElement;
        !           311:        if (m_pNodeTail != NULL)
        !           312:                m_pNodeTail->pNext = pNewNode;
        !           313:        else
        !           314:                m_pNodeHead = pNewNode;
        !           315:        m_pNodeTail = pNewNode;
        !           316:        return (POSITION) pNewNode;
        !           317: }
        !           318: 
        !           319: template <class TYPE, class ARG_TYPE, int IS_SERIAL, int HAS_CREATE>
        !           320: void CList<TYPE, ARG_TYPE, IS_SERIAL, HAS_CREATE>::AddHead(CList* pNewList)
        !           321: {
        !           322:        ASSERT_VALID(this);
        !           323: 
        !           324:        ASSERT(pNewList != NULL);
        !           325:        ASSERT(pNewList->IsKindOf(RUNTIME_CLASS(CList)));
        !           326:        ASSERT_VALID(pNewList);
        !           327: 
        !           328:        // add a list of same elements to head (maintain order)
        !           329:        POSITION pos = pNewList->GetTailPosition();
        !           330:        while (pos != NULL)
        !           331:                AddHead(pNewList->GetPrev(pos));
        !           332: }
        !           333: 
        !           334: template <class TYPE, class ARG_TYPE, int IS_SERIAL, int HAS_CREATE>
        !           335: void CList<TYPE, ARG_TYPE, IS_SERIAL, HAS_CREATE>::AddTail(CList* pNewList)
        !           336: {
        !           337:        ASSERT_VALID(this);
        !           338:        ASSERT(pNewList != NULL);
        !           339:        ASSERT(pNewList->IsKindOf(RUNTIME_CLASS(CList)));
        !           340:        ASSERT_VALID(pNewList);
        !           341: 
        !           342:        // add a list of same elements
        !           343:        POSITION pos = pNewList->GetHeadPosition();
        !           344:        while (pos)
        !           345:                AddTail(pNewList->GetNext(pos));
        !           346: }
        !           347: 
        !           348: template <class TYPE, class ARG_TYPE, int IS_SERIAL, int HAS_CREATE>
        !           349: TYPE CList<TYPE, ARG_TYPE, IS_SERIAL, HAS_CREATE>::RemoveHead()
        !           350: {
        !           351:        ASSERT_VALID(this);
        !           352:        ASSERT(m_pNodeHead != NULL);    // don't call on empty list !!!
        !           353: 
        !           354:        CNode* pOldNode = m_pNodeHead;
        !           355:        ASSERT(pOldNode != NULL);
        !           356:        TYPE returnValue = pOldNode->data;
        !           357: 
        !           358:        m_pNodeHead = pOldNode->pNext;
        !           359:        if (m_pNodeHead != NULL)
        !           360:                m_pNodeHead->pPrev = NULL;
        !           361:        else
        !           362:                m_pNodeTail = NULL;
        !           363:        FreeNode(pOldNode);
        !           364:        return returnValue;
        !           365: }
        !           366: 
        !           367: template <class TYPE, class ARG_TYPE, int IS_SERIAL, int HAS_CREATE>
        !           368: TYPE CList<TYPE, class ARG_TYPE, int IS_SERIAL, int HAS_CREATE>::RemoveTail()
        !           369: {
        !           370:        ASSERT_VALID(this);
        !           371:        ASSERT(m_pNodeTail != NULL);    // don't call on empty list !!!
        !           372: 
        !           373:        CNode* pOldNode = m_pNodeTail;
        !           374:        ASSERT(pOldNode != NULL);
        !           375:        TYPE returnValue = pOldNode->data;
        !           376: 
        !           377:        m_pNodeTail = pOldNode->pPrev;
        !           378:        if (m_pNodeTail != NULL)
        !           379:                m_pNodeTail->pNext = NULL;
        !           380:        else
        !           381:                m_pNodeHead = NULL;
        !           382:        FreeNode(pOldNode);
        !           383:        return returnValue;
        !           384: }
        !           385: 
        !           386: template <class TYPE, class ARG_TYPE, int IS_SERIAL, int HAS_CREATE>
        !           387: POSITION CList<TYPE>::InsertBefore(POSITION position, ARG_TYPE newElement)
        !           388: {
        !           389:        ASSERT_VALID(this);
        !           390: 
        !           391:        if (position == NULL)
        !           392:                return AddHead(newElement); // insert before nothing -> head of the list
        !           393: 
        !           394:        // Insert it before position
        !           395:        CNode* pOldNode = (CNode*) position;
        !           396:        CNode* pNewNode = NewNode(pOldNode->pPrev, pOldNode);
        !           397:        pNewNode->data = newElement;
        !           398: 
        !           399:        if (pOldNode->pPrev != NULL)
        !           400:        {
        !           401:                pOldNode->pPrev->pNext = pNewNode;
        !           402:        }
        !           403:        else
        !           404:        {
        !           405:                ASSERT(pOldNode == m_pNodeHead);
        !           406:                m_pNodeHead = pNewNode;
        !           407:        }
        !           408:        pOldNode->pPrev = pNewNode;
        !           409:        return (POSITION) pNewNode;
        !           410: }
        !           411: 
        !           412: template <class TYPE, class ARG_TYPE, int IS_SERIAL, int HAS_CREATE>
        !           413: POSITION CList<TYPE, ARG_TYPE, IS_SERIAL, HAS_CREATE>::InsertAfter(POSITION position, ARG_TYPE newElement)
        !           414: {
        !           415:        ASSERT_VALID(this);
        !           416: 
        !           417:        if (position == NULL)
        !           418:                return AddTail(newElement); // insert after nothing -> tail of the list
        !           419: 
        !           420:        // Insert it before position
        !           421:        CNode* pOldNode = (CNode*) position;
        !           422:        CNode* pNewNode = NewNode(pOldNode, pOldNode->pNext);
        !           423:        pNewNode->data = newElement;
        !           424: 
        !           425:        if (pOldNode->pNext != NULL)
        !           426:        {
        !           427:                pOldNode->pNext->pPrev = pNewNode;
        !           428:        }
        !           429:        else
        !           430:        {
        !           431:                ASSERT(pOldNode == m_pNodeTail);
        !           432:                m_pNodeTail = pNewNode;
        !           433:        }
        !           434:        pOldNode->pNext = pNewNode;
        !           435:        return (POSITION) pNewNode;
        !           436: }
        !           437: 
        !           438: template <class TYPE, class ARG_TYPE, int IS_SERIAL, int HAS_CREATE>
        !           439: void CList<TYPE, ARG_TYPE, IS_SERIAL, HAS_CREATE>::RemoveAt(POSITION position)
        !           440: {
        !           441:        ASSERT_VALID(this);
        !           442:        ASSERT(position != NULL);
        !           443: 
        !           444:        CNode* pOldNode = (CNode*) position;
        !           445: 
        !           446:        // remove pOldNode from list
        !           447:        if (pOldNode == m_pNodeHead)
        !           448:                m_pNodeHead = pOldNode->pNext;
        !           449:        else
        !           450:                pOldNode->pPrev->pNext = pOldNode->pNext;
        !           451:        if (pOldNode == m_pNodeTail)
        !           452:                m_pNodeTail = pOldNode->pPrev;
        !           453:        else
        !           454:                pOldNode->pNext->pPrev = pOldNode->pPrev;
        !           455:        FreeNode(pOldNode);
        !           456: }
        !           457: 
        !           458: 
        !           459: /////////////////////////////////////////////////////////////////////////////
        !           460: // slow operations
        !           461: 
        !           462: template <class TYPE, class ARG_TYPE, int IS_SERIAL, int HAS_CREATE>
        !           463: POSITION CList<TYPE, ARG_TYPE, IS_SERIAL, HAS_CREATE>::FindIndex(int nIndex) const
        !           464: {
        !           465:        ASSERT_VALID(this);
        !           466:        ASSERT(nIndex >= 0);
        !           467: 
        !           468:        if (nIndex >= m_nCount)
        !           469:                return NULL;        // went too far
        !           470: 
        !           471:        register CNode* pNode = m_pNodeHead;
        !           472:        while (nIndex--)
        !           473:                pNode = pNode->pNext;
        !           474:        return (POSITION) pNode;
        !           475: }
        !           476: 
        !           477: template <class TYPE, class ARG_TYPE, int IS_SERIAL, int HAS_CREATE>
        !           478: POSITION CList<TYPE, ARG_TYPE, IS_SERIAL, HAS_CREATE>::Find(ARG_TYPE searchValue, POSITION startAfter) const
        !           479: {
        !           480:        ASSERT_VALID(this);
        !           481: 
        !           482:        register CNode* pNode = (CNode*) startAfter;
        !           483:        if (pNode == NULL)
        !           484:                pNode = m_pNodeHead;        // start at head
        !           485:        else
        !           486:                pNode = pNode->pNext;       // start after the one specified
        !           487: 
        !           488:        for (; pNode != NULL; pNode = pNode->pNext)
        !           489:                if (pNode->data == searchValue)
        !           490:                        return (POSITION) pNode;
        !           491:        return NULL;
        !           492: }
        !           493: 
        !           494: /////////////////////////////////////////////////////////////////////////////
        !           495: // Serialization
        !           496: 
        !           497: #if IS_SERIAL
        !           498: template <class TYPE, class ARG_TYPE, int IS_SERIAL, int HAS_CREATE>
        !           499: void CList<TYPE, ARG_TYPE, IS_SERIAL, HAS_CREATE>::Serialize(CArchive& ar)
        !           500: {
        !           501:        ASSERT_VALID(this);
        !           502: 
        !           503:        CObject::Serialize(ar);
        !           504: 
        !           505:        if (ar.IsStoring())
        !           506:        {
        !           507:                ar << (WORD) m_nCount;
        !           508:                for (CNode* pNode = m_pNodeHead; pNode != NULL;
        !           509:                  pNode = pNode->pNext)
        !           510:                        ar << pNode->data;
        !           511:        }
        !           512:        else
        !           513:        {
        !           514:                WORD nNewCount;
        !           515:                ar >> nNewCount;
        !           516:                while (nNewCount--)
        !           517:                {
        !           518:                        TYPE newData;
        !           519:                        ar >> newData;
        !           520:                        AddTail(newData);
        !           521:                }
        !           522:        }
        !           523: }
        !           524: #endif //IS_SERIAL
        !           525: 
        !           526: /////////////////////////////////////////////////////////////////////////////
        !           527: // Diagnostics
        !           528: 
        !           529: #ifdef _DEBUG
        !           530: template <class TYPE, class ARG_TYPE, int IS_SERIAL, int HAS_CREATE>
        !           531: void CList<TYPE, ARG_TYPE, IS_SERIAL, HAS_CREATE>::Dump(CDumpContext& dc) const
        !           532: {
        !           533:        ASSERT_VALID(this);
        !           534: 
        !           535: #define MAKESTRING(x) #x
        !           536:        dc << "a " MAKESTRING(CList) " with " << m_nCount << " elements";
        !           537: #undef MAKESTRING
        !           538:        if (dc.GetDepth() > 0)
        !           539:        {
        !           540:                POSITION pos = GetHeadPosition();
        !           541:                dc << "\n";
        !           542: 
        !           543:                while (pos != NULL)
        !           544:                        dc << "\n\t" << GetNext(pos);
        !           545:        }
        !           546: }
        !           547: 
        !           548: template <class TYPE, class ARG_TYPE, int IS_SERIAL, int HAS_CREATE>
        !           549: void CList<TYPE, ARG_TYPE, IS_SERIAL, HAS_CREATE>::AssertValid() const
        !           550: {
        !           551:        CObject::AssertValid();
        !           552: 
        !           553:        if (m_nCount == 0)
        !           554:        {
        !           555:                // empty list
        !           556:                ASSERT(m_pNodeHead == NULL);
        !           557:                ASSERT(m_pNodeTail == NULL);
        !           558:        }
        !           559:        else
        !           560:        {
        !           561:                // non-empty list
        !           562:                ASSERT(m_pNodeHead != NULL);
        !           563:                ASSERT(m_pNodeTail != NULL);
        !           564:        }
        !           565: }
        !           566: #endif //_DEBUG
        !           567: 
        !           568: /////////////////////////////////////////////////////////////////////////////

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.