|
|
1.1 root 1:
2:
3: /////////////////////////////////////////////////////////////////////////////
4: //
5: // Implementation of Array of TYPEs
6: //
7: /////////////////////////////////////////////////////////////////////////////
8: // NOTE: we allocate an array of 'm_nMaxSize' elements, but only
9: // the current size 'm_nSize' contains properly constructed
10: // objects.
11:
12: #include "afxcoll.h"
13: #pragma hdrstop
14:
15: #ifdef AFX_COLL_SEG
16: #pragma code_seg(AFX_COLL_SEG)
17: #endif
18:
19: #include <limits.h>
20: #define SIZE_T_MAX UINT_MAX /* max size for a size_t */
21:
22: #include "array_x.h"
23:
24: IMPLEMENT_DYNAMIC(CAaaArray, CObject);
25:
26: #ifdef _DEBUG
27: #undef THIS_FILE
28: static char BASED_CODE THIS_FILE[] = __FILE__;
29: #endif
30:
31: #define new DEBUG_NEW
32:
33: /////////////////////////////////////////////////////////////////////////////
34:
35:
36: /////////////////////////////////////////////////////////////////////////////
37:
38:
39: CAaaArray::CAaaArray()
40: {
41: m_pData = NULL;
42: m_nSize = m_nMaxSize = m_nGrowBy = 0;
43: }
44:
45:
46: CAaaArray::~CAaaArray()
47: {
48: ASSERT_VALID(this);
49:
50: delete [] (BYTE*)m_pData;
51: }
52:
53:
54: void CAaaArray::SetSize(int nNewSize, int nGrowBy /* = -1 */)
55: {
56: ASSERT_VALID(this);
57: ASSERT(nNewSize >= 0);
58:
59: if (nGrowBy != -1)
60: m_nGrowBy = nGrowBy; // set new size
61:
62: if (nNewSize == 0)
63: {
64: // shrink to nothing
65: delete [] (BYTE*)m_pData;
66: m_pData = NULL;
67: m_nSize = m_nMaxSize = 0;
68: }
69: else if (m_pData == NULL)
70: {
71: // create one with exact size
72: #ifdef SIZE_T_MAX
73: ASSERT((long)nNewSize * sizeof(AAA) <= SIZE_T_MAX); // no overflow
74: #endif
75: m_pData = (AAA*) new BYTE[nNewSize * sizeof(AAA)];
76:
77: memset(m_pData, 0, nNewSize * sizeof(AAA)); // zero fill
78:
79: m_nSize = m_nMaxSize = nNewSize;
80: }
81: else if (nNewSize <= m_nMaxSize)
82: {
83: // it fits
84: if (nNewSize > m_nSize)
85: {
86: // initialize the new elements
87:
88: memset(&m_pData[m_nSize], 0, (nNewSize-m_nSize) * sizeof(AAA));
89:
90: }
91:
92: m_nSize = nNewSize;
93: }
94: else
95: {
96: // Otherwise grow array
97: int nNewMax;
98: if (nNewSize < m_nMaxSize + m_nGrowBy)
99: nNewMax = m_nMaxSize + m_nGrowBy; // granularity
100: else
101: nNewMax = nNewSize; // no slush
102:
103: #ifdef SIZE_T_MAX
104: ASSERT((long)nNewMax * sizeof(AAA) <= SIZE_T_MAX); // no overflow
105: #endif
106: AAA* pNewData = (AAA*) new BYTE[nNewMax * sizeof(AAA)];
107:
108: // copy new data from old
109: memcpy(pNewData, m_pData, m_nSize * sizeof(AAA));
110:
111: // construct remaining elements
112: ASSERT(nNewSize > m_nSize);
113:
114: memset(&pNewData[m_nSize], 0, (nNewSize-m_nSize) * sizeof(AAA));
115:
116:
117: // get rid of old stuff (note: no destructors called)
118: delete [] (BYTE*)m_pData;
119: m_pData = pNewData;
120: m_nSize = nNewSize;
121: m_nMaxSize = nNewMax;
122: }
123: }
124:
125:
126: void CAaaArray::FreeExtra()
127: {
128: ASSERT_VALID(this);
129:
130: if (m_nSize != m_nMaxSize)
131: {
132: // shrink to desired size
133: #ifdef SIZE_T_MAX
134: ASSERT((long)m_nSize * sizeof(AAA) <= SIZE_T_MAX); // no overflow
135: #endif
136: AAA* pNewData = (AAA*) new BYTE[m_nSize * sizeof(AAA)];
137: // copy new data from old
138: memcpy(pNewData, m_pData, m_nSize * sizeof(AAA));
139:
140: // get rid of old stuff (note: no destructors called)
141: delete [] (BYTE*)m_pData;
142: m_pData = pNewData;
143: m_nMaxSize = m_nSize;
144: }
145: }
146:
147: /////////////////////////////////////////////////////////////////////////////
148:
149:
150: void CAaaArray::SetAtGrow(int nIndex, AAA newElement)
151: {
152: ASSERT(nIndex >= 0);
153: if (nIndex >= m_nSize)
154: SetSize(nIndex+1);
155: m_pData[nIndex] = newElement;
156: }
157:
158:
159: void CAaaArray::InsertAt(int nIndex, AAA newElement, int nCount /*=1*/)
160: {
161: ASSERT_VALID(this);
162: ASSERT(nIndex >= 0); // will expand to meet need
163: ASSERT(nCount > 0); // zero or negative size not allowed
164:
165: if (nIndex >= m_nSize)
166: {
167: // adding after the end of the array
168: SetSize(nIndex + nCount); // grow so nIndex is valid
169: }
170: else
171: {
172: // inserting in the middle of the array
173: int nOldSize = m_nSize;
174: SetSize(m_nSize + nCount); // grow it to new size
175: // shift old data up to fill gap
176: memmove(&m_pData[nIndex+nCount], &m_pData[nIndex],
177: (nOldSize-nIndex) * sizeof(AAA));
178:
179: // re-init slots we copied from
180:
181: memset(&m_pData[nIndex], 0, nCount * sizeof(AAA));
182:
183: }
184:
185: // insert new value in the gap
186: ASSERT(nIndex + nCount <= m_nSize);
187: while (nCount--)
188: m_pData[nIndex++] = newElement;
189: }
190:
191:
192: void CAaaArray::RemoveAt(int nIndex, int nCount /* = 1 */)
193: {
194: ASSERT_VALID(this);
195: ASSERT(nIndex >= 0);
196: ASSERT(nCount >= 0);
197: ASSERT(nIndex + nCount <= m_nSize);
198:
199: // just remove a range
200: int nMoveCount = m_nSize - (nIndex + nCount);
201:
202: if (nMoveCount)
203: memcpy(&m_pData[nIndex], &m_pData[nIndex + nCount],
204: nMoveCount * sizeof(AAA));
205: m_nSize -= nCount;
206: }
207:
208:
209: void CAaaArray::InsertAt(int nStartIndex, CAaaArray* pNewArray)
210: {
211: ASSERT_VALID(this);
212: ASSERT(pNewArray != NULL);
213: ASSERT(pNewArray->IsKindOf(RUNTIME_CLASS(CAaaArray)));
214: ASSERT_VALID(pNewArray);
215: ASSERT(nStartIndex >= 0);
216:
217: if (pNewArray->GetSize() > 0)
218: {
219: InsertAt(nStartIndex, pNewArray->GetAt(0), pNewArray->GetSize());
220: for (int i = 0; i < pNewArray->GetSize(); i++)
221: SetAt(nStartIndex + i, pNewArray->GetAt(i));
222: }
223: }
224:
225: /////////////////////////////////////////////////////////////////////////////
226: // Serialization
227:
228:
229:
230: /////////////////////////////////////////////////////////////////////////////
231: // Diagnostics
232:
233: #if 0
234: #ifdef _DEBUG
235:
236: void CAaaArray::Dump(CDumpContext& dc) const
237: {
238: ASSERT_VALID(this);
239:
240: #define MAKESTRING(x) #x
241: dc << "a " MAKESTRING(CAaaArray) " with " << m_nSize << " elements";
242: #undef MAKESTRING
243: if (dc.GetDepth() > 0)
244: {
245: dc << "\n";
246: for (int i = 0; i < m_nSize; i++)
247: dc << "\n\t[" << i << "] = " << m_pData[i];
248: }
249: }
250:
251:
252: void CAaaArray::AssertValid() const
253: {
254: CObject::AssertValid();
255: if (m_pData == NULL)
256: {
257: ASSERT(m_nSize == 0);
258: ASSERT(m_nMaxSize == 0);
259: }
260: else
261: {
262: ASSERT(m_nSize <= m_nMaxSize);
263: }
264: }
265: #endif //_DEBUG
266: #endif // 0
267: /////////////////////////////////////////////////////////////////////////////
268:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.