//--------------------------------------------------------------------------- // StrMap.h // // Template class for a map of strings to something //--------------------------------------------------------------------------- #pragma once #ifndef _STRMAP_H_ #define _STRMAP_H_ #include "MyString.h" #include #include #include "myvector.h" template< class T > struct StringPairEqual { StringPairEqual( const String& str) : m_rstr( str ) {} bool operator()( const pair& rhs ) { return ( m_rstr == rhs.first ); } private: const String& m_rstr; }; template< class T > struct StringPairCompare { int operator()( const pair& lhs, const pair& rhs ) { return lhs.first.compare( rhs.first ); } }; // template function--finds the first element n for which cmp(val,vec[n]) is true and // cmp(val,vec[n-1]) is false template< class T, class Compare > __TYPENAME TVector::iterator binary_find( TVector& vec, const T& val, Compare& cmp ) { TVector::iterator iter = vec.begin(); if ( vec.size() > 0 ) { size_t top = vec.size() - 1; size_t bot = 0; size_t mid = top >> 1; while ( top != bot ) { int c = cmp( val, vec[mid] ); if ( c > 0 ) { // val > vec[mid] bot = mid + 1; mid = ( top + bot ) >> 1; } else if ( c < 0 ) { // val < vec[mid] top = mid; mid = ( top + bot ) >> 1; } else { // val == vec[mid] top = bot = mid; } } iter = vec.begin() + mid; if ( cmp( val, vec[mid] ) > 0 ) { iter++; } } return iter; } template< class T > class TStringMap { public: typedef String key_type; typedef T referent_type; typedef pair value_type; typedef TVector vector_type; typedef typename vector_type::reference reference; typedef typename vector_type::iterator iterator; typedef typename vector_type::const_iterator const_iterator; TStringMap(){}; ~TStringMap(){}; iterator begin() { return m_vec.begin(); } const_iterator begin() const { return m_vec.begin(); } iterator end() {return m_vec.end();} const_iterator end() const {return m_vec.end();} iterator find( const String& ); pair insert(const value_type& x); referent_type& operator[]( const String& ); referent_type& operator[]( size_t n ) { return m_vec[n].second; } const referent_type& operator[]( const String& ) const ; const referent_type& operator[]( size_t n ) const { return m_vec[n].second; } void clear(){ m_vec.clear(); } size_t size() const { return m_vec.size(); } private: vector_type m_vec; }; #if 0 template inline TStringMap::iterator TStringMap::begin() { return m_vec.begin(); } template inline TStringMap::const_iterator TStringMap::begin() const { return m_vec.begin(); } template inline TStringMap::iterator TStringMap::end() { return m_vec.end(); } template inline TStringMap::const_iterator TStringMap::end() const { return m_vec.end(); } #endif template inline __TYPENAME TStringMap::iterator TStringMap::find( const String& str ) { value_type vt(str,T()); iterator iter = binary_find( m_vec, vt, StringPairCompare() ); StringPairEqual spe(str); if ( ( iter != m_vec.end() ) && spe(*iter) ) { } else { iter = m_vec.end(); } return iter; } template inline pair< __TYPENAME TStringMap::iterator, bool > TStringMap::insert( const __TYPENAME TStringMap::value_type& val ) { bool inserted = false; iterator iter = binary_find( m_vec, val, StringPairCompare() ); StringPairEqual spe(val.first); if ( ( iter != m_vec.end() ) && spe(*iter) ) { } else { inserted = true; iter = m_vec.insert( iter, val ); } return pair::iterator, bool>( iter, inserted ); } template inline T& TStringMap::operator[]( const String& s ) { value_type vt(s,T()); iterator iter = binary_find( m_vec, vt, StringPairCompare() ); StringPairEqual spe(s); if ( ( iter != m_vec.end() ) && spe(*iter) ) { } else { iter = m_vec.insert( iter, vt ); } return (*iter).second; } #endif // !_STRMAP_H_