HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
UT_SymbolTable.h
Go to the documentation of this file.
1 /*
2  * PROPRIETARY INFORMATION. This software is proprietary to
3  * Side Effects Software Inc., and is not to be reproduced,
4  * transmitted, or disclosed in any way without written permission.
5  *
6  * NAME: UT_SymbolTable.h
7  *
8  * COMMENTS:
9  */
10 
11 #ifndef __UT_SymbolTable_h__
12 #define __UT_SymbolTable_h__
13 
14 #include "UT_API.h"
15 #include "UT_ContainerPrinter.h"
16 #include "UT_IteratorRange.h"
17 #include "UT_NonCopyable.h"
18 #include "UT_StringMap.h"
19 #include <SYS/SYS_Types.h>
20 
21 #include <iterator>
22 #include <iosfwd>
23 
24 #include <stdio.h>
25 
26 /// A UT_SymbolMap contains a UT_Map but provides the interface
27 /// required by what was UT_SymbolTable. Strings are passed as <tt>const char
28 /// *</tt>.
29 template <typename ITEM_T>
30 class UT_SymbolMap
31 {
32 public:
35  typedef typename MapType::iterator map_iterator;
36  typedef ITEM_T value_type;
37 
38  /// Constructor
39  explicit UT_SymbolMap()
40  : myMap()
41  {
42  }
43  /// Destructor
45  {
46  clear();
47  }
48 
50 
51  /// Add a symbol to the map
53  {
54  (*this)[symbol] = data;
55  }
56  /// Find a symbol in the map. If the symbol is found, the data pointer
57  /// passed in will be assigned to the ITEM_T in the map.
58  bool findSymbol(const UT_StringRef &symbol, ITEM_T *datap) const
59  {
60  const_map_iterator it = myMap.find(symbol);
61  if (it != myMap.end())
62  {
63  if (datap)
64  *datap = it->second;
65  return true;
66  }
67  return false;
68  }
69 
70  /// Find a symbol and return an iterator. Returns map_end() if the symbol
71  /// is not found in the map.
72  /// @{
74  {
75  return myMap.find(symbol);
76  }
77  const_map_iterator find(const UT_StringRef &symbol) const
78  {
79  return myMap.find(symbol);
80  }
81  /// @}
82 
83  /// Check if a symbol exists
84  bool contains(const UT_StringRef &symbol) const
85  { return myMap.count(symbol) > 0; }
86  /// Find out how many times a symbol exists (this will be either 0 or 1).
87  exint count(const UT_StringRef &symbol) const
88  { return myMap.count(symbol); }
89 
90  /// Erase a symbol from the map
91  bool deleteSymbol(const UT_StringRef &symbol)
92  {
93  myMap.erase(symbol);
94  return true;
95  }
96  /// @{
97  /// Erase a symbol from the map
98  exint erase(const UT_StringRef &symbol)
99  {
100  return myMap.erase(symbol);
101  }
103  {
104  return myMap.erase(it);
105  }
106  /// @}
107  /// Clear the map
108  void clear()
109  {
110  myMap.clear();
111  }
112 
113  /// Add a symbol and return the string reference
114  const char *addSymbolAndGetReference(const UT_StringHolder &symbol,
115  const ITEM_T &data)
116  {
117  addSymbol(symbol, data);
118 
119  UT_ASSERT_P(myMap.find(symbol) != myMap.end());
120  return myMap.find(symbol)->first.c_str();
121  }
122 
123 
124  /// @{
125  /// Query the number of elements in the map
126  exint entries() const { return myMap.size(); }
127  exint size() const { return myMap.size(); }
128  /// @}
129 
130  /// @{
131  /// Information about the buckets
132  exint bucket_count() const { return myMap.bucket_count(); }
133  exint capacity() const
134  { return exint(myMap.bucket_count()*myMap.max_load_factor()); }
135  /// @}
136 
137  /// Check if the map is empty
138  bool empty() const { return myMap.empty(); }
139 
140  /// Retrieve an entry in the table by name, creating it if it doesn't
141  /// already exist.
142  ITEM_T &operator[](const UT_StringHolder &symbol)
143  {
144  return myMap[symbol];
145  }
146  ITEM_T &insert(const UT_StringHolder &name, const ITEM_T &item)
147  {
148  // Assign and return the reference in the map
149  return ((*this)[name] = item);
150  }
151 
152  /// Call this method when you're adding entries to a table inside a loop
153  /// and you know how many entries you'll be adding. This will create at
154  /// least @c size buckets but also ensure the load factor is less than the
155  /// maximum load factor.
157  { myMap.rehash(size); }
158 
159  /// Get current load factor
160  float getLoadFactor() const
161  { return myMap.load_factor(); }
162 
163  /// @{
164  /// Adjust the maximum/minimum load factors
165  /// The table will automatically rebuild itself to keep the load factor
166  /// within the specified range. A minimum load factor of 0 means that
167  /// the table will never shrink when elements are deleted from it.
168  float getMaxLoadFactor() const
169  { return myMap.max_load_factor(); }
170  void setMaxLoadFactor(float f)
171  { myMap.max_load_factor(f); }
172  float getMinLoadFactor() const
173  { return 0.; }
174  void setMinLoadFactor(float) {}
175  /// @}
176 
177  /// Merge the specified table with ourselves.
179  {
180  const_map_iterator it, last;
181  last = table.map_end();
182  for (it = table.map_begin(); it != last; ++it)
183  (*this)[it->first] = it->second;
184  }
185 
186  /// "getStringReference" returns a pointer to the actual string that
187  /// is maintained in the symbol table. This can be used to implement
188  /// a shared string symbol table.
189  const char *getStringReference(const UT_StringRef &symbol)
190  {
191  const_map_iterator it = myMap.find(symbol);
192  if (it == map_end())
193  {
194  // If we don't have an entry, we create one. Duh.
195  return addSymbolAndGetReference(symbol, ITEM_T());
196  }
197  return it->first.c_str();
198  }
199 
200  /// Returns a unique key based using the passed-in string as a prefix.
201  UT_StringHolder makeUniqueKey(const char *name) const
202  {
203  if (!UTisstring(name))
204  return UT_StringHolder();
205 
206  UT_String s(name);
207  while (myMap.find(s) != myMap.end())
209 
211  n.adoptFromString(s);
212  return n;
213  }
214 
215  /// Return an approximation of how much memory we use
216  int64 getMemoryUsage(bool inclusive) const
217  {
218  int64 mem = inclusive ? sizeof(*this) : 0;
219  mem += myMap.getMemoryUsage(false);
220  // The keys store copies of the strings if SAFE_STRINGS, so we need to count them
221  for (const_map_iterator it = myMap.begin(); it != myMap.end(); ++it)
222  mem += it->first.getMemoryUsage(false);
223  return mem;
224  }
225 
226  /// @{
227  /// "traverse" invokes the given function with every member of the symbol
228  /// table. The order of traversal is undefined. If the function returns a
229  /// non-zero value the traversal continues. If it returns zero then
230  /// traversal stops. The return value is zero if the traversal was
231  /// interupted and one otherwise.
232  ///
233  /// Call traverseConst() if you will not be removing things from the
234  /// table while traversing, and traverse() if you might be. It is only
235  /// safe to remove the current item when using traverse() -- not other
236  /// items. If you call traverse() and add something to the table, you
237  /// may or may not encounter it later in the traversal.
239  int (*function)(ITEM_T &, const char *, void *),
240  void *data) const
241  {
242  for (const_map_iterator it = map_begin(); it != map_end(); ++it)
243  {
244  if (!function(const_cast<ITEM_T &>(it->second),
245  it->first.c_str(), data))
246  {
247  return 0;
248  }
249  }
250  return 1;
251  }
252  int traverse(int (*function)(ITEM_T &, const char *, void *),
253  void *data)
254  {
255  for (map_iterator it = map_begin(); it != map_end(); )
256  {
257  // Increment before calling the functor to ensure
258  // that 'it' remains valid even if we delete the
259  // current element. It's still unsafe to delete
260  // the next element.
261  map_iterator curr = it++;
262  if (!function(curr->second, curr->first.c_str(), data))
263  {
264  return 0;
265  }
266  }
267  return 1;
268  }
269  /// @}
270 
271  /// Iterator conforming to Houdini's atEnd(), advance() interface
272  template<typename T, typename IT>
274  {
275  public:
276  using iterator_category = std::forward_iterator_tag;
277  using value_type = T;
278  using difference_type = std::ptrdiff_t;
279  using pointer = T*;
280  using reference = T&;
281 
283  : myIt()
284  , myEnd()
285  {}
286 
287  // Converting constructor to const_iterator
288  template<typename ET, typename EIT>
290  : myIt(src.myIt), myEnd(src.myEnd) {}
291 
292  reference value() const { return const_cast<T &>(myIt->second); }
293  reference operator*() const { return thing(); }
294  pointer operator->() const { return &thing(); }
295 
296  reference thing() const { return value(); }
297 
298  const UT_StringHolder &key() const
299  { return myIt->first; }
300  const char *name() const
301  { return key().c_str(); }
302 
304  {
305  return myIt == cmp.myIt;
306  }
308  { return !(*this == cmp); }
309 
310  bool atEnd() const
311  {
312  return myIt == myEnd;
313  }
314 
316  {
317  ++myIt;
318  return *this;
319  }
320 
321  private:
322  base_iterator(const IT &it,
323  const IT &end)
324  : myIt(it)
325  , myEnd(end)
326  {}
327 
328  IT myIt, myEnd;
329 
330  friend class UT_SymbolMap<ITEM_T>;
331  };
332 
333  typedef base_iterator<ITEM_T, map_iterator> iterator;
334  typedef base_iterator<const ITEM_T, const_map_iterator> const_iterator;
335 
337 
338  iterator begin() { return iterator(myMap.begin(), myMap.end()); }
339  iterator end() { return iterator(myMap.end(), myMap.end()); }
340  const_iterator begin() const { return const_iterator(myMap.begin(), myMap.end()); }
341  const_iterator end() const { return const_iterator(myMap.end(), myMap.end()); }
342 
343  const_map_iterator map_begin() const { return myMap.begin(); }
344  const_map_iterator map_end() const { return myMap.end(); }
345  map_iterator map_begin() { return myMap.begin(); }
346  map_iterator map_end() { return myMap.end(); }
347 
349  { return UTmakeRange(myMap.begin(), myMap.end()); }
351  { return UTmakeRange(myMap.begin(), myMap.end()); }
352 
353  /// Write out some statistics pertaining to the underlying map container to
354  /// the output stream given.
355  void outputStats(std::ostream &os) const;
356 protected:
357  template<typename OS, typename T>
358  friend OS &operator<<(OS &os, const UT_SymbolMap<T> &d);
359 
361 };
362 
363 // Put implementation of outputStats() into .C file to avoid including iostream
364 namespace UT_SymbolTableDetail
365 {
366  UT_API extern
367  void outputStats(
368  std::ostream &os,
369  exint size,
370  exint bucket_count,
371  exint capacity,
372  float load_factor,
373  float min_load_factor,
374  float max_load_factor);
375 }
376 
377 template <typename T>
378 void
379 UT_SymbolMap<T>::outputStats(std::ostream &os) const
380 {
382  os, size(), bucket_count(), capacity(),
383  getLoadFactor(), getMinLoadFactor(), getMaxLoadFactor());
384 }
385 
386 template<typename OS, typename T>
387 inline OS &
388 operator<<(OS &os, const UT_SymbolMap<T> &d)
389 {
390  os << d.myMap;
391  return os;
392 }
393 
394 
395 #endif
exint capacity() const
void adoptFromString(UT_String &str)
ITEM_T & operator[](const UT_StringHolder &symbol)
UT_IteratorRange< map_iterator > map_range()
ITEM_T value_type
exint entries() const
void
Definition: png.h:1083
GLboolean * data
Definition: glcorearb.h:131
ITEM_T & insert(const UT_StringHolder &name, const ITEM_T &item)
int64 getMemoryUsage(bool inclusive) const
Definition: UT_Map.h:151
void setMinLoadFactor(float)
UT_IteratorRange< IterT > UTmakeRange(IterT &&b, IterT &&e)
int64 exint
Definition: SYS_Types.h:125
GLdouble s
Definition: glad.h:3009
void setMaxLoadFactor(float f)
#define UT_API
Definition: UT_API.h:14
int64 getMemoryUsage(bool inclusive) const
Return an approximation of how much memory we use.
const_map_iterator find(const UT_StringRef &symbol) const
void outputStats(std::ostream &os) const
bool operator==(const base_iterator< T, IT > &cmp) const
void clear()
Definition: UT_Map.h:184
base_iterator(const base_iterator< ET, EIT > &src)
int traverseConst(int(*function)(ITEM_T &, const char *, void *), void *data) const
MapType::const_iterator const_map_iterator
Parent::iterator iterator
Definition: UT_StringMap.h:52
base_iterator< const ITEM_T, const_map_iterator > const_iterator
IMATH_HOSTDEVICE constexpr int cmp(T a, T b) IMATH_NOEXCEPT
Definition: ImathFun.h:84
base_iterator< ITEM_T, map_iterator > iterator
const char * name() const
UT_StringHolder makeUniqueKey(const char *name) const
Returns a unique key based using the passed-in string as a prefix.
GLdouble n
Definition: glcorearb.h:2008
GLfloat f
Definition: glcorearb.h:1926
iterator end()
const_iterator traverser
void reserveTableSize(exint size)
#define UT_ASSERT_P(ZZ)
Definition: UT_Assert.h:155
exint erase(const UT_StringRef &symbol)
std::forward_iterator_tag iterator_category
GLuint GLuint end
Definition: glcorearb.h:475
#define UT_NON_COPYABLE(CLASS)
Define deleted copy constructor and assignment operator inside a class.
~UT_SymbolMap()
Destructor.
iterator erase(const_iterator pos)
Definition: UT_StringMap.h:58
base_iterator & operator++()
map_iterator find(const UT_StringRef &symbol)
long long int64
Definition: SYS_Types.h:116
SYS_FORCE_INLINE const char * c_str() const
iterator begin()
map_iterator map_begin()
GLuint const GLchar * name
Definition: glcorearb.h:786
Iterator conforming to Houdini's atEnd(), advance() interface.
UT_StringMap< ITEM_T > MapType
bool contains(const UT_StringRef &symbol) const
Check if a symbol exists.
int traverse(int(*function)(ITEM_T &, const char *, void *), void *data)
exint count(const UT_StringRef &symbol) const
Find out how many times a symbol exists (this will be either 0 or 1).
Parent::const_iterator const_iterator
Definition: UT_StringMap.h:51
GLenum GLenum GLsizei void * table
Definition: glad.h:5129
bool empty() const
Check if the map is empty.
map_iterator erase(const_map_iterator it)
void mergeTable(const UT_SymbolMap &table)
Merge the specified table with ourselves.
void incrementNumberedName(bool preserve_padding=false)
const_iterator end() const
UT_API void outputStats(std::ostream &os, exint size, exint bucket_count, exint capacity, float load_factor, float min_load_factor, float max_load_factor)
GLsizeiptr size
Definition: glcorearb.h:664
const_map_iterator map_begin() const
UT_SymbolMap()
Constructor.
reference value() const
const_map_iterator map_end() const
const_iterator begin() const
exint size() const
const UT_StringHolder & key() const
SYS_FORCE_INLINE bool UTisstring(const char *s)
const char * addSymbolAndGetReference(const UT_StringHolder &symbol, const ITEM_T &data)
Add a symbol and return the string reference.
map_iterator map_end()
bool findSymbol(const UT_StringRef &symbol, ITEM_T *datap) const
reference thing() const
bool operator!=(const base_iterator< T, IT > &cmp) const
UT_IteratorRange< const_map_iterator > map_range() const
#define const
Definition: zconf.h:214
bool deleteSymbol(const UT_StringRef &symbol)
Erase a symbol from the map.
const char * getStringReference(const UT_StringRef &symbol)
reference operator*() const
float getMaxLoadFactor() const
Definition: format.h:895
MapType::iterator map_iterator
float getLoadFactor() const
Get current load factor.
void addSymbol(const UT_StringHolder &symbol, const ITEM_T &data)
Add a symbol to the map.
GLenum src
Definition: glcorearb.h:1793
exint bucket_count() const
float getMinLoadFactor() const