Vegastrike 0.5.1 rc1  1.0
Original sources for Vegastrike Evolved
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
SharedPool.h
Go to the documentation of this file.
1 #ifndef __STRINGPOOL_H__INCLUDED__
2 #define __STRINGPOOL_H__INCLUDED__
3 #include "config.h"
4 #include <string>
5 #include "gnuhash.h"
6 
7 #ifndef INITIAL_STRINGPOOL_SIZE
8 #define INITIAL_STRINGPOOL_SIZE (1<<15)
9 #endif
10 
11 //Need reference counted strings, or we'll eat memory like crazy
12 template < class T, class RefcounterTraits = vsHashComp< T > >
14 {
15 public:
16  typedef vsUMap< T, unsigned int > ReferenceCounter;
18 
19 private:
20  ReferenceCounter referenceCounter;
21  static PoolType *ms_singleton;
22 
23 public:
24  typedef T ValueType;
25  typedef RefcounterTraits RefocounterTraitsType;
26 
28  {
29  return *ms_singleton;
30  }
31 
33  {
34  return ms_singleton;
35  }
36 
37  SharedPool();
38  ~SharedPool();
39 
40 public:
41  class Reference
42  {
43  typename ReferenceCounter::iterator _it;
44  ReferenceCounter *_rc;
45 
46  void unref()
47  {
48  if ( _rc && ( _it != _rc->end() ) ) {
49  if ( (_it->second == 0) || ( ( --(_it->second) ) == 0 ) )
50  _rc->erase( _it );
51  _it = _rc->end();
52  }
53  }
54 
55  void ref()
56  {
57  if ( _rc && ( _it != _rc->end() ) )
58  ++(_it->second);
59  }
60 
61 public: Reference() :
62  _it( SharedPool::getSingleton().referenceCounter.end() )
63  , _rc( &SharedPool::getSingleton().referenceCounter )
64  {}
65 
66  explicit Reference( const T &s ) :
67  _it( SharedPool::getSingleton().referenceCounter.end() )
68  , _rc( &SharedPool::getSingleton().referenceCounter )
69  {
70  set( s );
71  }
72 
73  explicit Reference( ReferenceCounter *pool ) :
74  _it( pool->end() )
75  , _rc( pool )
76  {}
77 
78  Reference( ReferenceCounter *pool, const T &s ) :
79  _it( pool->end() )
80  , _rc( pool )
81  {
82  set( s );
83  }
84 
85  Reference( const Reference &other ) :
86  _it( other._it )
87  , _rc( other._rc )
88  {
89  ref();
90  }
91 
93  {
94  unref();
95  }
96 
97  const T& get() const
98  {
99  static T empty_value;
100  return ( _rc && ( _it != _rc->end() ) ) ? _it->first : empty_value;
101  }
102 
103  Reference& set( const T &s )
104  {
105  unref();
106  if (_rc) {
107  _it = _rc->insert( std::pair< T, unsigned int > ( s, 0 ) ).first;
108  ref();
109  }
110  return *this;
111  }
112 
113  operator const T &() const
114  {
115  return get();
116  }
117 
118  Reference&operator=( const T &s )
119  {
120  return set( s );
121  }
122 
124  {
125  if (this == &s)
126  return *this;
127  if (s._rc == _rc) {
128  unref();
129  _it = s._it;
130  ref();
131  } else {
132  set( s.get() );
133  }
134  return *this;
135  }
136 
137  bool operator==( const T &s ) const
138  {
139  return get() == s;
140  }
141 
142  bool operator==( const Reference &r ) const
143  {
144  if ( _rc && (_rc == r._rc) )
145  return _it == r._it;
146 
147  else
148  return get() == r.get();
149  }
150 
151  bool operator<( const T &s ) const
152  {
153  return get() < s;
154  }
155 
156  bool operator<( const Reference &r ) const
157  {
158  return get() < r.get();
159  }
160 
161  bool operator!=( const T &s ) const
162  {
163  return get() != s;
164  }
165 
166  bool operator!=( const Reference &r ) const
167  {
168  return !(*this == r);
169  }
170  };
171 
172  Reference get( const T &s )
173  {
174  return Reference( &referenceCounter, s );
175  }
176 
177  Reference get()
178  {
179  return Reference( &referenceCounter );
180  }
181  friend class PoolType::Reference;
182 };
183 
184 class StringpoolTraits : public vsHashComp< std::string >
185 {
186 public:
188 };
189 
191 
193 
194 inline std::string operator+( const std::string &s, const StringPool::Reference &r )
195 {
196  return s+r.get();
197 }
198 
199 inline std::string operator+( const StringPool::Reference &r, const std::string &s )
200 {
201  return r.get()+s;
202 }
203 
204 template < typename T >
205 inline T& operator<<( T &stream, const StringPool::Reference &ref )
206 {
207  return stream<<ref.get();
208 }
209 
210 template < typename T >
211 bool operator==( const typename SharedPool< T >::Reference &r, const T &s )
212 {
213  return r.get() == s;
214 }
215 
216 #include "SharedPool.cpp"
217 #endif //__STRINGPOOL_H__INCLUDED__
218