"L. Spiro Engine"
|
00001 00020 #ifndef __LSTL_MULTIMAP_H__ 00021 #define __LSTL_MULTIMAP_H__ 00022 00023 #include "../LSTLib.h" 00024 #include "../Algorithm/LSTLAlgorithm.h" 00025 #include "../Vector/LSTLVector.h" 00026 #include "LSTLMultiMapBase.h" 00027 00028 #pragma warning( push ) 00029 00030 // warning C4127: conditional expression is constant 00031 #pragma warning( disable : 4127 ) 00032 00033 namespace lstl { 00034 00045 template <typename _tKeyType, typename _tMappedType> 00046 class CMultiMap : protected CMultiMapBase { 00047 // All is public. This class has no secrets. 00048 public : 00049 // == Various constructors. 00050 LSE_CALL CMultiMap() { 00051 } 00052 explicit LSE_CALL CMultiMap( const CMultiMap<_tKeyType, _tMappedType> &_mmSrc ) : 00053 m_vPairs( _mmSrc.m_vPairs ) { 00054 } 00055 explicit LSE_CALL CMultiMap( CAllocator * _paAllocator ) : 00056 m_vPairs( _paAllocator ) { 00057 } 00058 LSE_CALL ~CMultiMap() { 00059 } 00060 00061 00062 // == Operators. 00069 CMultiMap & LSE_CALL operator = ( const CMultiMap &_mmOther ) { 00070 m_vPairs = _mmOther.m_vPairs; 00071 00072 return (*this); 00073 } 00074 00075 00076 // == Functions. 00087 LSBOOL LSE_CALL Insert( const _tKeyType &_tKey, const _tMappedType &_tValue, _tMappedType ** _pptReturnValue = NULL ) { 00088 LSUINT32 ui32Index; 00089 if ( !GetItemIndex( _tKey, ui32Index ) ) { 00090 // Pair does not exist, so add it. 00091 LSTL_PAIR pPair; 00092 pPair.tKey = _tKey; 00093 // Do not add the value. 00094 if ( !m_vPairs.Insert( pPair, ui32Index ) ) { 00095 if ( _pptReturnValue ) { 00096 (*_pptReturnValue) = NULL; 00097 } 00098 return false; 00099 } 00100 // It was inserted. Apply the allocator to the vector. 00101 m_vPairs[ui32Index].vValues.SetAllocator( GetAllocator() ); 00102 } 00103 00104 // Key already exists. Add the mapped value to it. 00105 LSUINT32 ui32Total = m_vPairs[ui32Index].vValues.Length(); 00106 if ( !m_vPairs[ui32Index].vValues.Push( _tValue ) ) { 00107 if ( _pptReturnValue ) { 00108 (*_pptReturnValue) = NULL; 00109 } 00110 return false; 00111 } 00112 if ( _pptReturnValue ) { 00113 (*_pptReturnValue) = &m_vPairs[ui32Index].vValues[ui32Total]; 00114 } 00115 return true; 00116 } 00117 00124 LSVOID LSE_CALL RemoveNoDealloc( const _tKeyType * _ptKeys, LSUINT32 _ui32Total ) { 00125 for ( LSUINT32 I = _ui32Total; I--; ) { 00126 RemoveNoDealloc( _ptKeys[I] ); 00127 } 00128 } 00129 00135 LSVOID LSE_CALL RemoveNoDealloc( const _tKeyType &_tKey ) { 00136 LSUINT32 ui32Index; 00137 if ( GetItemIndex( _tKey, ui32Index ) ) { 00138 m_vPairs.RemoveNoDealloc( ui32Index ); 00139 } 00140 } 00141 00148 LSVOID LSE_CALL Remove( const _tKeyType * _ptKeys, LSUINT32 _ui32Total ) { 00149 for ( LSUINT32 I = _ui32Total; I--; ) { 00150 Remove( _ptKeys[I] ); 00151 } 00152 } 00153 00159 LSVOID LSE_CALL Remove( const _tKeyType &_tKey ) { 00160 LSUINT32 ui32Index; 00161 if ( GetItemIndex( _tKey, ui32Index ) ) { 00162 m_vPairs.Remove( ui32Index ); 00163 } 00164 } 00165 00169 LSVOID LSE_CALL ResetNoDealloc() { 00170 m_vPairs.ResetNoDealloc(); 00171 } 00172 00176 LSVOID LSE_CALL Reset() { 00177 m_vPairs.Reset(); 00178 } 00179 00185 LSUINT32 LSE_CALL Length() const { 00186 return m_vPairs.Length(); 00187 } 00188 00197 LSBOOL LSE_CALL GetItemIndex( const _tKeyType &_tKey, LSUINT32 &_ui32Index ) const { 00198 return CAlgorithm::BSearch( m_vPairs, _tKey, _ui32Index ); 00199 } 00200 00207 LSUINT32 LSE_CALL ItemsOnKey( LSUINT32 _ui32Index ) const { 00208 return m_vPairs[_ui32Index].vValues.Length(); 00209 } 00210 00219 _tMappedType & LSE_CALL GetByIndex( LSUINT32 _ui32KeyIndex, LSUINT32 _ui32Index ) { 00220 return m_vPairs[_ui32KeyIndex].vValues[_ui32Index]; 00221 } 00222 00231 const _tMappedType & LSE_CALL GetByIndex( LSUINT32 _ui32KeyIndex, LSUINT32 _ui32Index ) const { 00232 return m_vPairs[_ui32KeyIndex].vValues[_ui32Index]; 00233 } 00234 00242 LSVOID LSE_CALL SetAllocator( CAllocator * _paAllocator ) { 00243 m_vPairs.SetAllocator( _paAllocator ); 00244 } 00245 00251 CAllocator * LSE_CALL GetAllocator() { 00252 return m_vPairs.GetAllocator(); 00253 } 00254 00260 const CAllocator * LSE_CALL GetAllocator() const { 00261 return m_vPairs.GetAllocator(); 00262 } 00263 00264 00265 protected : 00266 // == Types. 00270 typedef struct LSTL_PAIR { 00274 _tKeyType tKey; 00275 00279 CVector<_tMappedType, LSUINT16, 1024UL> 00280 vValues; 00281 00288 LSTL_PAIR & LSE_CALL operator = ( const LSTL_PAIR &_pSrc ) { 00289 tKey = _pSrc.tKey; 00290 vValues = _pSrc.vValues; 00291 return (*this); 00292 } 00293 00300 LSBOOL LSE_CALL operator < ( const _tKeyType &_tVal ) const { 00301 return tKey < _tVal; 00302 } 00303 00310 LSBOOL LSE_CALL operator == ( const _tKeyType &_tVal ) const { 00311 return tKey == _tVal; 00312 } 00313 00317 LSE_CALL LSTL_PAIR() : 00318 tKey(), 00319 vValues() { 00320 } 00321 } * LPLSTL_PAIR, * const LPCLSTL_PAIR; 00322 00323 00324 // == Members. 00328 CVector<LSTL_PAIR, LSUINT32, 1024UL> m_vPairs; 00329 00330 }; 00331 00332 } // namespace lstl 00333 00334 #pragma warning( pop ) 00335 00336 #endif // __LSTL_MULTIMAP_H__