]> de.git.xonotic.org Git - xonotic/netradiant.git/blob - libs/string/pooledstring.h
my own uncrustify run
[xonotic/netradiant.git] / libs / string / pooledstring.h
1
2 #if !defined( INCLUDED_POOLEDSTRING_H )
3 #define INCLUDED_POOLEDSTRING_H
4
5 #include <map>
6 #include "generic/static.h"
7 #include "string/string.h"
8 #include "container/hashtable.h"
9 #include "container/hashfunc.h"
10
11 /// \brief The string pool class.
12 class StringPool : public HashTable<char*, std::size_t, RawStringHash, RawStringEqual>
13 {
14 };
15
16 inline void StringPool_analyse( StringPool& pool ){
17         typedef std::multimap<std::size_t, const char*> Ordered;
18         Ordered ordered;
19         std::size_t total = 0;
20         std::size_t pooled = 0;
21         for ( StringPool::iterator i = pool.begin(); i != pool.end(); ++i )
22         {
23                 std::size_t size =  string_length( ( *i ).key ) + 1;
24                 total += size * ( *i ).value;
25                 pooled += size + 20;
26                 ordered.insert( Ordered::value_type( ( *i ).value, ( *i ).key ) );
27         }
28         globalOutputStream() << "total: " << Unsigned( total ) << " pooled:" << Unsigned( pooled ) << "\n";
29         for ( Ordered::iterator i = ordered.begin(); i != ordered.end(); ++i )
30         {
31                 globalOutputStream() << ( *i ).second << " " << Unsigned( ( *i ).first ) << "\n";
32         }
33 }
34
35
36 /// \brief A string which can be copied with zero memory cost and minimal runtime cost.
37 ///
38 /// \param PoolContext The string pool context to use.
39 template<typename PoolContext>
40 class PooledString
41 {
42 StringPool::iterator m_i;
43 static StringPool::iterator increment( StringPool::iterator i ){
44         ++( *i ).value;
45         return i;
46 }
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 );
51         }
52         return increment( i );
53 }
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 ) );
59         }
60 }
61 public:
62 PooledString() : m_i( insert( "" ) ){
63 }
64 PooledString( const PooledString& other ) : m_i( increment( other.m_i ) ){
65 }
66 PooledString( const char* string ) : m_i( insert( string ) ){
67 }
68 ~PooledString(){
69         erase( m_i );
70 }
71 PooledString& operator=( const PooledString& other ){
72         PooledString tmp( other );
73         tmp.swap( *this );
74         return *this;
75 }
76 PooledString& operator=( const char* string ){
77         PooledString tmp( string );
78         tmp.swap( *this );
79         return *this;
80 }
81 void swap( PooledString& other ){
82         std::swap( m_i, other.m_i );
83 }
84 bool operator==( const PooledString& other ) const {
85         return m_i == other.m_i;
86 }
87 const char* c_str() const {
88         return ( *m_i ).key;
89 }
90 };
91
92
93 #endif