SpColl.h
上传用户:zhanglf88
上传日期:2013-11-19
资源大小:6036k
文件大小:21k
源码类别:

金融证券系统

开发平台:

Visual C++

  1. /*
  2. Cross Platform Core Code.
  3. Copyright(R) 2001-2002 Balang Software.
  4. All rights reserved.
  5. Using:
  6. class CSPArray,
  7. class CSPDWordArray,
  8. class CSPPtrArray,
  9. class CSPObArray,
  10. class CSPStringArray,
  11. class CSPMapStringToPtr;
  12. */
  13. #if !defined( __SP_COLLECT_H__ )
  14. #define __SP_COLLECT_H__
  15. #define SIZE_T_MAX  UINT_MAX            /* max size for a size_t */
  16. ////////////////////////////////////////////////////////////////////////////
  17. // Elements Operating Functions
  18. ////////////////////////////////////////////////////////////////////////////
  19. // WARNING!!!!!!
  20. // 1. 在其他dll或者可执行程序里,不能直接调用CSPArray<TYPE,TYPE&>的函数,因为在
  21. //    _DEBUG方式下,内存的分配、释放方式不同。
  22. ////////////////////////////////////////////////////////////////////////////
  23. #define _SPARRAY_INLINE
  24. ////////////////////////////////////////////////////////////////////////////
  25. // WARNING!!!!!!
  26. // 1. 下面的 operator new 和 delete 仅供SPConstructElements调用,用以调用元素的
  27. // 构造函数。
  28. inline void *__cdecl operator new(size_t, void *_P, int, int )
  29.         {return (_P); }
  30. #if     _MSC_VER >= 1200
  31. inline void __cdecl operator delete(void *, void *, int, int )
  32. {return; }
  33. #endif
  34. template<class TYPE>
  35. _SPARRAY_INLINE void __stdcall SPConstructElements(TYPE* pElements, int nCount)
  36. {
  37. SP_ASSERT(nCount == 0 ||
  38. SP_IsValidAddress((void*)pElements, nCount * sizeof(TYPE)));
  39. // first do bit-wise zero initialization
  40. memset((void*)pElements, 0, nCount * sizeof(TYPE));
  41. for (; nCount--; pElements++)
  42. ::new(((void*)pElements), 0, 0) TYPE;
  43. }
  44. template<class TYPE>
  45. _SPARRAY_INLINE void __stdcall SPDestructElements(TYPE* pElements, int nCount)
  46. {
  47. SP_ASSERT(nCount == 0 ||
  48. SP_IsValidAddress((void*)pElements, nCount * sizeof(TYPE)));
  49. // call the destructor(s)
  50. for (; nCount--; pElements++)
  51. pElements->~TYPE();
  52. }
  53. template<class TYPE>
  54. _SPARRAY_INLINE void __stdcall SPCopyElements(TYPE* pDest, const TYPE* pSrc, int nCount)
  55. {
  56. SP_ASSERT(nCount == 0 ||
  57. SP_IsValidAddress((void*)pDest, nCount * sizeof(TYPE)));
  58. SP_ASSERT(nCount == 0 ||
  59. SP_IsValidAddress((void*)pSrc, nCount * sizeof(TYPE)));
  60. // default is element-copy using assignment
  61. while (nCount--)
  62. *pDest++ = *pSrc++;
  63. }
  64. template<class TYPE>
  65. _SPARRAY_INLINE void __stdcall SPSerializeElements(CSPArchive& ar, TYPE* pElements, int nCount)
  66. {
  67. SP_ASSERT(nCount == 0 ||
  68. SP_IsValidAddress((void*)pElements, nCount * sizeof(TYPE)));
  69. // default is bit-wise read/write
  70. if (ar.IsStoring())
  71. ar.Write((void*)pElements, nCount * sizeof(TYPE));
  72. else
  73. ar.Read((void*)pElements, nCount * sizeof(TYPE));
  74. }
  75. template<class TYPE, class ARG_TYPE>
  76. _SPARRAY_INLINE BOOL __stdcall SPCompareElements(const TYPE* pElement1, const ARG_TYPE* pElement2)
  77. {
  78. SP_ASSERT(SP_IsValidAddress((void*)pElement1, sizeof(TYPE), FALSE));
  79. SP_ASSERT(SP_IsValidAddress((void*)pElement2, sizeof(ARG_TYPE), FALSE));
  80. return *pElement1 == *pElement2;
  81. }
  82. /////////////////////////////////////////////////////////////////////////////
  83. // CSPArray<TYPE, ARG_TYPE>
  84. template<class TYPE, class ARG_TYPE>
  85. class CSPArray : public Object
  86. {
  87. public:
  88. // Construction
  89. CSPArray();
  90. // Attributes
  91. int GetSize() const;
  92. int GetUpperBound() const;
  93. protected:
  94. virtual void SetSize(int nNewSize, int nGrowBy = -1);
  95. // Operations
  96. // Clean up
  97. virtual void FreeExtra();
  98. virtual void RemoveAll();
  99. public:
  100. // Accessing elements
  101. TYPE GetAt(int nIndex) const;
  102. void SetAt(int nIndex, ARG_TYPE newElement);
  103. TYPE& ElementAt(int nIndex);
  104. // Direct Access to the element data (may return NULL)
  105. const TYPE* GetData() const;
  106. TYPE* GetData();
  107. protected:
  108. // Potentially growing the array
  109. virtual void SetAtGrow(int nIndex, ARG_TYPE newElement);
  110. virtual int Add(ARG_TYPE newElement);
  111. virtual int Append(const CSPArray& src);
  112. virtual void Copy(const CSPArray& src);
  113. public:
  114. // overloaded operator helpers
  115. TYPE operator[](int nIndex) const;
  116. TYPE& operator[](int nIndex);
  117. protected:
  118. // Operations that move elements around
  119. virtual void InsertAt(int nIndex, ARG_TYPE newElement, int nCount = 1);
  120. virtual void RemoveAt(int nIndex, int nCount = 1);
  121. virtual void InsertAt(int nStartIndex, CSPArray* pNewArray);
  122. // Implementation
  123. protected:
  124. TYPE* m_pData;   // the actual array of data
  125. int m_nSize;     // # of elements (upperBound - 1)
  126. int m_nMaxSize;  // max allocated
  127. int m_nGrowBy;   // grow amount
  128. protected:
  129. virtual ~CSPArray();
  130. public:
  131. void Serialize(CSPArchive&);
  132. #ifdef _DEBUG
  133. void Dump() const;
  134. void AssertValid() const;
  135. #endif
  136. };
  137. /////////////////////////////////////////////////////////////////////////////
  138. // CSPArray<TYPE, ARG_TYPE> inline functions
  139. template<class TYPE, class ARG_TYPE>
  140. _SPARRAY_INLINE int CSPArray<TYPE, ARG_TYPE>::GetSize() const
  141. { return m_nSize; }
  142. template<class TYPE, class ARG_TYPE>
  143. _SPARRAY_INLINE int CSPArray<TYPE, ARG_TYPE>::GetUpperBound() const
  144. { return m_nSize-1; }
  145. template<class TYPE, class ARG_TYPE>
  146. _SPARRAY_INLINE void CSPArray<TYPE, ARG_TYPE>::RemoveAll()
  147. { SetSize(0, -1); }
  148. template<class TYPE, class ARG_TYPE>
  149. _SPARRAY_INLINE TYPE CSPArray<TYPE, ARG_TYPE>::GetAt(int nIndex) const
  150. { SP_ASSERT(nIndex >= 0 && nIndex < m_nSize);
  151. return m_pData[nIndex]; }
  152. template<class TYPE, class ARG_TYPE>
  153. _SPARRAY_INLINE void CSPArray<TYPE, ARG_TYPE>::SetAt(int nIndex, ARG_TYPE newElement)
  154. { SP_ASSERT(nIndex >= 0 && nIndex < m_nSize);
  155. m_pData[nIndex] = newElement; }
  156. template<class TYPE, class ARG_TYPE>
  157. _SPARRAY_INLINE TYPE& CSPArray<TYPE, ARG_TYPE>::ElementAt(int nIndex)
  158. { SP_ASSERT(nIndex >= 0 && nIndex < m_nSize);
  159. return m_pData[nIndex]; }
  160. template<class TYPE, class ARG_TYPE>
  161. _SPARRAY_INLINE const TYPE* CSPArray<TYPE, ARG_TYPE>::GetData() const
  162. { return (const TYPE*)m_pData; }
  163. template<class TYPE, class ARG_TYPE>
  164. _SPARRAY_INLINE TYPE* CSPArray<TYPE, ARG_TYPE>::GetData()
  165. { return (TYPE*)m_pData; }
  166. template<class TYPE, class ARG_TYPE>
  167. _SPARRAY_INLINE int CSPArray<TYPE, ARG_TYPE>::Add(ARG_TYPE newElement)
  168. { int nIndex = m_nSize;
  169. SetAtGrow(nIndex, newElement);
  170. return nIndex; }
  171. template<class TYPE, class ARG_TYPE>
  172. _SPARRAY_INLINE TYPE CSPArray<TYPE, ARG_TYPE>::operator[](int nIndex) const
  173. { return GetAt(nIndex); }
  174. template<class TYPE, class ARG_TYPE>
  175. _SPARRAY_INLINE TYPE& CSPArray<TYPE, ARG_TYPE>::operator[](int nIndex)
  176. { return ElementAt(nIndex); }
  177. /////////////////////////////////////////////////////////////////////////////
  178. // CSPArray<TYPE, ARG_TYPE> out-of-line functions
  179. template<class TYPE, class ARG_TYPE>
  180. CSPArray<TYPE, ARG_TYPE>::CSPArray()
  181. {
  182. m_pData = NULL;
  183. m_nSize = m_nMaxSize = m_nGrowBy = 0;
  184. }
  185. template<class TYPE, class ARG_TYPE>
  186. CSPArray<TYPE, ARG_TYPE>::~CSPArray()
  187. {
  188. SP_ASSERT_VALID(this);
  189. if (m_pData != NULL)
  190. {
  191. SPDestructElements<TYPE>(m_pData, m_nSize);
  192. delete[] (BYTE*)m_pData;
  193. m_pData = NULL;
  194. }
  195. m_nSize = m_nMaxSize = 0;
  196. }
  197. template<class TYPE, class ARG_TYPE>
  198. void CSPArray<TYPE, ARG_TYPE>::SetSize(int nNewSize, int nGrowBy)
  199. {
  200. SP_ASSERT_VALID(this);
  201. SP_ASSERT(nNewSize >= 0);
  202. if (nGrowBy != -1)
  203. m_nGrowBy = nGrowBy;  // set new size
  204. if (nNewSize == 0)
  205. {
  206. // shrink to nothing
  207. if (m_pData != NULL)
  208. {
  209. SPDestructElements<TYPE>(m_pData, m_nSize);
  210. delete[] (BYTE*)m_pData;
  211. m_pData = NULL;
  212. }
  213. m_nSize = m_nMaxSize = 0;
  214. }
  215. else if (m_pData == NULL)
  216. {
  217. // create one with exact size
  218. #ifdef SIZE_T_MAX
  219. SP_ASSERT(nNewSize <= SIZE_T_MAX/sizeof(TYPE));    // no overflow
  220. #endif
  221. m_pData = (TYPE*) new BYTE[nNewSize * sizeof(TYPE)];
  222. SPConstructElements<TYPE>(m_pData, nNewSize);
  223. m_nSize = m_nMaxSize = nNewSize;
  224. }
  225. else if (nNewSize <= m_nMaxSize)
  226. {
  227. // it fits
  228. if (nNewSize > m_nSize)
  229. {
  230. // initialize the new elements
  231. SPConstructElements<TYPE>(&m_pData[m_nSize], nNewSize-m_nSize);
  232. }
  233. else if (m_nSize > nNewSize)
  234. {
  235. // destroy the old elements
  236. SPDestructElements<TYPE>(&m_pData[nNewSize], m_nSize-nNewSize);
  237. }
  238. m_nSize = nNewSize;
  239. }
  240. else
  241. {
  242. // otherwise, grow array
  243. int nGrowBy = m_nGrowBy;
  244. if (nGrowBy == 0)
  245. {
  246. // heuristically determine growth when nGrowBy == 0
  247. //  (this avoids heap fragmentation in many situations)
  248. nGrowBy = m_nSize / 8;
  249. nGrowBy = (nGrowBy < 4) ? 4 : ((nGrowBy > 1024) ? 1024 : nGrowBy);
  250. }
  251. int nNewMax;
  252. if (nNewSize < m_nMaxSize + nGrowBy)
  253. nNewMax = m_nMaxSize + nGrowBy;  // granularity
  254. else
  255. nNewMax = nNewSize;  // no slush
  256. SP_ASSERT(nNewMax >= m_nMaxSize);  // no wrap around
  257. #ifdef SIZE_T_MAX
  258. SP_ASSERT(nNewMax <= SIZE_T_MAX/sizeof(TYPE)); // no overflow
  259. #endif
  260. TYPE* pNewData = (TYPE*) new BYTE[nNewMax * sizeof(TYPE)];
  261. // copy new data from old
  262. memcpy(pNewData, m_pData, m_nSize * sizeof(TYPE));
  263. // construct remaining elements
  264. SP_ASSERT(nNewSize > m_nSize);
  265. SPConstructElements<TYPE>(&pNewData[m_nSize], nNewSize-m_nSize);
  266. // get rid of old stuff (note: no destructors called)
  267. delete[] (BYTE*)m_pData;
  268. m_pData = pNewData;
  269. m_nSize = nNewSize;
  270. m_nMaxSize = nNewMax;
  271. }
  272. }
  273. template<class TYPE, class ARG_TYPE>
  274. int CSPArray<TYPE, ARG_TYPE>::Append(const CSPArray& src)
  275. {
  276. SP_ASSERT_VALID(this);
  277. SP_ASSERT(this != &src);   // cannot append to itself
  278. int nOldSize = m_nSize;
  279. SetSize(m_nSize + src.m_nSize);
  280. SPCopyElements<TYPE>(m_pData + nOldSize, src.m_pData, src.m_nSize);
  281. return nOldSize;
  282. }
  283. template<class TYPE, class ARG_TYPE>
  284. void CSPArray<TYPE, ARG_TYPE>::Copy(const CSPArray& src)
  285. {
  286. SP_ASSERT_VALID(this);
  287. SP_ASSERT(this != &src);   // cannot append to itself
  288. SetSize(src.m_nSize);
  289. SPCopyElements<TYPE>(m_pData, src.m_pData, src.m_nSize);
  290. }
  291. template<class TYPE, class ARG_TYPE>
  292. void CSPArray<TYPE, ARG_TYPE>::FreeExtra()
  293. {
  294. SP_ASSERT_VALID(this);
  295. if (m_nSize != m_nMaxSize)
  296. {
  297. // shrink to desired size
  298. #ifdef SIZE_T_MAX
  299. SP_ASSERT(m_nSize <= SIZE_T_MAX/sizeof(TYPE)); // no overflow
  300. #endif
  301. TYPE* pNewData = NULL;
  302. if (m_nSize != 0)
  303. {
  304. pNewData = (TYPE*) new BYTE[m_nSize * sizeof(TYPE)];
  305. // copy new data from old
  306. memcpy(pNewData, m_pData, m_nSize * sizeof(TYPE));
  307. }
  308. // get rid of old stuff (note: no destructors called)
  309. delete[] (BYTE*)m_pData;
  310. m_pData = pNewData;
  311. m_nMaxSize = m_nSize;
  312. }
  313. }
  314. template<class TYPE, class ARG_TYPE>
  315. void CSPArray<TYPE, ARG_TYPE>::SetAtGrow(int nIndex, ARG_TYPE newElement)
  316. {
  317. SP_ASSERT_VALID(this);
  318. SP_ASSERT(nIndex >= 0);
  319. if (nIndex >= m_nSize)
  320. SetSize(nIndex+1, -1);
  321. m_pData[nIndex] = newElement;
  322. }
  323. template<class TYPE, class ARG_TYPE>
  324. void CSPArray<TYPE, ARG_TYPE>::InsertAt(int nIndex, ARG_TYPE newElement, int nCount /*=1*/)
  325. {
  326. SP_ASSERT_VALID(this);
  327. SP_ASSERT(nIndex >= 0);    // will expand to meet need
  328. SP_ASSERT(nCount > 0);     // zero or negative size not allowed
  329. if (nIndex >= m_nSize)
  330. {
  331. // adding after the end of the array
  332. SetSize(nIndex + nCount, -1);   // grow so nIndex is valid
  333. }
  334. else
  335. {
  336. // inserting in the middle of the array
  337. int nOldSize = m_nSize;
  338. SetSize(m_nSize + nCount, -1);  // grow it to new size
  339. // destroy intial data before copying over it
  340. SPDestructElements<TYPE>(&m_pData[nOldSize], nCount);
  341. // shift old data up to fill gap
  342. memmove(&m_pData[nIndex+nCount], &m_pData[nIndex],
  343. (nOldSize-nIndex) * sizeof(TYPE));
  344. // re-init slots we copied from
  345. SPConstructElements<TYPE>(&m_pData[nIndex], nCount);
  346. }
  347. // insert new value in the gap
  348. SP_ASSERT(nIndex + nCount <= m_nSize);
  349. while (nCount--)
  350. m_pData[nIndex++] = newElement;
  351. }
  352. template<class TYPE, class ARG_TYPE>
  353. void CSPArray<TYPE, ARG_TYPE>::RemoveAt(int nIndex, int nCount)
  354. {
  355. SP_ASSERT_VALID(this);
  356. SP_ASSERT(nIndex >= 0);
  357. SP_ASSERT(nCount >= 0);
  358. SP_ASSERT(nIndex + nCount <= m_nSize);
  359. // just remove a range
  360. int nMoveCount = m_nSize - (nIndex + nCount);
  361. SPDestructElements<TYPE>(&m_pData[nIndex], nCount);
  362. if (nMoveCount)
  363. memmove(&m_pData[nIndex], &m_pData[nIndex + nCount],
  364. nMoveCount * sizeof(TYPE));
  365. m_nSize -= nCount;
  366. }
  367. template<class TYPE, class ARG_TYPE>
  368. void CSPArray<TYPE, ARG_TYPE>::InsertAt(int nStartIndex, CSPArray* pNewArray)
  369. {
  370. SP_ASSERT_VALID(this);
  371. SP_ASSERT(pNewArray != NULL);
  372. SP_ASSERT_VALID(pNewArray);
  373. SP_ASSERT(nStartIndex >= 0);
  374. if (pNewArray->GetSize() > 0)
  375. {
  376. InsertAt(nStartIndex, pNewArray->GetAt(0), pNewArray->GetSize());
  377. for (int i = 0; i < pNewArray->GetSize(); i++)
  378. SetAt(nStartIndex + i, pNewArray->GetAt(i));
  379. }
  380. }
  381. template<class TYPE, class ARG_TYPE>
  382. void CSPArray<TYPE, ARG_TYPE>::Serialize(CSPArchive& ar)
  383. {
  384. SP_ASSERT_VALID(this);
  385. // Object::Serialize(ar);
  386. if (ar.IsStoring())
  387. {
  388. ar.WriteCount(m_nSize);
  389. }
  390. else
  391. {
  392. DWORD nOldSize = ar.ReadCount();
  393. SetSize(nOldSize, -1);
  394. }
  395. SPSerializeElements<TYPE>(ar, m_pData, m_nSize);
  396. }
  397. #ifdef _DEBUG
  398. template<class TYPE, class ARG_TYPE>
  399. void CSPArray<TYPE, ARG_TYPE>::Dump() const
  400. {
  401. Object::Dump();
  402. }
  403. template<class TYPE, class ARG_TYPE>
  404. void CSPArray<TYPE, ARG_TYPE>::AssertValid() const
  405. {
  406. Object::AssertValid();
  407. if (m_pData == NULL)
  408. {
  409. SP_ASSERT(m_nSize == 0);
  410. SP_ASSERT(m_nMaxSize == 0);
  411. }
  412. else
  413. {
  414. SP_ASSERT(m_nSize >= 0);
  415. SP_ASSERT(m_nMaxSize >= 0);
  416. SP_ASSERT(m_nSize <= m_nMaxSize);
  417. SP_ASSERT(SP_IsValidAddress((void*)m_pData, m_nMaxSize * sizeof(TYPE)));
  418. }
  419. }
  420. #endif //_DEBUG
  421. ////////////////////////////////////////////////////////////////////////////
  422. // CSPDWordArray
  423. class STKLIB_API CSPDWordArray : public Object
  424. {
  425. public:
  426. // Construction
  427. CSPDWordArray();
  428. // Attributes
  429. int GetSize() const;
  430. int GetUpperBound() const;
  431. void SetSize(int nNewSize, int nGrowBy = -1);
  432. void Copy( const CSPDWordArray & src );
  433. // Operations
  434. // Clean up
  435. void FreeExtra();
  436. void RemoveAll();
  437. // Accessing elements
  438. DWORD GetAt(int nIndex) const;
  439. void SetAt(int nIndex, DWORD newElement);
  440. DWORD& ElementAt(int nIndex);
  441. // Potentially growing the array
  442. void SetAtGrow(int nIndex, DWORD newElement);
  443. int Add(DWORD newElement);
  444. // overloaded operator helpers
  445. DWORD operator[](int nIndex) const;
  446. DWORD& operator[](int nIndex);
  447. // Operations that move elements around
  448. void InsertAt(int nIndex, DWORD newElement, int nCount = 1);
  449. void RemoveAt(int nIndex, int nCount = 1);
  450. void InsertAt(int nStartIndex, CSPDWordArray* pNewArray);
  451. // 
  452. int AddUnique( DWORD newElement );
  453. void Sort( );
  454. BOOL IsEqualTo( CSPDWordArray & adw );
  455. DWORD * GetData();
  456. // Implementation
  457. protected:
  458. DWORD* m_pData;   // the actual array of data
  459. int m_nSize;     // # of elements (upperBound - 1)
  460. int m_nMaxSize;  // max allocated
  461. int m_nGrowBy;   // grow amount
  462. public:
  463. ~CSPDWordArray();
  464. void Serialize(CSPArchive&);
  465. #ifdef _DEBUG
  466. public:
  467. virtual void AssertValid() const;
  468. virtual void Dump( ) const;
  469. #endif
  470. };
  471. ////////////////////////////////////////////////////////////////////////////
  472. // CSPPrtArray
  473. class STKLIB_API CSPPtrArray : public Object
  474. {
  475. public:
  476. // Construction
  477. CSPPtrArray();
  478. // Attributes
  479. int GetSize() const;
  480. int GetUpperBound() const;
  481. void SetSize(int nNewSize, int nGrowBy = -1);
  482. // Operations
  483. // Clean up
  484. void FreeExtra();
  485. void RemoveAll();
  486. // Accessing elements
  487. void* GetAt(int nIndex) const;
  488. void SetAt(int nIndex, void* newElement);
  489. void*& ElementAt(int nIndex);
  490. // Potentially growing the array
  491. void SetAtGrow(int nIndex, void* newElement);
  492. int Add(void* newElement);
  493. // overloaded operator helpers
  494. void* operator[](int nIndex) const;
  495. void*& operator[](int nIndex);
  496. // Operations that move elements around
  497. void InsertAt(int nIndex, void* newElement, int nCount = 1);
  498. void RemoveAt(int nIndex, int nCount = 1);
  499. void InsertAt(int nStartIndex, CSPPtrArray* pNewArray);
  500. int Append(const CSPPtrArray& src);
  501. void Copy(const CSPPtrArray& src);
  502. // Implementation
  503. protected:
  504. void** m_pData;   // the actual array of data
  505. int m_nSize;     // # of elements (upperBound - 1)
  506. int m_nMaxSize;  // max allocated
  507. int m_nGrowBy;   // grow amount
  508. public:
  509. ~CSPPtrArray();
  510. #ifdef _DEBUG
  511. public:
  512. virtual void AssertValid() const;
  513. virtual void Dump( ) const;
  514. #endif
  515. };
  516. ////////////////////////////////////////////////////////////////////////////
  517. // CSPObArray
  518. class STKLIB_API CSPObArray : public Object
  519. {
  520. public:
  521. // Construction
  522. CSPObArray();
  523. // Attributes
  524. int GetSize() const;
  525. int GetUpperBound() const;
  526. void SetSize(int nNewSize, int nGrowBy = -1);
  527. // Operations
  528. // Clean up
  529. void FreeExtra();
  530. void RemoveAll();
  531. // Accessing elements
  532. Object* GetAt(int nIndex) const;
  533. void SetAt(int nIndex, Object* newElement);
  534. Object*& ElementAt(int nIndex);
  535. // Potentially growing the array
  536. void SetAtGrow(int nIndex, Object* newElement);
  537. int Add(Object* newElement);
  538. // overloaded operator helpers
  539. Object* operator[](int nIndex) const;
  540. Object*& operator[](int nIndex);
  541. // Operations that move elements around
  542. void InsertAt(int nIndex, Object* newElement, int nCount = 1);
  543. void RemoveAt(int nIndex, int nCount = 1);
  544. void InsertAt(int nStartIndex, CSPObArray* pNewArray);
  545. // Implementation
  546. protected:
  547. Object** m_pData;   // the actual array of data
  548. int m_nSize;     // # of elements (upperBound - 1)
  549. int m_nMaxSize;  // max allocated
  550. int m_nGrowBy;   // grow amount
  551. public:
  552. ~CSPObArray();
  553. #ifdef _DEBUG
  554. void Dump( ) const;
  555. void AssertValid() const;
  556. #endif
  557. };
  558. ////////////////////////////////////////////////////////////////////////////
  559. // CSPStringArray
  560. class STKLIB_API CSPStringArray : public Object
  561. {
  562. public:
  563. // Construction
  564. CSPStringArray();
  565. static CSPStringArray * m_pSortSPStringArray;
  566. // Attributes
  567. int GetSize() const;
  568. int GetUpperBound() const;
  569. void SetSize(int nNewSize, int nGrowBy = -1);
  570. int Append(const CSPStringArray& src);
  571. void Copy(const CSPStringArray& src);
  572. // Operations
  573. // Clean up
  574. void FreeExtra();
  575. void RemoveAll();
  576. // Accessing elements
  577. CSPString GetAt(int nIndex) const;
  578. void SetAt(int nIndex, const char* newElement);
  579. CSPString& ElementAt(int nIndex);
  580. // Potentially growing the array
  581. void SetAtGrow(int nIndex, const char* newElement);
  582. int Add(const char* newElement);
  583. // overloaded operator helpers
  584. CSPString operator[](int nIndex) const;
  585. CSPString& operator[](int nIndex);
  586. // Operations that move elements around
  587. void InsertAt(int nIndex, const char* newElement, int nCount = 1);
  588. void RemoveAt(int nIndex, int nCount = 1);
  589. void InsertAt(int nStartIndex, CSPStringArray* pNewArray);
  590. BOOL GetSortIDArray( CSPDWordArray & adwSortID );
  591. // Implementation
  592. protected:
  593. CSPString* m_pData;   // the actual array of data
  594. int m_nSize;     // # of elements (upperBound - 1)
  595. int m_nMaxSize;  // max allocated
  596. int m_nGrowBy;   // grow amount
  597. void SPConstructElements(CSPString* pElements, int nCount);
  598. void SPDestructElements(CSPString* pElements, int nCount);
  599. public:
  600. ~CSPStringArray();
  601. void Serialize(CSPArchive&);
  602. #ifdef _DEBUG
  603. void Dump() const;
  604. void AssertValid() const;
  605. #endif
  606. };
  607. /////////////////////////////////////////////////////////////////////////////
  608. // CSPPlex
  609. struct CSPPlex     // warning variable length structure
  610. {
  611. CSPPlex* pNext;
  612. #if (_AFX_PACKING >= 8)
  613. DWORD dwReserved[1];    // align on 8 byte boundary
  614. #endif
  615. // BYTE data[maxNum*elementSize];
  616. void* data() { return this+1; }
  617. static CSPPlex* PASCAL Create(CSPPlex*& head, UINT nMax, UINT cbElement);
  618. // like 'calloc' but no zero fill
  619. // may throw memory exceptions
  620. void FreeDataChain();       // free this one and links
  621. };
  622. /////////////////////////////////////////////////////////////////////////////
  623. // CSPMapStringToPtr
  624. // abstract iteration position
  625. struct __SPPOSITION { };
  626. typedef __SPPOSITION* SPPOSITION;
  627. #define BEFORE_START_SPPOSITION ((SPPOSITION)-1L)
  628. class STKLIB_API CSPMapStringToPtr : public Object
  629. {
  630. protected:
  631. // Association
  632. struct CAssoc
  633. {
  634. CAssoc* pNext;
  635. UINT nHashValue;  // needed for efficient iteration
  636. CSPString key;
  637. void* value;
  638. };
  639. public:
  640. // Construction
  641. CSPMapStringToPtr(int nBlockSize = 10);
  642. // Attributes
  643. // number of elements
  644. int GetCount() const;
  645. BOOL IsEmpty() const;
  646. // Lookup
  647. BOOL Lookup(LPCTSTR key, void*& rValue) const;
  648. BOOL LookupKey(LPCTSTR key, LPCTSTR& rKey) const;
  649. // Operations
  650. // Lookup and add if not there
  651. void*& operator[](LPCTSTR key);
  652. // add a new (key, value) pair
  653. void SetAt(LPCTSTR key, void* newValue);
  654. // removing existing (key, ?) pair
  655. BOOL RemoveKey(LPCTSTR key);
  656. void RemoveAll();
  657. // iterating all (key, value) pairs
  658. SPPOSITION GetStartPosition() const;
  659. void GetNextAssoc(SPPOSITION& rNextPosition, CSPString& rKey, void*& rValue) const;
  660. // advanced features for derived classes
  661. UINT GetHashTableSize() const;
  662. void InitHashTable(UINT hashSize, BOOL bAllocNow = TRUE);
  663. // Overridables: special non-virtual (see map implementation for details)
  664. // Routine used to user-provided hash keys
  665. UINT HashKey(LPCTSTR key) const;
  666. // Implementation
  667. protected:
  668. CAssoc** m_pHashTable;
  669. UINT m_nHashTableSize;
  670. int m_nCount;
  671. CAssoc* m_pFreeList;
  672. struct CSPPlex* m_pBlocks;
  673. int m_nBlockSize;
  674. CAssoc* NewAssoc();
  675. void FreeAssoc(CAssoc*);
  676. CAssoc* GetAssocAt(LPCTSTR, UINT&) const;
  677. public:
  678. ~CSPMapStringToPtr();
  679. #ifdef _DEBUG
  680. void Dump() const;
  681. void AssertValid() const;
  682. #endif
  683. protected:
  684. // local typedefs for CTypedPtrMap class template
  685. typedef CSPString BASE_KEY;
  686. typedef LPCTSTR BASE_ARG_KEY;
  687. typedef void* BASE_VALUE;
  688. typedef void* BASE_ARG_VALUE;
  689. };
  690. #ifdef _SP_ENABLE_INLINES
  691. #define _SPCOLL_INLINE inline
  692. #include "SpColl.inl"
  693. #undef _SPCOLL_INLINE
  694. #endif
  695. #endif //__SP_COLLECT_H__