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 TF_TYPEINFO_MAP_H
25 #define TF_TYPEINFO_MAP_H
26 
30 
31 #include "pxr/pxr.h"
32 
33 #include "pxr/base/tf/hash.h"
34 #include "pxr/base/tf/iterator.h"
35 
36 #include <boost/noncopyable.hpp>
37 #include "pxr/base/tf/hashmap.h"
38 
39 #include <typeinfo>
40 #include <string>
41 #include <list>
42 
43 PXR_NAMESPACE_OPEN_SCOPE
44 
62 template <class VALUE>
63 class TfTypeInfoMap : public boost::noncopyable {
64 public:
65 
66  // Default constructor passes 0 to TfHashMap constructors to keep size
67  // small. This is good since each defined TfType has one of these maps in it.
68  TfTypeInfoMap() : _nameMap(0), _stringCache(0) {}
69 
71  bool Exists(const std::type_info& key) const {
72  return Find(key) != NULL;
73  }
74 
78  bool Exists(const std::string& key) const {
79  return Find(key) != NULL;
80  }
81 
84  VALUE* Find(const std::type_info& key) const {
85  typename _TypeInfoCache::const_iterator i = _typeInfoCache.find(&key);
86  if (i != _typeInfoCache.end())
87  return &i->second->value;
88  else if (VALUE* v = Find(key.name())) {
89  return v;
90  }
91  return NULL;
92  }
93 
99  template <class Upgrader>
100  VALUE* Find(const std::type_info& key, Upgrader& upgrader) {
101  typename _TypeInfoCache::const_iterator i = _typeInfoCache.find(&key);
102  if (i != _typeInfoCache.end())
103  return &i->second->value;
104  else if (VALUE* v = Find(key.name())) {
105  upgrader();
106  _CreateAlias(key, key.name());
107  return v;
108  }
109  return NULL;
110  }
111 
116  VALUE* Find(const std::string& key) const {
117  typename _StringCache::const_iterator i = _stringCache.find(key);
118  return (i == _stringCache.end()) ? NULL : &i->second->value;
119  }
120 
127  void Set(const std::type_info& key, const VALUE& value) {
128  if (VALUE* v = Find(key))
129  *v = value;
130  else {
131  Set(key.name(), value);
132  _CreateAlias(key, key.name());
133  }
134  }
135 
141  void Set(const std::string& key, const VALUE& value) {
142  typename _StringCache::iterator i = _stringCache.find(key);
143 
144  if (i != _stringCache.end())
145  i->second->value = value;
146  else {
147  _Entry* e = &_nameMap[key];
148  e->primaryKey = key;
149  e->value = value;
150 
151  _stringCache[key] = e;
152  e->stringAliases.push_back(key);
153  }
154  }
155 
163  bool CreateAlias(const std::string& alias, const std::string& key) {
164  typename _StringCache::iterator i = _stringCache.find(key);
165  if (i != _stringCache.end())
166  return (_CreateAlias(alias, i->second), true);
167  else
168  return false;
169  }
170 
172  bool CreateAlias(const std::string& alias, const std::type_info& key) {
173  typename _TypeInfoCache::iterator i = _typeInfoCache.find(&key);
174  if (i != _typeInfoCache.end())
175  return (_CreateAlias(alias, i->second), true);
176  else
177  return false;
178  }
179 
181  void Remove(const std::type_info& key) {
182  Remove(key.name());
183  }
184 
186  void Remove(const std::string& key) {
187  typename _StringCache::iterator i = _stringCache.find(key);
188  if (i == _stringCache.end())
189  return;
190 
191  _Entry* e = i->second;
192 
193  for (TfIterator<_TypeInfoList> j = e->typeInfoAliases; j; ++j) {
194  _typeInfoCache.erase(*j);
195  }
196 
197  for (TfIterator<std::list<std::string> > j = e->stringAliases; j; ++j) {
198  _stringCache.erase(*j);
199  }
200 
201  _nameMap.erase(e->primaryKey);
202  }
203 
204 private:
205  typedef std::list<const std::type_info*> _TypeInfoList;
206 
207  struct _Entry {
208  mutable _TypeInfoList typeInfoAliases;
209  mutable std::list<std::string> stringAliases;
210  std::string primaryKey;
211  VALUE value;
212  };
213 
214  void _CreateAlias(const std::type_info& alias, const std::string& key) {
215  typename _StringCache::iterator i = _stringCache.find(key);
216  if (i != _stringCache.end())
217  _CreateAlias(alias, i->second);
218  }
219 
220  void _CreateAlias(const std::type_info& alias, _Entry* e) {
221  if (_typeInfoCache.find(&alias) == _typeInfoCache.end()) {
222  _typeInfoCache[&alias] = e;
223  e->typeInfoAliases.push_back(&alias);
224  }
225  }
226 
227  void _CreateAlias(const std::string& alias, _Entry* e) {
228  if (_stringCache.find(alias) == _stringCache.end()) {
229  _stringCache[alias] = e;
230  e->stringAliases.push_back(alias);
231  }
232  }
233 
234  typedef TfHashMap<std::string, _Entry, TfHash> _NameMap;
235  typedef TfHashMap<const std::type_info*, _Entry*, TfHash>
236  _TypeInfoCache;
237  typedef TfHashMap<std::string, _Entry*, TfHash> _StringCache;
238 
239  _NameMap _nameMap;
240 
241  _TypeInfoCache _typeInfoCache;
242  _StringCache _stringCache;
243 };
244 
245 PXR_NAMESPACE_CLOSE_SCOPE
246 
247 #endif // TF_TYPEINFO_MAP_H
VALUE * Find(const std::type_info &key, Upgrader &upgrader)
Return a pointer to the value stored under key, and NULL if key is not a key in the map...
Definition: typeInfoMap.h:100
void if(!TfPyIsInitialized())
Invokes wrapFunc to wrap type T if T is not already wrapped.
Definition: pyUtils.h:210
bool Exists(const std::type_info &key) const
Return true if the given key is present in the map.
Definition: typeInfoMap.h:71
void Remove(const std::type_info &key)
Remove this key (and any aliases associated with it).
Definition: typeInfoMap.h:181
A map whose key is a const std::type_info&amp;, or a string alias.
Definition: typeInfoMap.h:63
void Remove(const std::string &key)
Remove this key (and any aliases associated with it).
Definition: typeInfoMap.h:186
void Set(const std::string &key, const VALUE &value)
Set the value for a given key.
Definition: typeInfoMap.h:141
void Set(const std::type_info &key, const VALUE &value)
Set the value for a given key.
Definition: typeInfoMap.h:127
A simple iterator adapter for STL containers.
Definition: iterator.h:176
VALUE * Find(const std::string &key) const
Return a pointer to the value stored under key, and NULL if key is not a key in the map...
Definition: typeInfoMap.h:116
bool CreateAlias(const std::string &alias, const std::string &key)
Create an alias for a key.
Definition: typeInfoMap.h:163
VALUE * Find(const std::type_info &key) const
Return a pointer to the value stored under key, and NULL if key is not a key in the map...
Definition: typeInfoMap.h:84
bool Exists(const std::string &key) const
Return true if the given key is present in the map.
Definition: typeInfoMap.h:78
bool CreateAlias(const std::string &alias, const std::type_info &key)
Definition: typeInfoMap.h:172