#if !defined( INCLUDED_POOLEDSTRING_H ) #define INCLUDED_POOLEDSTRING_H #include #include "generic/static.h" #include "string/string.h" #include "container/hashtable.h" #include "container/hashfunc.h" /// \brief The string pool class. class StringPool : public HashTable { }; inline void StringPool_analyse( StringPool& pool ){ typedef std::multimap Ordered; Ordered ordered; std::size_t total = 0; std::size_t pooled = 0; for ( StringPool::iterator i = pool.begin(); i != pool.end(); ++i ) { std::size_t size = string_length( ( *i ).key ) + 1; total += size * ( *i ).value; pooled += size + 20; ordered.insert( Ordered::value_type( ( *i ).value, ( *i ).key ) ); } globalOutputStream() << "total: " << Unsigned( total ) << " pooled:" << Unsigned( pooled ) << "\n"; for ( Ordered::iterator i = ordered.begin(); i != ordered.end(); ++i ) { globalOutputStream() << ( *i ).second << " " << Unsigned( ( *i ).first ) << "\n"; } } /// \brief A string which can be copied with zero memory cost and minimal runtime cost. /// /// \param PoolContext The string pool context to use. template class PooledString { StringPool::iterator m_i; static StringPool::iterator increment( StringPool::iterator i ){ ++( *i ).value; return i; } static StringPool::iterator insert( const char* string ){ StringPool::iterator i = PoolContext::instance().find( const_cast( string ) ); if ( i == PoolContext::instance().end() ) { return PoolContext::instance().insert( string_clone( string ), 1 ); } return increment( i ); } static void erase( StringPool::iterator i ){ if ( --( *i ).value == 0 ) { char* string = ( *i ).key; PoolContext::instance().erase( i ); string_release( string, string_length( string ) ); } } public: PooledString() : m_i( insert( "" ) ){ } PooledString( const PooledString& other ) : m_i( increment( other.m_i ) ){ } PooledString( const char* string ) : m_i( insert( string ) ){ } ~PooledString(){ erase( m_i ); } PooledString& operator=( const PooledString& other ){ PooledString tmp( other ); tmp.swap( *this ); return *this; } PooledString& operator=( const char* string ){ PooledString tmp( string ); tmp.swap( *this ); return *this; } void swap( PooledString& other ){ std::swap( m_i, other.m_i ); } bool operator==( const PooledString& other ) const { return m_i == other.m_i; } const char* c_str() const { return ( *m_i ).key; } }; #endif