OpenClonk
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros
C4StringTable.h
Go to the documentation of this file.
1 /*
2  * OpenClonk, http://www.openclonk.org
3  *
4  * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/
5  * Copyright (c) 2009-2016, The OpenClonk Team and contributors
6  *
7  * Distributed under the terms of the ISC license; see accompanying file
8  * "COPYING" for details.
9  *
10  * "Clonk" is a registered trademark of Matthes Bender, used with permission.
11  * See accompanying file "TRADEMARK" for details.
12  *
13  * To redistribute this file separately, substitute the full license texts
14  * for the above references.
15  */
16 /* string table: holds all strings used by script engine */
17 
18 #ifndef C4STRINGTABLE_H
19 #define C4STRINGTABLE_H
20 
21 class C4RefCnt
22 {
23 public:
24  C4RefCnt() = default;
25  virtual ~C4RefCnt() = default;
26  // Add/Remove Reference
27  void IncRef() { RefCnt++; }
28  void DecRef() { if (!--RefCnt) delete this; }
29 protected:
30  // Reference counter
31  unsigned int RefCnt{0};
32 };
33 
34 class C4String: public C4RefCnt
35 {
36 public:
37  unsigned int Hash;
38 private:
39  StdCopyStrBuf Data; // string data
40 
41  explicit C4String(StdStrBuf strString);
42  C4String();
43  void operator=(const char * s);
44 
45  friend class C4StringTable;
46 public:
47  ~C4String() override;
48 
49  const char * GetCStr() const { return Data.getData(); }
50  StdStrBuf GetData() const { return Data.getRef(); }
51 
52 };
53 
54 template <class T>
56 {
57 public:
58  C4RefCntPointer(T* p): p(p) { IncRef(); }
59  C4RefCntPointer(): p(nullptr) { }
60  C4RefCntPointer(const C4RefCntPointer<T> & r) : p(r.p) { IncRef(); }
61  template <class U> C4RefCntPointer(const C4RefCntPointer<U> & r): p(r.p) { IncRef(); }
62  // Move constructor
63  C4RefCntPointer(C4RefCntPointer<T> &&r) : p(r.p) { r.p = nullptr; }
64  template <class U> C4RefCntPointer(C4RefCntPointer<U> &&r): p(r.p) { r.p = 0; }
65  // Move assignment
67  {
68  if (p != r.p)
69  {
70  DecRef();
71  p = r.p;
72  r.p = nullptr;
73  }
74  return *this;
75  }
77  {
78  if (p != r.p)
79  {
80  DecRef();
81  p = r.p;
82  r.p = 0;
83  }
84  return *this;
85  }
86  ~C4RefCntPointer() { DecRef(); }
87  template <class U> C4RefCntPointer& operator = (U* new_p)
88  {
89  if (p != new_p)
90  {
91  DecRef();
92  p = new_p;
93  IncRef();
94  }
95  return *this;
96  }
98  {
99  return *this = r.p;
100  }
101  template <class U> C4RefCntPointer& operator = (const C4RefCntPointer<U>& r)
102  {
103  return *this = r.p;
104  }
105  T& operator * () { return *p; }
106  const T& operator * () const { return *p; }
107  T* operator -> () { return p; }
108  const T* operator -> () const { return p; }
109  operator T * () { return p; }
110  operator const T * () const { return p; }
111  T *Get() const { return p; }
112 private:
113  void IncRef() { if (p) p->IncRef(); }
114  void DecRef() { if (p) p->DecRef(); }
115  T * p;
116 };
117 
118 template<typename T> class C4Set
119 {
120  unsigned int Capacity{2};
121  unsigned int Size{0};
122  T * Table;
123  T * GetPlaceFor(T const & e)
124  {
125  unsigned int h = Hash(e);
126  T * p = &Table[h % Capacity];
127  while (*p && !Equals(*p, e))
128  {
129  p = &Table[++h % Capacity];
130  }
131  return p;
132  }
133  T * AddInternal(T const & e)
134  {
135  T * p = GetPlaceFor(e);
136  *p = e;
137  return p;
138  }
139  T * AddInternal(T && e)
140  {
141  T * p = GetPlaceFor(e);
142  *p = std::move(e);
143  return p;
144  }
145  void ClearTable()
146  {
147  for (unsigned int i = 0; i < Capacity; ++i)
148  Table[i] = nullptr;
149  }
150  void MaintainCapacity()
151  {
152  if (Capacity - Size < std::max(2u, Capacity / 4))
153  {
154  unsigned int OCapacity = Capacity;
155  Capacity *= 2;
156  T * OTable = Table;
157  Table = new T[Capacity];
158  ClearTable();
159  for (unsigned int i = 0; i < OCapacity; ++i)
160  {
161  if (OTable[i])
162  AddInternal(std::move(OTable[i]));
163  }
164  delete [] OTable;
165  }
166  }
167 public:
168  template<typename H> static unsigned int Hash(const H &);
169  template<typename H> static bool Equals(const T &, const H &);
170  static bool Equals(const T & a, const T & b) { return a == b; }
171  C4Set(): Table(new T[Capacity])
172  {
173  ClearTable();
174  }
176  {
177  delete[] Table;
178  }
179  C4Set(const C4Set & b): Capacity(0), Size(0), Table(0)
180  {
181  *this = b;
182  }
184  {
185  Capacity = b.Capacity;
186  Size = b.Size;
187  delete[] Table;
188  Table = new T[Capacity];
189  for (unsigned int i = 0; i < Capacity; ++i)
190  Table[i] = b.Table[i];
191  return *this;
192  }
193  void CompileFunc(class StdCompiler *pComp, class C4ValueNumbers *);
194  void Clear()
195  {
196  ClearTable();
197  Size = 0;
198  }
199  template<typename H> T & Get(H e) const
200  {
201  unsigned int h = Hash(e);
202  T * r = &Table[h % Capacity];
203  while (*r && !Equals(*r, e))
204  {
205  r = &Table[++h % Capacity];
206  }
207  return *r;
208  }
209  template<typename H> bool Has(H e) const
210  {
211  unsigned int h = Hash(e);
212  T * r = &Table[h % Capacity];
213  while (*r && !Equals(*r, e))
214  {
215  r = &Table[++h % Capacity];
216  }
217  return !!*r;
218  }
219  unsigned int GetSize() const { return Size; }
220  T * Add(T const & e)
221  {
222  MaintainCapacity();
223  T * r = AddInternal(e);
224  ++Size;
225  return r;
226  }
227  T * Add(T && e)
228  {
229  MaintainCapacity();
230  T * r = AddInternal(std::move(e));
231  ++Size;
232  return r;
233  }
234  template<typename H> void Remove(H e)
235  {
236  unsigned int h = Hash(e);
237  T * r = &Table[h % Capacity];
238  while (*r && !Equals(*r, e))
239  {
240  r = &Table[++h % Capacity];
241  }
242  assert(*r);
243  *r = nullptr;
244  --Size;
245  // Move entries which might have collided with e
246  while (*(r = &Table[++h % Capacity]))
247  {
248  T m = *r;
249  *r = nullptr;
250  AddInternal(std::move(m));
251  }
252  }
253  T const * First() const { return Next(Table - 1); }
254  T const * Next(T const * p) const
255  {
256  while (++p != &Table[Capacity])
257  {
258  if (*p) return p;
259  }
260  return nullptr;
261  }
262  void Swap(C4Set<T> * S2)
263  {
264  unsigned int Capacity2 = S2->Capacity;
265  unsigned int Size2 = S2->Size;
266  T * Table2 = S2->Table;
267  S2->Capacity = Capacity;
268  S2->Size = Size;
269  S2->Table = Table;
270  Capacity = Capacity2;
271  Size = Size2;
272  Table = Table2;
273  }
274  static bool SortFunc(const T *p1, const T*p2)
275  {
276  // elements are guarantueed to be non-nullptr
277  return *p1<*p2;
278  }
279  std::list<const T *> GetSortedListOfElementPointers() const
280  {
281  // return a list of pointers to all elements in this set sorted by the standard less-than operation
282  // of the elements
283  // elements of resulting lists are guarantueed to be non-nullptr
284  // list remains valid as long as this set is not changed
285  std::list<const T *> result;
286  for (const T *p = First(); p; p = Next(p)) result.push_back(p);
287  result.sort(C4Set<T>::SortFunc);
288  return result;
289  }
290 };
291 
292 template<> template<>
293 inline unsigned int C4Set<C4String *>::Hash<const C4String *>(const C4String * const & e)
294 {
295  return e->Hash;
296 }
297 template<> template<>
298 inline unsigned int C4Set<C4String *>::Hash<C4String *>(C4String * const & e)
299 {
300  return e->Hash;
301 }
302 
304 {
305  // TODO: documentation comments can be removed
306  // as soon as all properties are documented
307 
381  P_Mode, // unused?
382  P_CausedBy, // unused?
383  P_Blasted, // unused?
384  P_IncineratingObj, // unused?
542 // Default Action Procedures
559 };
560 
561 // There is only one Stringtable
563 {
564 public:
565  C4StringTable();
566  virtual ~C4StringTable();
567 
569  C4String *RegString(const char * s) { return RegString(StdStrBuf(s)); }
570  // Find existing C4String
571  C4String *FindString(const char *strString) const;
572 
573 private:
574  C4Set<C4String *> Set;
575  friend class C4String;
576 
577 public:
578  // After the set, so these are destroyed with the set still alive
580 };
581 
582 extern C4StringTable Strings;
583 
584 #endif
const char * getData() const
Definition: StdBuf.h:442
C4String P[P_LAST]
void CompileFunc(class StdCompiler *pComp, class C4ValueNumbers *)
Definition: C4PropList.cpp:449
StdStrBuf GetData() const
Definition: C4StringTable.h:50
C4RefCntPointer(C4RefCntPointer< U > &&r)
Definition: C4StringTable.h:64
std::list< const T * > GetSortedListOfElementPointers() const
C4RefCntPointer & operator=(C4RefCntPointer< T > &&r)
Definition: C4StringTable.h:66
void IncRef()
Definition: C4StringTable.h:27
T * Add(T const &e)
C4String * String(const char *str)
Definition: C4AulDefFunc.h:30
#define b
C4String * FindString(const char *strString) const
bool Has(H e) const
static unsigned int Hash(const H &)
const char * GetCStr() const
Definition: C4StringTable.h:49
C4String * RegString(StdStrBuf String)
C4StringTable Strings
Definition: C4Globals.cpp:42
void Clear()
#define a
C4RefCntPointer(C4RefCntPointer< T > &&r)
Definition: C4StringTable.h:63
C4RefCntPointer(const C4RefCntPointer< U > &r)
Definition: C4StringTable.h:61
T * Add(T &&e)
C4RefCntPointer(const C4RefCntPointer< T > &r)
Definition: C4StringTable.h:60
virtual ~C4StringTable()
T & Get(H e) const
T const * Next(T const *p) const
StdStrBuf getRef() const
Definition: StdBuf.h:462
unsigned int GetSize() const
T * Get() const
unsigned int RefCnt
Definition: C4StringTable.h:31
static bool Equals(const T &a, const T &b)
C4String * RegString(const char *s)
unsigned int Hash
Definition: C4StringTable.h:37
C4Set & operator=(const C4Set &b)
void Remove(H e)
C4PropertyName
~C4String() override
C4Set(const C4Set &b)
static bool Equals(const T &, const H &)
static bool SortFunc(const T *p1, const T *p2)
virtual ~C4RefCnt()=default
T const * First() const
void DecRef()
Definition: C4StringTable.h:28
#define s
C4RefCnt()=default
void Swap(C4Set< T > *S2)