2 #if !defined( INCLUDED_POOLEDSTRING_H )
3 #define INCLUDED_POOLEDSTRING_H
6 #include "generic/static.h"
7 #include "string/string.h"
8 #include "container/hashtable.h"
9 #include "container/hashfunc.h"
11 /// \brief The string pool class.
12 class StringPool : public HashTable<char*, std::size_t, RawStringHash, RawStringEqual>
16 inline void StringPool_analyse( StringPool& pool ){
17 typedef std::multimap<std::size_t, const char*> Ordered;
19 std::size_t total = 0;
20 std::size_t pooled = 0;
21 for ( StringPool::iterator i = pool.begin(); i != pool.end(); ++i )
23 std::size_t size = string_length( ( *i ).key ) + 1;
24 total += size * ( *i ).value;
26 ordered.insert( Ordered::value_type( ( *i ).value, ( *i ).key ) );
28 globalOutputStream() << "total: " << Unsigned( total ) << " pooled:" << Unsigned( pooled ) << "\n";
29 for ( Ordered::iterator i = ordered.begin(); i != ordered.end(); ++i )
31 globalOutputStream() << ( *i ).second << " " << Unsigned( ( *i ).first ) << "\n";
36 /// \brief A string which can be copied with zero memory cost and minimal runtime cost.
38 /// \param PoolContext The string pool context to use.
39 template<typename PoolContext>
42 StringPool::iterator m_i;
43 static StringPool::iterator increment( StringPool::iterator i ){
47 static StringPool::iterator insert( const char* string ){
48 StringPool::iterator i = PoolContext::instance().find( const_cast<char*>( string ) );
49 if ( i == PoolContext::instance().end() ) {
50 return PoolContext::instance().insert( string_clone( string ), 1 );
52 return increment( i );
54 static void erase( StringPool::iterator i ){
55 if ( --( *i ).value == 0 ) {
56 char* string = ( *i ).key;
57 PoolContext::instance().erase( i );
58 string_release( string, string_length( string ) );
62 PooledString() : m_i( insert( "" ) ){
64 PooledString( const PooledString& other ) : m_i( increment( other.m_i ) ){
66 PooledString( const char* string ) : m_i( insert( string ) ){
71 PooledString& operator=( const PooledString& other ){
72 PooledString tmp( other );
76 PooledString& operator=( const char* string ){
77 PooledString tmp( string );
81 void swap( PooledString& other ){
82 std::swap( m_i, other.m_i );
84 bool operator==( const PooledString& other ) const {
85 return m_i == other.m_i;
87 const char* c_str() const {