Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

943 lines
22 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1991 - 1998.
  5. //
  6. // File: DYNARRAY.HXX
  7. //
  8. // Contents: Dynamic Array Template
  9. //
  10. // Classes: CDynArray
  11. // CCountedDynArray
  12. // CCountedIDynArray
  13. // CDynArrayInPlace
  14. // CDynArrayInPlaceNST
  15. // CDynStackInPlace
  16. //
  17. // History: 20-Jan-92 AmyA Created
  18. // 05-Feb-92 BartoszM Converted to macro
  19. // 19-Jun-92 KyleP Moved to Common
  20. // 06-Jan-93 AmyA Split into CDynArray and CDynStack
  21. // 17-Oct-94 BartoszM Converted to template
  22. // 10-Mar-98 KLam Added index operator to CCountedDynArray
  23. //
  24. //----------------------------------------------------------------------------
  25. #pragma once
  26. #include <new.h> // Global placement ::operator new
  27. #define arraySize 16
  28. //+---------------------------------------------------------------------------
  29. // Class: CDynArray
  30. //
  31. // Purpose: Template used to hold dynamically sized arrays of objects
  32. //
  33. // History: 19-Aug-98 KLam Added this header
  34. //
  35. //+---------------------------------------------------------------------------
  36. template<class CItem> class CDynArray
  37. {
  38. public:
  39. CDynArray(unsigned size = arraySize);
  40. void SetExactSize( unsigned size )
  41. {
  42. Free();
  43. if ( 0 != size )
  44. {
  45. _size = size;
  46. _aItem = new CItem *[_size];
  47. RtlZeroMemory( _aItem, _size*sizeof(CItem *) );
  48. }
  49. }
  50. CDynArray( CDynArray<CItem> & src );
  51. ~CDynArray();
  52. void Add(CItem *newItem, unsigned position);
  53. unsigned Size () const {return _size;}
  54. CItem * Get (unsigned position) const;
  55. CItem * GetItem( unsigned position ) const
  56. {
  57. // unlike Get(), no range-checking is done in free builds
  58. Win4Assert( position < _size );
  59. return _aItem[position];
  60. }
  61. void Clear();
  62. void Free()
  63. {
  64. Clear();
  65. delete _aItem;
  66. _aItem = 0;
  67. _size = 0;
  68. }
  69. CItem * Acquire (unsigned position);
  70. CItem * & operator[]( unsigned position ) const
  71. {
  72. Win4Assert( position < _size );
  73. return _aItem[position];
  74. }
  75. CItem ** GetPointer() const { return _aItem; }
  76. CItem ** AcquireAll()
  77. {
  78. CItem **ppTemp = _aItem;
  79. _size = 0;
  80. _aItem = 0;
  81. return ppTemp;
  82. }
  83. protected:
  84. //
  85. // _size **must** come before _aItem. See the copy constructor below
  86. // and remember the order of member initialization...
  87. //
  88. unsigned _size;
  89. CItem ** _aItem;
  90. };
  91. #define DECL_DYNARRAY( CMyDynArray, CItem )\
  92. typedef CDynArray<CItem> CMyDynArray;
  93. #define IMPL_DYNARRAY( CMyDynArray, CItem )
  94. template<class CItem> CDynArray<CItem>::CDynArray(unsigned size)
  95. : _size( size ), _aItem( 0 )
  96. {
  97. if ( 0 != _size )
  98. {
  99. _aItem = new CItem *[_size];
  100. RtlZeroMemory( _aItem, _size*sizeof(CItem *) );
  101. }
  102. }
  103. template<class CItem> CDynArray<CItem>::CDynArray( CDynArray<CItem> & src )
  104. : _size( src._size ),
  105. _aItem( src.AcquireAll() )
  106. {
  107. }
  108. template<class CItem> CDynArray<CItem>::~CDynArray()
  109. {
  110. Clear();
  111. delete _aItem;
  112. }
  113. template<class CItem> void CDynArray<CItem>::Clear()
  114. {
  115. for (unsigned i=0; i < _size; i++) {
  116. delete _aItem[i];
  117. _aItem[i] = 0;
  118. }
  119. }
  120. template<class CItem> CItem* CDynArray<CItem>::Acquire(unsigned position)
  121. {
  122. CItem *tmp = Get(position);
  123. if (tmp) _aItem[position] = 0;
  124. return tmp;
  125. }
  126. template<class CItem> void CDynArray<CItem>::Add(CItem *newItem, unsigned position)
  127. {
  128. if (position >= _size)
  129. {
  130. unsigned newsize = _size * 2;
  131. if ( newsize == 0 )
  132. newsize = arraySize;
  133. for( ; position>=newsize; newsize*=2);
  134. CItem **aNew = new CItem *[newsize];
  135. memcpy( aNew,
  136. _aItem,
  137. _size * sizeof( CItem *) );
  138. RtlZeroMemory( aNew + _size,
  139. (newsize-_size)*sizeof(CItem *) );
  140. delete _aItem;
  141. _aItem = aNew;
  142. _size = newsize;
  143. }
  144. Win4Assert( _aItem[position] == 0 );
  145. _aItem[position] = newItem;
  146. }
  147. template<class CItem> CItem* CDynArray<CItem>::Get(unsigned position) const
  148. {
  149. if ( position >= _size )
  150. return(0);
  151. return _aItem[position];
  152. }
  153. //+---------------------------------------------------------------------------
  154. // Class: CCountedDynArray
  155. //
  156. // Purpose: Template used to hold dynamically sized arrays of objects with a count
  157. //
  158. // History: 19-Aug-98 KLam Added this header
  159. //
  160. //+---------------------------------------------------------------------------
  161. template<class CItem> class CCountedDynArray: public CDynArray<CItem>
  162. {
  163. public:
  164. CCountedDynArray(unsigned size = arraySize)
  165. : CDynArray<CItem>( size ),
  166. _cItem( 0 )
  167. {
  168. }
  169. void Add(CItem *newItem, unsigned position)
  170. {
  171. CDynArray<CItem>::Add( newItem, position );
  172. if ( position + 1 > _cItem )
  173. _cItem = position + 1;
  174. }
  175. CItem * AcquireAndShrink(unsigned position)
  176. {
  177. XPtr<CItem> xItem( Acquire(position) );
  178. if ( 0 != _cItem && position < (_cItem-1) )
  179. {
  180. Add( Acquire(_cItem-1) , position );
  181. }
  182. return xItem.Acquire();
  183. }
  184. CItem * AcquireAndShrinkAndPreserveOrder(unsigned position)
  185. {
  186. XPtr<CItem> xItem( Acquire(position) );
  187. if ( 0 != _cItem && position < (_cItem-1) )
  188. {
  189. for ( unsigned i = position; i < (_cItem-1); i++ )
  190. Add( Acquire(i+1) , i );
  191. }
  192. return xItem.Acquire();
  193. }
  194. unsigned Count() const { return _cItem; }
  195. void Clear()
  196. {
  197. CDynArray<CItem>::Clear();
  198. _cItem = 0;
  199. }
  200. void Free()
  201. {
  202. CDynArray<CItem>::Free();
  203. _cItem = 0;
  204. }
  205. CItem * Acquire (unsigned position)
  206. {
  207. if ( position == (_cItem - 1) )
  208. _cItem--;
  209. return CDynArray<CItem>::Acquire( position );
  210. }
  211. CItem * & operator[]( unsigned position ) const
  212. {
  213. Win4Assert( position < _cItem );
  214. return _aItem[position];
  215. }
  216. protected:
  217. unsigned _cItem;
  218. };
  219. //+---------------------------------------------------------------------------
  220. // Class: CCountedIDynArray
  221. //
  222. // Purpose: Maintains an array of interface pointers
  223. //
  224. // History: 12-Mar-98 KLam Added this header
  225. // 12-Mar-98 KLam Added AddRef and Destructor does not assert
  226. // released items have a ref count of 0
  227. //
  228. // Notes:
  229. // The class assumes that the creator of the interface pointer has passed
  230. // ownership (and therefore the original reference count) to this object.
  231. // When the object is destroyed it releases each of the interface pointers
  232. // maintained by the object.
  233. // If you want the interfaces in this array to exist beyond the lifespan
  234. // of this class then you must AddRef each of those interface pointers.
  235. // Array can be sparse.
  236. //+---------------------------------------------------------------------------
  237. template<class CItem> class CCountedIDynArray: public CCountedDynArray<CItem>
  238. {
  239. public:
  240. CCountedIDynArray(unsigned size = arraySize)
  241. : CCountedDynArray<CItem>( size )
  242. {
  243. }
  244. ~CCountedIDynArray()
  245. {
  246. Release();
  247. for ( unsigned i = 0; i < _size; i++ )
  248. _aItem[ i ] = 0;
  249. }
  250. int Release(); // Calls Release on each interface
  251. void ReleaseAndShrink(); // Calls Release on each interface and packs array
  252. void AddRef(); // Calls AddRef on each interface
  253. void Free()
  254. {
  255. Release();
  256. CCountedDynArray<CItem>::Free();
  257. }
  258. private:
  259. void Clear(); // not a valid method on interfaces.
  260. };
  261. template<class CItem> void CCountedIDynArray<CItem>::AddRef()
  262. {
  263. for ( unsigned i=0; i < _cItem; i++ )
  264. if ( 0 != _aItem[i] )
  265. _aItem[i]->AddRef();
  266. }
  267. // Note: Could make the array sparse(r).
  268. // Value returned could be less than or equal to Count().
  269. template<class CItem> int CCountedIDynArray<CItem>::Release()
  270. {
  271. int cItems = 0;
  272. for (unsigned i=0; i < _cItem; i++)
  273. {
  274. if ( 0 != _aItem[i] )
  275. {
  276. if ( 0 == _aItem[i]->Release() )
  277. {
  278. _aItem[i] = 0;
  279. if ( i == _cItem - 1 )
  280. _cItem--;
  281. }
  282. else
  283. ++cItems;
  284. }
  285. }
  286. return cItems;
  287. }
  288. // Note: Packs the array and preserves the order
  289. template<class CItem> void CCountedIDynArray<CItem>::ReleaseAndShrink()
  290. {
  291. unsigned i=0;
  292. while ( i < _cItem )
  293. {
  294. if ( 0 != _aItem[i] && 0 == _aItem[i]->Release() )
  295. {
  296. // This method will decrement _cItem
  297. AcquireAndShrinkAndPreserveOrder(i);
  298. }
  299. else
  300. i++;
  301. }
  302. }
  303. //+---------------------------------------------------------------------------
  304. // Class: CDynArrayInPlace
  305. //
  306. // Purpose: Identical to CDynArray except array objects are stored in place,
  307. // instead of storing an array of pointers.
  308. //
  309. // History: 19-Aug-98 KLam Added this header
  310. //
  311. // Note: This reduces memory allocations, but does not work for objects
  312. // with destructors.
  313. //
  314. //+---------------------------------------------------------------------------
  315. template<class CItem> class CDynArrayInPlace
  316. {
  317. public:
  318. CDynArrayInPlace(unsigned size);
  319. CDynArrayInPlace();
  320. CDynArrayInPlace( CDynArrayInPlace const & src );
  321. CDynArrayInPlace( CDynArrayInPlace const & src, unsigned size );
  322. ~CDynArrayInPlace();
  323. void Add( const CItem &newItem, unsigned position);
  324. void Insert(const CItem& newItem, unsigned position);
  325. void Remove (unsigned position);
  326. unsigned Size () const {return _size;}
  327. CItem& Get (unsigned position) const;
  328. CItem * Get() { return _aItem; }
  329. void Clear();
  330. unsigned Count() const { return _count; }
  331. void SetSize(unsigned position)
  332. {
  333. if (position >= _size)
  334. _GrowToSize(position);
  335. }
  336. void SetExactSize( unsigned size )
  337. {
  338. Clear();
  339. if ( 0 != size )
  340. {
  341. _size = size;
  342. _aItem = new CItem [_size];
  343. RtlZeroMemory( _aItem, _size * sizeof(CItem) );
  344. }
  345. }
  346. void Shrink()
  347. {
  348. // make size == count, to save memory
  349. if ( 0 == _count )
  350. {
  351. Clear();
  352. }
  353. else if ( _count != _size )
  354. {
  355. CItem * p = new CItem [_count];
  356. _size = _count;
  357. RtlCopyMemory( p, _aItem, _count * sizeof CItem );
  358. delete (BYTE *) _aItem;
  359. _aItem = p;
  360. }
  361. }
  362. CItem* Acquire ()
  363. {
  364. CItem *temp = _aItem;
  365. _aItem = 0;
  366. _count = 0;
  367. _size = 0;
  368. return temp;
  369. }
  370. void Duplicate( CDynArrayInPlace<CItem> & aFrom )
  371. {
  372. Clear();
  373. if ( 0 != aFrom.Count() )
  374. {
  375. _size = _count = aFrom.Count();
  376. _aItem = new CItem [_size];
  377. memcpy( _aItem, aFrom._aItem, _size * sizeof( CItem ) );
  378. }
  379. }
  380. CItem & operator[]( unsigned position )
  381. {
  382. if ( position >= _count )
  383. {
  384. if ( position >= _size )
  385. _GrowToSize( position );
  386. _count = position + 1;
  387. }
  388. return _aItem[position];
  389. }
  390. CItem & operator[]( unsigned position ) const
  391. {
  392. Win4Assert( position < _count );
  393. return _aItem[position];
  394. }
  395. CItem const * GetPointer() { return _aItem; }
  396. unsigned SizeOfInUse() const { return sizeof CItem * Count(); }
  397. protected:
  398. void _GrowToSize( unsigned position );
  399. CItem * _aItem;
  400. unsigned _size;
  401. unsigned _count;
  402. };
  403. #define DECL_DYNARRAY_INPLACE( CMyDynArrayInPlace, CItem )\
  404. typedef CDynArrayInPlace<CItem> CMyDynArrayInPlace;
  405. #define IMPL_DYNARRAY_INPLACE( CMyDynArrayInPlace, CItem )
  406. template<class CItem> CDynArrayInPlace<CItem>::CDynArrayInPlace(unsigned size)
  407. : _size(size), _count(0), _aItem( 0 )
  408. {
  409. if ( 0 != size )
  410. {
  411. _aItem = new CItem [_size];
  412. RtlZeroMemory( _aItem, _size * sizeof(CItem) );
  413. }
  414. }
  415. template<class CItem> CDynArrayInPlace<CItem>::CDynArrayInPlace()
  416. : _size(0), _count(0), _aItem(0)
  417. {
  418. }
  419. template<class CItem> CDynArrayInPlace<CItem>::CDynArrayInPlace( CDynArrayInPlace const & src )
  420. : _size( src._size ),
  421. _count( src._count )
  422. {
  423. _aItem = new CItem [_size];
  424. RtlCopyMemory( _aItem, src._aItem, _size * sizeof(_aItem[0]) );
  425. }
  426. template<class CItem> CDynArrayInPlace<CItem>::CDynArrayInPlace(
  427. CDynArrayInPlace const & src,
  428. unsigned size )
  429. : _size( size ),
  430. _count( src._count )
  431. {
  432. // this constructor is useful if the size should be larger than the
  433. // # of items in the source array
  434. Win4Assert( _size >= _count );
  435. _aItem = new CItem [_size];
  436. RtlCopyMemory( _aItem, src._aItem, _count * sizeof CItem );
  437. }
  438. template<class CItem> CDynArrayInPlace<CItem>::~CDynArrayInPlace()
  439. {
  440. delete [] _aItem;
  441. }
  442. template<class CItem> void CDynArrayInPlace<CItem>::Clear()
  443. {
  444. delete [] _aItem;
  445. _aItem = 0;
  446. _size = 0;
  447. _count = 0;
  448. }
  449. template<class CItem> void CDynArrayInPlace<CItem>::_GrowToSize( unsigned position )
  450. {
  451. Win4Assert( position >= _size );
  452. unsigned newsize = _size * 2;
  453. if ( newsize == 0 )
  454. newsize = arraySize;
  455. for( ; position >= newsize; newsize *= 2)
  456. continue;
  457. CItem *aNew = new CItem [newsize];
  458. if (_size > 0)
  459. {
  460. memcpy( aNew,
  461. _aItem,
  462. _size * sizeof( CItem ) );
  463. }
  464. RtlZeroMemory( aNew + _size,
  465. (newsize-_size) * sizeof(CItem) );
  466. delete (BYTE*) _aItem;
  467. _aItem = aNew;
  468. _size = newsize;
  469. }
  470. template<class CItem> void CDynArrayInPlace<CItem>::Add(const CItem &newItem,
  471. unsigned position)
  472. {
  473. if (position >= _count)
  474. {
  475. if (position >= _size)
  476. _GrowToSize( position );
  477. _count = position + 1;
  478. }
  479. _aItem[position] = newItem;
  480. }
  481. template<class CItem> CItem& CDynArrayInPlace<CItem>::Get(unsigned position) const
  482. {
  483. Win4Assert( position < _count );
  484. return _aItem[position];
  485. }
  486. template<class CItem> void CDynArrayInPlace<CItem>::Insert(const CItem& newItem, unsigned pos)
  487. {
  488. Win4Assert(pos <= _count);
  489. Win4Assert(_count <= _size);
  490. if (_count == _size)
  491. {
  492. unsigned newsize;
  493. if ( _size == 0 )
  494. newsize = arraySize;
  495. else
  496. newsize = _size * 2;
  497. CItem *aNew = new CItem [newsize];
  498. memcpy( aNew,
  499. _aItem,
  500. pos * sizeof( CItem ) );
  501. memcpy( aNew + pos + 1,
  502. _aItem + pos,
  503. (_count - pos) * sizeof(CItem));
  504. delete (BYTE *) _aItem;
  505. _aItem = aNew;
  506. _size = newsize;
  507. }
  508. else
  509. {
  510. memmove ( _aItem + pos + 1,
  511. _aItem + pos,
  512. (_count - pos) * sizeof(CItem));
  513. }
  514. _aItem[pos] = newItem;
  515. _count++;
  516. }
  517. template<class CItem> void CDynArrayInPlace<CItem>::Remove(unsigned pos)
  518. {
  519. Win4Assert(pos < _count);
  520. Win4Assert(_count <= _size);
  521. if (pos < _count - 1)
  522. {
  523. memmove ( _aItem + pos,
  524. _aItem + pos + 1,
  525. (_count - pos - 1) * sizeof(CItem));
  526. }
  527. RtlZeroMemory( _aItem + _count - 1, sizeof(CItem) );
  528. _count--;
  529. if (_count == 0)
  530. {
  531. delete (BYTE*) _aItem;
  532. _aItem = 0;
  533. _size = 0;
  534. }
  535. }
  536. //+-------------------------------------------------------------------------
  537. //
  538. // Class: CDynArrayInPlaceNST
  539. //
  540. // Purpose: DynArrayInPlace for NonSimpleTypes
  541. //
  542. // History: 4-June-98 dlee Created
  543. //
  544. // Notes: This isn't for every class in the world; use with care.
  545. //
  546. //--------------------------------------------------------------------------
  547. template<class T> class CDynArrayInPlaceNST
  548. {
  549. public:
  550. CDynArrayInPlaceNST(unsigned size) :
  551. _size( size ), _count( 0 ), _aItem( 0 )
  552. {
  553. if ( 0 != size )
  554. {
  555. unsigned cb = _size * sizeof T;
  556. _aItem = (T *) new BYTE[ cb ];
  557. // Just in case...
  558. RtlZeroMemory( _aItem, cb );
  559. // Call all the default constructors
  560. for ( unsigned i = 0; i < _size; i++ )
  561. new( & _aItem[i] ) T;
  562. }
  563. }
  564. CDynArrayInPlaceNST() : _count(0), _size(0), _aItem(0) {}
  565. ~CDynArrayInPlaceNST() { Clear(); }
  566. unsigned Size () const { return _size; }
  567. unsigned Count() const { return _count; }
  568. T const * GetPointer() { return _aItem; }
  569. unsigned SizeOfInUse() const { return sizeof T * Count(); }
  570. void Add( const T &newItem, unsigned position)
  571. {
  572. if (position >= _count)
  573. {
  574. if (position >= _size)
  575. _GrowToSize( position );
  576. _count = position + 1;
  577. }
  578. _aItem[position] = newItem;
  579. }
  580. void Insert( const T& newItem, unsigned position )
  581. {
  582. Win4Assert(pos <= _count);
  583. Win4Assert(_count <= _size);
  584. if ( _count == _size )
  585. {
  586. unsigned newsize;
  587. if ( _size == 0 )
  588. newsize = arraySize;
  589. else
  590. newsize = _size * 2;
  591. unsigned cb = newSize * sizeof T;
  592. T * aNew = (T *) new BYTE[ cb ];
  593. RtlZeroMemory( & aNew[ newSize - 1 ], sizeof T );
  594. new( & _aItem[ newSize - 1 ]) T;
  595. memcpy( aNew,
  596. _aItem,
  597. pos * sizeof T );
  598. memcpy( aNew + pos + 1,
  599. _aItem + pos,
  600. (_count - pos) * sizeof T );
  601. delete [] (BYTE *) _aItem;
  602. _aItem = aNew;
  603. _size = newsize;
  604. }
  605. else
  606. {
  607. memmove( _aItem + pos + 1,
  608. _aItem + pos,
  609. (_count - pos) * sizeof T );
  610. }
  611. RtlCopyMemory( _aItem[pos], newItem, sizeof T );
  612. _count++;
  613. }
  614. #if 0 // probably broken...
  615. void Remove (unsigned position)
  616. {
  617. Win4Assert(pos < _count);
  618. Win4Assert(_count <= _size);
  619. if (pos < _count - 1)
  620. memmove ( _aItem + pos,
  621. _aItem + pos + 1,
  622. (_count - pos - 1) * sizeof T );
  623. RtlZeroMemory( _aItem + _count - 1, sizeof T );
  624. _count--;
  625. if ( 0 == _count )
  626. {
  627. delete [] (BYTE*) _aItem;
  628. _aItem = 0;
  629. _size = 0;
  630. }
  631. }
  632. #endif
  633. T & Get (unsigned position) const
  634. {
  635. Win4Assert( position < _count );
  636. return _aItem[ position ];
  637. }
  638. void Clear()
  639. {
  640. for ( unsigned i = 0; i < _size; i++ )
  641. _aItem[i].~T();
  642. delete [] (BYTE*) _aItem;
  643. _aItem = 0;
  644. _size = 0;
  645. _count = 0;
  646. }
  647. void SetSize(unsigned position)
  648. {
  649. if (position >= _size)
  650. _GrowToSize(position);
  651. }
  652. void SetExactSize( unsigned size )
  653. {
  654. Clear();
  655. if ( 0 != size )
  656. {
  657. _size = size;
  658. unsigned cb = _size * sizeof T;
  659. _aItem = (T *) new BYTE[ cb ];
  660. // Just in case...
  661. RtlZeroMemory( _aItem, cb );
  662. // Call all the default constructors
  663. for ( unsigned i = 0; i < _size; i++ )
  664. new( & _aItem[i] ) T;
  665. }
  666. }
  667. void Shrink()
  668. {
  669. // make size == count, to save memory
  670. if ( 0 == _count )
  671. {
  672. Clear();
  673. }
  674. else if ( _count != _size )
  675. {
  676. unsigned cb = _size * sizeof T;
  677. T * p = (T *) new BYTE[ cb ];
  678. _size = _count;
  679. RtlCopyMemory( p, _aItem, _count * sizeof T );
  680. delete [] (BYTE *) _aItem;
  681. _aItem = p;
  682. }
  683. }
  684. T * Acquire()
  685. {
  686. T *temp = _aItem;
  687. _aItem = 0;
  688. _count = 0;
  689. _size = 0;
  690. return temp;
  691. }
  692. void Duplicate( CDynArrayInPlaceNST<T> & aFrom )
  693. {
  694. Clear();
  695. if ( 0 != aFrom.Count() )
  696. {
  697. _size = _count = aFrom.Count();
  698. unsigned cb = _size * sizeof T;
  699. _aItem = (T *) new BYTE[ cb ];
  700. memcpy( _aItem, aFrom._aItem, _size * sizeof T );
  701. }
  702. }
  703. T & operator[]( unsigned position )
  704. {
  705. if ( position >= _count )
  706. {
  707. if ( position >= _size )
  708. _GrowToSize( position );
  709. _count = position + 1;
  710. }
  711. return _aItem[position];
  712. }
  713. T & operator[]( unsigned position ) const
  714. {
  715. Win4Assert( position < _count );
  716. return _aItem[position];
  717. }
  718. protected:
  719. void _GrowToSize( unsigned position )
  720. {
  721. Win4Assert( position >= _size );
  722. unsigned newSize = _size * 2;
  723. if ( newSize == 0 )
  724. newSize = arraySize;
  725. for( ; position >= newSize; newSize *= 2)
  726. continue;
  727. unsigned cb = newSize * sizeof T;
  728. T *aNew = (T *) new BYTE[ cb ];
  729. if (_size > 0)
  730. memcpy( aNew,
  731. _aItem,
  732. _size * sizeof T );
  733. RtlZeroMemory( aNew + _size,
  734. (newSize - _size) * sizeof T );
  735. for ( unsigned i = _size; i < newSize; i++ )
  736. new( & aNew[ i ] ) T;
  737. delete [] (BYTE*) _aItem;
  738. _aItem = aNew;
  739. _size = newSize;
  740. }
  741. T * _aItem;
  742. unsigned _size;
  743. unsigned _count;
  744. };
  745. //+---------------------------------------------------------------------------
  746. //
  747. // Class: CDynStackInPlace
  748. //
  749. // Purpose: Identical to CDynArrayInPlace except array is accessed as a stack.
  750. // Unlike CDynStack because the actual objects are stored, not
  751. // pointers. Useful for simple types.
  752. //
  753. // History: 19-Aug-98 KLam Added this header
  754. //
  755. //+---------------------------------------------------------------------------
  756. template<class T> class CDynStackInPlace : public CDynArrayInPlace<T>
  757. {
  758. public:
  759. CDynStackInPlace(unsigned size = arraySize);
  760. ~CDynStackInPlace() {};
  761. void Push(T newItem);
  762. unsigned Count () const { return _stackSize; }
  763. T & Pop();
  764. private:
  765. unsigned _stackSize;
  766. };
  767. template<class T> CDynStackInPlace<T>::CDynStackInPlace(unsigned size) :
  768. CDynArrayInPlace<T>(size),
  769. _stackSize(0)
  770. {
  771. }
  772. template<class T> void CDynStackInPlace<T>::Push(T newItem)
  773. {
  774. Add( newItem, _stackSize );
  775. _stackSize++;
  776. }
  777. template<class T> T & CDynStackInPlace<T>::Pop()
  778. {
  779. Win4Assert( _stackSize > 0 );
  780. _stackSize--;
  781. return Get(_stackSize);
  782. }