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

1.1     ! root        1: ////////////////////////////////////////////////////////////////////////////
        !             2: // class CArray<TYPE, ARG_TYPE, IS_SERIAL, HAS_CREATE> - an array 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 CArray : public CObject
        !            22: {
        !            23: #if IS_SERIAL
        !            24:        DECLARE_SERIAL(CArray)
        !            25: #else
        !            26:        DECLARE_DYNAMIC(CArray)
        !            27: #endif //!IS_SERIAL
        !            28: public:
        !            29: 
        !            30: // Construction
        !            31:        CArray();
        !            32: 
        !            33: // Attributes
        !            34:        int     GetSize() const
        !            35:                                { return m_nSize; }
        !            36:        int     GetUpperBound() const
        !            37:                                { return m_nSize-1; }
        !            38:        void    SetSize(int nNewSize, int nGrowBy = -1);
        !            39: 
        !            40: // Operations
        !            41:        // Clean up
        !            42:        void    FreeExtra();
        !            43:        void    RemoveAll()
        !            44:                                { SetSize(0); }
        !            45: 
        !            46:        // Accessing elements
        !            47:        TYPE    GetAt(int nIndex) const
        !            48:                                { ASSERT(nIndex >= 0 && nIndex < m_nSize);
        !            49:                                        return m_pData[nIndex]; }
        !            50:        void    SetAt(int nIndex, ARG_TYPE newElement)
        !            51:                                { ASSERT(nIndex >= 0 && nIndex < m_nSize);
        !            52:                                        m_pData[nIndex] = newElement; }
        !            53:        TYPE&   ElementAt(int nIndex)
        !            54:                                { ASSERT(nIndex >= 0 && nIndex < m_nSize);
        !            55:                                        return m_pData[nIndex]; }
        !            56: 
        !            57:        // Potentially growing the array
        !            58:        void    SetAtGrow(int nIndex, ARG_TYPE newElement);
        !            59:        int     Add(ARG_TYPE newElement)
        !            60:                                { int nIndex = m_nSize;
        !            61:                                        SetAtGrow(nIndex, newElement);
        !            62:                                        return nIndex; }
        !            63: 
        !            64:        // overloaded operator helpers
        !            65:        TYPE    operator[](int nIndex) const
        !            66:                                { return GetAt(nIndex); }
        !            67:        TYPE&   operator[](int nIndex)
        !            68:                                { return ElementAt(nIndex); }
        !            69: 
        !            70:        // Operations that move elements around
        !            71:        void    InsertAt(int nIndex, ARG_TYPE newElement, int nCount = 1);
        !            72:        void    RemoveAt(int nIndex, int nCount = 1);
        !            73:        void    InsertAt(int nStartIndex, CArray* pNewArray);
        !            74: 
        !            75: // Implementation
        !            76: protected:
        !            77:        TYPE*   m_pData;        // the actual array of data
        !            78:        int     m_nSize;        // # of elements (upperBound - 1)
        !            79:        int     m_nMaxSize;     // max allocated
        !            80:        int     m_nGrowBy;      // grow amount
        !            81: 
        !            82: public:
        !            83:        ~CArray();
        !            84: #if IS_SERIAL
        !            85:        void    Serialize(CArchive&);
        !            86: #endif //IS_SERIAL
        !            87: #ifdef _DEBUG
        !            88:        void    Dump(CDumpContext&) const;
        !            89:        void    AssertValid() const;
        !            90: #endif
        !            91: };
        !            92: 
        !            93: //$IMPLEMENT_TEMPLATE
        !            94: 
        !            95: /////////////////////////////////////////////////////////////////////////////
        !            96: //
        !            97: // Implementation of Array of TYPEs
        !            98: //
        !            99: /////////////////////////////////////////////////////////////////////////////
        !           100: // NOTE: we allocate an array of 'm_nMaxSize' elements, but only
        !           101: //  the current size 'm_nSize' contains properly constructed
        !           102: //  objects.
        !           103: 
        !           104: #include "afxcoll.h"
        !           105: #pragma hdrstop
        !           106: 
        !           107: #ifdef AFX_COLL_SEG
        !           108: #pragma code_seg(AFX_COLL_SEG)
        !           109: #endif
        !           110: 
        !           111: #include <limits.h>
        !           112: #define SIZE_T_MAX  UINT_MAX            /* max size for a size_t */
        !           113: 
        !           114: #if IS_SERIAL
        !           115: IMPLEMENT_SERIAL(CArray, CObject, 0);
        !           116: #else
        !           117: IMPLEMENT_DYNAMIC(CArray, CObject);
        !           118: #endif //!IS_SERIAL
        !           119: 
        !           120: #ifdef _DEBUG
        !           121: #undef THIS_FILE
        !           122: static char BASED_CODE THIS_FILE[] = __FILE__;
        !           123: #endif
        !           124: 
        !           125: #define new DEBUG_NEW
        !           126: 
        !           127: /////////////////////////////////////////////////////////////////////////////
        !           128: 
        !           129: #if HAS_CREATE
        !           130: #include "elements.h"       // used for special creation
        !           131: 
        !           132: static void NEAR ConstructElements(register TYPE* pNewData, int nCount)
        !           133: {
        !           134:        ASSERT(nCount >= 0);
        !           135: 
        !           136:        while (nCount--)
        !           137:        {
        !           138:                ConstructElement(pNewData);
        !           139:                pNewData++;
        !           140:        }
        !           141: }
        !           142: 
        !           143: static void NEAR DestructElements(register TYPE* pOldData, int nCount)
        !           144: {
        !           145:        ASSERT(nCount >= 0);
        !           146: 
        !           147:        while (nCount--)
        !           148:        {
        !           149:                pOldData->Empty();
        !           150:                pOldData++;
        !           151:        }
        !           152: }
        !           153: #endif //HAS_CREATE
        !           154: 
        !           155: /////////////////////////////////////////////////////////////////////////////
        !           156: 
        !           157: template<class TYPE, class ARG_TYPE, int IS_SERIAL, int HAS_CREATE>
        !           158: CArray<TYPE, ARG_TYPE, IS_SERIAL, HAS_CREATE>::CArray()
        !           159: {
        !           160:        m_pData = NULL;
        !           161:        m_nSize = m_nMaxSize = m_nGrowBy = 0;
        !           162: }
        !           163: 
        !           164: template<class TYPE, ARG_TYPE, int IS_SERIAL, int HAS_CREATE>
        !           165: CArray<TYPE, ARG_TYPE, IS_SERIAL, HAS_CREATE>::~CArray()
        !           166: {
        !           167:        ASSERT_VALID(this);
        !           168: 
        !           169: #if HAS_CREATE
        !           170:        DestructElements(m_pData, m_nSize);
        !           171: #endif //HAS_CREATE
        !           172:        delete [] (BYTE*)m_pData;
        !           173: }
        !           174: 
        !           175: template <class TYPE, class ARG_TYPE, int IS_SERIAL, int HAS_CREATE>
        !           176: void CArray<TYPE, ARG_TYPE, IS_SERIAL, HAS_CREATE>::SetSize(int nNewSize, int nGrowBy /* = -1 */)
        !           177: {
        !           178:        ASSERT_VALID(this);
        !           179:        ASSERT(nNewSize >= 0);
        !           180: 
        !           181:        if (nGrowBy != -1)
        !           182:                m_nGrowBy = nGrowBy;    // set new size
        !           183: 
        !           184:        if (nNewSize == 0)
        !           185:        {
        !           186:                // shrink to nothing
        !           187: #if HAS_CREATE
        !           188:                DestructElements(m_pData, m_nSize);
        !           189: #endif //HAS_CREATE
        !           190:                delete [] (BYTE*)m_pData;
        !           191:                m_pData = NULL;
        !           192:                m_nSize = m_nMaxSize = 0;
        !           193:        }
        !           194:        else if (m_pData == NULL)
        !           195:        {
        !           196:                // create one with exact size
        !           197: #ifdef SIZE_T_MAX
        !           198:                ASSERT((long)nNewSize * sizeof(TYPE) <= SIZE_T_MAX);    // no overflow
        !           199: #endif
        !           200:                m_pData = (TYPE*) new BYTE[nNewSize * sizeof(TYPE)];
        !           201: #if HAS_CREATE
        !           202:                ConstructElements(m_pData, nNewSize);
        !           203: #else
        !           204:                memset(m_pData, 0, nNewSize * sizeof(TYPE));        // zero fill
        !           205: #endif
        !           206:                m_nSize = m_nMaxSize = nNewSize;
        !           207:        }
        !           208:        else if (nNewSize <= m_nMaxSize)
        !           209:        {
        !           210:                // it fits
        !           211:                if (nNewSize > m_nSize)
        !           212:                {
        !           213:                        // initialize the new elements
        !           214: #if HAS_CREATE
        !           215:                        ConstructElements(&m_pData[m_nSize], nNewSize-m_nSize);
        !           216: #else
        !           217:                        memset(&m_pData[m_nSize], 0, (nNewSize-m_nSize) * sizeof(TYPE));
        !           218: #endif
        !           219:                }
        !           220: #if HAS_CREATE
        !           221:                else if (m_nSize > nNewSize) // destroy the old elements
        !           222:                        DestructElements(&m_pData[nNewSize], m_nSize-nNewSize);
        !           223: #endif
        !           224:                m_nSize = nNewSize;
        !           225:        }
        !           226:        else
        !           227:        {
        !           228:                // Otherwise grow array
        !           229:                int nNewMax;
        !           230:                if (nNewSize < m_nMaxSize + m_nGrowBy)
        !           231:                        nNewMax = m_nMaxSize + m_nGrowBy;   // granularity
        !           232:                else
        !           233:                        nNewMax = nNewSize; // no slush
        !           234: 
        !           235: #ifdef SIZE_T_MAX
        !           236:                ASSERT((long)nNewMax * sizeof(TYPE) <= SIZE_T_MAX); // no overflow
        !           237: #endif
        !           238:                TYPE* pNewData = (TYPE*) new BYTE[nNewMax * sizeof(TYPE)];
        !           239: 
        !           240:                // copy new data from old
        !           241:                memcpy(pNewData, m_pData, m_nSize * sizeof(TYPE));
        !           242: 
        !           243:                // construct remaining elements
        !           244:                ASSERT(nNewSize > m_nSize);
        !           245: #if HAS_CREATE
        !           246:                ConstructElements(&pNewData[m_nSize], nNewSize-m_nSize);
        !           247: #else
        !           248:                memset(&pNewData[m_nSize], 0, (nNewSize-m_nSize) * sizeof(TYPE));
        !           249: #endif
        !           250: 
        !           251:                // get rid of old stuff (note: no destructors called)
        !           252:                delete [] (BYTE*)m_pData;
        !           253:                m_pData = pNewData;
        !           254:                m_nSize = nNewSize;
        !           255:                m_nMaxSize = nNewMax;
        !           256:        }
        !           257: }
        !           258: 
        !           259: template <class TYPE, class ARG_TYPE, int IS_SERIAL, int HAS_CREATE>
        !           260: void CArray<TYPE, ARG_TYPE, IS_SERIAL, HAS_CREATE>::FreeExtra()
        !           261: {
        !           262:        ASSERT_VALID(this);
        !           263: 
        !           264:        if (m_nSize != m_nMaxSize)
        !           265:        {
        !           266:                // shrink to desired size
        !           267: #ifdef SIZE_T_MAX
        !           268:                ASSERT((long)m_nSize * sizeof(TYPE) <= SIZE_T_MAX); // no overflow
        !           269: #endif
        !           270:                TYPE* pNewData = (TYPE*) new BYTE[m_nSize * sizeof(TYPE)];
        !           271:                // copy new data from old
        !           272:                memcpy(pNewData, m_pData, m_nSize * sizeof(TYPE));
        !           273: 
        !           274:                // get rid of old stuff (note: no destructors called)
        !           275:                delete [] (BYTE*)m_pData;
        !           276:                m_pData = pNewData;
        !           277:                m_nMaxSize = m_nSize;
        !           278:        }
        !           279: }
        !           280: 
        !           281: /////////////////////////////////////////////////////////////////////////////
        !           282: 
        !           283: template <class TYPE, class ARG_TYPE, int IS_SERIAL, int HAS_CREATE>
        !           284: void CArray<TYPE, ARG_TYPE, IS_SERIAL, HAS_CREATE>::SetAtGrow(int nIndex, ARG_TYPE newElement)
        !           285: {
        !           286:        ASSERT(nIndex >= 0);
        !           287:        if (nIndex >= m_nSize)
        !           288:                SetSize(nIndex+1);
        !           289:        m_pData[nIndex] = newElement;
        !           290: }
        !           291: 
        !           292: template <class TYPE, class ARG_TYPE, int IS_SERIAL, int HAS_CREATE>
        !           293: void CArray<TYPE, ARG_TYPE, IS_SERIAL, HAS_CREATE>::InsertAt(int nIndex, ARG_TYPE newElement, int nCount /*=1*/)
        !           294: {
        !           295:        ASSERT_VALID(this);
        !           296:        ASSERT(nIndex >= 0);        // will expand to meet need
        !           297:        ASSERT(nCount > 0);     // zero or negative size not allowed
        !           298: 
        !           299:        if (nIndex >= m_nSize)
        !           300:        {
        !           301:                // adding after the end of the array
        !           302:                SetSize(nIndex + nCount);       // grow so nIndex is valid
        !           303:        }
        !           304:        else
        !           305:        {
        !           306:                // inserting in the middle of the array
        !           307:                int nOldSize = m_nSize;
        !           308:                SetSize(m_nSize + nCount); // grow it to new size
        !           309:                // shift old data up to fill gap
        !           310:                memmove(&m_pData[nIndex+nCount], &m_pData[nIndex],
        !           311:                        (nOldSize-nIndex) * sizeof(TYPE));
        !           312: 
        !           313:                // re-init slots we copied from
        !           314: #if HAS_CREATE
        !           315:                ConstructElements(&m_pData[nIndex], nCount);
        !           316: #else
        !           317:                memset(&m_pData[nIndex], 0, nCount * sizeof(TYPE));
        !           318: #endif
        !           319:        }
        !           320: 
        !           321:        // insert new value in the gap
        !           322:        ASSERT(nIndex + nCount <= m_nSize);
        !           323:        while (nCount--)
        !           324:                m_pData[nIndex++] = newElement;
        !           325: }
        !           326: 
        !           327: template <class TYPE, class ARG_TYPE, int IS_SERIAL, int HAS_CREATE>
        !           328: void CArray<TYPE, ARG_TYPE, IS_SERIAL, HAS_CREATE>::RemoveAt(int nIndex, int nCount /* = 1 */)
        !           329: {
        !           330:        ASSERT_VALID(this);
        !           331:        ASSERT(nIndex >= 0);
        !           332:        ASSERT(nCount >= 0);
        !           333:        ASSERT(nIndex + nCount <= m_nSize);
        !           334: 
        !           335:        // just remove a range
        !           336:        int nMoveCount = m_nSize - (nIndex + nCount);
        !           337: #if HAS_CREATE
        !           338:        DestructElements(&m_pData[nIndex], nCount);
        !           339: #endif
        !           340:        if (nMoveCount)
        !           341:                memcpy(&m_pData[nIndex], &m_pData[nIndex + nCount],
        !           342:                        nMoveCount * sizeof(TYPE));
        !           343:        m_nSize -= nCount;
        !           344: }
        !           345: 
        !           346: template <class TYPE, class ARG_TYPE, int IS_SERIAL, int HAS_CREATE>
        !           347: void CArray<TYPE, ARG_TYPE, IS_SERIAL, HAS_CREATE>::InsertAt(int nStartIndex, CArray* pNewArray)
        !           348: {
        !           349:        ASSERT_VALID(this);
        !           350:        ASSERT(pNewArray != NULL);
        !           351:        ASSERT(pNewArray->IsKindOf(RUNTIME_CLASS(CArray)));
        !           352:        ASSERT_VALID(pNewArray);
        !           353:        ASSERT(nStartIndex >= 0);
        !           354: 
        !           355:        if (pNewArray->GetSize() > 0)
        !           356:        {
        !           357:                InsertAt(nStartIndex, pNewArray->GetAt(0), pNewArray->GetSize());
        !           358:                for (int i = 0; i < pNewArray->GetSize(); i++)
        !           359:                        SetAt(nStartIndex + i, pNewArray->GetAt(i));
        !           360:        }
        !           361: }
        !           362: 
        !           363: /////////////////////////////////////////////////////////////////////////////
        !           364: // Serialization
        !           365: 
        !           366: template<class TYPE, class ARG_TYPE, int IS_SERIAL, int HAS_CREATE>
        !           367: #if IS_SERIAL
        !           368: void CArray<TYPE, ARG_TYPE, IS_SERIAL, HAS_CREATE>::Serialize(CArchive& ar)
        !           369: {
        !           370:        ASSERT_VALID(this);
        !           371: 
        !           372:        CObject::Serialize(ar);
        !           373: 
        !           374:        if (ar.IsStoring())
        !           375:        {
        !           376:                ar << (WORD) m_nSize;
        !           377:                for (int i = 0; i < m_nSize; i++)
        !           378:                        ar << m_pData[i];
        !           379:        }
        !           380:        else
        !           381:        {
        !           382:                WORD    nOldSize;
        !           383:                ar >> nOldSize;
        !           384:                SetSize(nOldSize);
        !           385: 
        !           386:                for (int i = 0; i < m_nSize; i++)
        !           387:                        ar >> m_pData[i];
        !           388:        }
        !           389: }
        !           390: #endif //IS_SERIAL
        !           391: 
        !           392: /////////////////////////////////////////////////////////////////////////////
        !           393: // Diagnostics
        !           394: 
        !           395: #ifdef _DEBUG
        !           396: template <class TYPE, class ARG_TYPE, int IS_SERIAL, int HAS_CREATE>
        !           397: void CArray<TYPE, ARG_TYPE, IS_SERIAL, HAS_CREATE>::Dump(CDumpContext& dc) const
        !           398: {
        !           399:        ASSERT_VALID(this);
        !           400: 
        !           401: #define MAKESTRING(x) #x
        !           402:        dc << "a " MAKESTRING(CArray) " with " << m_nSize << " elements";
        !           403: #undef MAKESTRING
        !           404:        if (dc.GetDepth() > 0)
        !           405:        {
        !           406:                dc << "\n";
        !           407:                for (int i = 0; i < m_nSize; i++)
        !           408:                        dc << "\n\t[" << i << "] = " << m_pData[i];
        !           409:        }
        !           410: }
        !           411: 
        !           412: template <class TYPE, class ARG_TYPE, int IS_SERIAL, int HAS_CREATE>
        !           413: void CArray<TYPE, ARG_TYPE, IS_SERIAL, HAS_CREATE>::AssertValid() const
        !           414: {
        !           415:        CObject::AssertValid();
        !           416:        if (m_pData == NULL)
        !           417:        {
        !           418:                ASSERT(m_nSize == 0);
        !           419:                ASSERT(m_nMaxSize == 0);
        !           420:        }
        !           421:        else
        !           422:        {
        !           423:                ASSERT(m_nSize <= m_nMaxSize);
        !           424:        }
        !           425: }
        !           426: #endif //_DEBUG
        !           427: 
        !           428: /////////////////////////////////////////////////////////////////////////////
        !           429: 

unix.superglobalmegacorp.com

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