Собственно задача понятна — получить класс который ведет себя "как basic_string"(при этом полный функционал вовсе не обязательно, отсюда отсутствие многого из интерфейса basic_string ), и в то же время сравнение объекто этого класса происходит через хэш). Смысла пинать функцию makeHash() особого нет( Её код тиснут из STL порта).
Основной критерйи по сути — возможность хранить в контейнерах STL.
template <class stringT>
class basic_hash_string
{
public:
typedef typename stringT::value_type value_type;
typedef typename stringT::size_type size_type;
typedef size_type hash_type;
void clear()
{
m_str.clear();
m_Hash = 0;
}
const size_type length() const
{
return m_str.length();
}
const hash_type getHash() const
{
return m_Hash;
}
basic_hash_string(const stringT& str)
{
assign( str.c_str() );
}
basic_hash_string(const value_type* value_type_str)
{
assign( value_type_str );
}
basic_hash_string& operator=(const stringT& Val)
{
assign( Val.c_str() );
return *this;
}
basic_hash_string& operator=(const value_type* value_type_str)
{
assign(value_type_str );
return *this;
}
basic_hash_string& operator+(const basic_hash_string& Val)
{
append( (static_cast<stringT>(Val)).c_str() );
return *this;
}
basic_hash_string& operator+(const stringT& Val)
{
append( Val.c_str() );
return *this;
}
basic_hash_string& operator+(const value_type* value_type_str)
{
append( value_type_str );
return *this;
}
basic_hash_string& operator+=(const basic_hash_string& Val)
{
append( (static_cast<stringT>(Val)).c_str() );
return *this;
}
basic_hash_string& operator+=(const stringT& Val)
{
append( Val.c_str() );
return *this;
}
basic_hash_string& operator+=(const value_type* value_type_str)
{
append( value_type_str );
return *this;
}
operator stringT()
{
return m_str;
}
const typename stringT::value_type* c_str() const
{
return Val.c_str();
}
const bool operator ==(const stringT& Val) const
{
return isEqual( Val.c_str() );
}
const bool operator ==(const basic_hash_string& Val) const
{
return m_Hash == Val.getHash();
}
const bool operator ==(const value_type* value_type_str) const
{
return isEqual( value_type_str );
}
const bool operator !=(const stringT& Val) const
{
return !isEqual( Val.c_str() );
}
const bool operator !=(const basic_hash_string& Val) const
{
return m_Hash != Val.getHash();
}
const bool operator !=(const value_type* value_type_str) const
{
return !isEqual( value_type_str );
}
private:
hash_type m_Hash;
stringT m_str;
const hash_type makeHash(const value_type * value) const
{
unsigned long h = 0;
for ( ; *value; ++value)
h = 5*h + *value;
return hash_type(h);
}
const bool isEqual(const value_type* value_type_st) const
{
return m_str == value_type_st;
}
void assign(const value_type* value_type_str)
{
m_Hash = makeHash( value_type_str );
m_str = value_type_str;
}
void append( const value_type* value_type_str )
{
m_str.append( value_type_str );
m_Hash = makeHash( value_type_str );
}
};
//пример использования
typedef basic_hash_string<string> hash_string;
string str1("123"), str2("321");
int i = 0;
hash_string HS1(str1), HS2("2"), HS3 = HS1;
if (HS2 == HS1)
i++;
if ( HS3 == str1 )
i--;
if (HS2 == "2")
i++;
if (HS2 != "4")
i++;
HS1 += str1;
HS1 += "312";
HS2 = HS1 + str2 ;