HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
UT_JSONValueMap.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_JSONValueMap.h ( UT Library, C++)
7  *
8  * COMMENTS: The order is maintained as objects are added to the map
9  */
10 
11 #ifndef __UT_JSONValueMap__
12 #define __UT_JSONValueMap__
13 
14 #include "UT_API.h"
15 #include "UT_Array.h"
16 #include "UT_ArrayStringMap.h"
17 #include "UT_StringArray.h"
18 #include "UT_StringHolder.h"
19 #include "UT_JSONValue.h"
20 #include <SYS/SYS_AtomicInt.h>
21 #include <SYS/SYS_Compiler.h>
22 #include <SYS/SYS_Types.h>
23 #include <SYS/SYS_Hash.h>
24 
25 #include <stdexcept>
26 
27 class UT_JSONValueArray;
28 class UT_JSONWriter;
29 
30 /// @brief UT_JSONValueMap stores a map/dictionary of UT_JSONValue objects
31 ///
32 /// UT_JSONValueMap stores a map of UT_JSONValue objects. Unlike a standard
33 /// Houdini UT_StringMap, this object maintains the sort order in which
34 /// objects were added.
35 ///
36 /// @see UT_JSONValue, UT_JSONValueArray
38 public:
40  ~UT_JSONValueMap();
41 
42  /// Reference count (for shared maps).
43  void bumpRef(int d)
44  {
45  if (!myRef.add(d))
46  delete this;
47  }
48  /// Get the number of references to this map.
49  SYS_NO_DISCARD_RESULT int getRef() const { return myRef.relaxedLoad(); }
50 
51  /// Maps are typically stored as shared pointers. This method will make a
52  /// unique copy. May return "this" (if the reference count is already unique).
53  UT_JSONValueMap *makeUnique() const;
54 
55  /// Save to an output stream
56  bool save(UT_JSONWriter &os) const;
57 
58  /// Dump to stdout (same as save to std::cout)
59  void dump() const;
60 
61  /// Get the list of keys
62  int64 getKeys(UT_StringArray &keys) const;
63 
64  /// Get a list of the keys. However, rather than duplicating the string
65  /// values, this method simply keeps shallow references. While it's more
66  /// efficient, it's also relies on the fact that the map will not change
67  /// while the string array exists.
68  int64 getKeyReferences(UT_StringArray &keys) const;
69 
70  /// Return the number of entries in the map
72  { return myArray.entries(); }
74  { return myArray.entries(); }
75 
76  /// Clear the entries in the map.
77  void clear();
78 
79  /// Access const entry by index
81  { return get(i); }
82  /// Access entry by index
84  { return get(i); }
85  /// Access const entry by name (may be NULL pointer if k is not a key)
87  { return get(k); }
88  /// Access entry by name (may be NULL pointer if k is not a key)
90  { return get(k); }
91 
92  /// Access const entry by index
94  { return get(i); }
95  /// Access entry by index
97  { return get(i); }
98  /// Access const entry by name (may be NULL pointer if k is not a key)
100  { return get(k); }
101  /// Access entry by name (may be NULL pointer if k is not a key)
103  { return get(k); }
104 
105  /// Access a const entry by index
107  { return myArray(i); }
108  /// Access an entry by index
110  { return myArray(i); }
111  /// Access const entry by name (may be NULL pointer if k is not a key)
112  SYS_NO_DISCARD_RESULT const UT_JSONValue *get(const UT_StringRef &k) const;
113  /// Access entry by name (may be NULL pointer if k is not a key)
115 
116  /// Access entry by name. If not found the default value is returned.
117  SYS_NO_DISCARD_RESULT int32 get(const UT_StringRef& key, int32 def_value) const;
118  /// Access entry by name. If not found the default value is returned.
119  SYS_NO_DISCARD_RESULT int64 get(const UT_StringRef& key, int64 def_value) const;
120  /// Access entry by name. If not found the default value is returned.
121  SYS_NO_DISCARD_RESULT UT_StringHolder get(const UT_StringRef& key, const UT_StringRef& def_value) const;
122  /// Access entry by name. If not found the default value is returned.
123  SYS_NO_DISCARD_RESULT UT_StringArray get(const UT_StringRef& key, const UT_StringArray& def_value) const;
124 
125  /// Access const object entry by name (may be NULL pointer if k is not a key)
126  /// This is a convenience function to get() if we know the key is an object.
127  SYS_NO_DISCARD_RESULT const UT_JSONValueMap *getObject(const UT_StringRef& k) const;
128  /// Access object entry by name (may be NULL pointer if k is not a key)
129  /// This is a convenience function to get() if we know the key is an object.
131  /// Access const array entry by name (may be NULL pointer if k is not a key)
132  /// This is a convenience function to get() if we know the key is an array.
133  SYS_NO_DISCARD_RESULT const UT_JSONValueArray* getArray(const UT_StringRef& k) const;
134  /// Access array entry by name (may be NULL pointer if k is not a key)
135  /// This is a convenience function to get() if we know the key is an array.
137 
139  {
140  UT_JSONValue *operator->() { return myValue; }
141  UT_JSONValue &operator*() { return *myValue; }
142  int64 index() const { return myIndex; }
143  UT_JSONValue *value() const { return myValue; }
144 
145  bool inserted() const { return second; }
146  bool replaced() const { return !second; }
147 
150  // second is a bool that mimics the std::map::insert() return value.
151  // It's true if the value was inserted. However, when it's false, the
152  // value in the map was @b REPLACED
153  bool second;
154  };
155 
156  /// Add key/value pair to the map. If the key already exists, the previous
157  /// value will be deleted.
159  const UT_JSONValue& value);
160 
161  /// Emplace a value into the map
162  template <typename... ARGS>
163  InsertResult emplace(const UT_StringHolder &key, ARGS&&... args)
164  {
165  return insert(key, UT_JSONValue(std::forward<ARGS>(args)...));
166  }
167 
168  /// Remove key/value pair from the map.
169  /// Do nothing if the key does not exist.
170  void remove(const UT_StringHolder &key);
171 
172  /// Rename a key in the map.
173  /// Do nothing if the old key does not exist.
174  /// If the old key exists and another entry uses the new key
175  /// then remove the other entry and rename the entry with the old key.
176  void rename(
177  const UT_StringHolder &old_key,
178  const UT_StringHolder &new_key);
179 
180  /// Adds a new array child to this map.
181  UT_JSONValueArray *addArrayChild(const UT_StringHolder &map_key);
182 
183  /// Adds a new map child to this map.
184  UT_JSONValueMap *addMapChild(const UT_StringHolder &map_key);
185 
186  /// Key/Value imports. See UT_JSONValue for all available import types.
187  /// Returns false if the key isn't in the map, or if the import from the
188  /// UT_JSONValue fails.
189  template <typename T>
190  bool import(const UT_StringRef &key, T &result) const;
191 
192  SYS_NO_DISCARD_RESULT SYS_HashType hash() const;
193  /// @{
194  /// Check equality
195  SYS_NO_DISCARD_RESULT bool operator==(const UT_JSONValueMap &arr) const;
197  { return !(*this == arr); }
198  /// @}
199 
200 
201 private:
202  using BaseMap = UT_ArrayStringMap<UT_JSONValue *>;
203 
205 
206  /// Iterator functionality so we can utilize C++11 range base for loops.
207  /// C++17 has deprecated inheritance from std::iterator.
208  /// We could easily promote myMap's iterators here but then we wouldn't
209  /// respect the 'append' order.
210 public:
211  class iterator
212  {
213  public:
214  iterator(exint _num, UT_JSONValueMap *_obj) : myIndex(_num), myObj(_obj){}
216  {
217  if (myIndex < myObj->myArray.entries())
218  ++myIndex;
219  return *this;
220  }
222  {
223  iterator retval = *this; ++(*this);
224  return retval;
225  }
227  {
228  if (myIndex > 0)
229  --myIndex;
230  return *this;
231  }
233  {
234  iterator retval = *this; --(*this);
235  return retval;
236  }
237  bool operator==(const iterator &other) const {return (myObj == other.myObj) && (myIndex == other.myIndex);}
238  bool operator!=(const iterator &other) const {return !(*this == other);}
240  {
241  return *myObj->getItemAt_(myIndex);
242  }
244  {
245  return myObj->getItemAt_(myIndex);
246  }
247 
248  // iterator traits
251  using pointer = const exint*;
252  using reference = const exint&;
253  using iterator_category = std::forward_iterator_tag;
254  private:
255  exint myIndex = 0;
256  UT_JSONValueMap *myObj;
257  };
258  iterator begin() { return iterator(0, this); }
259  iterator end() { return iterator(this->myArray.entries(), this); }
260  using const_iterator = const iterator;
261  const_iterator begin() const { return iterator(0, SYSconst_cast(this)); }
262  const_iterator end() const { return iterator(this->myArray.entries(), SYSconst_cast(this)); }
263 
264 private:
265  UT_Array<UT_JSONValue *> myArray;
266  BaseMap myMap;
267  SYS_AtomicInt32 myRef;
268 
269  friend class iterator;
270 };
271 
272 #endif
273 
const_iterator begin() const
void bumpRef(int d)
Reference count (for shared maps).
UT_JSONValueMap stores a map/dictionary of UT_JSONValue objects.
int int32
Definition: SYS_Types.h:39
SYS_NO_DISCARD_RESULT const UT_JSONValue * operator()(int64 i) const
Access const entry by index.
SYS_NO_DISCARD_RESULT UT_JSONValue * operator[](const UT_StringRef &k)
Access entry by name (may be NULL pointer if k is not a key)
SYS_NO_DISCARD_RESULT int64 entries() const
Return the number of entries in the map.
BaseMap::value_type value_type
SYS_NO_DISCARD_RESULT UT_JSONValue * operator[](int64 i)
Access entry by index.
UT_JSONValueArray stores a list of UT_JSONValue objects.
SYS_NO_DISCARD_RESULT bool operator!=(const UT_JSONValueMap &arr) const
SYS_FORCE_INLINE T * SYSconst_cast(const T *foo)
Definition: SYS_Types.h:136
int64 exint
Definition: SYS_Types.h:125
std::size_t SYS_HashType
Define the type for hash values.
Definition: SYS_Hash.h:19
#define UT_API
Definition: UT_API.h:14
Class which writes ASCII or binary JSON streams.
Definition: UT_JSONWriter.h:37
**But if you need a result
Definition: thread.h:613
UT_JSONValue * value() const
BaseMap::value_type * operator->()
SYS_NO_DISCARD_RESULT const UT_JSONValue * operator[](const UT_StringRef &k) const
Access const entry by name (may be NULL pointer if k is not a key)
OIIO_FORCEINLINE vbool4 insert(const vbool4 &a, bool val)
Helper: substitute val for a[i].
Definition: simd.h:3436
uint64 value_type
Definition: GA_PrimCompat.h:29
bool operator==(const iterator &other) const
bool operator!=(const iterator &other) const
bool operator==(const BaseDimensions< T > &a, const BaseDimensions< Y > &b)
Definition: Dimensions.h:137
SYS_NO_DISCARD_RESULT const UT_JSONValue * operator[](int64 i) const
Access const entry by index.
BaseMap::value_type & operator*()
long long int64
Definition: SYS_Types.h:116
#define SYS_NO_DISCARD_RESULT
Definition: SYS_Compiler.h:93
iterator(exint _num, UT_JSONValueMap *_obj)
SYS_NO_DISCARD_RESULT const UT_JSONValue * operator()(const UT_StringRef &k) const
Access const entry by name (may be NULL pointer if k is not a key)
SYS_NO_DISCARD_RESULT UT_JSONValue * operator()(int64 i)
Access entry by index.
SYS_NO_DISCARD_RESULT UT_JSONValue * operator()(const UT_StringRef &k)
Access entry by name (may be NULL pointer if k is not a key)
OIIO_UTIL_API bool rename(string_view from, string_view to, std::string &err)
GLuint index
Definition: glcorearb.h:786
std::forward_iterator_tag iterator_category
SYS_NO_DISCARD_RESULT int getRef() const
Get the number of references to this map.
Class to store JSON objects as C++ objects.
Definition: UT_JSONValue.h:99
**If you just want to fire and args
Definition: thread.h:609
Definition: core.h:1131
SYS_NO_DISCARD_RESULT int64 size() const
InsertResult emplace(const UT_StringHolder &key, ARGS &&...args)
Emplace a value into the map.
const_iterator end() const