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 {
39 public:
41  ~UT_JSONValueMap();
42 
43  /// Reference count (for shared maps).
44  void bumpRef(int d)
45  {
46  if (!myRef.add(d))
47  delete this;
48  }
49  /// Get the number of references to this map.
50  SYS_NO_DISCARD_RESULT int getRef() const { return myRef.relaxedLoad(); }
51 
52  /// Maps are typically stored as shared pointers. This method will make a
53  /// unique copy. May return "this" (if the reference count is already unique).
54  UT_JSONValueMap *makeUnique() const;
55 
56  /// Save to an output stream
57  bool save(UT_JSONWriter &os) const;
58 
59  /// Dump to stdout (same as save to std::cout)
60  void dump() const;
61 
62  /// Get the list of keys
63  int64 getKeys(UT_StringArray &keys) const;
64 
65  /// Get a list of the keys. However, rather than duplicating the string
66  /// values, this method simply keeps shallow references. While it's more
67  /// efficient, it's also relies on the fact that the map will not change
68  /// while the string array exists.
69  int64 getKeyReferences(UT_StringArray &keys) const;
70 
71  /// Return the number of entries in the map
73  { return myArray.entries(); }
75  { return myArray.entries(); }
76 
77  /// Clear the entries in the map.
78  void clear();
79 
80  /// Access const entry by index
82  { return get(i); }
83  /// Access entry by index
85  { return get(i); }
86  /// Access const entry by name (may be NULL pointer if k is not a key)
88  { return get(k); }
89  /// Access entry by name (may be NULL pointer if k is not a key)
91  { return get(k); }
92 
93  /// Access const entry by index
95  { return get(i); }
96  /// Access entry by index
98  { return get(i); }
99  /// Access const entry by name (may be NULL pointer if k is not a key)
101  { return get(k); }
102  /// Access entry by name (may be NULL pointer if k is not a key)
104  { return get(k); }
105 
106  /// Access a const entry by index
108  { return myArray(i); }
109  /// Access an entry by index
111  { return myArray(i); }
112  /// Access const entry by name (may be NULL pointer if k is not a key)
113  SYS_NO_DISCARD_RESULT const UT_JSONValue *get(const UT_StringRef &k) const;
114  /// Access entry by name (may be NULL pointer if k is not a key)
116 
117  /// Access entry by name. If not found the default value is returned.
118  SYS_NO_DISCARD_RESULT int32 get(const UT_StringRef& key, int32 def_value) const;
119  /// Access entry by name. If not found the default value is returned.
120  SYS_NO_DISCARD_RESULT int64 get(const UT_StringRef& key, int64 def_value) const;
121  /// Access entry by name. If not found the default value is returned.
122  SYS_NO_DISCARD_RESULT UT_StringHolder get(const UT_StringRef& key, const UT_StringRef& def_value) const;
123  /// Access entry by name. If not found the default value is returned.
124  SYS_NO_DISCARD_RESULT UT_StringArray get(const UT_StringRef& key, const UT_StringArray& def_value) const;
125 
126  /// Access const object entry by name (may be NULL pointer if k is not a key)
127  /// This is a convenience function to get() if we know the key is an object.
128  SYS_NO_DISCARD_RESULT const UT_JSONValueMap *getObject(const UT_StringRef& k) const;
129  /// Access object entry by name (may be NULL pointer if k is not a key)
130  /// This is a convenience function to get() if we know the key is an object.
132  /// Access const array entry by name (may be NULL pointer if k is not a key)
133  /// This is a convenience function to get() if we know the key is an array.
134  SYS_NO_DISCARD_RESULT const UT_JSONValueArray* getArray(const UT_StringRef& k) const;
135  /// Access array entry by name (may be NULL pointer if k is not a key)
136  /// This is a convenience function to get() if we know the key is an array.
138 
140  {
141  UT_JSONValue *operator->() { return myValue; }
142  UT_JSONValue &operator*() { return *myValue; }
143  int64 index() const { return myIndex; }
144  UT_JSONValue *value() const { return myValue; }
145 
146  bool inserted() const { return second; }
147  bool replaced() const { return !second; }
148 
151  // second is a bool that mimics the std::map::insert() return value.
152  // It's true if the value was inserted. However, when it's false, the
153  // value in the map was @b REPLACED
154  bool second;
155  };
156 
157  /// Add key/value pair to the map. If the key already exists, the previous
158  /// value will be deleted.
160  const UT_JSONValue& value);
161 
162  /// Emplace a value into the map
163  template <typename... ARGS>
164  InsertResult emplace(const UT_StringHolder &key, ARGS&&... args)
165  {
166  return insert(key, UT_JSONValue(std::forward<ARGS>(args)...));
167  }
168 
169  /// Remove key/value pair from the map.
170  /// Do nothing if the key does not exist.
171  void remove(const UT_StringHolder &key);
172 
173  /// Rename a key in the map.
174  /// Do nothing if the old key does not exist.
175  /// If the old key exists and another entry uses the new key
176  /// then remove the other entry and rename the entry with the old key.
177  void rename(
178  const UT_StringHolder &old_key,
179  const UT_StringHolder &new_key);
180 
181  /// Adds a new array child to this map.
182  UT_JSONValueArray *addArrayChild(const UT_StringHolder &map_key);
183 
184  /// Adds a new map child to this map.
185  UT_JSONValueMap *addMapChild(const UT_StringHolder &map_key);
186 
187  /// Key/Value imports. See UT_JSONValue for all available import types.
188  /// Returns false if the key isn't in the map, or if the import from the
189  /// UT_JSONValue fails.
190  template <typename T>
191  bool import(const UT_StringRef &key, T &result) const;
192 
193  SYS_NO_DISCARD_RESULT SYS_HashType hash() const;
194  /// @{
195  /// Check equality
196  SYS_NO_DISCARD_RESULT bool operator==(const UT_JSONValueMap &arr) const;
198  { return !(*this == arr); }
199  /// @}
200 
201 
202 private:
203  using BaseMap = UT_ArrayStringMap<UT_JSONValue *>;
204 
206 
207  /// Iterator functionality so we can utilize C++11 range base for loops.
208  /// C++17 has deprecated inheritance from std::iterator.
209  /// We could easily promote myMap's iterators here but then we wouldn't
210  /// respect the 'append' order.
211 public:
212  class iterator
213  {
214  public:
215  iterator(exint _num, UT_JSONValueMap *_obj) : myIndex(_num), myObj(_obj){}
217  {
218  if (myIndex < myObj->myArray.entries())
219  ++myIndex;
220  return *this;
221  }
223  {
224  iterator retval = *this; ++(*this);
225  return retval;
226  }
228  {
229  if (myIndex > 0)
230  --myIndex;
231  return *this;
232  }
234  {
235  iterator retval = *this; --(*this);
236  return retval;
237  }
238  bool operator==(const iterator &other) const {return (myObj == other.myObj) && (myIndex == other.myIndex);}
239  bool operator!=(const iterator &other) const {return !(*this == other);}
241  {
242  return *myObj->getItemAt_(myIndex);
243  }
245  {
246  return myObj->getItemAt_(myIndex);
247  }
248 
249  // iterator traits
252  using pointer = const exint*;
253  using reference = const exint&;
254  using iterator_category = std::forward_iterator_tag;
255  private:
256  exint myIndex = 0;
257  UT_JSONValueMap *myObj;
258  };
259  iterator begin() { return iterator(0, this); }
260  iterator end() { return iterator(this->myArray.entries(), this); }
261  using const_iterator = const iterator;
262  const_iterator begin() const { return iterator(0, SYSconst_cast(this)); }
263  const_iterator end() const { return iterator(this->myArray.entries(), SYSconst_cast(this)); }
264 
265 private:
266  UT_Array<UT_JSONValue *> myArray;
267  BaseMap myMap;
268  SYS_AtomicInt32 myRef;
269 
270  friend class iterator;
271 };
272 
273 #endif
274 
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.
GLsizei const GLfloat * value
Definition: glcorearb.h:824
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:622
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:3556
uint64 value_type
Definition: GA_PrimCompat.h:29
bool operator==(const iterator &other) const
bool operator!=(const iterator &other) const
typename set_type::value_type value_type
Definition: UT_ArrayMap.h:99
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:618
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