Leaked source code of windows server 2003
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.

882 lines
24 KiB

  1. //////////////////////////////////////////////////////////////////////////////
  2. //
  3. // Copyright (c) 2001 Microsoft Corporation
  4. //
  5. // Module Name:
  6. // DynamicArray.h
  7. //
  8. // Description:
  9. // This file contains an array template that doesn't throw exceptions.
  10. //
  11. // Documentation:
  12. //
  13. // Implementation Files:
  14. // None.
  15. //
  16. // Maintained By:
  17. // John Franco (jfranco) 22-AUG-2001
  18. //
  19. //////////////////////////////////////////////////////////////////////////////
  20. // Make sure that this file is included only once per compile path.
  21. #pragma once
  22. //////////////////////////////////////////////////////////////////////////////
  23. // Include Files
  24. //////////////////////////////////////////////////////////////////////////////
  25. //////////////////////////////////////////////////////////////////////////////
  26. // Constant Declarations
  27. //////////////////////////////////////////////////////////////////////////////
  28. //////////////////////////////////////////////////////////////////////////////
  29. // Template Declarations
  30. //////////////////////////////////////////////////////////////////////////////
  31. //////////////////////////////////////////////////////////////////////////////
  32. //++
  33. //
  34. // DynamicArray< Item, Assignment > template
  35. //
  36. // Description:
  37. // DynamicArray stores a variable number of Items in a contiguous block
  38. // of memory. It intends to be similar to std::vector, with the main
  39. // difference being that it handles errors through return values rather
  40. // than exceptions.
  41. //
  42. // Template Arguments:
  43. // Item - the type of the elements in the array.
  44. // requirements for Item:
  45. // - default constructor
  46. //
  47. // Assignment
  48. // The function that overwrites one Item with another; default is
  49. // one that assumes Item has an assignment operator that never fails.
  50. //
  51. // requirements for Assignment:
  52. // - default constructor
  53. // - HRESULT operator()( Item &, const Item & ) const;
  54. // or, PredecessorFunction can be a pointer to a function
  55. // taking two Item references and returning an HRESULT.
  56. //
  57. //--
  58. //////////////////////////////////////////////////////////////////////////////
  59. namespace Generics
  60. {
  61. template < class Item >
  62. struct DefaultAssignment
  63. {
  64. HRESULT operator()( Item& rItemDestInOut, const Item& crItemSourceIn ) const
  65. {
  66. rItemDestInOut = crItemSourceIn;
  67. return S_OK;
  68. }
  69. };
  70. template < class Item, class Assignment = DefaultAssignment<Item> >
  71. class DynamicArray
  72. {
  73. public:
  74. typedef Item* Iterator;
  75. typedef const Item* ConstIterator;
  76. DynamicArray( void );
  77. ~DynamicArray( void );
  78. HRESULT HrReserve( size_t cNewCapacityIn );
  79. HRESULT HrResize( size_t cNewSizeIn, const Item& crItemFillerIn = Item() );
  80. HRESULT HrPushBack( const Item& crItemToPushIn );
  81. HRESULT HrPopBack( void );
  82. HRESULT HrRemove( Iterator ItemToRemoveIn );
  83. HRESULT HrCompact( void );
  84. void Clear( void );
  85. void Swap( DynamicArray& rOtherInOut );
  86. size_t CCapacity( void ) const;
  87. size_t Count( void ) const;
  88. bool BEmpty( void ) const;
  89. Iterator ItBegin( void );
  90. ConstIterator ItBegin( void ) const;
  91. Iterator ItEnd( void );
  92. ConstIterator ItEnd( void ) const;
  93. Item& operator[]( size_t idxItemIn );
  94. const Item& operator[]( size_t idxItemIn ) const;
  95. private:
  96. DynamicArray( const DynamicArray& );
  97. DynamicArray& operator=( const DynamicArray& );
  98. HRESULT HrRaiseCapacity( size_t cAmountIn );
  99. Item* m_prgItems;
  100. size_t m_cItems;
  101. size_t m_cCapacity;
  102. Assignment m_opAssign;
  103. }; //*** class DynamicArray< Item, Assignment >
  104. //////////////////////////////////////////////////////////////////////////////
  105. //++
  106. //
  107. // DynamicArray< Item, Assignment >::DynamicArray
  108. //
  109. // Description:
  110. // Initializes the array as empty.
  111. //
  112. // Arguments:
  113. // None.
  114. //
  115. // Return Values:
  116. // None.
  117. //
  118. // Remarks:
  119. //
  120. //--
  121. //////////////////////////////////////////////////////////////////////////////
  122. template < class Item, class Assignment >
  123. DynamicArray< Item, Assignment >::DynamicArray( void ):
  124. m_prgItems( NULL ), m_cItems( 0 ), m_cCapacity( 0 ), m_opAssign() {}
  125. //////////////////////////////////////////////////////////////////////////////
  126. //++
  127. //
  128. // DynamicArray< Item, Assignment >::~DynamicArray
  129. //
  130. // Description:
  131. // Frees any memory held by the array, invoking destructors of any
  132. // objects within the array.
  133. //
  134. // Arguments:
  135. // None.
  136. //
  137. // Return Values:
  138. // None.
  139. //
  140. // Remarks:
  141. //
  142. //--
  143. //////////////////////////////////////////////////////////////////////////////
  144. template < class Item, class Assignment >
  145. DynamicArray< Item, Assignment >::~DynamicArray( void )
  146. {
  147. Clear();
  148. }
  149. //////////////////////////////////////////////////////////////////////////////
  150. //++
  151. //
  152. // DynamicArray< Item, Assignment >::HrPushBack
  153. //
  154. // Description:
  155. // Appends a copy of an object onto the end of the array,
  156. // growing the array if necessary.
  157. //
  158. // Arguments:
  159. // crItemToPushIn - The object to copy onto the end of the array.
  160. //
  161. // Return Values:
  162. // S_OK - The array has added a copy of the object to its end.
  163. //
  164. // Failure - Something went wrong, and the array's size is unchanged.
  165. //
  166. // Remarks:
  167. //
  168. // Analogous to std::vector::push_back.
  169. //
  170. //--
  171. //////////////////////////////////////////////////////////////////////////////
  172. template < class Item, class Assignment >
  173. inline HRESULT DynamicArray< Item, Assignment >::HrPushBack( const Item& crItemToPushIn )
  174. {
  175. HRESULT hr = S_OK;
  176. // Raise capacity if necessary.
  177. if ( m_cCapacity == 0 )
  178. {
  179. hr = HrRaiseCapacity( 1 );
  180. if ( FAILED( hr ) )
  181. {
  182. goto Cleanup;
  183. }
  184. }
  185. else if ( m_cItems == m_cCapacity )
  186. {
  187. hr = HrRaiseCapacity( m_cCapacity );
  188. if ( FAILED( hr ) )
  189. {
  190. goto Cleanup;
  191. }
  192. }
  193. // Copy crItemToPushIn into space just after any current contents.
  194. hr = m_opAssign( m_prgItems[ m_cItems ], crItemToPushIn );
  195. if ( FAILED( hr ) )
  196. {
  197. goto Cleanup;
  198. }
  199. m_cItems += 1;
  200. Cleanup:
  201. return hr;
  202. } //*** DynamicArray< Item, Assignment >::HrPushBack
  203. //////////////////////////////////////////////////////////////////////////////
  204. //++
  205. //
  206. // DynamicArray< Item, Assignment >::HrPopBack
  207. //
  208. // Description:
  209. // Discards the last element of the array, if one exists.
  210. //
  211. // Arguments:
  212. // crItemToPushIn - The object to copy onto the end of the array.
  213. //
  214. // Return Values:
  215. // S_OK - The array has added a copy of the object to its end.
  216. //
  217. // Remarks:
  218. //
  219. // Analogous to std::vector::pop_back.
  220. //
  221. // This does not destroy the last object in the array; it merely marks
  222. // that position as unused. To free the resources associated with the
  223. // popped object, call HrCompact.
  224. //
  225. //--
  226. //////////////////////////////////////////////////////////////////////////////
  227. template < class Item, class Assignment >
  228. inline HRESULT DynamicArray< Item, Assignment >::HrPopBack( void )
  229. {
  230. HRESULT hr = S_FALSE;
  231. if ( m_cItems > 0 )
  232. {
  233. m_cItems -= 1;
  234. hr = S_OK;
  235. }
  236. return hr;
  237. } //*** DynamicArray< Item, Assignment >::HrPopBack
  238. //////////////////////////////////////////////////////////////////////////////
  239. //++
  240. //
  241. // DynamicArray< Item, Assignment >::HrResize
  242. //
  243. // Description:
  244. // Change the effective size of the array.
  245. //
  246. // Arguments:
  247. // cNewSizeIn
  248. // The array's new size.
  249. //
  250. // crItemFillerIn
  251. // If the array is growing, copy this item into the spaces after the
  252. // array's current contents.
  253. //
  254. // Return Values:
  255. // S_OK
  256. // Subsequent calls to Count will return cNewSizeIn, and indexing
  257. // into the array with any value from zero up to cNewSizeIn - 1
  258. // will return a valid object reference.
  259. //
  260. // Failure
  261. // Something went wrong and the size is unchanged.
  262. //
  263. // Remarks:
  264. //
  265. // Analogous to std::vector::resize.
  266. //
  267. // If cNewSizeIn is not greater than the array's capacity, the array
  268. // performs no memory reallocations. To force the array to consume only
  269. // the memory necessary to contain the new size, call HrCompact.
  270. //
  271. //--
  272. //////////////////////////////////////////////////////////////////////////////
  273. template < class Item, class Assignment >
  274. HRESULT DynamicArray< Item, Assignment >::HrResize( size_t cNewSizeIn, const Item& crItemFillerIn )
  275. {
  276. HRESULT hr = S_OK;
  277. size_t idx = 0;
  278. // Raise capacity if necessary.
  279. if ( cNewSizeIn > m_cCapacity )
  280. {
  281. hr = HrRaiseCapacity( cNewSizeIn - m_cCapacity );
  282. if ( FAILED( hr ) )
  283. {
  284. goto Cleanup;
  285. }
  286. }
  287. // Fill any empty spaces with crItemFillerIn.
  288. for ( idx = m_cItems; idx < cNewSizeIn; ++idx )
  289. {
  290. hr = m_opAssign( m_prgItems[ idx ], crItemFillerIn );
  291. if ( FAILED( hr ) )
  292. {
  293. goto Cleanup;
  294. }
  295. }
  296. m_cItems = cNewSizeIn;
  297. Cleanup:
  298. return hr;
  299. } //*** DynamicArray< Item, Assignment >::HrResize
  300. //////////////////////////////////////////////////////////////////////////////
  301. //++
  302. //
  303. // DynamicArray< Item, Assignment >::HrReserve
  304. //
  305. // Description:
  306. // Set a lower bound for the array's capacity.
  307. //
  308. // Arguments:
  309. // cNewCapacityIn
  310. // The desired lower bound for the array's capacity.
  311. //
  312. // Return Values:
  313. // S_OK
  314. // Subsequent operations that change the array's size--HrResize,
  315. // HrPushBack, HrPopBack, HrRemove--will not cause a memory
  316. // reallocation as long as the size does not exceed cNewCapacityIn.
  317. // Also, subsequent calls to CCapacity will return a value not less
  318. // than cNewCapacityIn.
  319. //
  320. // (Calling Clear does reset the capacity to zero, however.)
  321. //
  322. // Failure
  323. // Something went wrong, and the capacity is unchanged.
  324. //
  325. // Remarks:
  326. //
  327. // Analogous to std::vector::reserve.
  328. //
  329. // If cNewCapacityIn is not greater than the array's capacity, the array's
  330. // capacity does not change. To force the array to consume only
  331. // the memory necessary to contain the current size, call HrCompact.
  332. //
  333. //--
  334. //////////////////////////////////////////////////////////////////////////////
  335. template < class Item, class Assignment >
  336. inline HRESULT DynamicArray< Item, Assignment >::HrReserve( size_t cNewCapacityIn )
  337. {
  338. HRESULT hr = S_OK;
  339. if ( cNewCapacityIn > m_cCapacity )
  340. {
  341. hr = HrRaiseCapacity( cNewCapacityIn - m_cCapacity );
  342. if ( FAILED( hr ) )
  343. {
  344. goto Cleanup;
  345. }
  346. }
  347. Cleanup:
  348. return hr;
  349. } //*** DynamicArray< Item, Assignment >::HrReserve
  350. //////////////////////////////////////////////////////////////////////////////
  351. //++
  352. //
  353. // DynamicArray< Item, Assignment >::HrRemove
  354. //
  355. // Description:
  356. // Eliminate a particular element from the array.
  357. //
  358. // Arguments:
  359. // ItemToRemoveIn
  360. // A pointer to the element to remove.
  361. //
  362. // Return Values:
  363. // S_OK
  364. // The array's size has decreased by one, and the given element is
  365. // gone.
  366. //
  367. // E_INVALIDARG
  368. // The given pointer was not within the array's valid range.
  369. //
  370. // Other failures
  371. // Something went wrong; those items preceding that given are
  372. // unchanged, but others may have been overwritten by their successors.
  373. //
  374. // Remarks:
  375. //
  376. // Analogous to std::vector::erase.
  377. //
  378. // This moves all successors to the element up by one, taking linear time.
  379. //
  380. //--
  381. //////////////////////////////////////////////////////////////////////////////
  382. template < class Item, class Assignment >
  383. HRESULT DynamicArray< Item, Assignment >::HrRemove( Iterator ItemToRemoveIn )
  384. {
  385. HRESULT hr = S_OK;
  386. Iterator it;
  387. if ( ( ItemToRemoveIn < m_prgItems ) || ( ItemToRemoveIn >= ItEnd() ) )
  388. {
  389. hr = E_INVALIDARG;
  390. goto Cleanup;
  391. }
  392. // Move all items after ItemToRemoveIn forward by one, overwriting *ItemToRemoveIn.
  393. for ( it = ItemToRemoveIn + 1; it != ItEnd(); ++it )
  394. {
  395. hr = m_opAssign( *( it - 1 ), *it );
  396. if ( FAILED( hr ) )
  397. {
  398. goto Cleanup;
  399. }
  400. }
  401. m_cItems -= 1;
  402. Cleanup:
  403. return hr;
  404. } //*** DynamicArray< Item, Assignment >::HrRemove
  405. //////////////////////////////////////////////////////////////////////////////
  406. //++
  407. //
  408. // DynamicArray< Item, Assignment >::HrCompact
  409. //
  410. // Description:
  411. // Force the array to consume just enough memory to hold its current
  412. // contents, performing a reallocation if necessary.
  413. //
  414. // Arguments:
  415. // None.
  416. //
  417. // Return Values:
  418. // S_OK - The array's size is now the same as its capacity.
  419. //
  420. // Failure - Something went wrong; the array is unchanged.
  421. //
  422. // Remarks:
  423. //
  424. // No analogue in std::vector.
  425. //
  426. //--
  427. //////////////////////////////////////////////////////////////////////////////
  428. template < class Item, class Assignment >
  429. HRESULT DynamicArray< Item, Assignment >::HrCompact( void )
  430. {
  431. HRESULT hr = S_OK;
  432. Item* prgNewArray = NULL;
  433. if ( m_cItems < m_cCapacity ) // Otherwise, it's already compact.
  434. {
  435. if ( m_cItems > 0 )
  436. {
  437. size_t idx = 0;
  438. // Allocate just enough memory to hold the current contents.
  439. prgNewArray = new Item[ m_cItems ];
  440. if ( prgNewArray == NULL )
  441. {
  442. hr = E_OUTOFMEMORY;
  443. goto Cleanup;
  444. }
  445. // Copy the current contents into the newly allocated memory.
  446. for ( idx = 0; idx < m_cItems; ++idx )
  447. {
  448. hr = m_opAssign( prgNewArray[ idx ], m_prgItems[ idx ] );
  449. if ( FAILED( hr ) )
  450. {
  451. goto Cleanup;
  452. }
  453. }
  454. // Take ownership of the new memory and discard the old.
  455. delete[] m_prgItems;
  456. m_prgItems = prgNewArray;
  457. prgNewArray = NULL;
  458. m_cCapacity = m_cItems;
  459. }
  460. else // No current contents, so just dump everything.
  461. {
  462. Clear();
  463. }
  464. }
  465. Cleanup:
  466. if ( prgNewArray != NULL )
  467. {
  468. delete[] prgNewArray;
  469. }
  470. return hr;
  471. } //*** DynamicArray< Item, Assignment >::HrCompact
  472. //////////////////////////////////////////////////////////////////////////////
  473. //++
  474. //
  475. // DynamicArray< Item, Assignment >::Clear
  476. //
  477. // Description:
  478. // Reset the array to its original, empty state, and release any
  479. // currently allocated memory.
  480. //
  481. // Arguments:
  482. // None.
  483. //
  484. // Return Values:
  485. // None.
  486. //
  487. // Remarks:
  488. //
  489. // Analogous to std::vector::clear.
  490. //
  491. //--
  492. //////////////////////////////////////////////////////////////////////////////
  493. template < class Item, class Assignment >
  494. void DynamicArray< Item, Assignment >::Clear( void )
  495. {
  496. if ( m_prgItems != NULL )
  497. {
  498. delete[] m_prgItems;
  499. m_prgItems = NULL;
  500. m_cItems = 0;
  501. m_cCapacity = 0;
  502. }
  503. } //*** DynamicArray< Item, Assignment >::Clear
  504. //////////////////////////////////////////////////////////////////////////////
  505. //++
  506. //
  507. // DynamicArray< Item, Assignment >::Swap
  508. //
  509. // Description:
  510. // Swaps the contents of this array with another.
  511. //
  512. // Arguments:
  513. // rOtherInOut - The array with which to swap.
  514. //
  515. // Return Values:
  516. // None.
  517. //
  518. // Remarks:
  519. //
  520. // Analogous to std::vector::swap.
  521. //
  522. //--
  523. //////////////////////////////////////////////////////////////////////////////
  524. template < class Item, class Assignment >
  525. void DynamicArray< Item, Assignment >::Swap( DynamicArray& rOtherInOut )
  526. {
  527. if ( this != &rOtherInOut )
  528. {
  529. Item* prgItemStash = m_prgItems;
  530. size_t cCountStash = m_cItems;
  531. size_t cCapacityStash = m_cCapacity;
  532. m_prgItems = rOtherInOut.m_prgItems;
  533. rOtherInOut.m_prgItems = prgItemStash;
  534. m_cItems = rOtherInOut.m_cItems;
  535. rOtherInOut.m_cItems = cCountStash;
  536. m_cCapacity = rOtherInOut.m_cCapacity;
  537. rOtherInOut.m_cCapacity = cCapacityStash;
  538. }
  539. } //*** DynamicArray< Item, Assignment >::Swap
  540. //////////////////////////////////////////////////////////////////////////////
  541. //++
  542. //
  543. // DynamicArray< Item, Assignment >::CCapacity
  544. //
  545. // Description:
  546. // Provide the array's current capacity.
  547. //
  548. // Arguments:
  549. // None.
  550. //
  551. // Return Values:
  552. // The array's current capacity.
  553. //
  554. // Remarks:
  555. //
  556. // Analogous to std::vector::capacity.
  557. //
  558. //--
  559. //////////////////////////////////////////////////////////////////////////////
  560. template < class Item, class Assignment >
  561. inline size_t DynamicArray< Item, Assignment >::CCapacity( void ) const
  562. {
  563. return m_cCapacity;
  564. }
  565. //////////////////////////////////////////////////////////////////////////////
  566. //++
  567. //
  568. // DynamicArray< Item, Assignment >::Count
  569. //
  570. // Description:
  571. // Provide the array's current size.
  572. //
  573. // Arguments:
  574. // None.
  575. //
  576. // Return Values:
  577. // The array's current size.
  578. //
  579. // Remarks:
  580. //
  581. // Analogous to std::vector::size.
  582. //
  583. //--
  584. //////////////////////////////////////////////////////////////////////////////
  585. template < class Item, class Assignment >
  586. inline size_t DynamicArray< Item, Assignment >::Count( void ) const
  587. {
  588. return m_cItems;
  589. }
  590. //////////////////////////////////////////////////////////////////////////////
  591. //++
  592. //
  593. // DynamicArray< Item, Assignment >::BEmpty
  594. //
  595. // Description:
  596. // Report whether the array contains anything.
  597. //
  598. // Arguments:
  599. // None.
  600. //
  601. // Return Values:
  602. // true - The array contains nothing.
  603. // false - The array contains something.
  604. //
  605. // Remarks:
  606. //
  607. // Analogous to std::vector::empty. Synonymous with Count() == 0.
  608. //
  609. //--
  610. //////////////////////////////////////////////////////////////////////////////
  611. template < class Item, class Assignment >
  612. inline bool DynamicArray< Item, Assignment >::BEmpty( void ) const
  613. {
  614. return ( m_cItems == 0 );
  615. }
  616. //////////////////////////////////////////////////////////////////////////////
  617. //++
  618. //
  619. // DynamicArray< Item, Assignment >::ItBegin
  620. //
  621. // Description:
  622. // Provide a pointer to the array's first element.
  623. //
  624. // Arguments:
  625. // None.
  626. //
  627. // Return Values:
  628. // A pointer to the array's first element if one exists, ItEnd() if not.
  629. //
  630. // Remarks:
  631. //
  632. // Analogous to std::vector::begin.
  633. //
  634. // The const overload provides a read-only pointer.
  635. //
  636. //--
  637. //////////////////////////////////////////////////////////////////////////////
  638. template < class Item, class Assignment >
  639. inline __TYPENAME DynamicArray< Item, Assignment >::Iterator DynamicArray< Item, Assignment >::ItBegin( void )
  640. {
  641. return m_prgItems;
  642. }
  643. template < class Item, class Assignment >
  644. inline __TYPENAME DynamicArray< Item, Assignment >::ConstIterator DynamicArray< Item, Assignment >::ItBegin( void ) const
  645. {
  646. return m_prgItems;
  647. }
  648. //////////////////////////////////////////////////////////////////////////////
  649. //++
  650. //
  651. // DynamicArray< Item, Assignment >::ItEnd
  652. //
  653. // Description:
  654. // Provide a "one past end" pointer to the array's contents.
  655. //
  656. // Arguments:
  657. // None.
  658. //
  659. // Return Values:
  660. // A "one past end" pointer to the array's contents if any exist,
  661. // ItBegin() if not.
  662. //
  663. // Remarks:
  664. //
  665. // Analogous to std::vector::end.
  666. //
  667. // A "one past end" pointer allows enumeration of all the array's
  668. // contents by the common loop,
  669. // for (it = a.ItBegin(); it != a.ItEnd(); ++it).
  670. //
  671. //--
  672. //////////////////////////////////////////////////////////////////////////////
  673. template < class Item, class Assignment >
  674. inline __TYPENAME DynamicArray< Item, Assignment >::Iterator DynamicArray< Item, Assignment >::ItEnd( void )
  675. {
  676. return ( m_prgItems + m_cItems );
  677. }
  678. template < class Item, class Assignment >
  679. inline __TYPENAME DynamicArray< Item, Assignment >::ConstIterator DynamicArray< Item, Assignment >::ItEnd( void ) const
  680. {
  681. return ( m_prgItems + m_cItems );
  682. }
  683. //////////////////////////////////////////////////////////////////////////////
  684. //++
  685. //
  686. // DynamicArray< Item, Assignment >::operator[]
  687. //
  688. // Description:
  689. // Provide subscripted, constant-time access to the array's contents.
  690. //
  691. // Arguments:
  692. // idxItemIn - The zero-based index of the item desired.
  693. //
  694. // Return Values:
  695. // A reference to the item at the given position.
  696. //
  697. // Remarks:
  698. //
  699. // Analogous to std::vector::operator[].
  700. // The const overload provides read-only access.
  701. // This makes no attempt at range-checking; the caller should use
  702. // Count() to determine whether the index is valid.
  703. //
  704. //--
  705. //////////////////////////////////////////////////////////////////////////////
  706. template < class Item, class Assignment >
  707. inline Item& DynamicArray< Item, Assignment >::operator[]( size_t idxItemIn )
  708. {
  709. return m_prgItems[ idxItemIn ];
  710. }
  711. template < class Item, class Assignment >
  712. inline const Item& DynamicArray< Item, Assignment >::operator[]( size_t idxItemIn ) const
  713. {
  714. return m_prgItems[ idxItemIn ];
  715. }
  716. //////////////////////////////////////////////////////////////////////////////
  717. //++
  718. //
  719. // DynamicArray< Item, Assignment >::HrRaiseCapacity
  720. //
  721. // Description:
  722. // Increase the array's capacity.
  723. //
  724. // Arguments:
  725. // cAmountIn - The amount by which to increase the array's capacity.
  726. //
  727. // Return Values:
  728. // S_OK
  729. // The array has enough memory to hold an additional cAmountIn items.
  730. //
  731. // Failure
  732. // Something went wrong, and the capacity is unchanged.
  733. //
  734. // Remarks:
  735. //
  736. // No analogue in std::vector; this is a private function.
  737. //
  738. //--
  739. //////////////////////////////////////////////////////////////////////////////
  740. template < class Item, class Assignment >
  741. HRESULT DynamicArray< Item, Assignment >::HrRaiseCapacity( size_t cAmountIn )
  742. {
  743. HRESULT hr = S_OK;
  744. size_t idx = 0;
  745. Item* prgNewArray = NULL;
  746. if ( cAmountIn == 0 ) // Nothing to do.
  747. {
  748. goto Cleanup;
  749. }
  750. // Allocate enough space for the new capacity
  751. prgNewArray = new Item[ m_cCapacity + cAmountIn ];
  752. if ( prgNewArray == NULL )
  753. {
  754. hr = E_OUTOFMEMORY;
  755. goto Cleanup;
  756. }
  757. // Copy the current contents into the new space.
  758. for ( idx = 0; idx < m_cItems; ++idx )
  759. {
  760. hr = m_opAssign( prgNewArray[ idx ], m_prgItems[ idx ] );
  761. if ( FAILED( hr ) )
  762. {
  763. goto Cleanup;
  764. }
  765. }
  766. // Take ownership of the new space.
  767. if ( m_prgItems != NULL )
  768. {
  769. delete[] m_prgItems;
  770. }
  771. m_prgItems = prgNewArray;
  772. prgNewArray = NULL;
  773. m_cCapacity += cAmountIn;
  774. Cleanup:
  775. if ( prgNewArray != NULL )
  776. {
  777. delete[] prgNewArray;
  778. }
  779. return hr;
  780. } //*** DynamicArray< Item, Assignment >::HrRaiseCapacity
  781. } //*** Generics namespace