ARRAY.CTT
上传用户:bangxh
上传日期:2007-01-31
资源大小:42235k
文件大小:18k
源码类别:

Windows编程

开发平台:

Visual C++

  1. ////////////////////////////////////////////////////////////////////////////
  2. // class CArray<TYPE, ARG_TYPE> - an array containing 'TYPE' elements,
  3. // passed in parameters as ARG_TYPE
  4. //
  5. // optional definitions:
  6. //  IS_SERIAL       - include serialization (see below for types)
  7. //  IS_RAW_SERIAL   - use CArchive::Write and Read for serialization
  8. //  IS_ARCHIVE_SERIAL - use CArchive insersion, extraction for serialization
  9. //  HAS_CREATE      - call constructors and destructors
  10. //
  11. // This is a part of the Microsoft Foundation Classes C++ library.
  12. // Copyright (C) 1994-1998 Microsoft Corporation
  13. // All rights reserved.
  14. //
  15. // This source code is only intended as a supplement to the
  16. // Microsoft Foundation Classes Reference and related
  17. // electronic documentation provided with the library.
  18. // See these sources for detailed information regarding the
  19. // Microsoft Foundation Classes product.
  20. ////////////////////////////////////////////////////////////////////////////
  21. //$DECLARE_TEMPLATE
  22. ////////////////////////////////////////////////////////////////////////////
  23. template<class TYPE, class ARG_TYPE>
  24. class CArray : public CObject
  25. {
  26. $ifdef IS_SERIAL
  27. DECLARE_SERIAL(CArray)
  28. $else
  29. DECLARE_DYNAMIC(CArray)
  30. $endif  //!IS_SERIAL
  31. public:
  32. // Construction
  33. CArray();
  34. // Attributes
  35. int GetSize() const;
  36. int GetUpperBound() const;
  37. void SetSize(int nNewSize, int nGrowBy = -1);
  38. // Operations
  39. // Clean up
  40. void FreeExtra();
  41. void RemoveAll();
  42. // Accessing elements
  43. TYPE GetAt(int nIndex) const;
  44. void SetAt(int nIndex, ARG_TYPE newElement);
  45. $ifdef INCLUDE_TYPEREF
  46. void SetAt(int nIndex, const TYPE& newElement);
  47. $endif
  48. TYPE& ElementAt(int nIndex);
  49. // Direct Access to the element data (may return NULL)
  50. const TYPE* GetData() const;
  51. TYPE* GetData();
  52. // Potentially growing the array
  53. void SetAtGrow(int nIndex, ARG_TYPE newElement);
  54. $ifdef INCLUDE_TYPEREF
  55. void SetAtGrow(int nIndex, const TYPE& newElement);
  56. $endif
  57. int Add(ARG_TYPE newElement);
  58. $ifdef INCLUDE_TYPEREF
  59. int Add(const TYPE& newElement);
  60. $endif
  61. int Append(const CArray& src);
  62. void Copy(const CArray& src);
  63. // overloaded operator helpers
  64. TYPE operator[](int nIndex) const;
  65. TYPE& operator[](int nIndex);
  66. // Operations that move elements around
  67. void InsertAt(int nIndex, ARG_TYPE newElement, int nCount = 1);
  68. $ifdef INCLUDE_TYPEREF
  69. void InsertAt(int nIndex, const TYPE& newElement, int nCount = 1);
  70. $endif
  71. void RemoveAt(int nIndex, int nCount = 1);
  72. void InsertAt(int nStartIndex, CArray* pNewArray);
  73. // Implementation
  74. protected:
  75. TYPE* m_pData;   // the actual array of data
  76. int m_nSize;     // # of elements (upperBound - 1)
  77. int m_nMaxSize;  // max allocated
  78. int m_nGrowBy;   // grow amount
  79. $ifdef INCLUDE_TYPEREF
  80. void InsertEmpty(int nIndex, int nCount);
  81. $endif
  82. public:
  83. ~CArray();
  84. $ifdef 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. protected:
  92. // local typedefs for class templates
  93. typedef TYPE BASE_TYPE;
  94. typedef ARG_TYPE BASE_ARG_TYPE;
  95. };
  96. //$IMPLEMENT_TEMPLATE_INLINES
  97. ////////////////////////////////////////////////////////////////////////////
  98. template<class TYPE, class ARG_TYPE>
  99. _AFXCOLL_INLINE int CArray<TYPE, ARG_TYPE>::GetSize() const
  100. { return m_nSize; }
  101. template<class TYPE, class ARG_TYPE>
  102. _AFXCOLL_INLINE int CArray<TYPE, ARG_TYPE>::GetUpperBound() const
  103. { return m_nSize-1; }
  104. template<class TYPE, class ARG_TYPE>
  105. _AFXCOLL_INLINE void CArray<TYPE, ARG_TYPE>::RemoveAll()
  106. { SetSize(0); }
  107. template<class TYPE, class ARG_TYPE>
  108. _AFXCOLL_INLINE TYPE CArray<TYPE, ARG_TYPE>::GetAt(int nIndex) const
  109. { ASSERT(nIndex >= 0 && nIndex < m_nSize);
  110. return m_pData[nIndex]; }
  111. template<class TYPE, class ARG_TYPE>
  112. _AFXCOLL_INLINE void CArray<TYPE, ARG_TYPE>::SetAt(int nIndex, ARG_TYPE newElement)
  113. { ASSERT(nIndex >= 0 && nIndex < m_nSize);
  114. m_pData[nIndex] = newElement; }
  115. $ifdef INCLUDE_TYPEREF
  116. template<class TYPE, class ARG_TYPE>
  117. _AFXCOLL_INLINE void CArray<TYPE, ARG_TYPE>::SetAt(int nIndex, const TYPE& newElement)
  118. { ASSERT(nIndex >= 0 && nIndex < m_nSize);
  119. m_pData[nIndex] = newElement; }
  120. $endif
  121. template<class TYPE, class ARG_TYPE>
  122. _AFXCOLL_INLINE TYPE& CArray<TYPE, ARG_TYPE>::ElementAt(int nIndex)
  123. { ASSERT(nIndex >= 0 && nIndex < m_nSize);
  124. return m_pData[nIndex]; }
  125. template<class TYPE, class ARG_TYPE>
  126. _AFXCOLL_INLINE const TYPE* CArray<TYPE, ARG_TYPE>::GetData() const
  127. { return (const TYPE*)m_pData; }
  128. template<class TYPE, class ARG_TYPE>
  129. _AFXCOLL_INLINE TYPE* CArray<TYPE, ARG_TYPE>::GetData()
  130. { return (TYPE*)m_pData; }
  131. template<class TYPE, class ARG_TYPE>
  132. _AFXCOLL_INLINE int CArray<TYPE, ARG_TYPE>::Add(ARG_TYPE newElement)
  133. { int nIndex = m_nSize;
  134. SetAtGrow(nIndex, newElement);
  135. return nIndex; }
  136. $ifdef INCLUDE_TYPEREF
  137. template<class TYPE, class ARG_TYPE>
  138. _AFXCOLL_INLINE int CArray<TYPE, ARG_TYPE>::Add(const TYPE& newElement)
  139. { int nIndex = m_nSize;
  140. SetAtGrow(nIndex, newElement);
  141. return nIndex; }
  142. $endif
  143. template<class TYPE, class ARG_TYPE>
  144. _AFXCOLL_INLINE TYPE CArray<TYPE, ARG_TYPE>::operator[](int nIndex) const
  145. { return GetAt(nIndex); }
  146. template<class TYPE, class ARG_TYPE>
  147. _AFXCOLL_INLINE TYPE& CArray<TYPE, ARG_TYPE>::operator[](int nIndex)
  148. { return ElementAt(nIndex); }
  149. //$IMPLEMENT_TEMPLATE
  150. // This is a part of the Microsoft Foundation Classes C++ library.
  151. // Copyright (C) 1992-1997 Microsoft Corporation
  152. // All rights reserved.
  153. //
  154. // This source code is only intended as a supplement to the
  155. // Microsoft Foundation Classes Reference and related
  156. // electronic documentation provided with the library.
  157. // See these sources for detailed information regarding the
  158. // Microsoft Foundation Classes product.
  159. /////////////////////////////////////////////////////////////////////////////
  160. //
  161. // Implementation of parameterized Array
  162. //
  163. /////////////////////////////////////////////////////////////////////////////
  164. // NOTE: we allocate an array of 'm_nMaxSize' elements, but only
  165. //  the current size 'm_nSize' contains properly constructed
  166. //  objects.
  167. #include "stdafx.h"
  168. #ifdef AFX_COLL_SEG
  169. #pragma code_seg(AFX_COLL_SEG)
  170. #endif
  171. #ifdef _DEBUG
  172. #undef THIS_FILE
  173. static char THIS_FILE[] = __FILE__;
  174. #endif
  175. #define new DEBUG_NEW
  176. $ifdef HAS_CREATE
  177. /////////////////////////////////////////////////////////////////////////////
  178. #include "elements.h"  // used for special creation
  179. static void ConstructElements(TYPE* pNewData, int nCount)
  180. {
  181. ASSERT(nCount >= 0);
  182. while (nCount--)
  183. {
  184. ConstructElement(pNewData);
  185. pNewData++;
  186. }
  187. }
  188. static void DestructElements(TYPE* pOldData, int nCount)
  189. {
  190. ASSERT(nCount >= 0);
  191. while (nCount--)
  192. {
  193. DestructElement(pOldData);
  194. pOldData++;
  195. }
  196. }
  197. static void CopyElements(TYPE* pDest, TYPE* pSrc, int nCount)
  198. {
  199. ASSERT(nCount >= 0);
  200. while (nCount--)
  201. {
  202. *pDest = *pSrc;
  203. ++pDest;
  204. ++pSrc;
  205. }
  206. }
  207. $endif //HAS_CREATE
  208. /////////////////////////////////////////////////////////////////////////////
  209. template<class TYPE, class ARG_TYPE>
  210. CArray<TYPE, ARG_TYPE>::CArray()
  211. {
  212. m_pData = NULL;
  213. m_nSize = m_nMaxSize = m_nGrowBy = 0;
  214. }
  215. template<class TYPE, ARG_TYPE>
  216. CArray<TYPE, ARG_TYPE>::~CArray()
  217. {
  218. ASSERT_VALID(this);
  219. $ifdef HAS_CREATE
  220. DestructElements(m_pData, m_nSize);
  221. $endif //HAS_CREATE
  222. delete[] (BYTE*)m_pData;
  223. }
  224. template<class TYPE, class ARG_TYPE>
  225. void CArray<TYPE, ARG_TYPE>::SetSize(int nNewSize, int nGrowBy)
  226. {
  227. ASSERT_VALID(this);
  228. ASSERT(nNewSize >= 0);
  229. if (nGrowBy != -1)
  230. m_nGrowBy = nGrowBy;  // set new size
  231. if (nNewSize == 0)
  232. {
  233. // shrink to nothing
  234. $ifdef HAS_CREATE
  235. DestructElements(m_pData, m_nSize);
  236. $endif //HAS_CREATE
  237. delete[] (BYTE*)m_pData;
  238. m_pData = NULL;
  239. m_nSize = m_nMaxSize = 0;
  240. }
  241. else if (m_pData == NULL)
  242. {
  243. // create one with exact size
  244. #ifdef SIZE_T_MAX
  245. ASSERT(nNewSize <= SIZE_T_MAX/sizeof(TYPE));    // no overflow
  246. #endif
  247. m_pData = (TYPE*) new BYTE[nNewSize * sizeof(TYPE)];
  248. $ifdef HAS_CREATE
  249. ConstructElements(m_pData, nNewSize);
  250. $else
  251. memset(m_pData, 0, nNewSize * sizeof(TYPE));  // zero fill
  252. $endif
  253. m_nSize = m_nMaxSize = nNewSize;
  254. }
  255. else if (nNewSize <= m_nMaxSize)
  256. {
  257. // it fits
  258. if (nNewSize > m_nSize)
  259. {
  260. // initialize the new elements
  261. $ifdef HAS_CREATE
  262. ConstructElements(&m_pData[m_nSize], nNewSize-m_nSize);
  263. $else
  264. memset(&m_pData[m_nSize], 0, (nNewSize-m_nSize) * sizeof(TYPE));
  265. $endif
  266. }
  267. $ifdef HAS_CREATE
  268. else if (m_nSize > nNewSize)  // destroy the old elements
  269. DestructElements(&m_pData[nNewSize], m_nSize-nNewSize);
  270. $endif
  271. m_nSize = nNewSize;
  272. }
  273. else
  274. {
  275. // otherwise, grow array
  276. int nGrowBy = m_nGrowBy;
  277. if (nGrowBy == 0)
  278. {
  279. // heuristically determine growth when nGrowBy == 0
  280. //  (this avoids heap fragmentation in many situations)
  281. nGrowBy = min(1024, max(4, m_nSize / 8));
  282. }
  283. int nNewMax;
  284. if (nNewSize < m_nMaxSize + nGrowBy)
  285. nNewMax = m_nMaxSize + nGrowBy;  // granularity
  286. else
  287. nNewMax = nNewSize;  // no slush
  288. ASSERT(nNewMax >= m_nMaxSize);  // no wrap around
  289. #ifdef SIZE_T_MAX
  290. ASSERT(nNewMax <= SIZE_T_MAX/sizeof(TYPE)); // no overflow
  291. #endif
  292. TYPE* pNewData = (TYPE*) new BYTE[nNewMax * sizeof(TYPE)];
  293. // copy new data from old
  294. memcpy(pNewData, m_pData, m_nSize * sizeof(TYPE));
  295. // construct remaining elements
  296. ASSERT(nNewSize > m_nSize);
  297. $ifdef HAS_CREATE
  298. ConstructElements(&pNewData[m_nSize], nNewSize-m_nSize);
  299. $else
  300. memset(&pNewData[m_nSize], 0, (nNewSize-m_nSize) * sizeof(TYPE));
  301. $endif
  302. // get rid of old stuff (note: no destructors called)
  303. delete[] (BYTE*)m_pData;
  304. m_pData = pNewData;
  305. m_nSize = nNewSize;
  306. m_nMaxSize = nNewMax;
  307. }
  308. }
  309. template<class TYPE, class ARG_TYPE>
  310. int CArray<TYPE, ARG_TYPE>::Append(const CArray& src)
  311. {
  312. ASSERT_VALID(this);
  313. ASSERT(this != &src);   // cannot append to itself
  314. int nOldSize = m_nSize;
  315. SetSize(m_nSize + src.m_nSize);
  316. $ifdef HAS_CREATE
  317. CopyElements(m_pData + nOldSize, src.m_pData, src.m_nSize);
  318. $else
  319. memcpy(m_pData + nOldSize, src.m_pData, src.m_nSize * sizeof(TYPE));
  320. $endif
  321. return nOldSize;
  322. }
  323. template<class TYPE, class ARG_TYPE>
  324. void CArray<TYPE, ARG_TYPE>::Copy(const CArray& src)
  325. {
  326. ASSERT_VALID(this);
  327. ASSERT(this != &src);   // cannot append to itself
  328. SetSize(src.m_nSize);
  329. $ifdef HAS_CREATE
  330. CopyElements(m_pData, src.m_pData, src.m_nSize);
  331. $else
  332. memcpy(m_pData, src.m_pData, src.m_nSize * sizeof(TYPE));
  333. $endif
  334. }
  335. template<class TYPE, class ARG_TYPE>
  336. void CArray<TYPE, ARG_TYPE>::FreeExtra()
  337. {
  338. ASSERT_VALID(this);
  339. if (m_nSize != m_nMaxSize)
  340. {
  341. // shrink to desired size
  342. #ifdef SIZE_T_MAX
  343. ASSERT(m_nSize <= SIZE_T_MAX/sizeof(TYPE)); // no overflow
  344. #endif
  345. TYPE* pNewData = NULL;
  346. if (m_nSize != 0)
  347. {
  348. pNewData = (TYPE*) new BYTE[m_nSize * sizeof(TYPE)];
  349. // copy new data from old
  350. memcpy(pNewData, m_pData, m_nSize * sizeof(TYPE));
  351. }
  352. // get rid of old stuff (note: no destructors called)
  353. delete[] (BYTE*)m_pData;
  354. m_pData = pNewData;
  355. m_nMaxSize = m_nSize;
  356. }
  357. }
  358. /////////////////////////////////////////////////////////////////////////////
  359. template<class TYPE, class ARG_TYPE>
  360. void CArray<TYPE, ARG_TYPE>::SetAtGrow(int nIndex, ARG_TYPE newElement)
  361. {
  362. ASSERT_VALID(this);
  363. ASSERT(nIndex >= 0);
  364. if (nIndex >= m_nSize)
  365. SetSize(nIndex+1);
  366. m_pData[nIndex] = newElement;
  367. }
  368. $ifdef INCLUDE_TYPEREF
  369. template<class TYPE, class ARG_TYPE>
  370. void CArray<TYPE, ARG_TYPE>::SetAtGrow(int nIndex, const TYPE& newElement)
  371. {
  372. ASSERT_VALID(this);
  373. ASSERT(nIndex >= 0);
  374. if (nIndex >= m_nSize)
  375. SetSize(nIndex+1);
  376. m_pData[nIndex] = newElement;
  377. }
  378. $endif
  379. $ifdef INCLUDE_TYPEREF
  380. template<class TYPE, class ARG_TYPE>
  381. void CArray<TYPE, ARG_TYPE>::InsertEmpty(int nIndex, int nCount)
  382. {
  383. ASSERT_VALID(this);
  384. ASSERT(nIndex >= 0);    // will expand to meet need
  385. ASSERT(nCount > 0);     // zero or negative size not allowed
  386. if (nIndex >= m_nSize)
  387. {
  388. // adding after the end of the array
  389. SetSize(nIndex + nCount);  // grow so nIndex is valid
  390. }
  391. else
  392. {
  393. // inserting in the middle of the array
  394. int nOldSize = m_nSize;
  395. SetSize(m_nSize + nCount);  // grow it to new size
  396. // shift old data up to fill gap
  397. memmove(&m_pData[nIndex+nCount], &m_pData[nIndex],
  398. (nOldSize-nIndex) * sizeof(TYPE));
  399. // re-init slots we copied from
  400. $ifdef HAS_CREATE
  401. ConstructElements(&m_pData[nIndex], nCount);
  402. $else
  403. memset(&m_pData[nIndex], 0, nCount * sizeof(TYPE));
  404. $endif
  405. }
  406. // insert new value in the gap
  407. ASSERT(nIndex + nCount <= m_nSize);
  408. }
  409. $endif
  410. template<class TYPE, class ARG_TYPE>
  411. void CArray<TYPE, ARG_TYPE>::InsertAt(int nIndex, ARG_TYPE newElement, int nCount)
  412. {
  413. $ifdef INCLUDE_TYPEREF
  414. // make room for new elements
  415. InsertEmpty(nIndex, nCount);
  416. $else
  417. ASSERT_VALID(this);
  418. ASSERT(nIndex >= 0);    // will expand to meet need
  419. ASSERT(nCount > 0);     // zero or negative size not allowed
  420. if (nIndex >= m_nSize)
  421. {
  422. // adding after the end of the array
  423. SetSize(nIndex + nCount);  // grow so nIndex is valid
  424. }
  425. else
  426. {
  427. // inserting in the middle of the array
  428. int nOldSize = m_nSize;
  429. SetSize(m_nSize + nCount);  // grow it to new size
  430. // shift old data up to fill gap
  431. memmove(&m_pData[nIndex+nCount], &m_pData[nIndex],
  432. (nOldSize-nIndex) * sizeof(TYPE));
  433. // re-init slots we copied from
  434. $ifdef HAS_CREATE
  435. ConstructElements(&m_pData[nIndex], nCount);
  436. $else
  437. memset(&m_pData[nIndex], 0, nCount * sizeof(TYPE));
  438. $endif
  439. }
  440. // insert new value in the gap
  441. ASSERT(nIndex + nCount <= m_nSize);
  442. $endif
  443. $ifndef INCLUDE_TYPEREF
  444. // copy elements into the empty space
  445. while (nCount--)
  446. m_pData[nIndex++] = newElement;
  447. $else
  448. // copy elements into the empty space
  449. TYPE temp = newElement;
  450. while (nCount--)
  451. m_pData[nIndex++] = temp;
  452. $endif
  453. }
  454. $ifdef INCLUDE_TYPEREF
  455. template<class TYPE, class ARG_TYPE>
  456. void CArray<TYPE, ARG_TYPE>::InsertAt(int nIndex, const TYPE& newElement, int nCount)
  457. {
  458. // make room for new elements
  459. InsertEmpty(nIndex, nCount);
  460. // copy elements into the empty space
  461. while (nCount--)
  462. m_pData[nIndex++] = newElement;
  463. }
  464. $endif
  465. template<class TYPE, class ARG_TYPE>
  466. void CArray<TYPE, ARG_TYPE>::RemoveAt(int nIndex, int nCount)
  467. {
  468. ASSERT_VALID(this);
  469. ASSERT(nIndex >= 0);
  470. ASSERT(nCount >= 0);
  471. ASSERT(nIndex + nCount <= m_nSize);
  472. // just remove a range
  473. int nMoveCount = m_nSize - (nIndex + nCount);
  474. $ifdef HAS_CREATE
  475. DestructElements(&m_pData[nIndex], nCount);
  476. $endif
  477. if (nMoveCount)
  478. memmove(&m_pData[nIndex], &m_pData[nIndex + nCount],
  479. nMoveCount * sizeof(TYPE));
  480. m_nSize -= nCount;
  481. }
  482. template<class TYPE, class ARG_TYPE>
  483. void CArray<TYPE, ARG_TYPE>::InsertAt(int nStartIndex, CArray* pNewArray)
  484. {
  485. ASSERT_VALID(this);
  486. ASSERT(pNewArray != NULL);
  487. ASSERT_KINDOF(CArray, pNewArray);
  488. ASSERT_VALID(pNewArray);
  489. ASSERT(nStartIndex >= 0);
  490. if (pNewArray->GetSize() > 0)
  491. {
  492. InsertAt(nStartIndex, pNewArray->GetAt(0), pNewArray->GetSize());
  493. for (int i = 0; i < pNewArray->GetSize(); i++)
  494. SetAt(nStartIndex + i, pNewArray->GetAt(i));
  495. }
  496. }
  497. $ifdef IS_ARCHIVE_SERIAL
  498. /////////////////////////////////////////////////////////////////////////////
  499. // Serialization
  500. template<class TYPE, class ARG_TYPE>
  501. void CArray<TYPE, ARG_TYPE>::Serialize(CArchive& ar)
  502. {
  503. ASSERT_VALID(this);
  504. CObject::Serialize(ar);
  505. if (ar.IsStoring())
  506. {
  507. ar.WriteCount(m_nSize);
  508. for (int i = 0; i < m_nSize; i++)
  509. ar << m_pData[i];
  510. }
  511. else
  512. {
  513. DWORD nOldSize = ar.ReadCount();
  514. SetSize(nOldSize);
  515. for (int i = 0; i < m_nSize; i++)
  516. ar >> m_pData[i];
  517. }
  518. }
  519. $endif //IS_ARCHIVE_SERIAL
  520. $ifdef IS_RAW_SERIAL
  521. /////////////////////////////////////////////////////////////////////////////
  522. // Serialization
  523. template<class TYPE, class ARG_TYPE>
  524. void CArray<TYPE, ARG_TYPE>::Serialize(CArchive& ar)
  525. {
  526. ASSERT_VALID(this);
  527. CObject::Serialize(ar);
  528. if (ar.IsStoring())
  529. {
  530. ar.WriteCount(m_nSize);
  531. ar.Write(m_pData, m_nSize * sizeof(TYPE));
  532. }
  533. else
  534. {
  535. DWORD nOldSize = ar.ReadCount();
  536. SetSize(nOldSize);
  537. ar.Read(m_pData, m_nSize * sizeof(TYPE));
  538. }
  539. }
  540. $endif //IS_RAW_SERIAL
  541. $ifdef IS_SWAP_SERIAL
  542. /////////////////////////////////////////////////////////////////////////////
  543. // Serialization
  544. template<class TYPE, class ARG_TYPE>
  545. void CArray<TYPE, ARG_TYPE>::Serialize(CArchive& ar)
  546. {
  547. ASSERT_VALID(this);
  548. CObject::Serialize(ar);
  549. if (ar.IsStoring())
  550. {
  551. ar.WriteCount(m_nSize);
  552. #ifdef _AFX_BYTESWAP
  553. if (!ar.IsByteSwapping())
  554. #endif
  555. ar.Write(m_pData, m_nSize * sizeof(TYPE));
  556. #ifdef _AFX_BYTESWAP
  557. else
  558. {
  559. // write each item individually so that it will be byte-swapped
  560. for (int i = 0; i < m_nSize; i++)
  561. ar << m_pData[i];
  562. }
  563. #endif
  564. }
  565. else
  566. {
  567. DWORD nOldSize = ar.ReadCount();
  568. SetSize(nOldSize);
  569. ar.Read(m_pData, m_nSize * sizeof(TYPE));
  570. #ifdef _AFX_BYTESWAP
  571. if (ar.IsByteSwapping())
  572. {
  573. for (int i = 0; i < m_nSize; i++)
  574. _AfxByteSwap(m_pData[i], (BYTE*)&m_pData[i]);
  575. }
  576. #endif
  577. }
  578. }
  579. $endif //IS_SWAP_SERIAL
  580. /////////////////////////////////////////////////////////////////////////////
  581. // Diagnostics
  582. #ifdef _DEBUG
  583. template<class TYPE, class ARG_TYPE>
  584. void CArray<TYPE, ARG_TYPE>::Dump(CDumpContext& dc) const
  585. {
  586. CObject::Dump(dc);
  587. dc << "with " << m_nSize << " elements";
  588. if (dc.GetDepth() > 0)
  589. {
  590. for (int i = 0; i < m_nSize; i++)
  591. dc << "nt[" << i << "] = " << m_pData[i];
  592. }
  593. dc << "n";
  594. }
  595. template<class TYPE, class ARG_TYPE>
  596. void CArray<TYPE, ARG_TYPE>::AssertValid() const
  597. {
  598. CObject::AssertValid();
  599. if (m_pData == NULL)
  600. {
  601. ASSERT(m_nSize == 0);
  602. ASSERT(m_nMaxSize == 0);
  603. }
  604. else
  605. {
  606. ASSERT(m_nSize >= 0);
  607. ASSERT(m_nMaxSize >= 0);
  608. ASSERT(m_nSize <= m_nMaxSize);
  609. ASSERT(AfxIsValidAddress(m_pData, m_nMaxSize * sizeof(TYPE)));
  610. }
  611. }
  612. #endif //_DEBUG
  613. #ifdef AFX_INIT_SEG
  614. #pragma code_seg(AFX_INIT_SEG)
  615. #endif
  616. $ifdef IS_SERIAL
  617. IMPLEMENT_SERIAL(CArray, CObject, 0)
  618. $else
  619. IMPLEMENT_DYNAMIC(CArray, CObject)
  620. $endif //!IS_SERIAL
  621. /////////////////////////////////////////////////////////////////////////////