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.
218 lines
4.3 KiB
218 lines
4.3 KiB
//---------------------------------------------------------------------------
|
|
// StrMap.h
|
|
//
|
|
// Template class for a map of strings to something
|
|
//---------------------------------------------------------------------------
|
|
#pragma once
|
|
#ifndef _STRMAP_H_
|
|
#define _STRMAP_H_
|
|
|
|
#include "MyString.h"
|
|
#include <utility>
|
|
#include <algorithm>
|
|
#include "myvector.h"
|
|
|
|
template< class T >
|
|
struct StringPairEqual
|
|
{
|
|
StringPairEqual( const String& str)
|
|
: m_rstr( str ) {}
|
|
bool operator()(
|
|
const pair<String, T>& rhs )
|
|
{
|
|
return ( m_rstr == rhs.first );
|
|
}
|
|
private:
|
|
const String& m_rstr;
|
|
};
|
|
|
|
template< class T >
|
|
struct StringPairCompare
|
|
{
|
|
int operator()(
|
|
const pair<String, T>& lhs,
|
|
const pair<String, T>& 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<T>::iterator
|
|
binary_find(
|
|
TVector<T>& vec,
|
|
const T& val,
|
|
Compare& cmp )
|
|
{
|
|
TVector<T>::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<key_type,referent_type> value_type;
|
|
typedef TVector<value_type> 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<iterator, bool> 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<class T>
|
|
inline
|
|
TStringMap<T>::iterator
|
|
TStringMap<T>::begin()
|
|
{
|
|
return m_vec.begin();
|
|
}
|
|
|
|
template<class T>
|
|
inline
|
|
TStringMap<T>::const_iterator
|
|
TStringMap<T>::begin()
|
|
const
|
|
{
|
|
return m_vec.begin();
|
|
}
|
|
|
|
template<class T>
|
|
inline
|
|
TStringMap<T>::iterator
|
|
TStringMap<T>::end()
|
|
{
|
|
return m_vec.end();
|
|
}
|
|
|
|
template<class T>
|
|
inline
|
|
TStringMap<T>::const_iterator
|
|
TStringMap<T>::end()
|
|
const
|
|
{
|
|
return m_vec.end();
|
|
}
|
|
|
|
#endif
|
|
|
|
template<class T>
|
|
inline
|
|
__TYPENAME TStringMap<T>::iterator
|
|
TStringMap<T>::find(
|
|
const String& str )
|
|
{
|
|
value_type vt(str,T());
|
|
iterator iter = binary_find( m_vec, vt, StringPairCompare<T>() );
|
|
StringPairEqual<T> spe(str);
|
|
if ( ( iter != m_vec.end() ) && spe(*iter) )
|
|
{
|
|
}
|
|
else
|
|
{
|
|
iter = m_vec.end();
|
|
}
|
|
return iter;
|
|
}
|
|
|
|
template<class T>
|
|
inline
|
|
pair< __TYPENAME TStringMap<T>::iterator, bool >
|
|
TStringMap<T>::insert(
|
|
const __TYPENAME TStringMap<T>::value_type& val )
|
|
{
|
|
bool inserted = false;
|
|
iterator iter = binary_find( m_vec, val, StringPairCompare<T>() );
|
|
StringPairEqual<T> spe(val.first);
|
|
if ( ( iter != m_vec.end() ) && spe(*iter) )
|
|
{
|
|
}
|
|
else
|
|
{
|
|
inserted = true;
|
|
iter = m_vec.insert( iter, val );
|
|
}
|
|
return pair<TStringMap<T>::iterator, bool>( iter, inserted );
|
|
}
|
|
|
|
template<class T>
|
|
inline
|
|
T&
|
|
TStringMap<T>::operator[](
|
|
const String& s )
|
|
{
|
|
value_type vt(s,T());
|
|
iterator iter = binary_find( m_vec, vt, StringPairCompare<T>() );
|
|
StringPairEqual<T> spe(s);
|
|
if ( ( iter != m_vec.end() ) && spe(*iter) )
|
|
{
|
|
}
|
|
else
|
|
{
|
|
iter = m_vec.insert( iter, vt );
|
|
}
|
|
return (*iter).second;
|
|
}
|
|
|
|
|
|
#endif // !_STRMAP_H_
|