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.

4089 lines
90 KiB

  1. // This is a part of the Active Template Library.
  2. // Copyright (C) 1996-2001 Microsoft Corporation
  3. // All rights reserved.
  4. //
  5. // This source code is only intended as a supplement to the
  6. // Active Template Library Reference and related
  7. // electronic documentation provided with the library.
  8. // See these sources for detailed information regarding the
  9. // Active Template Library product.
  10. #ifndef __ATLCOLL_H__
  11. #define __ATLCOLL_H__
  12. #pragma once
  13. #pragma warning(push)
  14. #pragma warning(disable: 4702) // Unreachable code. This file will have lots of it, especially without EH enabled.
  15. #pragma warning(disable: 4512) // assignment operator could not be generated
  16. #pragma warning(disable: 4290) // C++ Exception Specification ignored
  17. // abstract iteration position
  18. #ifndef _AFX
  19. struct __POSITION
  20. {
  21. };
  22. #endif
  23. typedef __POSITION* POSITION;
  24. #include <atlbase.h>
  25. //REVIEW: Just to fix VSEE
  26. #pragma push_macro("min")
  27. #pragma push_macro("max")
  28. #undef min
  29. #undef max
  30. #define min(a,b) (((a) < (b)) ? (a) : (b))
  31. #define max(a,b) (((a) > (b)) ? (a) : (b))
  32. #include <new.h>
  33. #ifndef _AFX_PACKING
  34. #define _AFX_PACKING 4
  35. #endif
  36. namespace ATL {
  37. struct CAtlPlex // warning variable length structure
  38. {
  39. CAtlPlex* pNext;
  40. #if (_AFX_PACKING >= 8)
  41. DWORD dwReserved[1]; // align on 8 byte boundary
  42. #endif
  43. // BYTE data[maxNum*elementSize];
  44. void* data() { return this+1; }
  45. static CAtlPlex* Create(CAtlPlex*& head, size_t nMax, size_t cbElement);
  46. // like 'calloc' but no zero fill
  47. // may throw memory exceptions
  48. void FreeDataChain(); // free this one and links
  49. };
  50. inline CAtlPlex* CAtlPlex::Create( CAtlPlex*& pHead, size_t nMax, size_t nElementSize )
  51. {
  52. CAtlPlex* pPlex;
  53. ATLASSERT( nMax > 0 );
  54. ATLASSERT( nElementSize > 0 );
  55. pPlex = static_cast< CAtlPlex* >( malloc( sizeof( CAtlPlex )+(nMax*nElementSize) ) );
  56. if( pPlex == NULL )
  57. {
  58. return( NULL );
  59. }
  60. pPlex->pNext = pHead;
  61. pHead = pPlex;
  62. return( pPlex );
  63. }
  64. inline void CAtlPlex::FreeDataChain()
  65. {
  66. CAtlPlex* pPlex;
  67. pPlex = this;
  68. while( pPlex != NULL )
  69. {
  70. CAtlPlex* pNext;
  71. pNext = pPlex->pNext;
  72. free( pPlex );
  73. pPlex = pNext;
  74. }
  75. }
  76. template< typename T >
  77. class CElementTraitsBase
  78. {
  79. public:
  80. typedef const T& INARGTYPE;
  81. typedef T& OUTARGTYPE;
  82. static void CopyElements( T* pDest, const T* pSrc, size_t nElements )
  83. {
  84. for( size_t iElement = 0; iElement < nElements; iElement++ )
  85. {
  86. pDest[iElement] = pSrc[iElement];
  87. }
  88. }
  89. static void RelocateElements( T* pDest, T* pSrc, size_t nElements )
  90. {
  91. // A simple memmove works for nearly all types.
  92. // You'll have to override this for types that have pointers to their
  93. // own members.
  94. memmove( pDest, pSrc, nElements*sizeof( T ) );
  95. }
  96. };
  97. template< typename T >
  98. class CDefaultHashTraits
  99. {
  100. public:
  101. static ULONG Hash( const T& element ) throw()
  102. {
  103. return( ULONG( ULONG_PTR( element ) ) );
  104. }
  105. };
  106. template< typename T >
  107. class CDefaultCompareTraits
  108. {
  109. public:
  110. static bool CompareElements( const T& element1, const T& element2 )
  111. {
  112. return( (element1 == element2) != 0 ); // != 0 to handle overloads of operator== that return BOOL instead of bool
  113. }
  114. static int CompareElementsOrdered( const T& element1, const T& element2 )
  115. {
  116. if( element1 < element2 )
  117. {
  118. return( -1 );
  119. }
  120. else if( element1 == element2 )
  121. {
  122. return( 0 );
  123. }
  124. else
  125. {
  126. ATLASSERT( element1 > element2 );
  127. return( 1 );
  128. }
  129. }
  130. };
  131. template< typename T >
  132. class CDefaultElementTraits :
  133. public CElementTraitsBase< T >,
  134. public CDefaultHashTraits< T >,
  135. public CDefaultCompareTraits< T >
  136. {
  137. };
  138. template< typename T >
  139. class CElementTraits :
  140. public CDefaultElementTraits< T >
  141. {
  142. };
  143. template<>
  144. class CElementTraits< GUID > :
  145. public CElementTraitsBase< T >
  146. {
  147. public:
  148. static ULONG Hash( INARGTYPE guid )
  149. {
  150. const DWORD* pdwData = reinterpret_cast< const DWORD* >( &guid );
  151. return( pdwData[0]^pdwData[1]^pdwData[2]^pdwData[3] );
  152. }
  153. static bool CompareElements( INARGTYPE element1, INARGTYPE element2 )
  154. {
  155. return( (element1 == element2) != 0 ); // != 0 to handle overloads of operator== that return BOOL instead of bool
  156. }
  157. static int CompareElementsOrdered( INARGTYPE element1, INARGTYPE element2 )
  158. {
  159. const DWORD* pdwData1 = reinterpret_cast< const DWORD* >( &element1 );
  160. const DWORD* pdwData2 = reinterpret_cast< const DWORD* >( &element2 );
  161. for( int iDWORD = 3; iDWORD >= 0; iDWORD-- )
  162. {
  163. if( pdwData1[iDWORD] > pdwData2[iDWORD] )
  164. {
  165. return( 1 );
  166. }
  167. else if( pdwData1[iDWORD] < pdwData2[iDWORD] )
  168. {
  169. return( -1 );
  170. }
  171. }
  172. return( 0 );
  173. }
  174. };
  175. template<>
  176. class CElementTraits< CComVariant > :
  177. public CElementTraitsBase< CComVariant >
  178. {
  179. public:
  180. typedef const VARIANT& INARGTYPE;
  181. // static ULONG Hash( INARGTYPE t ); // variant hashing is problematic
  182. static bool CompareElements( INARGTYPE element1, INARGTYPE element2 )
  183. {
  184. return VarCmp(const_cast<VARIANT*>(&element1), const_cast<VARIANT*>(&element2), LOCALE_USER_DEFAULT, 0)==VARCMP_EQ;
  185. }
  186. static int CompareElementsOrdered( INARGTYPE element1, INARGTYPE element2 )
  187. {
  188. HRESULT hr = VarCmp(const_cast<VARIANT*>(&element1), const_cast<VARIANT*>(&element2), LOCALE_USER_DEFAULT, 0);
  189. if( hr == VARCMP_LT )
  190. {
  191. return( -1 );
  192. }
  193. else if( hr == VARCMP_GT )
  194. {
  195. return( 1 );
  196. }
  197. else
  198. {
  199. ATLASSERT( hr == VARCMP_EQ || hr == VARCMP_NULL );
  200. return( 0 );
  201. }
  202. }
  203. };
  204. template<>
  205. class CElementTraits< CComBSTR > :
  206. public CElementTraitsBase< CComBSTR >
  207. {
  208. public:
  209. static ULONG Hash( INARGTYPE bstr ) throw()
  210. {
  211. ULONG nHash = 0;
  212. const OLECHAR* pch = bstr;
  213. ULONG nLength = bstr.Length();
  214. for( ULONG iChar = 0; iChar < nLength; iChar++ )
  215. {
  216. nHash = (nHash<<5)+nHash+pch[iChar];
  217. }
  218. return( nHash );
  219. }
  220. static bool CompareElements( INARGTYPE bstr1, INARGTYPE bstr2 ) throw()
  221. {
  222. return( bstr1 == bstr2 );
  223. }
  224. static int CompareElementsOrdered( INARGTYPE bstr1, INARGTYPE bstr2 ) throw()
  225. {
  226. if( bstr1 == NULL )
  227. {
  228. return( (bstr2 == NULL) ? 0 : -1 );
  229. }
  230. else if( bstr2 == NULL )
  231. {
  232. return( 1 );
  233. }
  234. HRESULT hr = VarBstrCmp( bstr1, bstr2, LOCALE_SYSTEM_DEFAULT, 0 );
  235. switch( hr )
  236. {
  237. case VARCMP_LT:
  238. return( -1 );
  239. break;
  240. case VARCMP_GT:
  241. return( 1 );
  242. break;
  243. case VARCMP_EQ:
  244. return( 0 );
  245. break;
  246. default:
  247. ATLASSERT( false );
  248. return( 0 );
  249. break;
  250. }
  251. }
  252. };
  253. template< typename I, const IID* piid = &__uuidof( I ) >
  254. class CComQIPtrElementTraits :
  255. public CDefaultElementTraits< ATL::CComQIPtr< I, piid > >
  256. {
  257. public:
  258. typedef I* INARGTYPE;
  259. };
  260. template< typename T >
  261. class CAutoPtrElementTraits :
  262. public CDefaultElementTraits< ATL::CAutoPtr< T > >
  263. {
  264. public:
  265. typedef ATL::CAutoPtr< T >& INARGTYPE;
  266. typedef T*& OUTARGTYPE;
  267. };
  268. template< typename T >
  269. class CAutoVectorPtrElementTraits :
  270. public CDefaultElementTraits< ATL::CAutoVectorPtr< T > >
  271. {
  272. public:
  273. typedef ATL::CAutoVectorPtr< T >& INARGTYPE;
  274. typedef T*& OUTARGTYPE;
  275. };
  276. template< typename T, class Allocator = ATL::CCRTAllocator >
  277. class CHeapPtrElementTraits :
  278. public CDefaultElementTraits< ATL::CHeapPtr< T, Allocator > >
  279. {
  280. public:
  281. typedef ATL::CHeapPtr< T, Allocator >& INARGTYPE;
  282. typedef T*& OUTARGTYPE;
  283. };
  284. template< typename T >
  285. class CStringElementTraits :
  286. public CElementTraitsBase< T >
  287. {
  288. public:
  289. typedef T::PCXSTR INARGTYPE;
  290. typedef T& OUTARGTYPE;
  291. static ULONG Hash( INARGTYPE str )
  292. {
  293. ATLASSERT( str != NULL );
  294. ULONG nHash = 0;
  295. const T::XCHAR* pch = str;
  296. while( *pch != 0 )
  297. {
  298. nHash = (nHash<<5)+nHash+(*pch);
  299. pch++;
  300. }
  301. return( nHash );
  302. }
  303. static bool CompareElements( INARGTYPE str1, INARGTYPE str2 )
  304. {
  305. return( T::StrTraits::StringCompare( str1, str2 ) == 0 );
  306. }
  307. static int CompareElementsOrdered( INARGTYPE str1, INARGTYPE str2 )
  308. {
  309. return( T::StrTraits::StringCompare( str1, str2 ) );
  310. }
  311. };
  312. template < typename T >
  313. class CDefaultCharTraits
  314. {
  315. };
  316. template <>
  317. class CDefaultCharTraits<char>
  318. {
  319. public:
  320. static char CharToUpper(char x)
  321. {
  322. return (char)toupper(x);
  323. }
  324. static char CharToLower(char x)
  325. {
  326. return (char)tolower(x);
  327. }
  328. };
  329. template <>
  330. class CDefaultCharTraits<wchar_t>
  331. {
  332. public:
  333. static wchar_t CharToUpper(wchar_t x)
  334. {
  335. return (wchar_t)towupper(x);
  336. }
  337. static wchar_t CharToLower(wchar_t x)
  338. {
  339. return (wchar_t)towlower(x);
  340. }
  341. };
  342. template< typename T, class CharTraits = CDefaultCharTraits<T::XCHAR> >
  343. class CStringElementTraitsI :
  344. public CElementTraitsBase< T >
  345. {
  346. public:
  347. typedef T::PCXSTR INARGTYPE;
  348. typedef T& OUTARGTYPE;
  349. static ULONG Hash( INARGTYPE str )
  350. {
  351. const T::XCHAR* pch;
  352. ULONG nHash;
  353. ATLASSERT( str != NULL );
  354. nHash = 0;
  355. pch = str;
  356. while( *pch != 0 )
  357. {
  358. nHash = (nHash<<5)+nHash+CharTraits::CharToUpper(*pch);
  359. pch++;
  360. }
  361. return( nHash );
  362. }
  363. static bool CompareElements( INARGTYPE str1, INARGTYPE str2 )
  364. {
  365. return( T::StrTraits::StringCompareIgnore( str1, str2 ) == 0 );
  366. }
  367. static int CompareElementsOrdered( INARGTYPE str1, INARGTYPE str2 )
  368. {
  369. return( T::StrTraits::StringCompareIgnore( str1, str2 ) );
  370. }
  371. };
  372. template< typename T >
  373. class CStringRefElementTraits :
  374. public CElementTraitsBase< T >
  375. {
  376. public:
  377. static ULONG Hash( INARGTYPE str ) throw()
  378. {
  379. ULONG nHash = 0;
  380. const T::XCHAR* pch = str;
  381. while( *pch != 0 )
  382. {
  383. nHash = (nHash<<5)+nHash+(*pch);
  384. pch++;
  385. }
  386. return( nHash );
  387. }
  388. static bool CompareElements( INARGTYPE element1, INARGTYPE element2 ) throw()
  389. {
  390. return( element1 == element2 );
  391. }
  392. static int CompareElementsOrdered( INARGTYPE str1, INARGTYPE str2 ) throw()
  393. {
  394. return( str1.Compare( str2 ) );
  395. }
  396. };
  397. template< typename T >
  398. class CPrimitiveElementTraits :
  399. public CDefaultElementTraits< T >
  400. {
  401. public:
  402. typedef T INARGTYPE;
  403. typedef T& OUTARGTYPE;
  404. };
  405. #define _DECLARE_PRIMITIVE_TRAITS( T ) \
  406. template<> \
  407. class CElementTraits< T > : \
  408. public CPrimitiveElementTraits< T > \
  409. { \
  410. };
  411. _DECLARE_PRIMITIVE_TRAITS( unsigned char )
  412. _DECLARE_PRIMITIVE_TRAITS( unsigned short )
  413. _DECLARE_PRIMITIVE_TRAITS( unsigned int )
  414. _DECLARE_PRIMITIVE_TRAITS( unsigned long )
  415. _DECLARE_PRIMITIVE_TRAITS( unsigned __int64 )
  416. _DECLARE_PRIMITIVE_TRAITS( signed char )
  417. _DECLARE_PRIMITIVE_TRAITS( char )
  418. _DECLARE_PRIMITIVE_TRAITS( short )
  419. _DECLARE_PRIMITIVE_TRAITS( int )
  420. _DECLARE_PRIMITIVE_TRAITS( long )
  421. _DECLARE_PRIMITIVE_TRAITS( __int64 )
  422. _DECLARE_PRIMITIVE_TRAITS( float )
  423. _DECLARE_PRIMITIVE_TRAITS( double )
  424. _DECLARE_PRIMITIVE_TRAITS( bool )
  425. #ifdef _NATIVE_WCHAR_T_DEFINED
  426. _DECLARE_PRIMITIVE_TRAITS( wchar_t )
  427. #endif
  428. _DECLARE_PRIMITIVE_TRAITS( void* )
  429. template< typename E, class ETraits = CElementTraits< E > >
  430. class CAtlArray
  431. {
  432. public:
  433. typedef ETraits::INARGTYPE INARGTYPE;
  434. typedef ETraits::OUTARGTYPE OUTARGTYPE;
  435. public:
  436. CAtlArray() throw();
  437. size_t GetCount() const throw();
  438. bool IsEmpty() const throw();
  439. bool SetCount( size_t nNewSize, int nGrowBy = -1 );
  440. void FreeExtra() throw();
  441. void RemoveAll() throw();
  442. const E& GetAt( size_t iElement ) const throw();
  443. void SetAt( size_t iElement, INARGTYPE element );
  444. E& GetAt( size_t iElement ) throw();
  445. const E* GetData() const throw();
  446. E* GetData() throw();
  447. void SetAtGrow( size_t iElement, INARGTYPE element );
  448. // Add an empty element to the end of the array
  449. size_t Add();
  450. // Add an element to the end of the array
  451. size_t Add( INARGTYPE element );
  452. size_t Append( const CAtlArray< E, ETraits >& aSrc );
  453. void Copy( const CAtlArray< E, ETraits >& aSrc );
  454. const E& operator[]( size_t iElement ) const throw();
  455. E& operator[]( size_t iElement ) throw();
  456. void InsertAt( size_t iElement, INARGTYPE element, size_t nCount = 1 );
  457. void InsertArrayAt( size_t iStart, const CAtlArray< E, ETraits >* paNew );
  458. void RemoveAt( size_t iElement, size_t nCount = 1 );
  459. #ifdef _DEBUG
  460. void AssertValid() const;
  461. #endif // _DEBUG
  462. private:
  463. bool GrowBuffer( size_t nNewSize );
  464. // Implementation
  465. private:
  466. E* m_pData;
  467. size_t m_nSize;
  468. size_t m_nMaxSize;
  469. int m_nGrowBy;
  470. private:
  471. static void CallConstructors( E* pElements, size_t nElements );
  472. static void CallDestructors( E* pElements, size_t nElements );
  473. public:
  474. ~CAtlArray() throw();
  475. private:
  476. // Private to prevent use
  477. CAtlArray( const CAtlArray& ) throw();
  478. CAtlArray& operator=( const CAtlArray& ) throw();
  479. };
  480. template< class I, const IID* piid = &__uuidof( I ) >
  481. class CInterfaceArray :
  482. public CAtlArray< ATL::CComQIPtr< I, piid >, CComQIPtrElementTraits< I, piid > >
  483. {
  484. public:
  485. CInterfaceArray() throw()
  486. {
  487. }
  488. private:
  489. // Private to prevent use
  490. CInterfaceArray( const CInterfaceArray& ) throw();
  491. CInterfaceArray& operator=( const CInterfaceArray& ) throw();
  492. };
  493. template< typename E >
  494. class CAutoPtrArray :
  495. public CAtlArray< ATL::CAutoPtr< E >, CAutoPtrElementTraits< E > >
  496. {
  497. public:
  498. CAutoPtrArray() throw()
  499. {
  500. }
  501. private:
  502. // Private to prevent use
  503. CAutoPtrArray( const CAutoPtrArray& ) throw();
  504. CAutoPtrArray& operator=( const CAutoPtrArray& ) throw();
  505. };
  506. template< typename E, class Allocator = ATL::CCRTAllocator >
  507. class CHeapPtrArray :
  508. public CAtlArray< ATL::CHeapPtr< E, Allocator >, CHeapPtrElementTraits< E, Allocator > >
  509. {
  510. public:
  511. CHeapPtrArray() throw()
  512. {
  513. }
  514. private:
  515. // Private to prevent use
  516. CHeapPtrArray( const CHeapPtrArray& ) throw();
  517. CHeapPtrArray& operator=( const CHeapPtrArray& ) throw();
  518. };
  519. template< typename E, class ETraits >
  520. inline size_t CAtlArray< E, ETraits >::GetCount() const
  521. {
  522. return( m_nSize );
  523. }
  524. template< typename E, class ETraits >
  525. inline bool CAtlArray< E, ETraits >::IsEmpty() const
  526. {
  527. return( m_nSize == 0 );
  528. }
  529. template< typename E, class ETraits >
  530. inline void CAtlArray< E, ETraits >::RemoveAll()
  531. {
  532. SetCount( 0, -1 );
  533. }
  534. template< typename E, class ETraits >
  535. inline const E& CAtlArray< E, ETraits >::GetAt( size_t iElement ) const
  536. {
  537. ATLASSERT( iElement < m_nSize );
  538. return( m_pData[iElement] );
  539. }
  540. template< typename E, class ETraits >
  541. inline void CAtlArray< E, ETraits >::SetAt( size_t iElement, INARGTYPE element )
  542. {
  543. ATLASSERT( iElement < m_nSize );
  544. m_pData[iElement] = element;
  545. }
  546. template< typename E, class ETraits >
  547. inline E& CAtlArray< E, ETraits >::GetAt( size_t iElement )
  548. {
  549. ATLASSERT( iElement < m_nSize );
  550. return( m_pData[iElement] );
  551. }
  552. template< typename E, class ETraits >
  553. inline const E* CAtlArray< E, ETraits >::GetData() const
  554. {
  555. return( m_pData );
  556. }
  557. template< typename E, class ETraits >
  558. inline E* CAtlArray< E, ETraits >::GetData()
  559. {
  560. return( m_pData );
  561. }
  562. template< typename E, class ETraits >
  563. inline size_t CAtlArray< E, ETraits >::Add()
  564. {
  565. size_t iElement;
  566. iElement = m_nSize;
  567. SetCount( m_nSize+1 );
  568. return( iElement );
  569. }
  570. #pragma push_macro("new")
  571. #undef new
  572. template< typename E, class ETraits >
  573. inline size_t CAtlArray< E, ETraits >::Add( INARGTYPE element )
  574. {
  575. size_t iElement;
  576. iElement = m_nSize;
  577. if( iElement >= m_nMaxSize )
  578. {
  579. bool bSuccess = GrowBuffer( iElement+1 );
  580. if( !bSuccess )
  581. {
  582. ATL::AtlThrow( E_OUTOFMEMORY );
  583. }
  584. }
  585. ::new( m_pData+iElement ) E( element );
  586. m_nSize++;
  587. return( iElement );
  588. }
  589. #pragma pop_macro("new")
  590. template< typename E, class ETraits >
  591. inline const E& CAtlArray< E, ETraits >::operator[]( size_t iElement ) const
  592. {
  593. ATLASSERT( iElement < m_nSize );
  594. return( m_pData[iElement] );
  595. }
  596. template< typename E, class ETraits >
  597. inline E& CAtlArray< E, ETraits >::operator[]( size_t iElement )
  598. {
  599. ATLASSERT( iElement < m_nSize );
  600. return( m_pData[iElement] );
  601. }
  602. template< typename E, class ETraits >
  603. CAtlArray< E, ETraits >::CAtlArray() :
  604. m_pData( NULL ),
  605. m_nSize( 0 ),
  606. m_nMaxSize( 0 ),
  607. m_nGrowBy( 0 )
  608. {
  609. }
  610. template< typename E, class ETraits >
  611. CAtlArray< E, ETraits >::~CAtlArray()
  612. {
  613. if( m_pData != NULL )
  614. {
  615. CallDestructors( m_pData, m_nSize );
  616. free( m_pData );
  617. }
  618. }
  619. template< typename E, class ETraits >
  620. bool CAtlArray< E, ETraits >::GrowBuffer( size_t nNewSize )
  621. {
  622. if( nNewSize > m_nMaxSize )
  623. {
  624. if( m_pData == NULL )
  625. {
  626. size_t nAllocSize = max( size_t( m_nGrowBy ), nNewSize );
  627. m_pData = static_cast< E* >( malloc( nAllocSize*sizeof( E ) ) );
  628. if( m_pData == NULL )
  629. {
  630. return( false );
  631. }
  632. m_nMaxSize = nAllocSize;
  633. }
  634. else
  635. {
  636. // otherwise, grow array
  637. size_t nGrowBy = m_nGrowBy;
  638. if( nGrowBy == 0 )
  639. {
  640. // heuristically determine growth when nGrowBy == 0
  641. // (this avoids heap fragmentation in many situations)
  642. nGrowBy = m_nSize/8;
  643. nGrowBy = (nGrowBy < 4) ? 4 : ((nGrowBy > 1024) ? 1024 : nGrowBy);
  644. }
  645. size_t nNewMax;
  646. if( nNewSize < (m_nMaxSize+nGrowBy) )
  647. nNewMax = m_nMaxSize+nGrowBy; // granularity
  648. else
  649. nNewMax = nNewSize; // no slush
  650. ATLASSERT( nNewMax >= m_nMaxSize ); // no wrap around
  651. #ifdef SIZE_T_MAX
  652. ATLASSERT( nNewMax <= SIZE_T_MAX/sizeof( E ) ); // no overflow
  653. #endif
  654. E* pNewData = static_cast< E* >( malloc( nNewMax*sizeof( E ) ) );
  655. if( pNewData == NULL )
  656. {
  657. return false;
  658. }
  659. // copy new data from old
  660. ETraits::RelocateElements( pNewData, m_pData, m_nSize );
  661. // get rid of old stuff (note: no destructors called)
  662. free( m_pData );
  663. m_pData = pNewData;
  664. m_nMaxSize = nNewMax;
  665. }
  666. }
  667. return true;
  668. }
  669. template< typename E, class ETraits >
  670. bool CAtlArray< E, ETraits >::SetCount( size_t nNewSize, int nGrowBy )
  671. {
  672. ATLASSERT_VALID(this);
  673. if( nGrowBy != -1 )
  674. {
  675. m_nGrowBy = nGrowBy; // set new size
  676. }
  677. if( nNewSize == 0 )
  678. {
  679. // shrink to nothing
  680. if( m_pData != NULL )
  681. {
  682. CallDestructors( m_pData, m_nSize );
  683. free( m_pData );
  684. m_pData = NULL;
  685. }
  686. m_nSize = 0;
  687. m_nMaxSize = 0;
  688. }
  689. else if( nNewSize <= m_nMaxSize )
  690. {
  691. // it fits
  692. if( nNewSize > m_nSize )
  693. {
  694. // initialize the new elements
  695. CallConstructors( m_pData+m_nSize, nNewSize-m_nSize );
  696. }
  697. else if( m_nSize > nNewSize )
  698. {
  699. // destroy the old elements
  700. CallDestructors( m_pData+nNewSize, m_nSize-nNewSize );
  701. }
  702. m_nSize = nNewSize;
  703. }
  704. else
  705. {
  706. bool bSuccess;
  707. bSuccess = GrowBuffer( nNewSize );
  708. if( !bSuccess )
  709. {
  710. return( false );
  711. }
  712. // construct new elements
  713. ATLASSERT( nNewSize > m_nSize );
  714. CallConstructors( m_pData+m_nSize, nNewSize-m_nSize );
  715. m_nSize = nNewSize;
  716. }
  717. return true;
  718. }
  719. template< typename E, class ETraits >
  720. size_t CAtlArray< E, ETraits >::Append( const CAtlArray< E, ETraits >& aSrc )
  721. {
  722. ATLASSERT_VALID(this);
  723. ATLASSERT( this != &aSrc ); // cannot append to itself
  724. size_t nOldSize = m_nSize;
  725. SetCount( m_nSize+aSrc.m_nSize );
  726. ETraits::CopyElements( m_pData+nOldSize, aSrc.m_pData, aSrc.m_nSize );
  727. return( nOldSize );
  728. }
  729. template< typename E, class ETraits >
  730. void CAtlArray< E, ETraits >::Copy( const CAtlArray< E, ETraits >& aSrc )
  731. {
  732. ATLASSERT_VALID(this);
  733. ATLASSERT( this != &aSrc ); // cannot append to itself
  734. SetCount( aSrc.m_nSize );
  735. ETraits::CopyElements( m_pData, aSrc.m_pData, aSrc.m_nSize );
  736. }
  737. template< typename E, class ETraits >
  738. void CAtlArray< E, ETraits >::FreeExtra()
  739. {
  740. ATLASSERT_VALID(this);
  741. if( m_nSize != m_nMaxSize )
  742. {
  743. // shrink to desired size
  744. #ifdef SIZE_T_MAX
  745. ATLASSERT( m_nSize <= (SIZE_T_MAX/sizeof( E )) ); // no overflow
  746. #endif
  747. E* pNewData = NULL;
  748. if( m_nSize != 0 )
  749. {
  750. pNewData = (E*)malloc( m_nSize*sizeof( E ) );
  751. if( pNewData == NULL )
  752. {
  753. return;
  754. }
  755. // copy new data from old
  756. ETraits::RelocateElements( pNewData, m_pData, m_nSize );
  757. }
  758. // get rid of old stuff (note: no destructors called)
  759. free( m_pData );
  760. m_pData = pNewData;
  761. m_nMaxSize = m_nSize;
  762. }
  763. }
  764. template< typename E, class ETraits >
  765. void CAtlArray< E, ETraits >::SetAtGrow( size_t iElement, INARGTYPE element )
  766. {
  767. ATLASSERT_VALID(this);
  768. size_t nOldSize;
  769. nOldSize = m_nSize;
  770. if( iElement >= m_nSize )
  771. SetCount( iElement+1, -1 );
  772. _ATLTRY
  773. {
  774. m_pData[iElement] = element;
  775. }
  776. _ATLCATCHALL()
  777. {
  778. if( m_nSize != nOldSize )
  779. {
  780. SetCount( nOldSize, -1 );
  781. }
  782. _ATLRETHROW;
  783. }
  784. }
  785. template< typename E, class ETraits >
  786. void CAtlArray< E, ETraits >::InsertAt( size_t iElement, INARGTYPE element, size_t nElements /*=1*/)
  787. {
  788. ATLASSERT_VALID(this);
  789. ATLASSERT( nElements > 0 ); // zero size not allowed
  790. if( iElement >= m_nSize )
  791. {
  792. // adding after the end of the array
  793. SetCount( iElement+nElements, -1 ); // grow so nIndex is valid
  794. }
  795. else
  796. {
  797. // inserting in the middle of the array
  798. size_t nOldSize = m_nSize;
  799. SetCount( m_nSize+nElements, -1 ); // grow it to new size
  800. // destroy intial data before copying over it
  801. CallDestructors( m_pData+nOldSize, nElements );
  802. // shift old data up to fill gap
  803. ETraits::RelocateElements( m_pData+(iElement+nElements), m_pData+iElement,
  804. nOldSize-iElement );
  805. _ATLTRY
  806. {
  807. // re-init slots we copied from
  808. CallConstructors( m_pData+iElement, nElements );
  809. }
  810. _ATLCATCHALL()
  811. {
  812. ETraits::RelocateElements( m_pData+iElement, m_pData+(iElement+nElements),
  813. nOldSize-iElement );
  814. SetCount( nOldSize, -1 );
  815. _ATLRETHROW;
  816. }
  817. }
  818. // insert new value in the gap
  819. ATLASSERT( (iElement+nElements) <= m_nSize );
  820. for( size_t iNewElement = iElement; iNewElement < (iElement+nElements); iNewElement++ )
  821. {
  822. m_pData[iNewElement] = element;
  823. }
  824. }
  825. template< typename E, class ETraits >
  826. void CAtlArray< E, ETraits >::RemoveAt( size_t iElement, size_t nElements )
  827. {
  828. ATLASSERT_VALID(this);
  829. ATLASSERT( (iElement+nElements) <= m_nSize );
  830. // just remove a range
  831. size_t nMoveCount = m_nSize-(iElement+nElements);
  832. CallDestructors( m_pData+iElement, nElements );
  833. if( nMoveCount > 0 )
  834. {
  835. ETraits::RelocateElements( m_pData+iElement, m_pData+(iElement+nElements),
  836. nMoveCount );
  837. }
  838. m_nSize -= nElements;
  839. }
  840. template< typename E, class ETraits >
  841. void CAtlArray< E, ETraits >::InsertArrayAt( size_t iStartElement,
  842. const CAtlArray< E, ETraits >* paNew )
  843. {
  844. ATLASSERT_VALID(this);
  845. ATLASSERT( paNew != NULL );
  846. ATLASSERT_VALID(paNew);
  847. if( paNew->GetCount() > 0 )
  848. {
  849. InsertAt( iStartElement, paNew->GetAt( 0 ), paNew->GetCount() );
  850. for( size_t iElement = 0; iElement < paNew->GetCount(); iElement++ )
  851. SetAt( iStartElement+iElement, paNew->GetAt( iElement ) );
  852. }
  853. }
  854. #ifdef _DEBUG
  855. template< typename E, class ETraits >
  856. void CAtlArray< E, ETraits >::AssertValid() const
  857. {
  858. if( m_pData == NULL )
  859. {
  860. ATLASSERT( m_nSize == 0 );
  861. ATLASSERT( m_nMaxSize == 0 );
  862. }
  863. else
  864. {
  865. ATLASSERT( m_nSize <= m_nMaxSize );
  866. ATLASSERT( AtlIsValidAddress( m_pData, m_nMaxSize * sizeof( E ) ) );
  867. }
  868. }
  869. #endif
  870. #pragma push_macro("new")
  871. #undef new
  872. template< typename E, class ETraits >
  873. void CAtlArray< E, ETraits >::CallConstructors( E* pElements, size_t nElements )
  874. {
  875. size_t iElement;
  876. _ATLTRY
  877. {
  878. for( iElement = 0; iElement < nElements; iElement++ )
  879. {
  880. ::new( pElements+iElement ) E;
  881. }
  882. }
  883. _ATLCATCHALL()
  884. {
  885. while( iElement > 0 )
  886. {
  887. iElement--;
  888. pElements[iElement].~E();
  889. }
  890. _ATLRETHROW;
  891. }
  892. }
  893. #pragma pop_macro("new")
  894. template< typename E, class ETraits >
  895. void CAtlArray< E, ETraits >::CallDestructors( E* pElements, size_t nElements )
  896. {
  897. (void)pElements; //REVIEW: Unreferenced formal warning if T doesn't have a real destructor
  898. for( size_t iElement = 0; iElement < nElements; iElement++ )
  899. {
  900. pElements[iElement].~E();
  901. }
  902. }
  903. template< typename E, class ETraits = CElementTraits< E > >
  904. class CAtlList
  905. {
  906. public:
  907. typedef ETraits::INARGTYPE INARGTYPE;
  908. private:
  909. class CNode :
  910. public __POSITION
  911. {
  912. public:
  913. CNode()
  914. {
  915. }
  916. CNode( INARGTYPE element ) :
  917. m_element( element )
  918. {
  919. }
  920. ~CNode() throw()
  921. {
  922. }
  923. public:
  924. CNode* m_pNext;
  925. CNode* m_pPrev;
  926. E m_element;
  927. private:
  928. CNode( const CNode& ) throw();
  929. };
  930. public:
  931. CAtlList( UINT nBlockSize = 10 ) throw();
  932. size_t GetCount() const throw();
  933. bool IsEmpty() const throw();
  934. E& GetHead() throw();
  935. const E& GetHead() const throw();
  936. E& GetTail() throw();
  937. const E& GetTail() const throw();
  938. E RemoveHead();
  939. E RemoveTail();
  940. void RemoveHeadNoReturn() throw();
  941. void RemoveTailNoReturn() throw();
  942. POSITION AddHead();
  943. POSITION AddHead( INARGTYPE element );
  944. void AddHeadList( const CAtlList< E, ETraits >* plNew );
  945. POSITION AddTail();
  946. POSITION AddTail( INARGTYPE element );
  947. void AddTailList( const CAtlList< E, ETraits >* plNew );
  948. void RemoveAll() throw();
  949. POSITION GetHeadPosition() const throw();
  950. POSITION GetTailPosition() const throw();
  951. E& GetNext( POSITION& pos ) throw();
  952. const E& GetNext( POSITION& pos ) const throw();
  953. E& GetPrev( POSITION& pos ) throw();
  954. const E& GetPrev( POSITION& pos ) const throw();
  955. E& GetAt( POSITION pos ) throw();
  956. const E& GetAt( POSITION pos ) const throw();
  957. void SetAt( POSITION pos, INARGTYPE element );
  958. void RemoveAt( POSITION pos ) throw();
  959. POSITION InsertBefore( POSITION pos, INARGTYPE element );
  960. POSITION InsertAfter( POSITION pos, INARGTYPE element );
  961. POSITION Find( INARGTYPE element, POSITION posStartAfter = NULL ) const throw();
  962. POSITION FindIndex( size_t iElement ) const throw();
  963. void MoveToHead( POSITION pos ) throw();
  964. void MoveToTail( POSITION pos ) throw();
  965. void SwapElements( POSITION pos1, POSITION pos2 ) throw();
  966. #ifdef _DEBUG
  967. void AssertValid() const;
  968. #endif // _DEBUG
  969. // Implementation
  970. private:
  971. CNode* m_pHead;
  972. CNode* m_pTail;
  973. size_t m_nElements;
  974. CAtlPlex* m_pBlocks;
  975. CNode* m_pFree;
  976. UINT m_nBlockSize;
  977. private:
  978. void GetFreeNode();
  979. CNode* NewNode( CNode* pPrev, CNode* pNext );
  980. CNode* NewNode( INARGTYPE element, CNode* pPrev, CNode* pNext );
  981. void FreeNode( CNode* pNode ) throw();
  982. public:
  983. ~CAtlList() throw();
  984. private:
  985. // Private to prevent use
  986. CAtlList( const CAtlList& ) throw();
  987. CAtlList& operator=( const CAtlList& ) throw();
  988. };
  989. template< class I, const IID* piid = &__uuidof( I ) >
  990. class CInterfaceList :
  991. public CAtlList< ATL::CComQIPtr< I, piid >, CComQIPtrElementTraits< I, piid > >
  992. {
  993. public:
  994. CInterfaceList( UINT nBlockSize = 10 ) throw() :
  995. CAtlList< ATL::CComQIPtr< I, piid >, CComQIPtrElementTraits< I, piid > >( nBlockSize )
  996. {
  997. }
  998. private:
  999. // Private to prevent use
  1000. CInterfaceList( const CInterfaceList& ) throw();
  1001. CInterfaceList& operator=( const CInterfaceList& ) throw();
  1002. };
  1003. template< typename E >
  1004. class CAutoPtrList :
  1005. public CAtlList< ATL::CAutoPtr< E >, CAutoPtrElementTraits< E > >
  1006. {
  1007. public:
  1008. CAutoPtrList( UINT nBlockSize = 10 ) throw() :
  1009. CAtlList< ATL::CAutoPtr< E >, CAutoPtrElementTraits< E > >( nBlockSize )
  1010. {
  1011. }
  1012. private:
  1013. // Private to prevent use
  1014. CAutoPtrList( const CAutoPtrList& ) throw();
  1015. CAutoPtrList& operator=( const CAutoPtrList& ) throw();
  1016. };
  1017. template< typename E, class Allocator = ATL::CCRTAllocator >
  1018. class CHeapPtrList :
  1019. public CAtlList< ATL::CHeapPtr< E, Allocator >, CHeapPtrElementTraits< E, Allocator > >
  1020. {
  1021. public:
  1022. CHeapPtrList( UINT nBlockSize = 10 ) throw() :
  1023. CAtlList< ATL::CHeapPtr< E, Allocator >, CHeapPtrElementTraits< E, Allocator > >( nBlockSize )
  1024. {
  1025. }
  1026. private:
  1027. // Private to prevent use
  1028. CHeapPtrList( const CHeapPtrList& ) throw();
  1029. CHeapPtrList& operator=( const CHeapPtrList& ) throw();
  1030. };
  1031. template< typename E, class ETraits >
  1032. inline size_t CAtlList< E, ETraits >::GetCount() const
  1033. {
  1034. return( m_nElements );
  1035. }
  1036. template< typename E, class ETraits >
  1037. inline bool CAtlList< E, ETraits >::IsEmpty() const
  1038. {
  1039. return( m_nElements == 0 );
  1040. }
  1041. template< typename E, class ETraits >
  1042. inline E& CAtlList< E, ETraits >::GetHead()
  1043. {
  1044. ATLASSERT( m_pHead != NULL );
  1045. return( m_pHead->m_element );
  1046. }
  1047. template< typename E, class ETraits >
  1048. inline const E& CAtlList< E, ETraits >::GetHead() const
  1049. {
  1050. ATLASSERT( m_pHead != NULL );
  1051. return( m_pHead->m_element );
  1052. }
  1053. template< typename E, class ETraits >
  1054. inline E& CAtlList< E, ETraits >::GetTail()
  1055. {
  1056. ATLASSERT( m_pTail != NULL );
  1057. return( m_pTail->m_element );
  1058. }
  1059. template< typename E, class ETraits >
  1060. inline const E& CAtlList< E, ETraits >::GetTail() const
  1061. {
  1062. ATLASSERT( m_pTail != NULL );
  1063. return( m_pTail->m_element );
  1064. }
  1065. template< typename E, class ETraits >
  1066. inline POSITION CAtlList< E, ETraits >::GetHeadPosition() const
  1067. {
  1068. return( POSITION( m_pHead ) );
  1069. }
  1070. template< typename E, class ETraits >
  1071. inline POSITION CAtlList< E, ETraits >::GetTailPosition() const
  1072. {
  1073. return( POSITION( m_pTail ) );
  1074. }
  1075. template< typename E, class ETraits >
  1076. inline E& CAtlList< E, ETraits >::GetNext( POSITION& pos )
  1077. {
  1078. CNode* pNode;
  1079. ATLASSERT( pos != NULL );
  1080. pNode = (CNode*)pos;
  1081. pos = POSITION( pNode->m_pNext );
  1082. return( pNode->m_element );
  1083. }
  1084. template< typename E, class ETraits >
  1085. inline const E& CAtlList< E, ETraits >::GetNext( POSITION& pos ) const
  1086. {
  1087. CNode* pNode;
  1088. ATLASSERT( pos != NULL );
  1089. pNode = (CNode*)pos;
  1090. pos = POSITION( pNode->m_pNext );
  1091. return( pNode->m_element );
  1092. }
  1093. template< typename E, class ETraits >
  1094. inline E& CAtlList< E, ETraits >::GetPrev( POSITION& pos )
  1095. {
  1096. CNode* pNode;
  1097. ATLASSERT( pos != NULL );
  1098. pNode = (CNode*)pos;
  1099. pos = POSITION( pNode->m_pPrev );
  1100. return( pNode->m_element );
  1101. }
  1102. template< typename E, class ETraits >
  1103. inline const E& CAtlList< E, ETraits >::GetPrev( POSITION& pos ) const
  1104. {
  1105. CNode* pNode;
  1106. ATLASSERT( pos != NULL );
  1107. pNode = (CNode*)pos;
  1108. pos = POSITION( pNode->m_pPrev );
  1109. return( pNode->m_element );
  1110. }
  1111. template< typename E, class ETraits >
  1112. inline E& CAtlList< E, ETraits >::GetAt( POSITION pos )
  1113. {
  1114. CNode* pNode;
  1115. ATLASSERT( pos != NULL );
  1116. pNode = (CNode*)pos;
  1117. return( pNode->m_element );
  1118. }
  1119. template< typename E, class ETraits >
  1120. inline const E& CAtlList< E, ETraits >::GetAt( POSITION pos ) const
  1121. {
  1122. CNode* pNode;
  1123. ATLASSERT( pos != NULL );
  1124. pNode = (CNode*)pos;
  1125. return( pNode->m_element );
  1126. }
  1127. template< typename E, class ETraits >
  1128. inline void CAtlList< E, ETraits >::SetAt( POSITION pos, INARGTYPE element )
  1129. {
  1130. CNode* pNode;
  1131. ATLASSERT( pos != NULL );
  1132. pNode = (CNode*)pos;
  1133. pNode->m_element = element;
  1134. }
  1135. template< typename E, class ETraits >
  1136. CAtlList< E, ETraits >::CAtlList( UINT nBlockSize ) :
  1137. m_nElements( 0 ),
  1138. m_pHead( NULL ),
  1139. m_pTail( NULL ),
  1140. m_nBlockSize( nBlockSize ),
  1141. m_pBlocks( NULL ),
  1142. m_pFree( NULL )
  1143. {
  1144. ATLASSERT( nBlockSize > 0 );
  1145. }
  1146. template< typename E, class ETraits >
  1147. void CAtlList< E, ETraits >::RemoveAll()
  1148. {
  1149. while( m_nElements > 0 )
  1150. {
  1151. CNode* pKill;
  1152. pKill = m_pHead;
  1153. ATLASSERT( pKill != NULL );
  1154. m_pHead = m_pHead->m_pNext;
  1155. FreeNode( pKill );
  1156. }
  1157. ATLASSERT( m_nElements == 0 );
  1158. m_pHead = NULL;
  1159. m_pTail = NULL;
  1160. m_pFree = NULL;
  1161. m_pBlocks->FreeDataChain();
  1162. m_pBlocks = NULL;
  1163. }
  1164. template< typename E, class ETraits >
  1165. CAtlList< E, ETraits >::~CAtlList()
  1166. {
  1167. RemoveAll();
  1168. ATLASSERT( m_nElements == 0 );
  1169. }
  1170. #pragma push_macro("new")
  1171. #undef new
  1172. template< typename E, class ETraits >
  1173. void CAtlList< E, ETraits >::GetFreeNode()
  1174. {
  1175. if( m_pFree == NULL )
  1176. {
  1177. CAtlPlex* pPlex;
  1178. CNode* pNode;
  1179. pPlex = CAtlPlex::Create( m_pBlocks, m_nBlockSize, sizeof( CNode ) );
  1180. if( pPlex == NULL )
  1181. {
  1182. ATL::AtlThrow( E_OUTOFMEMORY );
  1183. }
  1184. pNode = (CNode*)pPlex->data();
  1185. pNode += m_nBlockSize-1;
  1186. for( int iBlock = m_nBlockSize-1; iBlock >= 0; iBlock-- )
  1187. {
  1188. pNode->m_pNext = m_pFree;
  1189. m_pFree = pNode;
  1190. pNode--;
  1191. }
  1192. }
  1193. ATLASSERT( m_pFree != NULL );
  1194. }
  1195. template< typename E, class ETraits >
  1196. CAtlList< E, ETraits >::CNode* CAtlList< E, ETraits >::NewNode( CNode* pPrev, CNode* pNext )
  1197. {
  1198. GetFreeNode();
  1199. CNode* pNewNode = m_pFree;
  1200. CNode* pNextFree = m_pFree->m_pNext;
  1201. ::new( pNewNode ) CNode;
  1202. m_pFree = pNextFree;
  1203. pNewNode->m_pPrev = pPrev;
  1204. pNewNode->m_pNext = pNext;
  1205. m_nElements++;
  1206. ATLASSERT( m_nElements > 0 );
  1207. return( pNewNode );
  1208. }
  1209. template< typename E, class ETraits >
  1210. CAtlList< E, ETraits >::CNode* CAtlList< E, ETraits >::NewNode( INARGTYPE element, CNode* pPrev,
  1211. CNode* pNext )
  1212. {
  1213. GetFreeNode();
  1214. CNode* pNewNode = m_pFree;
  1215. CNode* pNextFree = m_pFree->m_pNext;
  1216. ::new( pNewNode ) CNode( element );
  1217. m_pFree = pNextFree;
  1218. pNewNode->m_pPrev = pPrev;
  1219. pNewNode->m_pNext = pNext;
  1220. m_nElements++;
  1221. ATLASSERT( m_nElements > 0 );
  1222. return( pNewNode );
  1223. }
  1224. #pragma pop_macro("new")
  1225. template< typename E, class ETraits >
  1226. void CAtlList< E, ETraits >::FreeNode( CNode* pNode )
  1227. {
  1228. pNode->~CNode();
  1229. pNode->m_pNext = m_pFree;
  1230. m_pFree = pNode;
  1231. ATLASSERT( m_nElements > 0 );
  1232. m_nElements--;
  1233. if( m_nElements == 0 )
  1234. {
  1235. RemoveAll();
  1236. }
  1237. }
  1238. template< typename E, class ETraits >
  1239. POSITION CAtlList< E, ETraits >::AddHead()
  1240. {
  1241. CNode* pNode = NewNode( NULL, m_pHead );
  1242. if( m_pHead != NULL )
  1243. {
  1244. m_pHead->m_pPrev = pNode;
  1245. }
  1246. else
  1247. {
  1248. m_pTail = pNode;
  1249. }
  1250. m_pHead = pNode;
  1251. return( POSITION( pNode ) );
  1252. }
  1253. template< typename E, class ETraits >
  1254. POSITION CAtlList< E, ETraits >::AddHead( INARGTYPE element )
  1255. {
  1256. CNode* pNode;
  1257. pNode = NewNode( element, NULL, m_pHead );
  1258. if( m_pHead != NULL )
  1259. {
  1260. m_pHead->m_pPrev = pNode;
  1261. }
  1262. else
  1263. {
  1264. m_pTail = pNode;
  1265. }
  1266. m_pHead = pNode;
  1267. return( POSITION( pNode ) );
  1268. }
  1269. template< typename E, class ETraits >
  1270. POSITION CAtlList< E, ETraits >::AddTail()
  1271. {
  1272. CNode* pNode = NewNode( m_pTail, NULL );
  1273. if( m_pTail != NULL )
  1274. {
  1275. m_pTail->m_pNext = pNode;
  1276. }
  1277. else
  1278. {
  1279. m_pHead = pNode;
  1280. }
  1281. m_pTail = pNode;
  1282. return( POSITION( pNode ) );
  1283. }
  1284. template< typename E, class ETraits >
  1285. POSITION CAtlList< E, ETraits >::AddTail( INARGTYPE element )
  1286. {
  1287. CNode* pNode;
  1288. pNode = NewNode( element, m_pTail, NULL );
  1289. if( m_pTail != NULL )
  1290. {
  1291. m_pTail->m_pNext = pNode;
  1292. }
  1293. else
  1294. {
  1295. m_pHead = pNode;
  1296. }
  1297. m_pTail = pNode;
  1298. return( POSITION( pNode ) );
  1299. }
  1300. template< typename E, class ETraits >
  1301. void CAtlList< E, ETraits >::AddHeadList( const CAtlList< E, ETraits >* plNew )
  1302. {
  1303. POSITION pos;
  1304. ATLASSERT( plNew != NULL );
  1305. pos = plNew->GetTailPosition();
  1306. while( pos != NULL )
  1307. {
  1308. INARGTYPE element = plNew->GetPrev( pos );
  1309. AddHead( element );
  1310. }
  1311. }
  1312. template< typename E, class ETraits >
  1313. void CAtlList< E, ETraits >::AddTailList( const CAtlList< E, ETraits >* plNew )
  1314. {
  1315. POSITION pos;
  1316. ATLASSERT( plNew != NULL );
  1317. pos = plNew->GetHeadPosition();
  1318. while( pos != NULL )
  1319. {
  1320. INARGTYPE element = plNew->GetNext( pos );
  1321. AddTail( element );
  1322. }
  1323. }
  1324. template< typename E, class ETraits >
  1325. E CAtlList< E, ETraits >::RemoveHead()
  1326. {
  1327. CNode* pNode;
  1328. ATLASSERT( m_pHead != NULL );
  1329. pNode = m_pHead;
  1330. E element( pNode->m_element );
  1331. m_pHead = pNode->m_pNext;
  1332. if( m_pHead != NULL )
  1333. {
  1334. m_pHead->m_pPrev = NULL;
  1335. }
  1336. else
  1337. {
  1338. m_pTail = NULL;
  1339. }
  1340. FreeNode( pNode );
  1341. return( element );
  1342. }
  1343. template< typename E, class ETraits >
  1344. void CAtlList< E, ETraits >::RemoveHeadNoReturn() throw()
  1345. {
  1346. ATLASSERT( m_pHead != NULL );
  1347. CNode* pNode = m_pHead;
  1348. m_pHead = pNode->m_pNext;
  1349. if( m_pHead != NULL )
  1350. {
  1351. m_pHead->m_pPrev = NULL;
  1352. }
  1353. else
  1354. {
  1355. m_pTail = NULL;
  1356. }
  1357. FreeNode( pNode );
  1358. }
  1359. template< typename E, class ETraits >
  1360. E CAtlList< E, ETraits >::RemoveTail()
  1361. {
  1362. CNode* pNode;
  1363. ATLASSERT( m_pTail != NULL );
  1364. pNode = m_pTail;
  1365. E element( pNode->m_element );
  1366. m_pTail = pNode->m_pPrev;
  1367. if( m_pTail != NULL )
  1368. {
  1369. m_pTail->m_pNext = NULL;
  1370. }
  1371. else
  1372. {
  1373. m_pHead = NULL;
  1374. }
  1375. FreeNode( pNode );
  1376. return( element );
  1377. }
  1378. template< typename E, class ETraits >
  1379. void CAtlList< E, ETraits >::RemoveTailNoReturn() throw()
  1380. {
  1381. ATLASSERT( m_pTail != NULL );
  1382. CNode* pNode = m_pTail;
  1383. m_pTail = pNode->m_pPrev;
  1384. if( m_pTail != NULL )
  1385. {
  1386. m_pTail->m_pNext = NULL;
  1387. }
  1388. else
  1389. {
  1390. m_pHead = NULL;
  1391. }
  1392. FreeNode( pNode );
  1393. }
  1394. template< typename E, class ETraits >
  1395. POSITION CAtlList< E, ETraits >::InsertBefore( POSITION pos, INARGTYPE element )
  1396. {
  1397. ATLASSERT_VALID(this);
  1398. if( pos == NULL )
  1399. return AddHead( element ); // insert before nothing -> head of the list
  1400. // Insert it before position
  1401. CNode* pOldNode = (CNode*)pos;
  1402. CNode* pNewNode = NewNode( element, pOldNode->m_pPrev, pOldNode );
  1403. if( pOldNode->m_pPrev != NULL )
  1404. {
  1405. ATLASSERT(AtlIsValidAddress(pOldNode->m_pPrev, sizeof(CNode)));
  1406. pOldNode->m_pPrev->m_pNext = pNewNode;
  1407. }
  1408. else
  1409. {
  1410. ATLASSERT( pOldNode == m_pHead );
  1411. m_pHead = pNewNode;
  1412. }
  1413. pOldNode->m_pPrev = pNewNode;
  1414. return( POSITION( pNewNode ) );
  1415. }
  1416. template< typename E, class ETraits >
  1417. POSITION CAtlList< E, ETraits >::InsertAfter( POSITION pos, INARGTYPE element )
  1418. {
  1419. ATLASSERT_VALID(this);
  1420. if( pos == NULL )
  1421. return AddTail( element ); // insert after nothing -> tail of the list
  1422. // Insert it after position
  1423. CNode* pOldNode = (CNode*)pos;
  1424. CNode* pNewNode = NewNode( element, pOldNode, pOldNode->m_pNext );
  1425. if( pOldNode->m_pNext != NULL )
  1426. {
  1427. ATLASSERT(AtlIsValidAddress(pOldNode->m_pNext, sizeof(CNode)));
  1428. pOldNode->m_pNext->m_pPrev = pNewNode;
  1429. }
  1430. else
  1431. {
  1432. ATLASSERT( pOldNode == m_pTail );
  1433. m_pTail = pNewNode;
  1434. }
  1435. pOldNode->m_pNext = pNewNode;
  1436. return( POSITION( pNewNode ) );
  1437. }
  1438. template< typename E, class ETraits >
  1439. void CAtlList< E, ETraits >::RemoveAt( POSITION pos )
  1440. {
  1441. ATLASSERT_VALID(this);
  1442. CNode* pOldNode = (CNode*)pos;
  1443. ATLASSERT(AtlIsValidAddress(pOldNode, sizeof(CNode)));
  1444. // remove pOldNode from list
  1445. if( pOldNode == m_pHead )
  1446. {
  1447. m_pHead = pOldNode->m_pNext;
  1448. }
  1449. else
  1450. {
  1451. ATLASSERT(AtlIsValidAddress(pOldNode->m_pPrev, sizeof(CNode)));
  1452. pOldNode->m_pPrev->m_pNext = pOldNode->m_pNext;
  1453. }
  1454. if( pOldNode == m_pTail )
  1455. {
  1456. m_pTail = pOldNode->m_pPrev;
  1457. }
  1458. else
  1459. {
  1460. ATLASSERT(AtlIsValidAddress(pOldNode->m_pNext, sizeof(CNode)));
  1461. pOldNode->m_pNext->m_pPrev = pOldNode->m_pPrev;
  1462. }
  1463. FreeNode( pOldNode );
  1464. }
  1465. template< typename E, class ETraits >
  1466. POSITION CAtlList< E, ETraits >::FindIndex( size_t iElement ) const
  1467. {
  1468. ATLASSERT_VALID(this);
  1469. if( iElement >= m_nElements )
  1470. return NULL; // went too far
  1471. CNode* pNode = m_pHead;
  1472. for( size_t iSearch = 0; iSearch < iElement; iSearch++ )
  1473. {
  1474. pNode = pNode->m_pNext;
  1475. }
  1476. return( POSITION( pNode ) );
  1477. }
  1478. template< typename E, class ETraits >
  1479. void CAtlList< E, ETraits >::MoveToHead( POSITION pos ) throw()
  1480. {
  1481. ATLASSERT( pos != NULL );
  1482. CNode* pNode = static_cast< CNode* >( pos );
  1483. if( pNode == m_pHead )
  1484. {
  1485. // Already at the head
  1486. return;
  1487. }
  1488. if( pNode->m_pNext == NULL )
  1489. {
  1490. ATLASSERT( pNode == m_pTail );
  1491. m_pTail = pNode->m_pPrev;
  1492. }
  1493. else
  1494. {
  1495. pNode->m_pNext->m_pPrev = pNode->m_pPrev;
  1496. }
  1497. ATLASSERT( pNode->m_pPrev != NULL ); // This node can't be the head, since we already checked that case
  1498. pNode->m_pPrev->m_pNext = pNode->m_pNext;
  1499. m_pHead->m_pPrev = pNode;
  1500. pNode->m_pNext = m_pHead;
  1501. pNode->m_pPrev = NULL;
  1502. m_pHead = pNode;
  1503. }
  1504. template< typename E, class ETraits >
  1505. void CAtlList< E, ETraits >::MoveToTail( POSITION pos ) throw()
  1506. {
  1507. ATLASSERT( pos != NULL );
  1508. CNode* pNode = static_cast< CNode* >( pos );
  1509. if( pNode == m_pTail )
  1510. {
  1511. // Already at the tail
  1512. return;
  1513. }
  1514. if( pNode->m_pPrev == NULL )
  1515. {
  1516. ATLASSERT( pNode == m_pHead );
  1517. m_pHead = pNode->m_pNext;
  1518. }
  1519. else
  1520. {
  1521. pNode->m_pPrev->m_pNext = pNode->m_pNext;
  1522. }
  1523. ATLASSERT( pNode->m_pNext != NULL ); // This node can't be the tail, since we already checked that case
  1524. pNode->m_pNext->m_pPrev = pNode->m_pPrev;
  1525. m_pTail->m_pNext = pNode;
  1526. pNode->m_pPrev = m_pTail;
  1527. pNode->m_pNext = NULL;
  1528. m_pTail = pNode;
  1529. }
  1530. template< typename E, class ETraits >
  1531. void CAtlList< E, ETraits >::SwapElements( POSITION pos1, POSITION pos2 ) throw()
  1532. {
  1533. ATLASSERT( pos1 != NULL );
  1534. ATLASSERT( pos2 != NULL );
  1535. if( pos1 == pos2 )
  1536. {
  1537. // Nothing to do
  1538. return;
  1539. }
  1540. CNode* pNode1 = static_cast< CNode* >( pos1 );
  1541. CNode* pNode2 = static_cast< CNode* >( pos2 );
  1542. if( pNode2->m_pNext == pNode1 )
  1543. {
  1544. // Swap pNode2 and pNode1 so that the next case works
  1545. CNode* pNodeTemp = pNode1;
  1546. pNode1 = pNode2;
  1547. pNode2 = pNodeTemp;
  1548. }
  1549. if( pNode1->m_pNext == pNode2 )
  1550. {
  1551. // Node1 and Node2 are adjacent
  1552. pNode2->m_pPrev = pNode1->m_pPrev;
  1553. if( pNode1->m_pPrev != NULL )
  1554. {
  1555. pNode1->m_pPrev->m_pNext = pNode2;
  1556. }
  1557. else
  1558. {
  1559. ATLASSERT( m_pHead == pNode1 );
  1560. m_pHead = pNode2;
  1561. }
  1562. pNode1->m_pNext = pNode2->m_pNext;
  1563. if( pNode2->m_pNext != NULL )
  1564. {
  1565. pNode2->m_pNext->m_pPrev = pNode1;
  1566. }
  1567. else
  1568. {
  1569. ATLASSERT( m_pTail == pNode2 );
  1570. m_pTail = pNode1;
  1571. }
  1572. pNode2->m_pNext = pNode1;
  1573. pNode1->m_pPrev = pNode2;
  1574. }
  1575. else
  1576. {
  1577. // The two nodes are not adjacent
  1578. CNode* pNodeTemp;
  1579. pNodeTemp = pNode1->m_pPrev;
  1580. pNode1->m_pPrev = pNode2->m_pPrev;
  1581. pNode2->m_pPrev = pNodeTemp;
  1582. pNodeTemp = pNode1->m_pNext;
  1583. pNode1->m_pNext = pNode2->m_pNext;
  1584. pNode2->m_pNext = pNodeTemp;
  1585. if( pNode1->m_pNext != NULL )
  1586. {
  1587. pNode1->m_pNext->m_pPrev = pNode1;
  1588. }
  1589. else
  1590. {
  1591. ATLASSERT( m_pTail == pNode2 );
  1592. m_pTail = pNode1;
  1593. }
  1594. if( pNode1->m_pPrev != NULL )
  1595. {
  1596. pNode1->m_pPrev->m_pNext = pNode1;
  1597. }
  1598. else
  1599. {
  1600. ATLASSERT( m_pHead == pNode2 );
  1601. m_pHead = pNode1;
  1602. }
  1603. if( pNode2->m_pNext != NULL )
  1604. {
  1605. pNode2->m_pNext->m_pPrev = pNode2;
  1606. }
  1607. else
  1608. {
  1609. ATLASSERT( m_pTail == pNode1 );
  1610. m_pTail = pNode2;
  1611. }
  1612. if( pNode2->m_pPrev != NULL )
  1613. {
  1614. pNode2->m_pPrev->m_pNext = pNode2;
  1615. }
  1616. else
  1617. {
  1618. ATLASSERT( m_pHead == pNode1 );
  1619. m_pHead = pNode2;
  1620. }
  1621. }
  1622. }
  1623. template< typename E, class ETraits >
  1624. POSITION CAtlList< E, ETraits >::Find( INARGTYPE element, POSITION posStartAfter ) const
  1625. {
  1626. ATLASSERT_VALID(this);
  1627. CNode* pNode = (CNode*)posStartAfter;
  1628. if( pNode == NULL )
  1629. {
  1630. pNode = m_pHead; // start at head
  1631. }
  1632. else
  1633. {
  1634. ATLASSERT(AtlIsValidAddress(pNode, sizeof(CNode)));
  1635. pNode = pNode->m_pNext; // start after the one specified
  1636. }
  1637. for( ; pNode != NULL; pNode = pNode->m_pNext )
  1638. {
  1639. if( ETraits::CompareElements( pNode->m_element, element ) )
  1640. return( POSITION( pNode ) );
  1641. }
  1642. return( NULL );
  1643. }
  1644. #ifdef _DEBUG
  1645. template< typename E, class ETraits >
  1646. void CAtlList< E, ETraits >::AssertValid() const
  1647. {
  1648. if( IsEmpty() )
  1649. {
  1650. // empty list
  1651. ATLASSERT(m_pHead == NULL);
  1652. ATLASSERT(m_pTail == NULL);
  1653. }
  1654. else
  1655. {
  1656. // non-empty list
  1657. ATLASSERT(AtlIsValidAddress(m_pHead, sizeof(CNode)));
  1658. ATLASSERT(AtlIsValidAddress(m_pTail, sizeof(CNode)));
  1659. }
  1660. }
  1661. #endif
  1662. template< typename K, typename V, class KTraits = CElementTraits< K >, class VTraits = CElementTraits< V > >
  1663. class CAtlMap
  1664. {
  1665. public:
  1666. typedef KTraits::INARGTYPE KINARGTYPE;
  1667. typedef KTraits::OUTARGTYPE KOUTARGTYPE;
  1668. typedef VTraits::INARGTYPE VINARGTYPE;
  1669. typedef VTraits::OUTARGTYPE VOUTARGTYPE;
  1670. class CPair :
  1671. public __POSITION
  1672. {
  1673. protected:
  1674. CPair( KINARGTYPE key ) :
  1675. m_key( key )
  1676. {
  1677. }
  1678. public:
  1679. const K m_key;
  1680. V m_value;
  1681. };
  1682. private:
  1683. class CNode :
  1684. public CPair
  1685. {
  1686. public:
  1687. CNode( KINARGTYPE key, UINT nHash ) :
  1688. CPair( key ),
  1689. m_nHash( nHash )
  1690. {
  1691. }
  1692. public:
  1693. UINT GetHash() const throw()
  1694. {
  1695. return( m_nHash );
  1696. }
  1697. public:
  1698. CNode* m_pNext;
  1699. UINT m_nHash;
  1700. };
  1701. public:
  1702. CAtlMap( UINT nBins = 17, float fOptimalLoad = 0.75f,
  1703. float fLoThreshold = 0.25f, float fHiThreshold = 2.25f, UINT nBlockSize = 10 ) throw();
  1704. size_t GetCount() const throw();
  1705. bool IsEmpty() const throw();
  1706. bool Lookup( KINARGTYPE key, VOUTARGTYPE value ) const;
  1707. const CPair* Lookup( KINARGTYPE key ) const throw();
  1708. CPair* Lookup( KINARGTYPE key ) throw();
  1709. V& operator[]( KINARGTYPE key ) throw();
  1710. POSITION SetAt( KINARGTYPE key, VINARGTYPE value );
  1711. void SetValueAt( POSITION pos, VINARGTYPE value );
  1712. bool RemoveKey( KINARGTYPE key ) throw();
  1713. void RemoveAll() throw();
  1714. void RemoveAtPos( POSITION pos ) throw();
  1715. POSITION GetStartPosition() const throw();
  1716. void GetNextAssoc( POSITION& pos, KOUTARGTYPE key, VOUTARGTYPE value ) const;
  1717. const CPair* GetNext( POSITION& pos ) const throw();
  1718. CPair* GetNext( POSITION& pos ) throw();
  1719. const K& GetNextKey( POSITION& pos ) const throw();
  1720. const V& GetNextValue( POSITION& pos ) const throw();
  1721. V& GetNextValue( POSITION& pos ) throw();
  1722. void GetAt( POSITION pos, KOUTARGTYPE key, VOUTARGTYPE value ) const;
  1723. CPair* GetAt( POSITION pos ) throw();
  1724. const CPair* GetAt( POSITION pos ) const throw();
  1725. const K& GetKeyAt( POSITION pos ) const throw();
  1726. const V& GetValueAt( POSITION pos ) const throw();
  1727. V& GetValueAt( POSITION pos ) throw();
  1728. UINT GetHashTableSize() const throw();
  1729. bool InitHashTable( UINT nBins, bool bAllocNow = true );
  1730. void EnableAutoRehash() throw();
  1731. void DisableAutoRehash() throw();
  1732. void Rehash( UINT nBins = 0 );
  1733. void SetOptimalLoad( float fOptimalLoad, float fLoThreshold, float fHiThreshold,
  1734. bool bRehashNow = false );
  1735. #ifdef _DEBUG
  1736. void AssertValid() const;
  1737. #endif // _DEBUG
  1738. // Implementation
  1739. private:
  1740. CNode** m_ppBins;
  1741. size_t m_nElements;
  1742. UINT m_nBins;
  1743. float m_fOptimalLoad;
  1744. float m_fLoThreshold;
  1745. float m_fHiThreshold;
  1746. size_t m_nHiRehashThreshold;
  1747. size_t m_nLoRehashThreshold;
  1748. ULONG m_nLockCount;
  1749. UINT m_nBlockSize;
  1750. CAtlPlex* m_pBlocks;
  1751. CNode* m_pFree;
  1752. private:
  1753. bool IsLocked() const throw();
  1754. UINT PickSize( size_t nElements ) const throw();
  1755. CNode* NewNode( KINARGTYPE key, UINT iBin, UINT nHash );
  1756. void FreeNode( CNode* pNode ) throw();
  1757. void FreePlexes() throw();
  1758. CNode* GetNode( KINARGTYPE key, UINT& iBin, UINT& nHash, CNode*& pPrev ) const throw();
  1759. CNode* CreateNode( KINARGTYPE key, UINT iBin, UINT nHash );
  1760. void RemoveNode( CNode* pNode, CNode* pPrev ) throw();
  1761. CNode* FindNextNode( CNode* pNode ) const throw();
  1762. void UpdateRehashThresholds() throw();
  1763. public:
  1764. ~CAtlMap() throw();
  1765. private:
  1766. // Private to prevent use
  1767. CAtlMap( const CAtlMap& ) throw();
  1768. CAtlMap& operator=( const CAtlMap& ) throw();
  1769. };
  1770. template< typename K, typename I, class KTraits = CElementTraits< K > >
  1771. class CMapToInterface :
  1772. public CAtlMap< K, ATL::CComQIPtr< I >, KTraits, CComQIPtrElementTraits< I > >
  1773. {
  1774. public:
  1775. CMapToInterface( UINT nBins = 17 ) throw();
  1776. private:
  1777. // Private to prevent use
  1778. CMapToInterface( const CMapToInterface& ) throw();
  1779. CMapToInterface& operator=( const CMapToInterface& ) throw();
  1780. };
  1781. template< typename K, typename I, class KTraits >
  1782. inline CMapToInterface< K, I, KTraits >::CMapToInterface( UINT nBins ) :
  1783. CAtlMap< K, ATL::CComQIPtr< I >, KTraits, CComQIPtrElementTraits< I > >( nBins )
  1784. {
  1785. }
  1786. template< typename K, typename V, class KTraits = CElementTraits< K > >
  1787. class CMapToAutoPtr :
  1788. public CAtlMap< K, ATL::CAutoPtr< V >, KTraits, CAutoPtrElementTraits< V > >
  1789. {
  1790. public:
  1791. CMapToAutoPtr( UINT nBins = 17 ) throw();
  1792. private:
  1793. // Private to prevent use
  1794. CMapToAutoPtr( const CMapToAutoPtr& ) throw();
  1795. CMapToAutoPtr& operator=( const CMapToAutoPtr& ) throw();
  1796. };
  1797. template< typename K, typename V, class KTraits >
  1798. inline CMapToAutoPtr< K, V, KTraits >::CMapToAutoPtr( UINT nBins ) :
  1799. CAtlMap< K, ATL::CAutoPtr< V >, KTraits, CAutoPtrElementTraits< V > >( nBins )
  1800. {
  1801. }
  1802. template< typename K, typename V, class KTraits, class VTraits >
  1803. inline size_t CAtlMap< K, V, KTraits, VTraits >::GetCount() const
  1804. {
  1805. return( m_nElements );
  1806. }
  1807. template< typename K, typename V, class KTraits, class VTraits >
  1808. inline bool CAtlMap< K, V, KTraits, VTraits >::IsEmpty() const
  1809. {
  1810. return( m_nElements == 0 );
  1811. }
  1812. template< typename K, typename V, class KTraits, class VTraits >
  1813. inline V& CAtlMap< K, V, KTraits, VTraits >::operator[]( KINARGTYPE key )
  1814. {
  1815. CNode* pNode;
  1816. UINT iBin;
  1817. UINT nHash;
  1818. CNode* pPrev;
  1819. pNode = GetNode( key, iBin, nHash, pPrev );
  1820. if( pNode == NULL )
  1821. {
  1822. pNode = CreateNode( key, iBin, nHash );
  1823. }
  1824. return( pNode->m_value );
  1825. }
  1826. template< typename K, typename V, class KTraits, class VTraits >
  1827. inline UINT CAtlMap< K, V, KTraits, VTraits >::GetHashTableSize() const
  1828. {
  1829. return( m_nBins );
  1830. }
  1831. template< typename K, typename V, class KTraits, class VTraits >
  1832. inline void CAtlMap< K, V, KTraits, VTraits >::GetAt( POSITION pos, KOUTARGTYPE key, VOUTARGTYPE value ) const
  1833. {
  1834. CNode* pNode;
  1835. ATLASSERT( pos != NULL );
  1836. pNode = static_cast< CNode* >( pos );
  1837. key = pNode->m_key;
  1838. value = pNode->m_value;
  1839. }
  1840. template< typename K, typename V, class KTraits, class VTraits >
  1841. inline CAtlMap< K, V, KTraits, VTraits >::CPair* CAtlMap< K, V, KTraits, VTraits >::GetAt( POSITION pos ) throw()
  1842. {
  1843. ATLASSERT( pos != NULL );
  1844. return( static_cast< CPair* >( pos ) );
  1845. }
  1846. template< typename K, typename V, class KTraits, class VTraits >
  1847. inline const CAtlMap< K, V, KTraits, VTraits >::CPair* CAtlMap< K, V, KTraits, VTraits >::GetAt( POSITION pos ) const throw()
  1848. {
  1849. ATLASSERT( pos != NULL );
  1850. return( static_cast< const CPair* >( pos ) );
  1851. }
  1852. template< typename K, typename V, class KTraits, class VTraits >
  1853. inline const K& CAtlMap< K, V, KTraits, VTraits >::GetKeyAt( POSITION pos ) const
  1854. {
  1855. CNode* pNode;
  1856. ATLASSERT( pos != NULL );
  1857. pNode = (CNode*)pos;
  1858. return( pNode->m_key );
  1859. }
  1860. template< typename K, typename V, class KTraits, class VTraits >
  1861. inline const V& CAtlMap< K, V, KTraits, VTraits >::GetValueAt( POSITION pos ) const
  1862. {
  1863. CNode* pNode;
  1864. ATLASSERT( pos != NULL );
  1865. pNode = (CNode*)pos;
  1866. return( pNode->m_value );
  1867. }
  1868. template< typename K, typename V, class KTraits, class VTraits >
  1869. inline V& CAtlMap< K, V, KTraits, VTraits >::GetValueAt( POSITION pos )
  1870. {
  1871. CNode* pNode;
  1872. ATLASSERT( pos != NULL );
  1873. pNode = (CNode*)pos;
  1874. return( pNode->m_value );
  1875. }
  1876. template< typename K, typename V, class KTraits, class VTraits >
  1877. inline void CAtlMap< K, V, KTraits, VTraits >::DisableAutoRehash() throw()
  1878. {
  1879. m_nLockCount++;
  1880. }
  1881. template< typename K, typename V, class KTraits, class VTraits >
  1882. inline void CAtlMap< K, V, KTraits, VTraits >::EnableAutoRehash() throw()
  1883. {
  1884. ATLASSERT( m_nLockCount > 0 );
  1885. m_nLockCount--;
  1886. }
  1887. template< typename K, typename V, class KTraits, class VTraits >
  1888. inline bool CAtlMap< K, V, KTraits, VTraits >::IsLocked() const
  1889. {
  1890. return( m_nLockCount != 0 );
  1891. }
  1892. template< typename K, typename V, class KTraits, class VTraits >
  1893. UINT CAtlMap< K, V, KTraits, VTraits >::PickSize( size_t nElements ) const
  1894. {
  1895. // List of primes such that s_anPrimes[i] is the smallest prime greater than 2^(5+i/3)
  1896. static const UINT s_anPrimes[] =
  1897. {
  1898. 17, 23, 29, 37, 41, 53, 67, 83, 103, 131, 163, 211, 257, 331, 409, 521, 647, 821,
  1899. 1031, 1291, 1627, 2053, 2591, 3251, 4099, 5167, 6521, 8209, 10331,
  1900. 13007, 16411, 20663, 26017, 32771, 41299, 52021, 65537, 82571, 104033,
  1901. 131101, 165161, 208067, 262147, 330287, 416147, 524309, 660563,
  1902. 832291, 1048583, 1321139, 1664543, 2097169, 2642257, 3329023, 4194319,
  1903. 5284493, 6658049, 8388617, 10568993, 13316089, UINT_MAX
  1904. };
  1905. UINT nBinsEstimate = UINT( min( UINT_MAX, (size_t)(nElements/m_fOptimalLoad) ) );
  1906. // Find the smallest prime greater than our estimate
  1907. int iPrime = 0;
  1908. while( nBinsEstimate > s_anPrimes[iPrime] )
  1909. {
  1910. iPrime++;
  1911. }
  1912. if( s_anPrimes[iPrime] == UINT_MAX )
  1913. {
  1914. return( nBinsEstimate );
  1915. }
  1916. else
  1917. {
  1918. return( s_anPrimes[iPrime] );
  1919. }
  1920. }
  1921. template< typename K, typename V, class KTraits, class VTraits >
  1922. CAtlMap< K, V, KTraits, VTraits >::CNode* CAtlMap< K, V, KTraits, VTraits >::CreateNode(
  1923. KINARGTYPE key, UINT iBin, UINT nHash )
  1924. {
  1925. CNode* pNode;
  1926. if( m_ppBins == NULL )
  1927. {
  1928. bool bSuccess;
  1929. bSuccess = InitHashTable( m_nBins );
  1930. if( !bSuccess )
  1931. {
  1932. ATL::AtlThrow( E_OUTOFMEMORY );
  1933. }
  1934. }
  1935. pNode = NewNode( key, iBin, nHash );
  1936. return( pNode );
  1937. }
  1938. template< typename K, typename V, class KTraits, class VTraits >
  1939. POSITION CAtlMap< K, V, KTraits, VTraits >::GetStartPosition() const
  1940. {
  1941. if( IsEmpty() )
  1942. {
  1943. return( NULL );
  1944. }
  1945. for( UINT iBin = 0; iBin < m_nBins; iBin++ )
  1946. {
  1947. if( m_ppBins[iBin] != NULL )
  1948. {
  1949. return( POSITION( m_ppBins[iBin] ) );
  1950. }
  1951. }
  1952. ATLASSERT( false );
  1953. return( NULL );
  1954. }
  1955. template< typename K, typename V, class KTraits, class VTraits >
  1956. POSITION CAtlMap< K, V, KTraits, VTraits >::SetAt( KINARGTYPE key, VINARGTYPE value )
  1957. {
  1958. CNode* pNode;
  1959. UINT iBin;
  1960. UINT nHash;
  1961. CNode* pPrev;
  1962. pNode = GetNode( key, iBin, nHash, pPrev );
  1963. if( pNode == NULL )
  1964. {
  1965. pNode = CreateNode( key, iBin, nHash );
  1966. _ATLTRY
  1967. {
  1968. pNode->m_value = value;
  1969. }
  1970. _ATLCATCHALL()
  1971. {
  1972. RemoveAtPos( POSITION( pNode ) );
  1973. _ATLRETHROW;
  1974. }
  1975. }
  1976. else
  1977. {
  1978. pNode->m_value = value;
  1979. }
  1980. return( POSITION( pNode ) );
  1981. }
  1982. template< typename K, typename V, class KTraits, class VTraits >
  1983. void CAtlMap< K, V, KTraits, VTraits >::SetValueAt( POSITION pos, VINARGTYPE value )
  1984. {
  1985. ATLASSERT( pos != NULL );
  1986. CNode* pNode = static_cast< CNode* >( pos );
  1987. pNode->m_value = value;
  1988. }
  1989. template< typename K, typename V, class KTraits, class VTraits >
  1990. CAtlMap< K, V, KTraits, VTraits >::CAtlMap( UINT nBins, float fOptimalLoad,
  1991. float fLoThreshold, float fHiThreshold, UINT nBlockSize ) :
  1992. m_ppBins( NULL ),
  1993. m_nBins( nBins ),
  1994. m_nElements( 0 ),
  1995. m_nLockCount( 0 ), // Start unlocked
  1996. m_fOptimalLoad( fOptimalLoad ),
  1997. m_fLoThreshold( fLoThreshold ),
  1998. m_fHiThreshold( fHiThreshold ),
  1999. m_nHiRehashThreshold( UINT_MAX ),
  2000. m_nLoRehashThreshold( 0 ),
  2001. m_pBlocks( NULL ),
  2002. m_pFree( NULL ),
  2003. m_nBlockSize( nBlockSize )
  2004. {
  2005. ATLASSERT( nBins > 0 );
  2006. ATLASSERT( nBlockSize > 0 );
  2007. SetOptimalLoad( fOptimalLoad, fLoThreshold, fHiThreshold, false );
  2008. }
  2009. template< typename K, typename V, class KTraits, class VTraits >
  2010. void CAtlMap< K, V, KTraits, VTraits >::SetOptimalLoad( float fOptimalLoad, float fLoThreshold,
  2011. float fHiThreshold, bool bRehashNow )
  2012. {
  2013. ATLASSERT( fOptimalLoad > 0 );
  2014. ATLASSERT( (fLoThreshold >= 0) && (fLoThreshold < fOptimalLoad) );
  2015. ATLASSERT( fHiThreshold > fOptimalLoad );
  2016. m_fOptimalLoad = fOptimalLoad;
  2017. m_fLoThreshold = fLoThreshold;
  2018. m_fHiThreshold = fHiThreshold;
  2019. UpdateRehashThresholds();
  2020. if( bRehashNow && ((m_nElements > m_nHiRehashThreshold) ||
  2021. (m_nElements < m_nLoRehashThreshold)) )
  2022. {
  2023. Rehash( PickSize( m_nElements ) );
  2024. }
  2025. }
  2026. template< typename K, typename V, class KTraits, class VTraits >
  2027. void CAtlMap< K, V, KTraits, VTraits >::UpdateRehashThresholds() throw()
  2028. {
  2029. m_nHiRehashThreshold = size_t( m_fHiThreshold*m_nBins );
  2030. m_nLoRehashThreshold = size_t( m_fLoThreshold*m_nBins );
  2031. if( m_nLoRehashThreshold < 17 )
  2032. {
  2033. m_nLoRehashThreshold = 0;
  2034. }
  2035. }
  2036. template< typename K, typename V, class KTraits, class VTraits >
  2037. bool CAtlMap< K, V, KTraits, VTraits >::InitHashTable( UINT nBins, bool bAllocNow )
  2038. {
  2039. ATLASSERT( m_nElements == 0 );
  2040. ATLASSERT( nBins > 0 );
  2041. if( m_ppBins != NULL )
  2042. {
  2043. delete[] m_ppBins;
  2044. m_ppBins = NULL;
  2045. }
  2046. if( bAllocNow )
  2047. {
  2048. ATLTRY( m_ppBins = new CNode*[nBins] );
  2049. if( m_ppBins == NULL )
  2050. {
  2051. return false;
  2052. }
  2053. memset( m_ppBins, 0, sizeof( CNode* )*nBins );
  2054. }
  2055. m_nBins = nBins;
  2056. UpdateRehashThresholds();
  2057. return true;
  2058. }
  2059. template< typename K, typename V, class KTraits, class VTraits >
  2060. void CAtlMap< K, V, KTraits, VTraits >::RemoveAll()
  2061. {
  2062. DisableAutoRehash();
  2063. if( m_ppBins != NULL )
  2064. {
  2065. for( UINT iBin = 0; iBin < m_nBins; iBin++ )
  2066. {
  2067. CNode* pNext;
  2068. pNext = m_ppBins[iBin];
  2069. while( pNext != NULL )
  2070. {
  2071. CNode* pKill;
  2072. pKill = pNext;
  2073. pNext = pNext->m_pNext;
  2074. FreeNode( pKill );
  2075. }
  2076. }
  2077. }
  2078. delete[] m_ppBins;
  2079. m_ppBins = NULL;
  2080. m_nElements = 0;
  2081. if( !IsLocked() )
  2082. {
  2083. InitHashTable( PickSize( m_nElements ), false );
  2084. }
  2085. FreePlexes();
  2086. EnableAutoRehash();
  2087. }
  2088. template< typename K, typename V, class KTraits, class VTraits >
  2089. CAtlMap< K, V, KTraits, VTraits >::~CAtlMap()
  2090. {
  2091. RemoveAll();
  2092. }
  2093. #pragma push_macro("new")
  2094. #undef new
  2095. template< typename K, typename V, class KTraits, class VTraits >
  2096. CAtlMap< K, V, KTraits, VTraits >::CNode* CAtlMap< K, V, KTraits, VTraits >::NewNode(
  2097. KINARGTYPE key, UINT iBin, UINT nHash )
  2098. {
  2099. CNode* pNewNode;
  2100. if( m_pFree == NULL )
  2101. {
  2102. CAtlPlex* pPlex;
  2103. CNode* pNode;
  2104. pPlex = CAtlPlex::Create( m_pBlocks, m_nBlockSize, sizeof( CNode ) );
  2105. if( pPlex == NULL )
  2106. {
  2107. ATL::AtlThrow( E_OUTOFMEMORY );
  2108. }
  2109. pNode = (CNode*)pPlex->data();
  2110. pNode += m_nBlockSize-1;
  2111. for( int iBlock = m_nBlockSize-1; iBlock >= 0; iBlock-- )
  2112. {
  2113. pNode->m_pNext = m_pFree;
  2114. m_pFree = pNode;
  2115. pNode--;
  2116. }
  2117. }
  2118. ATLASSERT( m_pFree != NULL );
  2119. pNewNode = m_pFree;
  2120. m_pFree = pNewNode->m_pNext;
  2121. _ATLTRY
  2122. {
  2123. ::new( pNewNode ) CNode( key, nHash );
  2124. }
  2125. _ATLCATCHALL()
  2126. {
  2127. pNewNode->m_pNext = m_pFree;
  2128. m_pFree = pNewNode;
  2129. _ATLRETHROW;
  2130. }
  2131. m_nElements++;
  2132. pNewNode->m_pNext = m_ppBins[iBin];
  2133. m_ppBins[iBin] = pNewNode;
  2134. if( (m_nElements > m_nHiRehashThreshold) && !IsLocked() )
  2135. {
  2136. Rehash( PickSize( m_nElements ) );
  2137. }
  2138. return( pNewNode );
  2139. }
  2140. #pragma pop_macro("new")
  2141. template< typename K, typename V, class KTraits, class VTraits >
  2142. void CAtlMap< K, V, KTraits, VTraits >::FreeNode( CNode* pNode )
  2143. {
  2144. ATLASSERT( pNode != NULL );
  2145. pNode->~CNode();
  2146. pNode->m_pNext = m_pFree;
  2147. m_pFree = pNode;
  2148. ATLASSERT( m_nElements > 0 );
  2149. m_nElements--;
  2150. if( (m_nElements < m_nLoRehashThreshold) && !IsLocked() )
  2151. {
  2152. Rehash( PickSize( m_nElements ) );
  2153. }
  2154. if( m_nElements == 0 )
  2155. {
  2156. FreePlexes();
  2157. }
  2158. }
  2159. template< typename K, typename V, class KTraits, class VTraits >
  2160. void CAtlMap< K, V, KTraits, VTraits >::FreePlexes() throw()
  2161. {
  2162. m_pFree = NULL;
  2163. if( m_pBlocks != NULL )
  2164. {
  2165. m_pBlocks->FreeDataChain();
  2166. m_pBlocks = NULL;
  2167. }
  2168. }
  2169. template< typename K, typename V, class KTraits, class VTraits >
  2170. CAtlMap< K, V, KTraits, VTraits >::CNode* CAtlMap< K, V, KTraits, VTraits >::GetNode(
  2171. KINARGTYPE key, UINT& iBin, UINT& nHash, CNode*& pPrev ) const
  2172. {
  2173. CNode* pFollow;
  2174. nHash = KTraits::Hash( key );
  2175. iBin = nHash%m_nBins;
  2176. if( m_ppBins == NULL )
  2177. {
  2178. return( NULL );
  2179. }
  2180. pFollow = NULL;
  2181. pPrev = NULL;
  2182. for( CNode* pNode = m_ppBins[iBin]; pNode != NULL; pNode = pNode->m_pNext )
  2183. {
  2184. if( (pNode->GetHash() == nHash) && KTraits::CompareElements( pNode->m_key, key ) )
  2185. {
  2186. pPrev = pFollow;
  2187. return( pNode );
  2188. }
  2189. pFollow = pNode;
  2190. }
  2191. return( NULL );
  2192. }
  2193. template< typename K, typename V, class KTraits, class VTraits >
  2194. bool CAtlMap< K, V, KTraits, VTraits >::Lookup( KINARGTYPE key, VOUTARGTYPE value ) const
  2195. {
  2196. UINT iBin;
  2197. UINT nHash;
  2198. CNode* pNode;
  2199. CNode* pPrev;
  2200. pNode = GetNode( key, iBin, nHash, pPrev );
  2201. if( pNode == NULL )
  2202. {
  2203. return( false );
  2204. }
  2205. value = pNode->m_value;
  2206. return( true );
  2207. }
  2208. template< typename K, typename V, class KTraits, class VTraits >
  2209. const CAtlMap< K, V, KTraits, VTraits >::CPair* CAtlMap< K, V, KTraits, VTraits >::Lookup( KINARGTYPE key ) const
  2210. {
  2211. UINT iBin;
  2212. UINT nHash;
  2213. CNode* pNode;
  2214. CNode* pPrev;
  2215. pNode = GetNode( key, iBin, nHash, pPrev );
  2216. return( pNode );
  2217. }
  2218. template< typename K, typename V, class KTraits, class VTraits >
  2219. CAtlMap< K, V, KTraits, VTraits >::CPair* CAtlMap< K, V, KTraits, VTraits >::Lookup( KINARGTYPE key )
  2220. {
  2221. UINT iBin;
  2222. UINT nHash;
  2223. CNode* pNode;
  2224. CNode* pPrev;
  2225. pNode = GetNode( key, iBin, nHash, pPrev );
  2226. return( pNode );
  2227. }
  2228. template< typename K, typename V, class KTraits, class VTraits >
  2229. bool CAtlMap< K, V, KTraits, VTraits >::RemoveKey( KINARGTYPE key )
  2230. {
  2231. CNode* pNode;
  2232. UINT iBin;
  2233. UINT nHash;
  2234. CNode* pPrev;
  2235. pPrev = NULL;
  2236. pNode = GetNode( key, iBin, nHash, pPrev );
  2237. if( pNode == NULL )
  2238. {
  2239. return( false );
  2240. }
  2241. RemoveNode( pNode, pPrev );
  2242. return( true );
  2243. }
  2244. template< typename K, typename V, class KTraits, class VTraits >
  2245. void CAtlMap< K, V, KTraits, VTraits >::RemoveNode( CNode* pNode, CNode* pPrev )
  2246. {
  2247. UINT iBin;
  2248. ATLASSERT( pNode != NULL );
  2249. iBin = pNode->GetHash()%m_nBins;
  2250. if( pPrev == NULL )
  2251. {
  2252. ATLASSERT( m_ppBins[iBin] == pNode );
  2253. m_ppBins[iBin] = pNode->m_pNext;
  2254. }
  2255. else
  2256. {
  2257. ATLASSERT( pPrev->m_pNext == pNode );
  2258. pPrev->m_pNext = pNode->m_pNext;
  2259. }
  2260. FreeNode( pNode );
  2261. }
  2262. template< typename K, typename V, class KTraits, class VTraits >
  2263. void CAtlMap< K, V, KTraits, VTraits >::RemoveAtPos( POSITION pos )
  2264. {
  2265. CNode* pNode;
  2266. CNode* pPrev;
  2267. UINT iBin;
  2268. ATLASSERT( pos != NULL );
  2269. pNode = static_cast< CNode* >( pos );
  2270. iBin = pNode->GetHash()%m_nBins;
  2271. ATLASSERT( m_ppBins[iBin] != NULL );
  2272. if( pNode == m_ppBins[iBin] )
  2273. {
  2274. pPrev = NULL;
  2275. }
  2276. else
  2277. {
  2278. pPrev = m_ppBins[iBin];
  2279. while( pPrev->m_pNext != pNode )
  2280. {
  2281. pPrev = pPrev->m_pNext;
  2282. ATLASSERT( pPrev != NULL );
  2283. }
  2284. }
  2285. RemoveNode( pNode, pPrev );
  2286. }
  2287. template< typename K, typename V, class KTraits, class VTraits >
  2288. void CAtlMap< K, V, KTraits, VTraits >::Rehash( UINT nBins )
  2289. {
  2290. CNode** ppBins = NULL;
  2291. if( nBins == 0 )
  2292. {
  2293. nBins = PickSize( m_nElements );
  2294. }
  2295. if( nBins == m_nBins )
  2296. {
  2297. return;
  2298. }
  2299. ATLTRACE(atlTraceMap, 2, _T("Rehash: %u bins\n"), nBins );
  2300. if( m_ppBins == NULL )
  2301. {
  2302. // Just set the new number of bins
  2303. InitHashTable( nBins, false );
  2304. return;
  2305. }
  2306. ATLTRY(ppBins = new CNode*[nBins]);
  2307. if (ppBins == NULL)
  2308. {
  2309. ATL::AtlThrow( E_OUTOFMEMORY );
  2310. }
  2311. memset( ppBins, 0, nBins*sizeof( CNode* ) );
  2312. // Nothing gets copied. We just rewire the old nodes
  2313. // into the new bins.
  2314. for( UINT iSrcBin = 0; iSrcBin < m_nBins; iSrcBin++ )
  2315. {
  2316. CNode* pNode;
  2317. pNode = m_ppBins[iSrcBin];
  2318. while( pNode != NULL )
  2319. {
  2320. CNode* pNext;
  2321. UINT iDestBin;
  2322. pNext = pNode->m_pNext; // Save so we don't trash it
  2323. iDestBin = pNode->GetHash()%nBins;
  2324. pNode->m_pNext = ppBins[iDestBin];
  2325. ppBins[iDestBin] = pNode;
  2326. pNode = pNext;
  2327. }
  2328. }
  2329. delete[] m_ppBins;
  2330. m_ppBins = ppBins;
  2331. m_nBins = nBins;
  2332. UpdateRehashThresholds();
  2333. }
  2334. template< typename K, typename V, class KTraits, class VTraits >
  2335. void CAtlMap< K, V, KTraits, VTraits >::GetNextAssoc( POSITION& pos, KOUTARGTYPE key,
  2336. VOUTARGTYPE value ) const
  2337. {
  2338. CNode* pNode;
  2339. CNode* pNext;
  2340. ATLASSERT( m_ppBins != NULL );
  2341. ATLASSERT( pos != NULL );
  2342. pNode = (CNode*)pos;
  2343. pNext = FindNextNode( pNode );
  2344. pos = POSITION( pNext );
  2345. key = pNode->m_key;
  2346. value = pNode->m_value;
  2347. }
  2348. template< typename K, typename V, class KTraits, class VTraits >
  2349. const CAtlMap< K, V, KTraits, VTraits >::CPair* CAtlMap< K, V, KTraits, VTraits >::GetNext( POSITION& pos ) const
  2350. {
  2351. CNode* pNode;
  2352. CNode* pNext;
  2353. ATLASSERT( m_ppBins != NULL );
  2354. ATLASSERT( pos != NULL );
  2355. pNode = (CNode*)pos;
  2356. pNext = FindNextNode( pNode );
  2357. pos = POSITION( pNext );
  2358. return( pNode );
  2359. }
  2360. template< typename K, typename V, class KTraits, class VTraits >
  2361. CAtlMap< K, V, KTraits, VTraits >::CPair* CAtlMap< K, V, KTraits, VTraits >::GetNext(
  2362. POSITION& pos ) throw()
  2363. {
  2364. ATLASSERT( m_ppBins != NULL );
  2365. ATLASSERT( pos != NULL );
  2366. CNode* pNode = static_cast< CNode* >( pos );
  2367. CNode* pNext = FindNextNode( pNode );
  2368. pos = POSITION( pNext );
  2369. return( pNode );
  2370. }
  2371. template< typename K, typename V, class KTraits, class VTraits >
  2372. const K& CAtlMap< K, V, KTraits, VTraits >::GetNextKey( POSITION& pos ) const
  2373. {
  2374. CNode* pNode;
  2375. CNode* pNext;
  2376. ATLASSERT( m_ppBins != NULL );
  2377. ATLASSERT( pos != NULL );
  2378. pNode = (CNode*)pos;
  2379. pNext = FindNextNode( pNode );
  2380. pos = POSITION( pNext );
  2381. return( pNode->m_key );
  2382. }
  2383. template< typename K, typename V, class KTraits, class VTraits >
  2384. const V& CAtlMap< K, V, KTraits, VTraits >::GetNextValue( POSITION& pos ) const
  2385. {
  2386. CNode* pNode;
  2387. CNode* pNext;
  2388. ATLASSERT( m_ppBins != NULL );
  2389. ATLASSERT( pos != NULL );
  2390. pNode = (CNode*)pos;
  2391. pNext = FindNextNode( pNode );
  2392. pos = POSITION( pNext );
  2393. return( pNode->m_value );
  2394. }
  2395. template< typename K, typename V, class KTraits, class VTraits >
  2396. V& CAtlMap< K, V, KTraits, VTraits >::GetNextValue( POSITION& pos )
  2397. {
  2398. CNode* pNode;
  2399. CNode* pNext;
  2400. ATLASSERT( m_ppBins != NULL );
  2401. ATLASSERT( pos != NULL );
  2402. pNode = (CNode*)pos;
  2403. pNext = FindNextNode( pNode );
  2404. pos = POSITION( pNext );
  2405. return( pNode->m_value );
  2406. }
  2407. template< typename K, typename V, class KTraits, class VTraits >
  2408. CAtlMap< K, V, KTraits, VTraits >::CNode* CAtlMap< K, V, KTraits, VTraits >::FindNextNode( CNode* pNode ) const
  2409. {
  2410. CNode* pNext;
  2411. if( pNode->m_pNext != NULL )
  2412. {
  2413. pNext = pNode->m_pNext;
  2414. }
  2415. else
  2416. {
  2417. UINT iBin;
  2418. pNext = NULL;
  2419. iBin = (pNode->GetHash()%m_nBins)+1;
  2420. while( (pNext == NULL) && (iBin < m_nBins) )
  2421. {
  2422. if( m_ppBins[iBin] != NULL )
  2423. {
  2424. pNext = m_ppBins[iBin];
  2425. }
  2426. iBin++;
  2427. }
  2428. }
  2429. return( pNext );
  2430. }
  2431. #ifdef _DEBUG
  2432. template< typename K, typename V, class KTraits, class VTraits >
  2433. void CAtlMap< K, V, KTraits, VTraits >::AssertValid() const
  2434. {
  2435. ATLASSERT( m_nBins > 0 );
  2436. // non-empty map should have hash table
  2437. ATLASSERT( IsEmpty() || (m_ppBins != NULL) );
  2438. }
  2439. #endif
  2440. #pragma push_macro("new")
  2441. #undef new
  2442. //
  2443. // The red-black tree code is based on the the descriptions in
  2444. // "Introduction to Algorithms", by Cormen, Leiserson, and Rivest
  2445. //
  2446. template< typename K, typename V, class KTraits = CElementTraits< K >, class VTraits = CElementTraits< V > >
  2447. class CRBTree
  2448. {
  2449. public:
  2450. typedef KTraits::INARGTYPE KINARGTYPE;
  2451. typedef KTraits::OUTARGTYPE KOUTARGTYPE;
  2452. typedef VTraits::INARGTYPE VINARGTYPE;
  2453. typedef VTraits::OUTARGTYPE VOUTARGTYPE;
  2454. public:
  2455. class CPair :
  2456. public __POSITION
  2457. {
  2458. protected:
  2459. CPair( KINARGTYPE key, VINARGTYPE value ) :
  2460. m_key( key ),
  2461. m_value( value )
  2462. {
  2463. }
  2464. ~CPair() throw()
  2465. {
  2466. }
  2467. public:
  2468. const K m_key;
  2469. V m_value;
  2470. };
  2471. private:
  2472. class CNode :
  2473. public CPair
  2474. {
  2475. public:
  2476. enum RB_COLOR
  2477. {
  2478. RB_RED,
  2479. RB_BLACK
  2480. };
  2481. public:
  2482. RB_COLOR m_eColor;
  2483. CNode* m_pLeft;
  2484. CNode* m_pRight;
  2485. CNode* m_pParent;
  2486. CNode( KINARGTYPE key, VINARGTYPE value ) :
  2487. CPair( key, value ),
  2488. m_pParent( NULL ),
  2489. m_eColor( RB_BLACK )
  2490. {
  2491. }
  2492. ~CNode() throw()
  2493. {
  2494. }
  2495. };
  2496. private:
  2497. CNode* m_pRoot;
  2498. size_t m_nCount;
  2499. CNode* m_pFree;
  2500. CAtlPlex* m_pBlocks;
  2501. size_t m_nBlockSize;
  2502. // sentinel node
  2503. CNode *m_pNil;
  2504. // methods
  2505. bool IsNil(CNode *p) const throw();
  2506. void SetNil(CNode **p) throw();
  2507. CNode* NewNode( KINARGTYPE key, VINARGTYPE value ) throw( ... );
  2508. void FreeNode(CNode* pNode) throw();
  2509. void RemovePostOrder(CNode* pNode) throw();
  2510. CNode* LeftRotate(CNode* pNode) throw();
  2511. CNode* RightRotate(CNode* pNode) throw();
  2512. void SwapNode(CNode* pDest, CNode* pSrc) throw();
  2513. CNode* InsertImpl( KINARGTYPE key, VINARGTYPE value ) throw( ... );
  2514. void RBDeleteFixup(CNode* pNode) throw();
  2515. bool RBDelete(CNode* pZ) throw();
  2516. #ifdef _DEBUG
  2517. // internal debugging code to verify red-black properties of tree:
  2518. // 1) Every node is either red or black
  2519. // 2) Every leaf (NIL) is black
  2520. // 3) If a node is red, both its children are black
  2521. // 4) Every simple path from a node to a descendant leaf node contains
  2522. // the same number of black nodes
  2523. private:
  2524. void VerifyIntegrity(const CNode *pNode, int nCurrBlackDepth, int &nBlackDepth) const throw();
  2525. public:
  2526. void VerifyIntegrity() const throw();
  2527. #endif // _DEBUG
  2528. protected:
  2529. CNode* Minimum(CNode* pNode) const throw();
  2530. CNode* Maximum(CNode* pNode) const throw();
  2531. CNode* Predecessor( CNode* pNode ) const throw();
  2532. CNode* Successor(CNode* pNode) const throw();
  2533. CNode* RBInsert( KINARGTYPE key, VINARGTYPE value ) throw( ... );
  2534. CNode* Find(KINARGTYPE key) const throw();
  2535. CNode* FindPrefix( KINARGTYPE key ) const throw();
  2536. protected:
  2537. explicit CRBTree( size_t nBlockSize = 10 ) throw(); // protected to prevent instantiation
  2538. public:
  2539. ~CRBTree() throw();
  2540. void RemoveAll() throw();
  2541. void RemoveAt(POSITION pos) throw();
  2542. size_t GetCount() const throw();
  2543. bool IsEmpty() const throw();
  2544. POSITION FindFirstKeyAfter( KINARGTYPE key ) const throw();
  2545. POSITION GetHeadPosition() const throw();
  2546. POSITION GetTailPosition() const throw();
  2547. void GetNextAssoc( POSITION& pos, KOUTARGTYPE key, VOUTARGTYPE value ) const;
  2548. const CPair* GetNext(POSITION& pos) const throw();
  2549. CPair* GetNext(POSITION& pos) throw();
  2550. const CPair* GetPrev(POSITION& pos) const throw();
  2551. CPair* GetPrev(POSITION& pos) throw();
  2552. const K& GetNextKey(POSITION& pos) const throw();
  2553. const V& GetNextValue(POSITION& pos) const throw();
  2554. V& GetNextValue(POSITION& pos) throw();
  2555. CPair* GetAt( POSITION pos ) throw();
  2556. const CPair* GetAt( POSITION pos ) const throw();
  2557. void GetAt(POSITION pos, KOUTARGTYPE key, VOUTARGTYPE value) const;
  2558. const K& GetKeyAt(POSITION pos) const throw();
  2559. const V& GetValueAt(POSITION pos) const throw();
  2560. V& GetValueAt(POSITION pos) throw();
  2561. void SetValueAt(POSITION pos, VINARGTYPE value);
  2562. private:
  2563. // Private to prevent use
  2564. CRBTree( const CRBTree& ) throw();
  2565. CRBTree& operator=( const CRBTree& ) throw();
  2566. };
  2567. template< typename K, typename V, class KTraits, class VTraits >
  2568. inline bool CRBTree< K, V, KTraits, VTraits >::IsNil(CNode *p) const
  2569. {
  2570. return ( p == m_pNil );
  2571. }
  2572. template< typename K, typename V, class KTraits, class VTraits >
  2573. inline void CRBTree< K, V, KTraits, VTraits >::SetNil(CNode **p)
  2574. {
  2575. ATLASSERT( p != NULL );
  2576. *p = m_pNil;
  2577. }
  2578. template< typename K, typename V, class KTraits, class VTraits >
  2579. CRBTree< K, V, KTraits, VTraits >::CRBTree( size_t nBlockSize ) throw() :
  2580. m_pRoot( NULL ),
  2581. m_nCount( 0 ),
  2582. m_nBlockSize( nBlockSize ),
  2583. m_pFree( NULL ),
  2584. m_pBlocks( NULL ),
  2585. m_pNil( NULL )
  2586. {
  2587. ATLASSERT( nBlockSize > 0 );
  2588. }
  2589. template< typename K, typename V, class KTraits, class VTraits >
  2590. CRBTree< K, V, KTraits, VTraits >::~CRBTree() throw()
  2591. {
  2592. RemoveAll();
  2593. if (m_pNil != NULL)
  2594. {
  2595. free(m_pNil);
  2596. }
  2597. }
  2598. template< typename K, typename V, class KTraits, class VTraits >
  2599. void CRBTree< K, V, KTraits, VTraits >::RemoveAll() throw()
  2600. {
  2601. if (!IsNil(m_pRoot))
  2602. RemovePostOrder(m_pRoot);
  2603. m_nCount = 0;
  2604. m_pBlocks->FreeDataChain();
  2605. m_pBlocks = NULL;
  2606. m_pFree = NULL;
  2607. m_pRoot = m_pNil;
  2608. }
  2609. template< typename K, typename V, class KTraits, class VTraits >
  2610. size_t CRBTree< K, V, KTraits, VTraits >::GetCount() const throw()
  2611. {
  2612. return m_nCount;
  2613. }
  2614. template< typename K, typename V, class KTraits, class VTraits >
  2615. bool CRBTree< K, V, KTraits, VTraits >::IsEmpty() const throw()
  2616. {
  2617. return( m_nCount == 0 );
  2618. }
  2619. template< typename K, typename V, class KTraits, class VTraits >
  2620. POSITION CRBTree< K, V, KTraits, VTraits >::FindFirstKeyAfter( KINARGTYPE key ) const throw()
  2621. {
  2622. return( FindPrefix( key ) );
  2623. }
  2624. template< typename K, typename V, class KTraits, class VTraits >
  2625. void CRBTree< K, V, KTraits, VTraits >::RemoveAt(POSITION pos) throw()
  2626. {
  2627. ATLASSERT(pos != NULL);
  2628. RBDelete(static_cast<CNode*>(pos));
  2629. }
  2630. template< typename K, typename V, class KTraits, class VTraits >
  2631. POSITION CRBTree< K, V, KTraits, VTraits >::GetHeadPosition() const throw()
  2632. {
  2633. return( Minimum( m_pRoot ) );
  2634. }
  2635. template< typename K, typename V, class KTraits, class VTraits >
  2636. POSITION CRBTree< K, V, KTraits, VTraits >::GetTailPosition() const throw()
  2637. {
  2638. return( Maximum( m_pRoot ) );
  2639. }
  2640. template< typename K, typename V, class KTraits, class VTraits >
  2641. void CRBTree< K, V, KTraits, VTraits >::GetNextAssoc( POSITION& pos, KOUTARGTYPE key, VOUTARGTYPE value ) const
  2642. {
  2643. ATLASSERT(pos != NULL);
  2644. CNode* pNode = static_cast< CNode* >(pos);
  2645. key = pNode->m_key;
  2646. value = pNode->m_value;
  2647. pos = Successor(pNode);
  2648. }
  2649. template< typename K, typename V, class KTraits, class VTraits >
  2650. const CRBTree< K, V, KTraits, VTraits >::CPair* CRBTree< K, V, KTraits, VTraits >::GetNext(POSITION& pos) const throw()
  2651. {
  2652. ATLASSERT(pos != NULL);
  2653. CNode* pNode = static_cast< CNode* >(pos);
  2654. pos = Successor(pNode);
  2655. return pNode;
  2656. }
  2657. template< typename K, typename V, class KTraits, class VTraits >
  2658. CRBTree< K, V, KTraits, VTraits >::CPair* CRBTree< K, V, KTraits, VTraits >::GetNext(POSITION& pos) throw()
  2659. {
  2660. ATLASSERT(pos != NULL);
  2661. CNode* pNode = static_cast< CNode* >(pos);
  2662. pos = Successor(pNode);
  2663. return pNode;
  2664. }
  2665. template< typename K, typename V, class KTraits, class VTraits >
  2666. const CRBTree< K, V, KTraits, VTraits >::CPair* CRBTree< K, V, KTraits, VTraits >::GetPrev(POSITION& pos) const throw()
  2667. {
  2668. ATLASSERT(pos != NULL);
  2669. CNode* pNode = static_cast< CNode* >(pos);
  2670. pos = Predecessor(pNode);
  2671. return pNode;
  2672. }
  2673. template< typename K, typename V, class KTraits, class VTraits >
  2674. CRBTree< K, V, KTraits, VTraits >::CPair* CRBTree< K, V, KTraits, VTraits >::GetPrev(POSITION& pos) throw()
  2675. {
  2676. ATLASSERT(pos != NULL);
  2677. CNode* pNode = static_cast< CNode* >(pos);
  2678. pos = Predecessor(pNode);
  2679. return pNode;
  2680. }
  2681. template< typename K, typename V, class KTraits, class VTraits >
  2682. const K& CRBTree< K, V, KTraits, VTraits >::GetNextKey(POSITION& pos) const throw()
  2683. {
  2684. ATLASSERT(pos != NULL);
  2685. CNode* pNode = static_cast<CNode*>(pos);
  2686. pos = Successor(pNode);
  2687. return pNode->m_key;
  2688. }
  2689. template< typename K, typename V, class KTraits, class VTraits >
  2690. const V& CRBTree< K, V, KTraits, VTraits >::GetNextValue(POSITION& pos) const throw()
  2691. {
  2692. ATLASSERT(pos != NULL);
  2693. CNode* pNode = static_cast<CNode*>(pos);
  2694. pos = Successor(pNode);
  2695. return pNode->m_value;
  2696. }
  2697. template< typename K, typename V, class KTraits, class VTraits >
  2698. V& CRBTree< K, V, KTraits, VTraits >::GetNextValue(POSITION& pos) throw()
  2699. {
  2700. ATLASSERT(pos != NULL);
  2701. CNode* pNode = static_cast<CNode*>(pos);
  2702. pos = Successor(pNode);
  2703. return pNode->m_value;
  2704. }
  2705. template< typename K, typename V, class KTraits, class VTraits >
  2706. CRBTree< K, V, KTraits, VTraits >::CPair* CRBTree< K, V, KTraits, VTraits >::GetAt( POSITION pos ) throw()
  2707. {
  2708. ATLASSERT( pos != NULL );
  2709. return( static_cast< CPair* >( pos ) );
  2710. }
  2711. template< typename K, typename V, class KTraits, class VTraits >
  2712. const CRBTree< K, V, KTraits, VTraits >::CPair* CRBTree< K, V, KTraits, VTraits >::GetAt( POSITION pos ) const throw()
  2713. {
  2714. ATLASSERT( pos != NULL );
  2715. return( static_cast< const CPair* >( pos ) );
  2716. }
  2717. template< typename K, typename V, class KTraits, class VTraits >
  2718. void CRBTree< K, V, KTraits, VTraits >::GetAt(POSITION pos, KOUTARGTYPE key, VOUTARGTYPE value) const
  2719. {
  2720. ATLASSERT(pos != NULL);
  2721. key = static_cast<CNode*>(pos)->m_key;
  2722. value = static_cast<CNode*>(pos)->m_value;
  2723. }
  2724. template< typename K, typename V, class KTraits, class VTraits >
  2725. const K& CRBTree< K, V, KTraits, VTraits >::GetKeyAt(POSITION pos) const throw()
  2726. {
  2727. ATLASSERT(pos != NULL);
  2728. return static_cast<CNode*>(pos)->m_key;
  2729. }
  2730. template< typename K, typename V, class KTraits, class VTraits >
  2731. const V& CRBTree< K, V, KTraits, VTraits >::GetValueAt(POSITION pos) const throw()
  2732. {
  2733. ATLASSERT(pos != NULL);
  2734. return static_cast<CNode*>(pos)->m_value;
  2735. }
  2736. template< typename K, typename V, class KTraits, class VTraits >
  2737. V& CRBTree< K, V, KTraits, VTraits >::GetValueAt(POSITION pos) throw()
  2738. {
  2739. ATLASSERT(pos != NULL);
  2740. return static_cast<CNode*>(pos)->m_value;
  2741. }
  2742. template< typename K, typename V, class KTraits, class VTraits >
  2743. void CRBTree< K, V, KTraits, VTraits >::SetValueAt(POSITION pos, VINARGTYPE value)
  2744. {
  2745. ATLASSERT(pos != NULL);
  2746. static_cast<CNode*>(pos)->m_value = value;
  2747. }
  2748. template< typename K, typename V, class KTraits, class VTraits >
  2749. CRBTree< K, V, KTraits, VTraits >::CNode* CRBTree< K, V, KTraits, VTraits >::NewNode( KINARGTYPE key, VINARGTYPE value ) throw( ... )
  2750. {
  2751. if( m_pFree == NULL )
  2752. {
  2753. if (m_pNil == NULL)
  2754. {
  2755. m_pNil = reinterpret_cast<CNode *>(malloc(sizeof( CNode )));
  2756. if (m_pNil == NULL)
  2757. {
  2758. AtlThrow( E_OUTOFMEMORY );
  2759. }
  2760. memset(m_pNil, 0x00, sizeof(CNode));
  2761. m_pNil->m_eColor = CNode::RB_BLACK;
  2762. m_pNil->m_pParent = m_pNil->m_pLeft = m_pNil->m_pRight = m_pNil;
  2763. m_pRoot = m_pNil;
  2764. }
  2765. CAtlPlex* pPlex = CAtlPlex::Create( m_pBlocks, m_nBlockSize, sizeof( CNode ) );
  2766. if( pPlex == NULL )
  2767. {
  2768. AtlThrow( E_OUTOFMEMORY );
  2769. }
  2770. CNode* pNode = static_cast< CNode* >( pPlex->data() );
  2771. pNode += m_nBlockSize-1;
  2772. for( INT_PTR iBlock = m_nBlockSize-1; iBlock >= 0; iBlock-- )
  2773. {
  2774. pNode->m_pLeft = m_pFree;
  2775. m_pFree = pNode;
  2776. pNode--;
  2777. }
  2778. }
  2779. ATLASSERT( m_pFree != NULL );
  2780. CNode* pNewNode = m_pFree;
  2781. ::new( pNewNode ) CNode( key, value );
  2782. m_pFree = m_pFree->m_pLeft;
  2783. pNewNode->m_eColor = CNode::RB_RED;
  2784. SetNil(&pNewNode->m_pLeft);
  2785. SetNil(&pNewNode->m_pRight);
  2786. SetNil(&pNewNode->m_pParent);
  2787. m_nCount++;
  2788. ATLASSERT( m_nCount > 0 );
  2789. return( pNewNode );
  2790. }
  2791. template< typename K, typename V, class KTraits, class VTraits >
  2792. void CRBTree< K, V, KTraits, VTraits >::FreeNode(CNode* pNode) throw()
  2793. {
  2794. ATLASSERT(pNode != NULL);
  2795. pNode->~CNode();
  2796. pNode->m_pLeft = m_pFree;
  2797. m_pFree = pNode;
  2798. ATLASSERT( m_nCount > 0 );
  2799. m_nCount--;
  2800. }
  2801. template< typename K, typename V, class KTraits, class VTraits >
  2802. void CRBTree< K, V, KTraits, VTraits >::RemovePostOrder(CNode* pNode) throw()
  2803. {
  2804. if (IsNil(pNode))
  2805. return;
  2806. RemovePostOrder(pNode->m_pLeft);
  2807. RemovePostOrder(pNode->m_pRight);
  2808. FreeNode( pNode );
  2809. }
  2810. template< typename K, typename V, class KTraits, class VTraits >
  2811. CRBTree< K, V, KTraits, VTraits >::CNode* CRBTree< K, V, KTraits, VTraits >::LeftRotate(CNode* pNode) throw()
  2812. {
  2813. ATLASSERT(pNode != NULL);
  2814. CNode* pRight = pNode->m_pRight;
  2815. pNode->m_pRight = pRight->m_pLeft;
  2816. if (!IsNil(pRight->m_pLeft))
  2817. pRight->m_pLeft->m_pParent = pNode;
  2818. pRight->m_pParent = pNode->m_pParent;
  2819. if (IsNil(pNode->m_pParent))
  2820. m_pRoot = pRight;
  2821. else if (pNode == pNode->m_pParent->m_pLeft)
  2822. pNode->m_pParent->m_pLeft = pRight;
  2823. else
  2824. pNode->m_pParent->m_pRight = pRight;
  2825. pRight->m_pLeft = pNode;
  2826. pNode->m_pParent = pRight;
  2827. return pNode;
  2828. }
  2829. template< typename K, typename V, class KTraits, class VTraits >
  2830. CRBTree< K, V, KTraits, VTraits >::CNode* CRBTree< K, V, KTraits, VTraits >::RightRotate(CNode* pNode) throw()
  2831. {
  2832. ATLASSERT(pNode != NULL);
  2833. CNode* pLeft = pNode->m_pLeft;
  2834. pNode->m_pLeft = pLeft->m_pRight;
  2835. if (!IsNil(pLeft->m_pRight))
  2836. pLeft->m_pRight->m_pParent = pNode;
  2837. pLeft->m_pParent = pNode->m_pParent;
  2838. if (IsNil(pNode->m_pParent))
  2839. m_pRoot = pLeft;
  2840. else if (pNode == pNode->m_pParent->m_pRight)
  2841. pNode->m_pParent->m_pRight = pLeft;
  2842. else
  2843. pNode->m_pParent->m_pLeft = pLeft;
  2844. pLeft->m_pRight = pNode;
  2845. pNode->m_pParent = pLeft;
  2846. return pNode;
  2847. }
  2848. template< typename K, typename V, class KTraits, class VTraits >
  2849. CRBTree< K, V, KTraits, VTraits >::CNode* CRBTree< K, V, KTraits, VTraits >::Find(KINARGTYPE key) const throw()
  2850. {
  2851. CNode* pKey = NULL;
  2852. CNode* pNode = m_pRoot;
  2853. while( !IsNil(pNode) && (pKey == NULL) )
  2854. {
  2855. int nCompare = KTraits::CompareElementsOrdered( key, pNode->m_key );
  2856. if( nCompare == 0 )
  2857. {
  2858. pKey = pNode;
  2859. }
  2860. else
  2861. {
  2862. if( nCompare < 0 )
  2863. {
  2864. pNode = pNode->m_pLeft;
  2865. }
  2866. else
  2867. {
  2868. pNode = pNode->m_pRight;
  2869. }
  2870. }
  2871. }
  2872. if( pKey == NULL )
  2873. {
  2874. return( NULL );
  2875. }
  2876. #pragma warning(push)
  2877. #pragma warning(disable:4127)
  2878. while( true )
  2879. {
  2880. CNode* pPrev = Predecessor( pKey );
  2881. if( (pPrev != NULL) && KTraits::CompareElements( key, pPrev->m_key ) )
  2882. {
  2883. pKey = pPrev;
  2884. }
  2885. else
  2886. {
  2887. return( pKey );
  2888. }
  2889. }
  2890. #pragma warning(pop)
  2891. }
  2892. template< typename K, typename V, class KTraits, class VTraits >
  2893. CRBTree< K, V, KTraits, VTraits >::CNode* CRBTree< K, V, KTraits, VTraits >::FindPrefix( KINARGTYPE key ) const throw()
  2894. {
  2895. // First, attempt to find a node that matches the key exactly
  2896. CNode* pParent = NULL;
  2897. CNode* pKey = NULL;
  2898. CNode* pNode = m_pRoot;
  2899. while( !IsNil(pNode) && (pKey == NULL) )
  2900. {
  2901. pParent = pNode;
  2902. int nCompare = KTraits::CompareElementsOrdered( key, pNode->m_key );
  2903. if( nCompare == 0 )
  2904. {
  2905. pKey = pNode;
  2906. }
  2907. else if( nCompare < 0 )
  2908. {
  2909. pNode = pNode->m_pLeft;
  2910. }
  2911. else
  2912. {
  2913. pNode = pNode->m_pRight;
  2914. }
  2915. }
  2916. if( pKey != NULL )
  2917. {
  2918. // We found a node with the exact key, so find the first node in
  2919. // the tree with that key by walking backwards until we find a node
  2920. // that doesn't match the key
  2921. while( true )
  2922. {
  2923. CNode* pPrev = Predecessor( pKey );
  2924. if( (pPrev != NULL) && KTraits::CompareElements( key, pPrev->m_key ) )
  2925. {
  2926. pKey = pPrev;
  2927. }
  2928. else
  2929. {
  2930. return( pKey );
  2931. }
  2932. }
  2933. }
  2934. else if (pParent != NULL)
  2935. {
  2936. // No node matched the key exactly, so pick the first node with
  2937. // a key greater than the given key
  2938. int nCompare = KTraits::CompareElementsOrdered( key, pParent->m_key );
  2939. if( nCompare < 0 )
  2940. {
  2941. pKey = pParent;
  2942. }
  2943. else
  2944. {
  2945. ATLASSERT( nCompare > 0 );
  2946. pKey = Successor( pParent );
  2947. }
  2948. }
  2949. return( pKey );
  2950. }
  2951. template< typename K, typename V, class KTraits, class VTraits >
  2952. void CRBTree< K, V, KTraits, VTraits >::SwapNode(CNode* pDest, CNode* pSrc) throw()
  2953. {
  2954. ATLASSERT(pDest != NULL);
  2955. ATLASSERT(pSrc != NULL);
  2956. pDest->m_pParent = pSrc->m_pParent;
  2957. if (pSrc->m_pParent->m_pLeft == pSrc)
  2958. pSrc->m_pParent->m_pLeft = pDest;
  2959. else
  2960. pSrc->m_pParent->m_pRight = pDest;
  2961. pDest->m_pRight = pSrc->m_pRight;
  2962. pDest->m_pLeft = pSrc->m_pLeft;
  2963. pDest->m_eColor = pSrc->m_eColor;
  2964. pDest->m_pRight->m_pParent = pDest;
  2965. pDest->m_pLeft->m_pParent = pDest;
  2966. if (m_pRoot == pSrc)
  2967. {
  2968. m_pRoot = pDest;
  2969. }
  2970. }
  2971. template< typename K, typename V, class KTraits, class VTraits >
  2972. CRBTree< K, V, KTraits, VTraits >::CNode* CRBTree< K, V, KTraits, VTraits >::InsertImpl( KINARGTYPE key, VINARGTYPE value ) throw( ... )
  2973. {
  2974. CNode* pNew = NewNode( key, value );
  2975. CNode* pY = NULL;
  2976. CNode* pX = m_pRoot;
  2977. while (!IsNil(pX))
  2978. {
  2979. pY = pX;
  2980. if( KTraits::CompareElementsOrdered( key, pX->m_key ) <= 0 )
  2981. pX = pX->m_pLeft;
  2982. else
  2983. pX = pX->m_pRight;
  2984. }
  2985. pNew->m_pParent = pY;
  2986. if (pY == NULL)
  2987. {
  2988. m_pRoot = pNew;
  2989. }
  2990. else if( KTraits::CompareElementsOrdered( key, pY->m_key ) <= 0 )
  2991. pY->m_pLeft = pNew;
  2992. else
  2993. pY->m_pRight = pNew;
  2994. return pNew;
  2995. }
  2996. template< typename K, typename V, class KTraits, class VTraits >
  2997. void CRBTree< K, V, KTraits, VTraits >::RBDeleteFixup(CNode* pNode) throw()
  2998. {
  2999. CNode* pX = pNode;
  3000. CNode* pW = NULL;
  3001. while (pX != m_pRoot && pX->m_eColor == CNode::RB_BLACK)
  3002. {
  3003. if (pX == pX->m_pParent->m_pLeft)
  3004. {
  3005. pW = pX->m_pParent->m_pRight;
  3006. if (pW->m_eColor == CNode::RB_RED)
  3007. {
  3008. pW->m_eColor = CNode::RB_BLACK;
  3009. pW->m_pParent->m_eColor = CNode::RB_RED;
  3010. LeftRotate(pX->m_pParent);
  3011. pW = pX->m_pParent->m_pRight;
  3012. }
  3013. if (pW->m_pLeft->m_eColor == CNode::RB_BLACK && pW->m_pRight->m_eColor == CNode::RB_BLACK)
  3014. {
  3015. pW->m_eColor = CNode::RB_RED;
  3016. pX = pX->m_pParent;
  3017. }
  3018. else
  3019. {
  3020. if (pW->m_pRight->m_eColor == CNode::RB_BLACK)
  3021. {
  3022. pW->m_pLeft->m_eColor = CNode::RB_BLACK;
  3023. pW->m_eColor = CNode::RB_RED;
  3024. RightRotate(pW);
  3025. pW = pX->m_pParent->m_pRight;
  3026. }
  3027. pW->m_eColor = pX->m_pParent->m_eColor;
  3028. pX->m_pParent->m_eColor = CNode::RB_BLACK;
  3029. pW->m_pRight->m_eColor = CNode::RB_BLACK;
  3030. LeftRotate(pX->m_pParent);
  3031. pX = m_pRoot;
  3032. }
  3033. }
  3034. else
  3035. {
  3036. pW = pX->m_pParent->m_pLeft;
  3037. if (pW->m_eColor == CNode::RB_RED)
  3038. {
  3039. pW->m_eColor = CNode::RB_BLACK;
  3040. pW->m_pParent->m_eColor = CNode::RB_RED;
  3041. RightRotate(pX->m_pParent);
  3042. pW = pX->m_pParent->m_pLeft;
  3043. }
  3044. if (pW->m_pRight->m_eColor == CNode::RB_BLACK && pW->m_pLeft->m_eColor == CNode::RB_BLACK)
  3045. {
  3046. pW->m_eColor = CNode::RB_RED;
  3047. pX = pX->m_pParent;
  3048. }
  3049. else
  3050. {
  3051. if (pW->m_pLeft->m_eColor == CNode::RB_BLACK)
  3052. {
  3053. pW->m_pRight->m_eColor = CNode::RB_BLACK;
  3054. pW->m_eColor = CNode::RB_RED;
  3055. LeftRotate(pW);
  3056. pW = pX->m_pParent->m_pLeft;
  3057. }
  3058. pW->m_eColor = pX->m_pParent->m_eColor;
  3059. pX->m_pParent->m_eColor = CNode::RB_BLACK;
  3060. pW->m_pLeft->m_eColor = CNode::RB_BLACK;
  3061. RightRotate(pX->m_pParent);
  3062. pX = m_pRoot;
  3063. }
  3064. }
  3065. }
  3066. pX->m_eColor = CNode::RB_BLACK;
  3067. }
  3068. template< typename K, typename V, class KTraits, class VTraits >
  3069. bool CRBTree< K, V, KTraits, VTraits >::RBDelete(CNode* pZ) throw()
  3070. {
  3071. if (pZ == NULL)
  3072. return false;
  3073. CNode* pY = NULL;
  3074. CNode* pX = NULL;
  3075. if (IsNil(pZ->m_pLeft) || IsNil(pZ->m_pRight))
  3076. pY = pZ;
  3077. else
  3078. pY = Successor(pZ);
  3079. if (!IsNil(pY->m_pLeft))
  3080. pX = pY->m_pLeft;
  3081. else
  3082. pX = pY->m_pRight;
  3083. pX->m_pParent = pY->m_pParent;
  3084. if (IsNil(pY->m_pParent))
  3085. m_pRoot = pX;
  3086. else if (pY == pY->m_pParent->m_pLeft)
  3087. pY->m_pParent->m_pLeft = pX;
  3088. else
  3089. pY->m_pParent->m_pRight = pX;
  3090. if (pY->m_eColor == CNode::RB_BLACK)
  3091. RBDeleteFixup(pX);
  3092. if (pY != pZ)
  3093. SwapNode(pY, pZ);
  3094. if (m_pRoot != NULL)
  3095. SetNil(&m_pRoot->m_pParent);
  3096. FreeNode( pZ );
  3097. return true;
  3098. }
  3099. template< typename K, typename V, class KTraits, class VTraits >
  3100. CRBTree< K, V, KTraits, VTraits >::CNode* CRBTree< K, V, KTraits, VTraits >::Minimum(CNode* pNode) const throw()
  3101. {
  3102. if (pNode == NULL || IsNil(pNode))
  3103. {
  3104. return NULL;
  3105. }
  3106. CNode* pMin = pNode;
  3107. while (!IsNil(pMin->m_pLeft))
  3108. {
  3109. pMin = pMin->m_pLeft;
  3110. }
  3111. return pMin;
  3112. }
  3113. template< typename K, typename V, class KTraits, class VTraits >
  3114. CRBTree< K, V, KTraits, VTraits >::CNode* CRBTree< K, V, KTraits, VTraits >::Maximum(CNode* pNode) const throw()
  3115. {
  3116. if (pNode == NULL || IsNil(pNode))
  3117. {
  3118. return NULL;
  3119. }
  3120. CNode* pMax = pNode;
  3121. while (!IsNil(pMax->m_pRight))
  3122. {
  3123. pMax = pMax->m_pRight;
  3124. }
  3125. return pMax;
  3126. }
  3127. template< typename K, typename V, class KTraits, class VTraits >
  3128. CRBTree< K, V, KTraits, VTraits >::CNode* CRBTree< K, V, KTraits, VTraits >::Predecessor( CNode* pNode ) const throw()
  3129. {
  3130. if( pNode == NULL )
  3131. {
  3132. return( NULL );
  3133. }
  3134. if( !IsNil(pNode->m_pLeft) )
  3135. {
  3136. return( Maximum( pNode->m_pLeft ) );
  3137. }
  3138. CNode* pParent = pNode->m_pParent;
  3139. CNode* pLeft = pNode;
  3140. while( !IsNil(pParent) && (pLeft == pParent->m_pLeft) )
  3141. {
  3142. pLeft = pParent;
  3143. pParent = pParent->m_pParent;
  3144. }
  3145. if (IsNil(pParent))
  3146. {
  3147. pParent = NULL;
  3148. }
  3149. return( pParent );
  3150. }
  3151. template< typename K, typename V, class KTraits, class VTraits >
  3152. CRBTree< K, V, KTraits, VTraits >::CNode* CRBTree< K, V, KTraits, VTraits >::Successor(CNode* pNode) const throw()
  3153. {
  3154. if ( pNode == NULL )
  3155. {
  3156. return NULL;
  3157. }
  3158. if ( !IsNil(pNode->m_pRight) )
  3159. {
  3160. return Minimum(pNode->m_pRight);
  3161. }
  3162. CNode* pParent = pNode->m_pParent;
  3163. CNode* pRight = pNode;
  3164. while ( !IsNil(pParent) && (pRight == pParent->m_pRight) )
  3165. {
  3166. pRight = pParent;
  3167. pParent = pParent->m_pParent;
  3168. }
  3169. if (IsNil(pParent))
  3170. {
  3171. pParent = NULL;
  3172. }
  3173. return pParent;
  3174. }
  3175. template< typename K, typename V, class KTraits, class VTraits >
  3176. CRBTree< K, V, KTraits, VTraits >::CNode* CRBTree< K, V, KTraits, VTraits >::RBInsert( KINARGTYPE key, VINARGTYPE value ) throw( ... )
  3177. {
  3178. CNode* pNewNode = InsertImpl( key, value );
  3179. CNode* pX = pNewNode;
  3180. pX->m_eColor = CNode::RB_RED;
  3181. CNode* pY = NULL;
  3182. while (pX != m_pRoot && pX->m_pParent->m_eColor == CNode::RB_RED)
  3183. {
  3184. if (pX->m_pParent == pX->m_pParent->m_pParent->m_pLeft)
  3185. {
  3186. pY = pX->m_pParent->m_pParent->m_pRight;
  3187. if (pY != NULL && pY->m_eColor == CNode::RB_RED)
  3188. {
  3189. pX->m_pParent->m_eColor = CNode::RB_BLACK;
  3190. pY->m_eColor = CNode::RB_BLACK;
  3191. pX->m_pParent->m_pParent->m_eColor = CNode::RB_RED;
  3192. pX = pX->m_pParent->m_pParent;
  3193. }
  3194. else
  3195. {
  3196. if (pX == pX->m_pParent->m_pRight)
  3197. {
  3198. pX = pX->m_pParent;
  3199. LeftRotate(pX);
  3200. }
  3201. pX->m_pParent->m_eColor = CNode::RB_BLACK;
  3202. pX->m_pParent->m_pParent->m_eColor = CNode::RB_RED;
  3203. RightRotate(pX->m_pParent->m_pParent);
  3204. }
  3205. }
  3206. else
  3207. {
  3208. pY = pX->m_pParent->m_pParent->m_pLeft;
  3209. if (pY != NULL && pY->m_eColor == CNode::RB_RED)
  3210. {
  3211. pX->m_pParent->m_eColor = CNode::RB_BLACK;
  3212. pY->m_eColor = CNode::RB_BLACK;
  3213. pX->m_pParent->m_pParent->m_eColor = CNode::RB_RED;
  3214. pX = pX->m_pParent->m_pParent;
  3215. }
  3216. else
  3217. {
  3218. if (pX == pX->m_pParent->m_pLeft)
  3219. {
  3220. pX = pX->m_pParent;
  3221. RightRotate(pX);
  3222. }
  3223. pX->m_pParent->m_eColor = CNode::RB_BLACK;
  3224. pX->m_pParent->m_pParent->m_eColor = CNode::RB_RED;
  3225. LeftRotate(pX->m_pParent->m_pParent);
  3226. }
  3227. }
  3228. }
  3229. m_pRoot->m_eColor = CNode::RB_BLACK;
  3230. SetNil(&m_pRoot->m_pParent);
  3231. return( pNewNode );
  3232. }
  3233. #ifdef _DEBUG
  3234. template< typename K, typename V, class KTraits, class VTraits >
  3235. void CRBTree< K, V, KTraits, VTraits >::VerifyIntegrity(const CNode *pNode, int nCurrBlackDepth, int &nBlackDepth) const
  3236. {
  3237. bool bCheckForBlack = false;
  3238. bool bLeaf = true;
  3239. if (pNode->m_eColor == CNode::RB_RED)
  3240. bCheckForBlack = true;
  3241. else
  3242. nCurrBlackDepth++;
  3243. ATLASSERT(pNode->m_pLeft != NULL);
  3244. if (!IsNil(pNode->m_pLeft))
  3245. {
  3246. bLeaf = false;
  3247. if (bCheckForBlack)
  3248. {
  3249. ATLASSERT(pNode->m_pLeft->m_eColor == CNode::RB_BLACK);
  3250. }
  3251. VerifyIntegrity(pNode->m_pLeft, nCurrBlackDepth, nBlackDepth);
  3252. }
  3253. ATLASSERT(pNode->m_pRight != NULL);
  3254. if (!IsNil(pNode->m_pRight))
  3255. {
  3256. bLeaf = false;
  3257. if (bCheckForBlack)
  3258. {
  3259. ATLASSERT(pNode->m_pRight->m_eColor == CNode::RB_BLACK);
  3260. }
  3261. VerifyIntegrity(pNode->m_pRight, nCurrBlackDepth, nBlackDepth);
  3262. }
  3263. ATLASSERT( pNode->m_pParent != NULL );
  3264. ATLASSERT( ( IsNil(pNode->m_pParent) ) ||
  3265. ( pNode->m_pParent->m_pLeft == pNode ) ||
  3266. ( pNode->m_pParent->m_pRight == pNode ) );
  3267. if (bLeaf)
  3268. {
  3269. if (nBlackDepth == 0)
  3270. {
  3271. nBlackDepth = nCurrBlackDepth;
  3272. }
  3273. else
  3274. {
  3275. ATLASSERT(nBlackDepth == nCurrBlackDepth);
  3276. }
  3277. }
  3278. }
  3279. template< typename K, typename V, class KTraits, class VTraits >
  3280. void CRBTree< K, V, KTraits, VTraits >::VerifyIntegrity() const
  3281. {
  3282. if ((m_pRoot == NULL) || (IsNil(m_pRoot)))
  3283. return;
  3284. ATLASSERT(m_pRoot->m_eColor == CNode::RB_BLACK);
  3285. int nBlackDepth = 0;
  3286. VerifyIntegrity(m_pRoot, 0, nBlackDepth);
  3287. }
  3288. #endif // _DEBUG
  3289. template< typename K, typename V, class KTraits = CElementTraits< K >, class VTraits = CElementTraits< V > >
  3290. class CRBMap :
  3291. public CRBTree< K, V, KTraits, VTraits >
  3292. {
  3293. public:
  3294. explicit CRBMap( size_t nBlockSize = 10 ) throw();
  3295. ~CRBMap() throw();
  3296. bool Lookup( KINARGTYPE key, VOUTARGTYPE value ) const throw( ... );
  3297. const CPair* Lookup( KINARGTYPE key ) const throw();
  3298. CPair* Lookup( KINARGTYPE key ) throw();
  3299. POSITION SetAt( KINARGTYPE key, VINARGTYPE value ) throw( ... );
  3300. bool RemoveKey( KINARGTYPE key ) throw();
  3301. };
  3302. template< typename K, typename V, class KTraits, class VTraits >
  3303. CRBMap< K, V, KTraits, VTraits >::CRBMap( size_t nBlockSize ) throw() :
  3304. CRBTree< K, V, KTraits, VTraits >( nBlockSize )
  3305. {
  3306. }
  3307. template< typename K, typename V, class KTraits, class VTraits >
  3308. CRBMap< K, V, KTraits, VTraits >::~CRBMap() throw()
  3309. {
  3310. }
  3311. template< typename K, typename V, class KTraits, class VTraits >
  3312. const CRBMap< K, V, KTraits, VTraits >::CPair* CRBMap< K, V, KTraits, VTraits >::Lookup( KINARGTYPE key ) const throw()
  3313. {
  3314. return Find(key);
  3315. }
  3316. template< typename K, typename V, class KTraits, class VTraits >
  3317. CRBMap< K, V, KTraits, VTraits >::CPair* CRBMap< K, V, KTraits, VTraits >::Lookup( KINARGTYPE key ) throw()
  3318. {
  3319. return Find(key);
  3320. }
  3321. template< typename K, typename V, class KTraits, class VTraits >
  3322. bool CRBMap< K, V, KTraits, VTraits >::Lookup( KINARGTYPE key, VOUTARGTYPE value ) const throw( ... )
  3323. {
  3324. const CPair* pLookup = Find( key );
  3325. if( pLookup == NULL )
  3326. return false;
  3327. value = pLookup->m_value;
  3328. return true;
  3329. }
  3330. template< typename K, typename V, class KTraits, class VTraits >
  3331. POSITION CRBMap< K, V, KTraits, VTraits >::SetAt( KINARGTYPE key, VINARGTYPE value ) throw( ... )
  3332. {
  3333. CPair* pNode = Find( key );
  3334. if( pNode == NULL )
  3335. {
  3336. return( RBInsert( key, value ) );
  3337. }
  3338. else
  3339. {
  3340. pNode->m_value = value;
  3341. return( pNode );
  3342. }
  3343. }
  3344. template< typename K, typename V, class KTraits, class VTraits >
  3345. bool CRBMap< K, V, KTraits, VTraits >::RemoveKey( KINARGTYPE key ) throw()
  3346. {
  3347. POSITION pos = Lookup( key );
  3348. if( pos != NULL )
  3349. {
  3350. RemoveAt( pos );
  3351. return( true );
  3352. }
  3353. else
  3354. {
  3355. return( false );
  3356. }
  3357. }
  3358. template< typename K, typename V, class KTraits = CElementTraits< K >, class VTraits = CElementTraits< V > >
  3359. class CRBMultiMap :
  3360. public CRBTree< K, V, KTraits, VTraits >
  3361. {
  3362. public:
  3363. explicit CRBMultiMap( size_t nBlockSize = 10 ) throw();
  3364. ~CRBMultiMap() throw();
  3365. POSITION Insert( KINARGTYPE key, VINARGTYPE value ) throw( ... );
  3366. size_t RemoveKey( KINARGTYPE key ) throw();
  3367. POSITION FindFirstWithKey( KINARGTYPE key ) const throw();
  3368. const CPair* GetNextWithKey( POSITION& pos, KINARGTYPE key ) const throw();
  3369. CPair* GetNextWithKey( POSITION& pos, KINARGTYPE key ) throw();
  3370. const V& GetNextValueWithKey( POSITION& pos, KINARGTYPE key ) const throw();
  3371. V& GetNextValueWithKey( POSITION& pos, KINARGTYPE key ) throw();
  3372. };
  3373. template< typename K, typename V, class KTraits, class VTraits >
  3374. CRBMultiMap< K, V, KTraits, VTraits >::CRBMultiMap( size_t nBlockSize ) throw() :
  3375. CRBTree< K, V, KTraits, VTraits >( nBlockSize )
  3376. {
  3377. }
  3378. template< typename K, typename V, class KTraits, class VTraits >
  3379. CRBMultiMap< K, V, KTraits, VTraits >::~CRBMultiMap() throw()
  3380. {
  3381. }
  3382. template< typename K, typename V, class KTraits, class VTraits >
  3383. POSITION CRBMultiMap< K, V, KTraits, VTraits >::Insert( KINARGTYPE key, VINARGTYPE value ) throw( ... )
  3384. {
  3385. return( RBInsert( key, value ) );
  3386. }
  3387. template< typename K, typename V, class KTraits, class VTraits >
  3388. size_t CRBMultiMap< K, V, KTraits, VTraits >::RemoveKey( KINARGTYPE key ) throw()
  3389. {
  3390. size_t nElementsDeleted = 0;
  3391. POSITION pos = FindFirstWithKey( key );
  3392. while( pos != NULL )
  3393. {
  3394. POSITION posDelete = pos;
  3395. GetNextWithKey( pos, key );
  3396. RemoveAt( posDelete );
  3397. nElementsDeleted++;
  3398. }
  3399. return( nElementsDeleted );
  3400. }
  3401. template< typename K, typename V, class KTraits, class VTraits >
  3402. POSITION CRBMultiMap< K, V, KTraits, VTraits >::FindFirstWithKey( KINARGTYPE key ) const throw()
  3403. {
  3404. return( Find( key ) );
  3405. }
  3406. template< typename K, typename V, class KTraits, class VTraits >
  3407. const CRBMultiMap< K, V, KTraits, VTraits >::CPair* CRBMultiMap< K, V, KTraits, VTraits >::GetNextWithKey( POSITION& pos, KINARGTYPE key ) const throw()
  3408. {
  3409. ATLASSERT( pos != NULL );
  3410. const CPair* pNode = GetNext( pos );
  3411. if( (pos == NULL) || !KTraits::CompareElements( static_cast< CPair* >( pos )->m_key, key ) )
  3412. {
  3413. pos = NULL;
  3414. }
  3415. return( pNode );
  3416. }
  3417. template< typename K, typename V, class KTraits, class VTraits >
  3418. CRBMultiMap< K, V, KTraits, VTraits >::CPair* CRBMultiMap< K, V, KTraits, VTraits >::GetNextWithKey( POSITION& pos, KINARGTYPE key ) throw()
  3419. {
  3420. ATLASSERT( pos != NULL );
  3421. CPair* pNode = GetNext( pos );
  3422. if( (pos == NULL) || !KTraits::CompareElements( static_cast< CPair* >( pos )->m_key, key ) )
  3423. {
  3424. pos = NULL;
  3425. }
  3426. return( pNode );
  3427. }
  3428. template< typename K, typename V, class KTraits, class VTraits >
  3429. const V& CRBMultiMap< K, V, KTraits, VTraits >::GetNextValueWithKey( POSITION& pos, KINARGTYPE key ) const throw()
  3430. {
  3431. const CPair* pPair = GetNextWithKey( pos, key );
  3432. return( pPair->m_value );
  3433. }
  3434. template< typename K, typename V, class KTraits, class VTraits >
  3435. V& CRBMultiMap< K, V, KTraits, VTraits >::GetNextValueWithKey( POSITION& pos, KINARGTYPE key ) throw()
  3436. {
  3437. CPair* pPair = GetNextWithKey( pos, key );
  3438. return( pPair->m_value );
  3439. }
  3440. #pragma pop_macro("new")
  3441. }; // namespace ATL
  3442. //REVIEW: Just to fix VSEE
  3443. #pragma pop_macro("min")
  3444. #pragma pop_macro("max")
  3445. #pragma warning(pop)
  3446. #endif // __ATLCOLL_H__