HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
typeInfoMap.h
Go to the documentation of this file.
1 //
2 // Copyright 2016 Pixar
3 //
4 // Licensed under the Apache License, Version 2.0 (the "Apache License")
5 // with the following modification; you may not use this file except in
6 // compliance with the Apache License and the following modification to it:
7 // Section 6. Trademarks. is deleted and replaced with:
8 //
9 // 6. Trademarks. This License does not grant permission to use the trade
10 // names, trademarks, service marks, or product names of the Licensor
11 // and its affiliates, except as required to comply with Section 4(c) of
12 // the License and to reproduce the content of the NOTICE file.
13 //
14 // You may obtain a copy of the Apache License at
15 //
16 // http://www.apache.org/licenses/LICENSE-2.0
17 //
18 // Unless required by applicable law or agreed to in writing, software
19 // distributed under the Apache License with the above modification is
20 // distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
21 // KIND, either express or implied. See the Apache License for the specific
22 // language governing permissions and limitations under the Apache License.
23 //
24 #ifndef PXR_BASE_TF_TYPE_INFO_MAP_H
25 #define PXR_BASE_TF_TYPE_INFO_MAP_H
26 
27 /// \file tf/typeInfoMap.h
28 /// \ingroup group_tf_RuntimeTyping
29 /// \ingroup group_tf_Containers
30 
31 #include "pxr/pxr.h"
32 
33 #include "pxr/base/tf/hash.h"
34 #include "pxr/base/tf/iterator.h"
35 
36 #include "pxr/base/tf/hashmap.h"
37 
38 #include <typeinfo>
39 #include <string>
40 #include <list>
41 
43 
44 /// \class TfTypeInfoMap
45 /// \ingroup group_tf_RuntimeTyping
46 /// \ingroup group_tf_Containers
47 ///
48 /// A map whose key is a const std::type_info&, or a string alias.
49 ///
50 /// A \c TfTypeInfoMap stores values of arbitrary type (template parameter
51 /// VALUE) under a key that is either a \c const \c std::type_info&, or an \c
52 /// std::string. Note that the \c std::type_info structure is many-to-one
53 /// with respect to its name, i.e. two distinct instances of a \c
54 /// std::type_info can represent the same type. Thus, a naive implementation
55 /// that does pointer comparison on the address of a \c std::type_info can
56 /// fail. The \c TfTypeInfoMap takes care of this aliasing.
57 ///
58 /// Additionally, the table lets one create additional string aliases for a
59 /// given entry.
60 ///
61 template <class VALUE>
63  TfTypeInfoMap(const TfTypeInfoMap&) = delete;
64  TfTypeInfoMap& operator=(const TfTypeInfoMap&) = delete;
65 public:
66 
67  // Default constructor passes 0 to TfHashMap constructors to keep size
68  // small. This is good since each defined TfType has one of these maps in it.
69  TfTypeInfoMap() : _nameMap(0), _stringCache(0) {}
70 
71  /// Return true if the given key is present in the map.
72  bool Exists(const std::type_info& key) const {
73  return Find(key) != NULL;
74  }
75 
76  /// Return true if the given key is present in the map.
77  ///
78  /// Note that lookup by \c std::type_info is preferable for speed reasons.
79  bool Exists(const std::string& key) const {
80  return Find(key) != NULL;
81  }
82 
83  /// Return a pointer to the value stored under \p key, and NULL if \p key
84  /// is not a key in the map.
85  VALUE* Find(const std::type_info& key) const {
86  typename _TypeInfoCache::const_iterator i = _typeInfoCache.find(&key);
87  if (i != _typeInfoCache.end())
88  return &i->second->value;
89  else if (VALUE* v = Find(key.name())) {
90  return v;
91  }
92  return NULL;
93  }
94 
95  /// Return a pointer to the value stored under \p key, and NULL if \p key
96  /// is not a key in the map. For efficiency of future lookups this will
97  /// cache the result if it falls back to a string based lookup. In that
98  /// case before updating the cache it will call the functor \p upgrader
99  /// to allow the client to upgrade any lock to exclusive access.
100  template <class Upgrader>
101  VALUE* Find(const std::type_info& key, Upgrader& upgrader) {
102  typename _TypeInfoCache::const_iterator i = _typeInfoCache.find(&key);
103  if (i != _typeInfoCache.end())
104  return &i->second->value;
105  else if (VALUE* v = Find(key.name())) {
106  upgrader();
107  _CreateAlias(key, key.name());
108  return v;
109  }
110  return NULL;
111  }
112 
113  /// Return a pointer to the value stored under \p key, and NULL if \p key
114  /// is not a key in the map.
115  ///
116  /// Note that lookup by \c std::type_info is preferable for speed reasons.
117  VALUE* Find(const std::string& key) const {
118  typename _StringCache::const_iterator i = _stringCache.find(key);
119  return (i == _stringCache.end()) ? NULL : &i->second->value;
120  }
121 
122  /// Set the value for a given key.
123  ///
124  /// Note that if \p key is not already in the table, this creates a new
125  /// entry. Also, \p key.name() is automatically made linked with this
126  /// entry, so that future queries can be made via \p key.name(), though
127  /// lookup by \c std::type_info is greatly preferred.
128  void Set(const std::type_info& key, const VALUE& value) {
129  if (VALUE* v = Find(key))
130  *v = value;
131  else {
132  Set(key.name(), value);
133  _CreateAlias(key, key.name());
134  }
135  }
136 
137  /// Set the value for a given key.
138  ///
139  /// Note that if \p key is not already in the table, this creates a new
140  /// entry. Also, lookup by \c std::type_info is preferable for speed
141  /// reasons.
142  void Set(const std::string& key, const VALUE& value) {
143  typename _StringCache::iterator i = _stringCache.find(key);
144 
145  if (i != _stringCache.end())
146  i->second->value = value;
147  else {
148  _Entry* e = &_nameMap[key];
149  e->primaryKey = key;
150  e->value = value;
151 
152  _stringCache[key] = e;
153  e->stringAliases.push_back(key);
154  }
155  }
156 
157  /// Create an alias for a key.
158  ///
159  /// Queries with a key of \p alias will return the same data associated
160  /// with queries for \p key.
161  ///
162  /// If \p key is not presently a member of the map, this function does
163  /// nothing and returns \c false.
164  bool CreateAlias(const std::string& alias, const std::string& key) {
165  typename _StringCache::iterator i = _stringCache.find(key);
166  if (i != _stringCache.end())
167  return (_CreateAlias(alias, i->second), true);
168  else
169  return false;
170  }
171 
172  /// \overload
173  bool CreateAlias(const std::string& alias, const std::type_info& key) {
174  typename _TypeInfoCache::iterator i = _typeInfoCache.find(&key);
175  if (i != _typeInfoCache.end())
176  return (_CreateAlias(alias, i->second), true);
177  else
178  return false;
179  }
180 
181  /// Remove this key (and any aliases associated with it).
182  void Remove(const std::type_info& key) {
183  Remove(key.name());
184  }
185 
186  /// Remove this key (and any aliases associated with it).
187  void Remove(const std::string& key) {
188  typename _StringCache::iterator i = _stringCache.find(key);
189  if (i == _stringCache.end())
190  return;
191 
192  _Entry* e = i->second;
193 
194  for (TfIterator<_TypeInfoList> j = e->typeInfoAliases; j; ++j) {
195  _typeInfoCache.erase(*j);
196  }
197 
198  for (TfIterator<std::list<std::string> > j = e->stringAliases; j; ++j) {
199  _stringCache.erase(*j);
200  }
201 
202  // `e` points into the node owned by _nameMap. Passing
203  // e->primaryKey to erase() would cause the node to be
204  // deleted. However, the implementation of erase may access
205  // the key again after the node has been deleted (at least,
206  // when TfHashMap is __gnu_cxx::hash_map.)
207  const std::string primaryKey = std::move(e->primaryKey);
208  _nameMap.erase(primaryKey);
209  }
210 
211 private:
212  typedef std::list<const std::type_info*> _TypeInfoList;
213 
214  struct _Entry {
215  mutable _TypeInfoList typeInfoAliases;
216  mutable std::list<std::string> stringAliases;
217  std::string primaryKey;
218  VALUE value;
219  };
220 
221  void _CreateAlias(const std::type_info& alias, const std::string& key) {
222  typename _StringCache::iterator i = _stringCache.find(key);
223  if (i != _stringCache.end())
224  _CreateAlias(alias, i->second);
225  }
226 
227  void _CreateAlias(const std::type_info& alias, _Entry* e) {
228  if (_typeInfoCache.find(&alias) == _typeInfoCache.end()) {
229  _typeInfoCache[&alias] = e;
230  e->typeInfoAliases.push_back(&alias);
231  }
232  }
233 
234  void _CreateAlias(const std::string& alias, _Entry* e) {
235  if (_stringCache.find(alias) == _stringCache.end()) {
236  _stringCache[alias] = e;
237  e->stringAliases.push_back(alias);
238  }
239  }
240 
243  _TypeInfoCache;
244  typedef TfHashMap<std::string, _Entry*, TfHash> _StringCache;
245 
246  _NameMap _nameMap;
247 
248  _TypeInfoCache _typeInfoCache;
249  _StringCache _stringCache;
250 };
251 
253 
254 #endif // PXR_BASE_TF_TYPE_INFO_MAP_H
void Remove(const std::string &key)
Remove this key (and any aliases associated with it).
Definition: typeInfoMap.h:187
const GLdouble * v
Definition: glcorearb.h:837
bool Exists(const std::string &key) const
Definition: typeInfoMap.h:79
iterator end()
Definition: hashmap.h:318
GLsizei const GLchar *const * string
Definition: glcorearb.h:814
GLsizei const GLfloat * value
Definition: glcorearb.h:824
VALUE * Find(const std::type_info &key, Upgrader &upgrader)
Definition: typeInfoMap.h:101
bool Exists(const std::type_info &key) const
Return true if the given key is present in the map.
Definition: typeInfoMap.h:72
bool CreateAlias(const std::string &alias, const std::type_info &key)
Definition: typeInfoMap.h:173
VALUE * Find(const std::string &key) const
Definition: typeInfoMap.h:117
void Set(const std::type_info &key, const VALUE &value)
Definition: typeInfoMap.h:128
GLint j
Definition: glad.h:2733
PXR_NAMESPACE_CLOSE_SCOPE PXR_NAMESPACE_OPEN_SCOPE
Definition: path.h:1432
VALUE * Find(const std::type_info &key) const
Definition: typeInfoMap.h:85
bool CreateAlias(const std::string &alias, const std::string &key)
Definition: typeInfoMap.h:164
#define PXR_NAMESPACE_CLOSE_SCOPE
Definition: pxr.h:91
if(num_boxed_items<=0)
Definition: UT_RTreeImpl.h:697
Definition: core.h:1131
void Remove(const std::type_info &key)
Remove this key (and any aliases associated with it).
Definition: typeInfoMap.h:182
void Set(const std::string &key, const VALUE &value)
Definition: typeInfoMap.h:142