home *** CD-ROM | disk | FTP | other *** search
/ Programming Languages Suite / ProgLangD.iso / C++-7 / DISK10 / MFC / INCLUDE / AFXCOLL.H$ / afxcoll
Encoding:
Text File  |  1992-03-03  |  36.3 KB  |  1,449 lines

  1. // Microsoft Foundation Classes C++ library. 
  2. // Copyright (C) 1992 Microsoft Corporation, 
  3. // All rights reserved. 
  4.  
  5. // This source code is only intended as a supplement to the 
  6. // Microsoft Foundation Classes Reference and Microsoft 
  7. // QuickHelp documentation provided with the library. 
  8. // See these sources for detailed information regarding the 
  9. // Microsoft Foundation Classes product. 
  10.  
  11.  
  12. #ifndef __AFXCOLL_H__
  13. #define __AFXCOLL_H__
  14.  
  15. #ifndef __AFX_H__
  16. #include "afx.h"
  17. #endif
  18.  
  19. /////////////////////////////////////////////////////////////////////////////
  20. // Classes declared in this file
  21.  
  22. //CObject
  23.     // Arrays
  24.     class CByteArray;           // array of BYTE
  25.     class CWordArray;           // array of WORD
  26.     class CDWordArray;          // array of DWORD
  27.     class CPtrArray;            // array of void*
  28.     class CObArray;             // array of CObject*
  29.  
  30.     // Lists
  31.     class CPtrList;             // list of void*
  32.     class CObList;              // list of CObject*
  33.  
  34.     // Maps (aka Dictionaries)
  35.     class CMapWordToOb;         // map from WORD to CObject*
  36.     class CMapWordToPtr;        // map from WORD to void*
  37.     class CMapPtrToWord;        // map from void* to WORD
  38.     class CMapPtrToPtr;         // map from void* to void*
  39.  
  40.     // Special String variants
  41.     class CStringArray;         // array of CStrings
  42.     class CStringList;          // list of CStrings
  43.     class CMapStringToPtr;      // map from CString to void*
  44.     class CMapStringToOb;       // map from CString to CObject*
  45.     class CMapStringToString;   // map from CString to CString
  46.  
  47. /////////////////////////////////////////////////////////////////////////////
  48.  
  49. #ifdef _DEBUG
  50. extern char BASED_CODE _afxSzAfxColl[]; // defined in dumpcont.cpp
  51. #undef THIS_FILE
  52. #define THIS_FILE _afxSzAfxColl
  53. #endif
  54.  
  55.  
  56. ////////////////////////////////////////////////////////////////////////////
  57.  
  58.  
  59. class CByteArray : public CObject
  60. {
  61.  
  62.     DECLARE_SERIAL(CByteArray)
  63. public:
  64.  
  65. // Construction
  66.     CByteArray();
  67.  
  68. // Attributes
  69.     int     GetSize() const
  70.                 { return m_nSize; }
  71.     int     GetUpperBound() const
  72.                 { return m_nSize-1; }
  73.     void    SetSize(int nNewSize, int nGrowBy = -1);
  74.  
  75. // Operations
  76.     // Clean up
  77.     void    FreeExtra();
  78.     void    RemoveAll()
  79.                 { SetSize(0); }
  80.  
  81.     // Accessing elements
  82.     BYTE    GetAt(int nIndex) const
  83.                 { ASSERT(nIndex >= 0 && nIndex < m_nSize);
  84.                     return m_pData[nIndex]; }
  85.     void    SetAt(int nIndex, BYTE newElement)
  86.                 { ASSERT(nIndex >= 0 && nIndex < m_nSize);
  87.                     m_pData[nIndex] = newElement; }
  88.     BYTE&   ElementAt(int nIndex)
  89.                 { ASSERT(nIndex >= 0 && nIndex < m_nSize);
  90.                     return m_pData[nIndex]; }
  91.  
  92.     // Potentially growing the array
  93.     void    SetAtGrow(int nIndex, BYTE newElement);
  94.     int     Add(BYTE newElement)
  95.                 { int nIndex = m_nSize;
  96.                     SetAtGrow(nIndex, newElement);
  97.                     return nIndex; }
  98.  
  99.     // overloaded operator helpers
  100.     BYTE    operator[](int nIndex) const
  101.                 { return GetAt(nIndex); }
  102.     BYTE&   operator[](int nIndex)
  103.                 { return ElementAt(nIndex); }
  104.  
  105.     // Operations that move elements around
  106.     void    InsertAt(int nIndex, BYTE newElement, int nCount = 1);
  107.     void    RemoveAt(int nIndex, int nCount = 1);
  108.     void    InsertAt(int nStartIndex, CByteArray* pNewArray);
  109.  
  110. // Implementation
  111. protected:
  112.     BYTE*   m_pData;        // the actual array of data
  113.     int     m_nSize;        // # of elements (upperBound - 1)
  114.     int     m_nMaxSize;     // max allocated
  115.     int     m_nGrowBy;      // grow amount
  116.  
  117. public:
  118.     ~CByteArray();
  119.  
  120.     void    Serialize(CArchive&);
  121. #ifdef _DEBUG
  122.     void    Dump(CDumpContext&) const;
  123.     void    AssertValid() const;
  124. #endif
  125. };
  126.  
  127.  
  128.  
  129. ////////////////////////////////////////////////////////////////////////////
  130.  
  131.  
  132. class CWordArray : public CObject
  133. {
  134.  
  135.     DECLARE_SERIAL(CWordArray)
  136. public:
  137.  
  138. // Construction
  139.     CWordArray();
  140.  
  141. // Attributes
  142.     int     GetSize() const
  143.                 { return m_nSize; }
  144.     int     GetUpperBound() const
  145.                 { return m_nSize-1; }
  146.     void    SetSize(int nNewSize, int nGrowBy = -1);
  147.  
  148. // Operations
  149.     // Clean up
  150.     void    FreeExtra();
  151.     void    RemoveAll()
  152.                 { SetSize(0); }
  153.  
  154.     // Accessing elements
  155.     WORD    GetAt(int nIndex) const
  156.                 { ASSERT(nIndex >= 0 && nIndex < m_nSize);
  157.                     return m_pData[nIndex]; }
  158.     void    SetAt(int nIndex, WORD newElement)
  159.                 { ASSERT(nIndex >= 0 && nIndex < m_nSize);
  160.                     m_pData[nIndex] = newElement; }
  161.     WORD&   ElementAt(int nIndex)
  162.                 { ASSERT(nIndex >= 0 && nIndex < m_nSize);
  163.                     return m_pData[nIndex]; }
  164.  
  165.     // Potentially growing the array
  166.     void    SetAtGrow(int nIndex, WORD newElement);
  167.     int     Add(WORD newElement)
  168.                 { int nIndex = m_nSize;
  169.                     SetAtGrow(nIndex, newElement);
  170.                     return nIndex; }
  171.  
  172.     // overloaded operator helpers
  173.     WORD    operator[](int nIndex) const
  174.                 { return GetAt(nIndex); }
  175.     WORD&   operator[](int nIndex)
  176.                 { return ElementAt(nIndex); }
  177.  
  178.     // Operations that move elements around
  179.     void    InsertAt(int nIndex, WORD newElement, int nCount = 1);
  180.     void    RemoveAt(int nIndex, int nCount = 1);
  181.     void    InsertAt(int nStartIndex, CWordArray* pNewArray);
  182.  
  183. // Implementation
  184. protected:
  185.     WORD*   m_pData;        // the actual array of data
  186.     int     m_nSize;        // # of elements (upperBound - 1)
  187.     int     m_nMaxSize;     // max allocated
  188.     int     m_nGrowBy;      // grow amount
  189.  
  190. public:
  191.     ~CWordArray();
  192.  
  193.     void    Serialize(CArchive&);
  194. #ifdef _DEBUG
  195.     void    Dump(CDumpContext&) const;
  196.     void    AssertValid() const;
  197. #endif
  198. };
  199.  
  200.  
  201.  
  202. ////////////////////////////////////////////////////////////////////////////
  203.  
  204.  
  205. class CDWordArray : public CObject
  206. {
  207.  
  208.     DECLARE_SERIAL(CDWordArray)
  209. public:
  210.  
  211. // Construction
  212.     CDWordArray();
  213.  
  214. // Attributes
  215.     int     GetSize() const
  216.                 { return m_nSize; }
  217.     int     GetUpperBound() const
  218.                 { return m_nSize-1; }
  219.     void    SetSize(int nNewSize, int nGrowBy = -1);
  220.  
  221. // Operations
  222.     // Clean up
  223.     void    FreeExtra();
  224.     void    RemoveAll()
  225.                 { SetSize(0); }
  226.  
  227.     // Accessing elements
  228.     DWORD    GetAt(int nIndex) const
  229.                 { ASSERT(nIndex >= 0 && nIndex < m_nSize);
  230.                     return m_pData[nIndex]; }
  231.     void    SetAt(int nIndex, DWORD newElement)
  232.                 { ASSERT(nIndex >= 0 && nIndex < m_nSize);
  233.                     m_pData[nIndex] = newElement; }
  234.     DWORD&   ElementAt(int nIndex)
  235.                 { ASSERT(nIndex >= 0 && nIndex < m_nSize);
  236.                     return m_pData[nIndex]; }
  237.  
  238.     // Potentially growing the array
  239.     void    SetAtGrow(int nIndex, DWORD newElement);
  240.     int     Add(DWORD newElement)
  241.                 { int nIndex = m_nSize;
  242.                     SetAtGrow(nIndex, newElement);
  243.                     return nIndex; }
  244.  
  245.     // overloaded operator helpers
  246.     DWORD    operator[](int nIndex) const
  247.                 { return GetAt(nIndex); }
  248.     DWORD&   operator[](int nIndex)
  249.                 { return ElementAt(nIndex); }
  250.  
  251.     // Operations that move elements around
  252.     void    InsertAt(int nIndex, DWORD newElement, int nCount = 1);
  253.     void    RemoveAt(int nIndex, int nCount = 1);
  254.     void    InsertAt(int nStartIndex, CDWordArray* pNewArray);
  255.  
  256. // Implementation
  257. protected:
  258.     DWORD*   m_pData;        // the actual array of data
  259.     int     m_nSize;        // # of elements (upperBound - 1)
  260.     int     m_nMaxSize;     // max allocated
  261.     int     m_nGrowBy;      // grow amount
  262.  
  263. public:
  264.     ~CDWordArray();
  265.  
  266.     void    Serialize(CArchive&);
  267. #ifdef _DEBUG
  268.     void    Dump(CDumpContext&) const;
  269.     void    AssertValid() const;
  270. #endif
  271. };
  272.  
  273.  
  274.  
  275. ////////////////////////////////////////////////////////////////////////////
  276.  
  277.  
  278. class CPtrArray : public CObject
  279. {
  280.  
  281.     DECLARE_DYNAMIC(CPtrArray)
  282. public:
  283.  
  284. // Construction
  285.     CPtrArray();
  286.  
  287. // Attributes
  288.     int     GetSize() const
  289.                 { return m_nSize; }
  290.     int     GetUpperBound() const
  291.                 { return m_nSize-1; }
  292.     void    SetSize(int nNewSize, int nGrowBy = -1);
  293.  
  294. // Operations
  295.     // Clean up
  296.     void    FreeExtra();
  297.     void    RemoveAll()
  298.                 { SetSize(0); }
  299.  
  300.     // Accessing elements
  301.     void*    GetAt(int nIndex) const
  302.                 { ASSERT(nIndex >= 0 && nIndex < m_nSize);
  303.                     return m_pData[nIndex]; }
  304.     void    SetAt(int nIndex, void* newElement)
  305.                 { ASSERT(nIndex >= 0 && nIndex < m_nSize);
  306.                     m_pData[nIndex] = newElement; }
  307.     void*&   ElementAt(int nIndex)
  308.                 { ASSERT(nIndex >= 0 && nIndex < m_nSize);
  309.                     return m_pData[nIndex]; }
  310.  
  311.     // Potentially growing the array
  312.     void    SetAtGrow(int nIndex, void* newElement);
  313.     int     Add(void* newElement)
  314.                 { int nIndex = m_nSize;
  315.                     SetAtGrow(nIndex, newElement);
  316.                     return nIndex; }
  317.  
  318.     // overloaded operator helpers
  319.     void*    operator[](int nIndex) const
  320.                 { return GetAt(nIndex); }
  321.     void*&   operator[](int nIndex)
  322.                 { return ElementAt(nIndex); }
  323.  
  324.     // Operations that move elements around
  325.     void    InsertAt(int nIndex, void* newElement, int nCount = 1);
  326.     void    RemoveAt(int nIndex, int nCount = 1);
  327.     void    InsertAt(int nStartIndex, CPtrArray* pNewArray);
  328.  
  329. // Implementation
  330. protected:
  331.     void**   m_pData;        // the actual array of data
  332.     int     m_nSize;        // # of elements (upperBound - 1)
  333.     int     m_nMaxSize;     // max allocated
  334.     int     m_nGrowBy;      // grow amount
  335.  
  336. public:
  337.     ~CPtrArray();
  338. #ifdef _DEBUG
  339.     void    Dump(CDumpContext&) const;
  340.     void    AssertValid() const;
  341. #endif
  342. };
  343.  
  344.  
  345.  
  346. ////////////////////////////////////////////////////////////////////////////
  347.  
  348.  
  349. class CObArray : public CObject
  350. {
  351.  
  352.     DECLARE_SERIAL(CObArray)
  353. public:
  354.  
  355. // Construction
  356.     CObArray();
  357.  
  358. // Attributes
  359.     int     GetSize() const
  360.                 { return m_nSize; }
  361.     int     GetUpperBound() const
  362.                 { return m_nSize-1; }
  363.     void    SetSize(int nNewSize, int nGrowBy = -1);
  364.  
  365. // Operations
  366.     // Clean up
  367.     void    FreeExtra();
  368.     void    RemoveAll()
  369.                 { SetSize(0); }
  370.  
  371.     // Accessing elements
  372.     CObject*    GetAt(int nIndex) const
  373.                 { ASSERT(nIndex >= 0 && nIndex < m_nSize);
  374.                     return m_pData[nIndex]; }
  375.     void    SetAt(int nIndex, CObject* newElement)
  376.                 { ASSERT(nIndex >= 0 && nIndex < m_nSize);
  377.                     m_pData[nIndex] = newElement; }
  378.     CObject*&   ElementAt(int nIndex)
  379.                 { ASSERT(nIndex >= 0 && nIndex < m_nSize);
  380.                     return m_pData[nIndex]; }
  381.  
  382.     // Potentially growing the array
  383.     void    SetAtGrow(int nIndex, CObject* newElement);
  384.     int     Add(CObject* newElement)
  385.                 { int nIndex = m_nSize;
  386.                     SetAtGrow(nIndex, newElement);
  387.                     return nIndex; }
  388.  
  389.     // overloaded operator helpers
  390.     CObject*    operator[](int nIndex) const
  391.                 { return GetAt(nIndex); }
  392.     CObject*&   operator[](int nIndex)
  393.                 { return ElementAt(nIndex); }
  394.  
  395.     // Operations that move elements around
  396.     void    InsertAt(int nIndex, CObject* newElement, int nCount = 1);
  397.     void    RemoveAt(int nIndex, int nCount = 1);
  398.     void    InsertAt(int nStartIndex, CObArray* pNewArray);
  399.  
  400. // Implementation
  401. protected:
  402.     CObject**   m_pData;        // the actual array of data
  403.     int     m_nSize;        // # of elements (upperBound - 1)
  404.     int     m_nMaxSize;     // max allocated
  405.     int     m_nGrowBy;      // grow amount
  406.  
  407. public:
  408.     ~CObArray();
  409.  
  410.     void    Serialize(CArchive&);
  411. #ifdef _DEBUG
  412.     void    Dump(CDumpContext&) const;
  413.     void    AssertValid() const;
  414. #endif
  415. };
  416.  
  417.  
  418.  
  419. ////////////////////////////////////////////////////////////////////////////
  420.  
  421.  
  422. class CStringArray : public CObject
  423. {
  424.  
  425.     DECLARE_SERIAL(CStringArray)
  426. public:
  427.  
  428. // Construction
  429.     CStringArray();
  430.  
  431. // Attributes
  432.     int     GetSize() const
  433.                 { return m_nSize; }
  434.     int     GetUpperBound() const
  435.                 { return m_nSize-1; }
  436.     void    SetSize(int nNewSize, int nGrowBy = -1);
  437.  
  438. // Operations
  439.     // Clean up
  440.     void    FreeExtra();
  441.     void    RemoveAll()
  442.                 { SetSize(0); }
  443.  
  444.     // Accessing elements
  445.     CString    GetAt(int nIndex) const
  446.                 { ASSERT(nIndex >= 0 && nIndex < m_nSize);
  447.                     return m_pData[nIndex]; }
  448.     void    SetAt(int nIndex, const char* newElement)
  449.                 { ASSERT(nIndex >= 0 && nIndex < m_nSize);
  450.                     m_pData[nIndex] = newElement; }
  451.     CString&   ElementAt(int nIndex)
  452.                 { ASSERT(nIndex >= 0 && nIndex < m_nSize);
  453.                     return m_pData[nIndex]; }
  454.  
  455.     // Potentially growing the array
  456.     void    SetAtGrow(int nIndex, const char* newElement);
  457.     int     Add(const char* newElement)
  458.                 { int nIndex = m_nSize;
  459.                     SetAtGrow(nIndex, newElement);
  460.                     return nIndex; }
  461.  
  462.     // overloaded operator helpers
  463.     CString    operator[](int nIndex) const
  464.                 { return GetAt(nIndex); }
  465.     CString&   operator[](int nIndex)
  466.                 { return ElementAt(nIndex); }
  467.  
  468.     // Operations that move elements around
  469.     void    InsertAt(int nIndex, const char* newElement, int nCount = 1);
  470.     void    RemoveAt(int nIndex, int nCount = 1);
  471.     void    InsertAt(int nStartIndex, CStringArray* pNewArray);
  472.  
  473. // Implementation
  474. protected:
  475.     CString*   m_pData;        // the actual array of data
  476.     int     m_nSize;        // # of elements (upperBound - 1)
  477.     int     m_nMaxSize;     // max allocated
  478.     int     m_nGrowBy;      // grow amount
  479.  
  480. public:
  481.     ~CStringArray();
  482.  
  483.     void    Serialize(CArchive&);
  484. #ifdef _DEBUG
  485.     void    Dump(CDumpContext&) const;
  486.     void    AssertValid() const;
  487. #endif
  488. };
  489.  
  490.  
  491.  
  492. /////////////////////////////////////////////////////////////////////////////
  493.  
  494.  
  495. class CPtrList : public CObject
  496. {
  497.  
  498.     DECLARE_DYNAMIC(CPtrList)
  499.  
  500. protected:
  501.     struct CNode
  502.     {
  503.         CNode*  pNext;
  504.         CNode*  pPrev;
  505.         void*    data;
  506.     };
  507. public:
  508.  
  509. // Construction
  510.     CPtrList(int nBlockSize=10);
  511.  
  512. // Attributes (head and tail)
  513.     // count of elements
  514.     int     GetCount() const
  515.                 { return m_nCount; }
  516.     BOOL    IsEmpty() const
  517.                 { return m_nCount == 0; }
  518.  
  519.     // peek at head or tail
  520.     void*&   GetHead()
  521.                 { ASSERT(m_pNodeHead != NULL);
  522.                     return m_pNodeHead->data; }
  523.     void*    GetHead() const
  524.                 { ASSERT(m_pNodeHead != NULL);
  525.                     return m_pNodeHead->data; }
  526.     void*&   GetTail()
  527.                 { ASSERT(m_pNodeTail != NULL);
  528.                     return m_pNodeTail->data; }
  529.     void*    GetTail() const
  530.                 { ASSERT(m_pNodeTail != NULL);
  531.                     return m_pNodeTail->data; }
  532.  
  533. // Operations
  534.     // get head or tail (and remove it) - don't call on empty list !
  535.     void*    RemoveHead();
  536.     void*    RemoveTail();
  537.  
  538.     // add before head or after tail
  539.     POSITION AddHead(void* newElement);
  540.     POSITION AddTail(void* newElement);
  541.  
  542.     // add another list of elements before head or after tail
  543.     void    AddHead(CPtrList* pNewList);
  544.     void    AddTail(CPtrList* pNewList);
  545.  
  546.     // remove all elements
  547.     void    RemoveAll();
  548.  
  549.     // iteration
  550.     POSITION GetHeadPosition() const
  551.                 { return (POSITION) m_pNodeHead; }
  552.     POSITION GetTailPosition() const
  553.                 { return (POSITION) m_pNodeTail; }
  554.     void*&   GetNext(POSITION& rPosition) // return *Position++
  555.                 { CNode* pNode = (CNode*) rPosition;
  556.                     ASSERT(pNode != NULL);
  557.                     rPosition = (POSITION) pNode->pNext;
  558.                     return pNode->data; }
  559.     void*    GetNext(POSITION& rPosition) const // return *Position++
  560.                 { CNode* pNode = (CNode*) rPosition;
  561.                     ASSERT(pNode != NULL);
  562.                     rPosition = (POSITION) pNode->pNext;
  563.                     return pNode->data; }
  564.     void*&   GetPrev(POSITION& rPosition) // return *Position--
  565.                 { CNode* pNode = (CNode*) rPosition;
  566.                     ASSERT(pNode != NULL);
  567.                     rPosition = (POSITION) pNode->pPrev;
  568.                     return pNode->data; }
  569.     void*    GetPrev(POSITION& rPosition) const // return *Position--
  570.                 { CNode* pNode = (CNode*) rPosition;
  571.                     ASSERT(pNode != NULL);
  572.                     rPosition = (POSITION) pNode->pPrev;
  573.                     return pNode->data; }
  574.  
  575.     // getting/modifying an element at a given position
  576.     void*&   GetAt(POSITION position)
  577.                 { CNode* pNode = (CNode*) position;
  578.                     ASSERT(pNode != NULL);
  579.                     return pNode->data; }
  580.     void*    GetAt(POSITION position) const
  581.                 { CNode* pNode = (CNode*) position;
  582.                     ASSERT(pNode != NULL);
  583.                     return pNode->data; }
  584.     void    SetAt(POSITION pos, void* newElement)
  585.                 { CNode* pNode = (CNode*) pos;
  586.                     ASSERT(pNode != NULL);
  587.                     pNode->data = newElement; }
  588.     void    RemoveAt(POSITION position);
  589.  
  590.     // inserting before or after a given position
  591.     POSITION InsertBefore(POSITION position, void* newElement);
  592.     POSITION InsertAfter(POSITION position, void* newElement);
  593.  
  594.     // helper functions (note: O(n) speed)
  595.     POSITION Find(void* searchValue, POSITION startAfter = NULL) const;
  596.                         // defaults to starting at the HEAD
  597.                         // return NULL if not found
  598.     POSITION FindIndex(int nIndex) const;
  599.                         // get the 'nIndex'th element (may return NULL)
  600.  
  601. // Implementation
  602. protected:
  603.     CNode*  m_pNodeHead;
  604.     CNode*  m_pNodeTail;
  605.     int     m_nCount;
  606.     CNode*  m_pNodeFree;
  607.     struct CPlex* m_pBlocks;
  608.     int     m_nBlockSize;
  609.  
  610.     CNode*  NewNode(CNode*, CNode*);
  611.     void    FreeNode(CNode*);
  612.  
  613. public:
  614.     ~CPtrList();
  615. #ifdef _DEBUG
  616.     void    Dump(CDumpContext&) const;
  617.     void    AssertValid() const;
  618. #endif
  619. };
  620.  
  621.  
  622.  
  623. /////////////////////////////////////////////////////////////////////////////
  624.  
  625.  
  626. class CObList : public CObject
  627. {
  628.  
  629.     DECLARE_SERIAL(CObList)
  630.  
  631. protected:
  632.     struct CNode
  633.     {
  634.         CNode*  pNext;
  635.         CNode*  pPrev;
  636.         CObject*    data;
  637.     };
  638. public:
  639.  
  640. // Construction
  641.     CObList(int nBlockSize=10);
  642.  
  643. // Attributes (head and tail)
  644.     // count of elements
  645.     int     GetCount() const
  646.                 { return m_nCount; }
  647.     BOOL    IsEmpty() const
  648.                 { return m_nCount == 0; }
  649.  
  650.     // peek at head or tail
  651.     CObject*&   GetHead()
  652.                 { ASSERT(m_pNodeHead != NULL);
  653.                     return m_pNodeHead->data; }
  654.     CObject*    GetHead() const
  655.                 { ASSERT(m_pNodeHead != NULL);
  656.                     return m_pNodeHead->data; }
  657.     CObject*&   GetTail()
  658.                 { ASSERT(m_pNodeTail != NULL);
  659.                     return m_pNodeTail->data; }
  660.     CObject*    GetTail() const
  661.                 { ASSERT(m_pNodeTail != NULL);
  662.                     return m_pNodeTail->data; }
  663.  
  664. // Operations
  665.     // get head or tail (and remove it) - don't call on empty list !
  666.     CObject*    RemoveHead();
  667.     CObject*    RemoveTail();
  668.  
  669.     // add before head or after tail
  670.     POSITION AddHead(CObject* newElement);
  671.     POSITION AddTail(CObject* newElement);
  672.  
  673.     // add another list of elements before head or after tail
  674.     void    AddHead(CObList* pNewList);
  675.     void    AddTail(CObList* pNewList);
  676.  
  677.     // remove all elements
  678.     void    RemoveAll();
  679.  
  680.     // iteration
  681.     POSITION GetHeadPosition() const
  682.                 { return (POSITION) m_pNodeHead; }
  683.     POSITION GetTailPosition() const
  684.                 { return (POSITION) m_pNodeTail; }
  685.     CObject*&   GetNext(POSITION& rPosition) // return *Position++
  686.                 { CNode* pNode = (CNode*) rPosition;
  687.                     ASSERT(pNode != NULL);
  688.                     rPosition = (POSITION) pNode->pNext;
  689.                     return pNode->data; }
  690.     CObject*    GetNext(POSITION& rPosition) const // return *Position++
  691.                 { CNode* pNode = (CNode*) rPosition;
  692.                     ASSERT(pNode != NULL);
  693.                     rPosition = (POSITION) pNode->pNext;
  694.                     return pNode->data; }
  695.     CObject*&   GetPrev(POSITION& rPosition) // return *Position--
  696.                 { CNode* pNode = (CNode*) rPosition;
  697.                     ASSERT(pNode != NULL);
  698.                     rPosition = (POSITION) pNode->pPrev;
  699.                     return pNode->data; }
  700.     CObject*    GetPrev(POSITION& rPosition) const // return *Position--
  701.                 { CNode* pNode = (CNode*) rPosition;
  702.                     ASSERT(pNode != NULL);
  703.                     rPosition = (POSITION) pNode->pPrev;
  704.                     return pNode->data; }
  705.  
  706.     // getting/modifying an element at a given position
  707.     CObject*&   GetAt(POSITION position)
  708.                 { CNode* pNode = (CNode*) position;
  709.                     ASSERT(pNode != NULL);
  710.                     return pNode->data; }
  711.     CObject*    GetAt(POSITION position) const
  712.                 { CNode* pNode = (CNode*) position;
  713.                     ASSERT(pNode != NULL);
  714.                     return pNode->data; }
  715.     void    SetAt(POSITION pos, CObject* newElement)
  716.                 { CNode* pNode = (CNode*) pos;
  717.                     ASSERT(pNode != NULL);
  718.                     pNode->data = newElement; }
  719.     void    RemoveAt(POSITION position);
  720.  
  721.     // inserting before or after a given position
  722.     POSITION InsertBefore(POSITION position, CObject* newElement);
  723.     POSITION InsertAfter(POSITION position, CObject* newElement);
  724.  
  725.     // helper functions (note: O(n) speed)
  726.     POSITION Find(CObject* searchValue, POSITION startAfter = NULL) const;
  727.                         // defaults to starting at the HEAD
  728.                         // return NULL if not found
  729.     POSITION FindIndex(int nIndex) const;
  730.                         // get the 'nIndex'th element (may return NULL)
  731.  
  732. // Implementation
  733. protected:
  734.     CNode*  m_pNodeHead;
  735.     CNode*  m_pNodeTail;
  736.     int     m_nCount;
  737.     CNode*  m_pNodeFree;
  738.     struct CPlex* m_pBlocks;
  739.     int     m_nBlockSize;
  740.  
  741.     CNode*  NewNode(CNode*, CNode*);
  742.     void    FreeNode(CNode*);
  743.  
  744. public:
  745.     ~CObList();
  746.  
  747.     void    Serialize(CArchive&);
  748. #ifdef _DEBUG
  749.     void    Dump(CDumpContext&) const;
  750.     void    AssertValid() const;
  751. #endif
  752. };
  753.  
  754.  
  755.  
  756. /////////////////////////////////////////////////////////////////////////////
  757.  
  758.  
  759. class CStringList : public CObject
  760. {
  761.  
  762.     DECLARE_SERIAL(CStringList)
  763.  
  764. protected:
  765.     struct CNode
  766.     {
  767.         CNode*  pNext;
  768.         CNode*  pPrev;
  769.         CString    data;
  770.     };
  771. public:
  772.  
  773. // Construction
  774.     CStringList(int nBlockSize=10);
  775.  
  776. // Attributes (head and tail)
  777.     // count of elements
  778.     int     GetCount() const
  779.                 { return m_nCount; }
  780.     BOOL    IsEmpty() const
  781.                 { return m_nCount == 0; }
  782.  
  783.     // peek at head or tail
  784.     CString&   GetHead()
  785.                 { ASSERT(m_pNodeHead != NULL);
  786.                     return m_pNodeHead->data; }
  787.     CString    GetHead() const
  788.                 { ASSERT(m_pNodeHead != NULL);
  789.                     return m_pNodeHead->data; }
  790.     CString&   GetTail()
  791.                 { ASSERT(m_pNodeTail != NULL);
  792.                     return m_pNodeTail->data; }
  793.     CString    GetTail() const
  794.                 { ASSERT(m_pNodeTail != NULL);
  795.                     return m_pNodeTail->data; }
  796.  
  797. // Operations
  798.     // get head or tail (and remove it) - don't call on empty list !
  799.     CString    RemoveHead();
  800.     CString    RemoveTail();
  801.  
  802.     // add before head or after tail
  803.     POSITION AddHead(const char* newElement);
  804.     POSITION AddTail(const char* newElement);
  805.  
  806.     // add another list of elements before head or after tail
  807.     void    AddHead(CStringList* pNewList);
  808.     void    AddTail(CStringList* pNewList);
  809.  
  810.     // remove all elements
  811.     void    RemoveAll();
  812.  
  813.     // iteration
  814.     POSITION GetHeadPosition() const
  815.                 { return (POSITION) m_pNodeHead; }
  816.     POSITION GetTailPosition() const
  817.                 { return (POSITION) m_pNodeTail; }
  818.     CString&   GetNext(POSITION& rPosition) // return *Position++
  819.                 { CNode* pNode = (CNode*) rPosition;
  820.                     ASSERT(pNode != NULL);
  821.                     rPosition = (POSITION) pNode->pNext;
  822.                     return pNode->data; }
  823.     CString    GetNext(POSITION& rPosition) const // return *Position++
  824.                 { CNode* pNode = (CNode*) rPosition;
  825.                     ASSERT(pNode != NULL);
  826.                     rPosition = (POSITION) pNode->pNext;
  827.                     return pNode->data; }
  828.     CString&   GetPrev(POSITION& rPosition) // return *Position--
  829.                 { CNode* pNode = (CNode*) rPosition;
  830.                     ASSERT(pNode != NULL);
  831.                     rPosition = (POSITION) pNode->pPrev;
  832.                     return pNode->data; }
  833.     CString    GetPrev(POSITION& rPosition) const // return *Position--
  834.                 { CNode* pNode = (CNode*) rPosition;
  835.                     ASSERT(pNode != NULL);
  836.                     rPosition = (POSITION) pNode->pPrev;
  837.                     return pNode->data; }
  838.  
  839.     // getting/modifying an element at a given position
  840.     CString&   GetAt(POSITION position)
  841.                 { CNode* pNode = (CNode*) position;
  842.                     ASSERT(pNode != NULL);
  843.                     return pNode->data; }
  844.     CString    GetAt(POSITION position) const
  845.                 { CNode* pNode = (CNode*) position;
  846.                     ASSERT(pNode != NULL);
  847.                     return pNode->data; }
  848.     void    SetAt(POSITION pos, const char* newElement)
  849.                 { CNode* pNode = (CNode*) pos;
  850.                     ASSERT(pNode != NULL);
  851.                     pNode->data = newElement; }
  852.     void    RemoveAt(POSITION position);
  853.  
  854.     // inserting before or after a given position
  855.     POSITION InsertBefore(POSITION position, const char* newElement);
  856.     POSITION InsertAfter(POSITION position, const char* newElement);
  857.  
  858.     // helper functions (note: O(n) speed)
  859.     POSITION Find(const char* searchValue, POSITION startAfter = NULL) const;
  860.                         // defaults to starting at the HEAD
  861.                         // return NULL if not found
  862.     POSITION FindIndex(int nIndex) const;
  863.                         // get the 'nIndex'th element (may return NULL)
  864.  
  865. // Implementation
  866. protected:
  867.     CNode*  m_pNodeHead;
  868.     CNode*  m_pNodeTail;
  869.     int     m_nCount;
  870.     CNode*  m_pNodeFree;
  871.     struct CPlex* m_pBlocks;
  872.     int     m_nBlockSize;
  873.  
  874.     CNode*  NewNode(CNode*, CNode*);
  875.     void    FreeNode(CNode*);
  876.  
  877. public:
  878.     ~CStringList();
  879.  
  880.     void    Serialize(CArchive&);
  881. #ifdef _DEBUG
  882.     void    Dump(CDumpContext&) const;
  883.     void    AssertValid() const;
  884. #endif
  885. };
  886.  
  887.  
  888.  
  889. /////////////////////////////////////////////////////////////////////////////
  890.  
  891.  
  892. class CMapWordToPtr : public CObject
  893. {
  894.  
  895.     DECLARE_DYNAMIC(CMapWordToPtr)
  896. protected:
  897.     // Association
  898.     struct CAssoc
  899.     {
  900.         CAssoc* pNext;
  901.         UINT    nHashValue; // needed for efficient iteration
  902.         WORD     key;
  903.         void*   value;
  904.     };
  905. public:
  906.  
  907. // Construction
  908.     CMapWordToPtr(int nBlockSize=10);
  909.  
  910. // Attributes
  911.     // number of elements
  912.     int     GetCount() const
  913.                 { return m_nCount; }
  914.     BOOL    IsEmpty() const
  915.                 { return m_nCount == 0; }
  916.     // Lookup
  917.     BOOL    Lookup(WORD key, void*& rValue) const;
  918.  
  919. // Operations
  920.     // Lookup and add if not there
  921.     void*&  operator[](WORD key);
  922.  
  923.     // add a new (key, value) pair
  924.     void    SetAt(WORD key, void* newValue)
  925.                 { (*this)[key] = newValue; }
  926.  
  927.     // removing existing (key, ?) pair
  928.     BOOL    RemoveKey(WORD key);
  929.     void    RemoveAll();
  930.  
  931.     // iterating all (key, value) pairs
  932.     POSITION GetStartPosition() const
  933.                 { return (m_nCount == 0) ? NULL : BEFORE_START_POSITION; }
  934.     void    GetNextAssoc(POSITION& rNextPosition, WORD& rKey, void*& rValue) const;
  935.  
  936.     // advanced features for derived classes
  937.     UINT    GetHashTableSize() const
  938.                 { return m_nHashTableSize; }
  939.     void    InitHashTable(UINT hashSize);
  940.  
  941. // Overridables: special non-virtual (see map implementation for details)
  942.     // Routine used to user-provided hash keys
  943.     UINT    HashKey(WORD key) const;
  944.  
  945. // Implementation
  946. protected:
  947.     CAssoc** m_pHashTable;
  948.     UINT    m_nHashTableSize;
  949.     int     m_nCount;
  950.     CAssoc* m_pFreeList;
  951.     struct CPlex* m_pBlocks;
  952.     int     m_nBlockSize;
  953.  
  954.     CAssoc* NewAssoc();
  955.     void    FreeAssoc(CAssoc*);
  956.     CAssoc* GetAssocAt(WORD, UINT&) const;
  957.  
  958. public:
  959.     ~CMapWordToPtr();
  960. #ifdef _DEBUG
  961.     void    Dump(CDumpContext&) const;
  962.     void    AssertValid() const;
  963. #endif
  964. };
  965.  
  966.  
  967.  
  968. /////////////////////////////////////////////////////////////////////////////
  969.  
  970.  
  971. class CMapPtrToWord : public CObject
  972. {
  973.  
  974.     DECLARE_DYNAMIC(CMapPtrToWord)
  975. protected:
  976.     // Association
  977.     struct CAssoc
  978.     {
  979.         CAssoc* pNext;
  980.         UINT    nHashValue; // needed for efficient iteration
  981.         void*     key;
  982.         WORD   value;
  983.     };
  984. public:
  985.  
  986. // Construction
  987.     CMapPtrToWord(int nBlockSize=10);
  988.  
  989. // Attributes
  990.     // number of elements
  991.     int     GetCount() const
  992.                 { return m_nCount; }
  993.     BOOL    IsEmpty() const
  994.                 { return m_nCount == 0; }
  995.     // Lookup
  996.     BOOL    Lookup(void* key, WORD& rValue) const;
  997.  
  998. // Operations
  999.     // Lookup and add if not there
  1000.     WORD&  operator[](void* key);
  1001.  
  1002.     // add a new (key, value) pair
  1003.     void    SetAt(void* key, WORD newValue)
  1004.                 { (*this)[key] = newValue; }
  1005.  
  1006.     // removing existing (key, ?) pair
  1007.     BOOL    RemoveKey(void* key);
  1008.     void    RemoveAll();
  1009.  
  1010.     // iterating all (key, value) pairs
  1011.     POSITION GetStartPosition() const
  1012.                 { return (m_nCount == 0) ? NULL : BEFORE_START_POSITION; }
  1013.     void    GetNextAssoc(POSITION& rNextPosition, void*& rKey, WORD& rValue) const;
  1014.  
  1015.     // advanced features for derived classes
  1016.     UINT    GetHashTableSize() const
  1017.                 { return m_nHashTableSize; }
  1018.     void    InitHashTable(UINT hashSize);
  1019.  
  1020. // Overridables: special non-virtual (see map implementation for details)
  1021.     // Routine used to user-provided hash keys
  1022.     UINT    HashKey(void* key) const;
  1023.  
  1024. // Implementation
  1025. protected:
  1026.     CAssoc** m_pHashTable;
  1027.     UINT    m_nHashTableSize;
  1028.     int     m_nCount;
  1029.     CAssoc* m_pFreeList;
  1030.     struct CPlex* m_pBlocks;
  1031.     int     m_nBlockSize;
  1032.  
  1033.     CAssoc* NewAssoc();
  1034.     void    FreeAssoc(CAssoc*);
  1035.     CAssoc* GetAssocAt(void*, UINT&) const;
  1036.  
  1037. public:
  1038.     ~CMapPtrToWord();
  1039. #ifdef _DEBUG
  1040.     void    Dump(CDumpContext&) const;
  1041.     void    AssertValid() const;
  1042. #endif
  1043. };
  1044.  
  1045.  
  1046.  
  1047. /////////////////////////////////////////////////////////////////////////////
  1048.  
  1049.  
  1050. class CMapPtrToPtr : public CObject
  1051. {
  1052.  
  1053.     DECLARE_DYNAMIC(CMapPtrToPtr)
  1054. protected:
  1055.     // Association
  1056.     struct CAssoc
  1057.     {
  1058.         CAssoc* pNext;
  1059.         UINT    nHashValue; // needed for efficient iteration
  1060.         void*     key;
  1061.         void*   value;
  1062.     };
  1063. public:
  1064.  
  1065. // Construction
  1066.     CMapPtrToPtr(int nBlockSize=10);
  1067.  
  1068. // Attributes
  1069.     // number of elements
  1070.     int     GetCount() const
  1071.                 { return m_nCount; }
  1072.     BOOL    IsEmpty() const
  1073.                 { return m_nCount == 0; }
  1074.     // Lookup
  1075.     BOOL    Lookup(void* key, void*& rValue) const;
  1076.  
  1077. // Operations
  1078.     // Lookup and add if not there
  1079.     void*&  operator[](void* key);
  1080.  
  1081.     // add a new (key, value) pair
  1082.     void    SetAt(void* key, void* newValue)
  1083.                 { (*this)[key] = newValue; }
  1084.  
  1085.     // removing existing (key, ?) pair
  1086.     BOOL    RemoveKey(void* key);
  1087.     void    RemoveAll();
  1088.  
  1089.     // iterating all (key, value) pairs
  1090.     POSITION GetStartPosition() const
  1091.                 { return (m_nCount == 0) ? NULL : BEFORE_START_POSITION; }
  1092.     void    GetNextAssoc(POSITION& rNextPosition, void*& rKey, void*& rValue) const;
  1093.  
  1094.     // advanced features for derived classes
  1095.     UINT    GetHashTableSize() const
  1096.                 { return m_nHashTableSize; }
  1097.     void    InitHashTable(UINT hashSize);
  1098.  
  1099. // Overridables: special non-virtual (see map implementation for details)
  1100.     // Routine used to user-provided hash keys
  1101.     UINT    HashKey(void* key) const;
  1102.  
  1103. // Implementation
  1104. protected:
  1105.     CAssoc** m_pHashTable;
  1106.     UINT    m_nHashTableSize;
  1107.     int     m_nCount;
  1108.     CAssoc* m_pFreeList;
  1109.     struct CPlex* m_pBlocks;
  1110.     int     m_nBlockSize;
  1111.  
  1112.     CAssoc* NewAssoc();
  1113.     void    FreeAssoc(CAssoc*);
  1114.     CAssoc* GetAssocAt(void*, UINT&) const;
  1115.  
  1116. public:
  1117.     ~CMapPtrToPtr();
  1118. #ifdef _DEBUG
  1119.     void    Dump(CDumpContext&) const;
  1120.     void    AssertValid() const;
  1121. #endif
  1122. };
  1123.  
  1124.  
  1125.  
  1126. /////////////////////////////////////////////////////////////////////////////
  1127.  
  1128.  
  1129. class CMapWordToOb : public CObject
  1130. {
  1131.  
  1132.     DECLARE_SERIAL(CMapWordToOb)
  1133. protected:
  1134.     // Association
  1135.     struct CAssoc
  1136.     {
  1137.         CAssoc* pNext;
  1138.         UINT    nHashValue; // needed for efficient iteration
  1139.         WORD     key;
  1140.         CObject*   value;
  1141.     };
  1142. public:
  1143.  
  1144. // Construction
  1145.     CMapWordToOb(int nBlockSize=10);
  1146.  
  1147. // Attributes
  1148.     // number of elements
  1149.     int     GetCount() const
  1150.                 { return m_nCount; }
  1151.     BOOL    IsEmpty() const
  1152.                 { return m_nCount == 0; }
  1153.     // Lookup
  1154.     BOOL    Lookup(WORD key, CObject*& rValue) const;
  1155.  
  1156. // Operations
  1157.     // Lookup and add if not there
  1158.     CObject*&  operator[](WORD key);
  1159.  
  1160.     // add a new (key, value) pair
  1161.     void    SetAt(WORD key, CObject* newValue)
  1162.                 { (*this)[key] = newValue; }
  1163.  
  1164.     // removing existing (key, ?) pair
  1165.     BOOL    RemoveKey(WORD key);
  1166.     void    RemoveAll();
  1167.  
  1168.     // iterating all (key, value) pairs
  1169.     POSITION GetStartPosition() const
  1170.                 { return (m_nCount == 0) ? NULL : BEFORE_START_POSITION; }
  1171.     void    GetNextAssoc(POSITION& rNextPosition, WORD& rKey, CObject*& rValue) const;
  1172.  
  1173.     // advanced features for derived classes
  1174.     UINT    GetHashTableSize() const
  1175.                 { return m_nHashTableSize; }
  1176.     void    InitHashTable(UINT hashSize);
  1177.  
  1178. // Overridables: special non-virtual (see map implementation for details)
  1179.     // Routine used to user-provided hash keys
  1180.     UINT    HashKey(WORD key) const;
  1181.  
  1182. // Implementation
  1183. protected:
  1184.     CAssoc** m_pHashTable;
  1185.     UINT    m_nHashTableSize;
  1186.     int     m_nCount;
  1187.     CAssoc* m_pFreeList;
  1188.     struct CPlex* m_pBlocks;
  1189.     int     m_nBlockSize;
  1190.  
  1191.     CAssoc* NewAssoc();
  1192.     void    FreeAssoc(CAssoc*);
  1193.     CAssoc* GetAssocAt(WORD, UINT&) const;
  1194.  
  1195. public:
  1196.     ~CMapWordToOb();
  1197.  
  1198.     void    Serialize(CArchive&);
  1199. #ifdef _DEBUG
  1200.     void    Dump(CDumpContext&) const;
  1201.     void    AssertValid() const;
  1202. #endif
  1203. };
  1204.  
  1205.  
  1206.  
  1207. /////////////////////////////////////////////////////////////////////////////
  1208.  
  1209.  
  1210. class CMapStringToPtr : public CObject
  1211. {
  1212.  
  1213.     DECLARE_DYNAMIC(CMapStringToPtr)
  1214. protected:
  1215.     // Association
  1216.     struct CAssoc
  1217.     {
  1218.         CAssoc* pNext;
  1219.         UINT    nHashValue; // needed for efficient iteration
  1220.         CString key;
  1221.         void*   value;
  1222.     };
  1223. public:
  1224.  
  1225. // Construction
  1226.     CMapStringToPtr(int nBlockSize=10);
  1227.  
  1228. // Attributes
  1229.     // number of elements
  1230.     int     GetCount() const
  1231.                 { return m_nCount; }
  1232.     BOOL    IsEmpty() const
  1233.                 { return m_nCount == 0; }
  1234.     // Lookup
  1235.     BOOL    Lookup(const char* key, void*& rValue) const;
  1236.  
  1237. // Operations
  1238.     // Lookup and add if not there
  1239.     void*&  operator[](const char* key);
  1240.  
  1241.     // add a new (key, value) pair
  1242.     void    SetAt(const char* key, void* newValue)
  1243.                 { (*this)[key] = newValue; }
  1244.  
  1245.     // removing existing (key, ?) pair
  1246.     BOOL    RemoveKey(const char* key);
  1247.     void    RemoveAll();
  1248.  
  1249.     // iterating all (key, value) pairs
  1250.     POSITION GetStartPosition() const
  1251.                 { return (m_nCount == 0) ? NULL : BEFORE_START_POSITION; }
  1252.     void    GetNextAssoc(POSITION& rNextPosition, CString& rKey, void*& rValue) const;
  1253.  
  1254.     // advanced features for derived classes
  1255.     UINT    GetHashTableSize() const
  1256.                 { return m_nHashTableSize; }
  1257.     void    InitHashTable(UINT hashSize);
  1258.  
  1259. // Overridables: special non-virtual (see map implementation for details)
  1260.     // Routine used to user-provided hash keys
  1261.     UINT    HashKey(const char* key) const;
  1262.  
  1263. // Implementation
  1264. protected:
  1265.     CAssoc** m_pHashTable;
  1266.     UINT    m_nHashTableSize;
  1267.     int     m_nCount;
  1268.     CAssoc* m_pFreeList;
  1269.     struct CPlex* m_pBlocks;
  1270.     int     m_nBlockSize;
  1271.  
  1272.     CAssoc* NewAssoc();
  1273.     void    FreeAssoc(CAssoc*);
  1274.     CAssoc* GetAssocAt(const char*, UINT&) const;
  1275.  
  1276. public:
  1277.     ~CMapStringToPtr();
  1278. #ifdef _DEBUG
  1279.     void    Dump(CDumpContext&) const;
  1280.     void    AssertValid() const;
  1281. #endif
  1282. };
  1283.  
  1284.  
  1285.  
  1286. /////////////////////////////////////////////////////////////////////////////
  1287.  
  1288.  
  1289. class CMapStringToOb : public CObject
  1290. {
  1291.  
  1292.     DECLARE_SERIAL(CMapStringToOb)
  1293. protected:
  1294.     // Association
  1295.     struct CAssoc
  1296.     {
  1297.         CAssoc* pNext;
  1298.         UINT    nHashValue; // needed for efficient iteration
  1299.         CString key;
  1300.         CObject*   value;
  1301.     };
  1302. public:
  1303.  
  1304. // Construction
  1305.     CMapStringToOb(int nBlockSize=10);
  1306.  
  1307. // Attributes
  1308.     // number of elements
  1309.     int     GetCount() const
  1310.                 { return m_nCount; }
  1311.     BOOL    IsEmpty() const
  1312.                 { return m_nCount == 0; }
  1313.     // Lookup
  1314.     BOOL    Lookup(const char* key, CObject*& rValue) const;
  1315.  
  1316. // Operations
  1317.     // Lookup and add if not there
  1318.     CObject*&  operator[](const char* key);
  1319.  
  1320.     // add a new (key, value) pair
  1321.     void    SetAt(const char* key, CObject* newValue)
  1322.                 { (*this)[key] = newValue; }
  1323.  
  1324.     // removing existing (key, ?) pair
  1325.     BOOL    RemoveKey(const char* key);
  1326.     void    RemoveAll();
  1327.  
  1328.     // iterating all (key, value) pairs
  1329.     POSITION GetStartPosition() const
  1330.                 { return (m_nCount == 0) ? NULL : BEFORE_START_POSITION; }
  1331.     void    GetNextAssoc(POSITION& rNextPosition, CString& rKey, CObject*& rValue) const;
  1332.  
  1333.     // advanced features for derived classes
  1334.     UINT    GetHashTableSize() const
  1335.                 { return m_nHashTableSize; }
  1336.     void    InitHashTable(UINT hashSize);
  1337.  
  1338. // Overridables: special non-virtual (see map implementation for details)
  1339.     // Routine used to user-provided hash keys
  1340.     UINT    HashKey(const char* key) const;
  1341.  
  1342. // Implementation
  1343. protected:
  1344.     CAssoc** m_pHashTable;
  1345.     UINT    m_nHashTableSize;
  1346.     int     m_nCount;
  1347.     CAssoc* m_pFreeList;
  1348.     struct CPlex* m_pBlocks;
  1349.     int     m_nBlockSize;
  1350.  
  1351.     CAssoc* NewAssoc();
  1352.     void    FreeAssoc(CAssoc*);
  1353.     CAssoc* GetAssocAt(const char*, UINT&) const;
  1354.  
  1355. public:
  1356.     ~CMapStringToOb();
  1357.  
  1358.     void    Serialize(CArchive&);
  1359. #ifdef _DEBUG
  1360.     void    Dump(CDumpContext&) const;
  1361.     void    AssertValid() const;
  1362. #endif
  1363. };
  1364.  
  1365.  
  1366.  
  1367. /////////////////////////////////////////////////////////////////////////////
  1368.  
  1369.  
  1370. class CMapStringToString : public CObject
  1371. {
  1372.  
  1373.     DECLARE_SERIAL(CMapStringToString)
  1374. protected:
  1375.     // Association
  1376.     struct CAssoc
  1377.     {
  1378.         CAssoc* pNext;
  1379.         UINT    nHashValue; // needed for efficient iteration
  1380.         CString key;
  1381.         CString   value;
  1382.     };
  1383. public:
  1384.  
  1385. // Construction
  1386.     CMapStringToString(int nBlockSize=10);
  1387.  
  1388. // Attributes
  1389.     // number of elements
  1390.     int     GetCount() const
  1391.                 { return m_nCount; }
  1392.     BOOL    IsEmpty() const
  1393.                 { return m_nCount == 0; }
  1394.     // Lookup
  1395.     BOOL    Lookup(const char* key, CString& rValue) const;
  1396.  
  1397. // Operations
  1398.     // Lookup and add if not there
  1399.     CString&  operator[](const char* key);
  1400.  
  1401.     // add a new (key, value) pair
  1402.     void    SetAt(const char* key, const char* newValue)
  1403.                 { (*this)[key] = newValue; }
  1404.  
  1405.     // removing existing (key, ?) pair
  1406.     BOOL    RemoveKey(const char* key);
  1407.     void    RemoveAll();
  1408.  
  1409.     // iterating all (key, value) pairs
  1410.     POSITION GetStartPosition() const
  1411.                 { return (m_nCount == 0) ? NULL : BEFORE_START_POSITION; }
  1412.     void    GetNextAssoc(POSITION& rNextPosition, CString& rKey, CString& rValue) const;
  1413.  
  1414.     // advanced features for derived classes
  1415.     UINT    GetHashTableSize() const
  1416.                 { return m_nHashTableSize; }
  1417.     void    InitHashTable(UINT hashSize);
  1418.  
  1419. // Overridables: special non-virtual (see map implementation for details)
  1420.     // Routine used to user-provided hash keys
  1421.     UINT    HashKey(const char* key) const;
  1422.  
  1423. // Implementation
  1424. protected:
  1425.     CAssoc** m_pHashTable;
  1426.     UINT    m_nHashTableSize;
  1427.     int     m_nCount;
  1428.     CAssoc* m_pFreeList;
  1429.     struct CPlex* m_pBlocks;
  1430.     int     m_nBlockSize;
  1431.  
  1432.     CAssoc* NewAssoc();
  1433.     void    FreeAssoc(CAssoc*);
  1434.     CAssoc* GetAssocAt(const char*, UINT&) const;
  1435.  
  1436. public:
  1437.     ~CMapStringToString();
  1438.  
  1439.     void    Serialize(CArchive&);
  1440. #ifdef _DEBUG
  1441.     void    Dump(CDumpContext&) const;
  1442.     void    AssertValid() const;
  1443. #endif
  1444. };
  1445.  
  1446. #undef THIS_FILE 
  1447. #define THIS_FILE __FILE__ 
  1448. #endif //!__AFXCOLL_H__ 
  1449.