blob: 00e32c98a1d544131c865b033d922da0a3631c8b [file] [log] [blame]
Baptiste Lepilleur7469f1d2010-04-20 21:35:19 +00001// Copyright 2007-2010 Baptiste Lepilleur
2// Distributed under MIT license, or public domain if desired and
3// recognized in your jurisdiction.
4// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE
5
Christopher Dunn6d135cb2007-06-13 15:51:04 +00006#ifndef CPPTL_JSON_H_INCLUDED
Aaron Jacobs9fa4e842014-07-01 08:48:54 +10007#define CPPTL_JSON_H_INCLUDED
Christopher Dunn6d135cb2007-06-13 15:51:04 +00008
Baptiste Lepilleureadc4782011-05-02 21:09:30 +00009#if !defined(JSON_IS_AMALGAMATION)
Aaron Jacobs9fa4e842014-07-01 08:48:54 +100010#include "forwards.h"
Baptiste Lepilleureadc4782011-05-02 21:09:30 +000011#endif // if !defined(JSON_IS_AMALGAMATION)
Aaron Jacobs9fa4e842014-07-01 08:48:54 +100012#include <string>
13#include <vector>
Christopher Dunn6d135cb2007-06-13 15:51:04 +000014
Aaron Jacobs9fa4e842014-07-01 08:48:54 +100015#ifndef JSON_USE_CPPTL_SMALLMAP
16#include <map>
17#else
18#include <cpptl/smallmap.h>
19#endif
20#ifdef JSON_USE_CPPTL
21#include <cpptl/forwards.h>
22#endif
Christopher Dunn6d135cb2007-06-13 15:51:04 +000023
Aaron Jacobs9fa4e842014-07-01 08:48:54 +100024// Disable warning C4251: <data member>: <type> needs to have dll-interface to
25// be used by...
Baptiste Lepilleureafd7022013-05-08 20:21:11 +000026#if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)
Aaron Jacobs9fa4e842014-07-01 08:48:54 +100027#pragma warning(push)
28#pragma warning(disable : 4251)
Baptiste Lepilleureafd7022013-05-08 20:21:11 +000029#endif // if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)
30
Christopher Dunn6d135cb2007-06-13 15:51:04 +000031/** \brief JSON (JavaScript Object Notation).
32 */
33namespace Json {
34
Aaron Jacobs9fa4e842014-07-01 08:48:54 +100035/** \brief Type of the value held by a Value object.
36 */
37enum ValueType {
38 nullValue = 0, ///< 'null' value
39 intValue, ///< signed integer value
40 uintValue, ///< unsigned integer value
41 realValue, ///< double value
42 stringValue, ///< UTF-8 string value
43 booleanValue, ///< bool value
44 arrayValue, ///< array value (ordered list)
45 objectValue ///< object value (collection of name/value pairs).
46};
Christopher Dunn6d135cb2007-06-13 15:51:04 +000047
Aaron Jacobs9fa4e842014-07-01 08:48:54 +100048enum CommentPlacement {
49 commentBefore = 0, ///< a comment placed on the line before a value
50 commentAfterOnSameLine, ///< a comment just after a value on the same line
51 commentAfter, ///< a comment on the line after a value (only make sense for
Aaron Jacobs3a0c4fc2014-07-01 09:20:48 +100052 /// root value)
Aaron Jacobs9fa4e842014-07-01 08:48:54 +100053 numberOfCommentPlacement
54};
Christopher Dunn6d135cb2007-06-13 15:51:04 +000055
56//# ifdef JSON_USE_CPPTL
57// typedef CppTL::AnyEnumerator<const char *> EnumMemberNames;
58// typedef CppTL::AnyEnumerator<const Value &> EnumValues;
59//# endif
60
Aaron Jacobs9fa4e842014-07-01 08:48:54 +100061/** \brief Lightweight wrapper to tag static string.
62 *
63 * Value constructor and objectValue member assignement takes advantage of the
64 * StaticString and avoid the cost of string duplication when storing the
65 * string or the member name.
66 *
67 * Example of usage:
68 * \code
69 * Json::Value aValue( StaticString("some text") );
70 * Json::Value object;
71 * static const StaticString code("code");
72 * object[code] = 1234;
73 * \endcode
74 */
75class JSON_API StaticString {
76public:
77 explicit StaticString(const char *czstring) : str_(czstring) {}
Christopher Dunn6d135cb2007-06-13 15:51:04 +000078
Aaron Jacobs9fa4e842014-07-01 08:48:54 +100079 operator const char *() const { return str_; }
Christopher Dunn6d135cb2007-06-13 15:51:04 +000080
Aaron Jacobs9fa4e842014-07-01 08:48:54 +100081 const char *c_str() const { return str_; }
Christopher Dunn6d135cb2007-06-13 15:51:04 +000082
Aaron Jacobs9fa4e842014-07-01 08:48:54 +100083private:
84 const char *str_;
85};
Christopher Dunn6d135cb2007-06-13 15:51:04 +000086
Aaron Jacobs9fa4e842014-07-01 08:48:54 +100087/** \brief Represents a <a HREF="http://www.json.org">JSON</a> value.
88 *
89 * This class is a discriminated union wrapper that can represents a:
90 * - signed integer [range: Value::minInt - Value::maxInt]
91 * - unsigned integer (range: 0 - Value::maxUInt)
92 * - double
93 * - UTF-8 string
94 * - boolean
95 * - 'null'
96 * - an ordered list of Value
97 * - collection of name/value pairs (javascript object)
98 *
99 * The type of the held value is represented by a #ValueType and
100 * can be obtained using type().
101 *
102 * values of an #objectValue or #arrayValue can be accessed using operator[]()
103 *methods.
104 * Non const methods will automatically create the a #nullValue element
105 * if it does not exist.
106 * The sequence of an #arrayValue will be automatically resize and initialized
107 * with #nullValue. resize() can be used to enlarge or truncate an #arrayValue.
108 *
109 * The get() methods can be used to obtanis default value in the case the
110 *required element
111 * does not exist.
112 *
113 * It is possible to iterate over the list of a #objectValue values using
114 * the getMemberNames() method.
115 */
116class JSON_API Value {
117 friend class ValueIteratorBase;
118#ifdef JSON_VALUE_USE_INTERNAL_MAP
119 friend class ValueInternalLink;
120 friend class ValueInternalMap;
121#endif
122public:
123 typedef std::vector<std::string> Members;
124 typedef ValueIterator iterator;
125 typedef ValueConstIterator const_iterator;
126 typedef Json::UInt UInt;
127 typedef Json::Int Int;
128#if defined(JSON_HAS_INT64)
129 typedef Json::UInt64 UInt64;
130 typedef Json::Int64 Int64;
Baptiste Lepilleur842e9ac2010-12-27 17:45:23 +0000131#endif // defined(JSON_HAS_INT64)
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000132 typedef Json::LargestInt LargestInt;
133 typedef Json::LargestUInt LargestUInt;
134 typedef Json::ArrayIndex ArrayIndex;
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000135
Christopher Dunn28836b82014-07-05 13:52:19 -0700136 static const Value& null;
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000137 /// Minimum signed integer value that can be stored in a Json::Value.
138 static const LargestInt minLargestInt;
139 /// Maximum signed integer value that can be stored in a Json::Value.
140 static const LargestInt maxLargestInt;
141 /// Maximum unsigned integer value that can be stored in a Json::Value.
142 static const LargestUInt maxLargestUInt;
Baptiste Lepilleur842e9ac2010-12-27 17:45:23 +0000143
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000144 /// Minimum signed int value that can be stored in a Json::Value.
145 static const Int minInt;
146 /// Maximum signed int value that can be stored in a Json::Value.
147 static const Int maxInt;
148 /// Maximum unsigned int value that can be stored in a Json::Value.
149 static const UInt maxUInt;
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000150
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000151#if defined(JSON_HAS_INT64)
152 /// Minimum signed 64 bits int value that can be stored in a Json::Value.
153 static const Int64 minInt64;
154 /// Maximum signed 64 bits int value that can be stored in a Json::Value.
155 static const Int64 maxInt64;
156 /// Maximum unsigned 64 bits int value that can be stored in a Json::Value.
157 static const UInt64 maxUInt64;
Aaron Jacobsf1053e72011-05-24 03:18:02 +0000158#endif // defined(JSON_HAS_INT64)
Baptiste Lepilleur842e9ac2010-12-27 17:45:23 +0000159
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000160private:
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000161#ifndef JSONCPP_DOC_EXCLUDE_IMPLEMENTATION
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000162#ifndef JSON_VALUE_USE_INTERNAL_MAP
163 class CZString {
164 public:
165 enum DuplicationPolicy {
166 noDuplication = 0,
167 duplicate,
168 duplicateOnCopy
169 };
170 CZString(ArrayIndex index);
171 CZString(const char *cstr, DuplicationPolicy allocate);
172 CZString(const CZString &other);
173 ~CZString();
Billy Donahue45cd9492014-09-08 08:00:39 -0400174 CZString &operator=(CZString other);
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000175 bool operator<(const CZString &other) const;
176 bool operator==(const CZString &other) const;
177 ArrayIndex index() const;
178 const char *c_str() const;
179 bool isStaticString() const;
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000180
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000181 private:
182 void swap(CZString &other);
183 const char *cstr_;
184 ArrayIndex index_;
185 };
186
187public:
188#ifndef JSON_USE_CPPTL_SMALLMAP
189 typedef std::map<CZString, Value> ObjectValues;
190#else
191 typedef CppTL::SmallMap<CZString, Value> ObjectValues;
192#endif // ifndef JSON_USE_CPPTL_SMALLMAP
193#endif // ifndef JSON_VALUE_USE_INTERNAL_MAP
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000194#endif // ifndef JSONCPP_DOC_EXCLUDE_IMPLEMENTATION
195
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000196public:
197 /** \brief Create a default Value of the given type.
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000198
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000199 This is a very useful constructor.
200 To create an empty array, pass arrayValue.
201 To create an empty object, pass objectValue.
202 Another Value can then be set to this one by assignment.
203This is useful since clear() and resize() will not alter types.
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000204
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000205 Examples:
206\code
207Json::Value null_value; // null
208Json::Value arr_value(Json::arrayValue); // []
209Json::Value obj_value(Json::objectValue); // {}
210\endcode
211 */
212 Value(ValueType type = nullValue);
213 Value(Int value);
214 Value(UInt value);
Baptiste Lepilleur842e9ac2010-12-27 17:45:23 +0000215#if defined(JSON_HAS_INT64)
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000216 Value(Int64 value);
217 Value(UInt64 value);
Baptiste Lepilleur842e9ac2010-12-27 17:45:23 +0000218#endif // if defined(JSON_HAS_INT64)
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000219 Value(double value);
220 Value(const char *value);
221 Value(const char *beginValue, const char *endValue);
222 /** \brief Constructs a value from a static string.
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000223
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000224 * Like other value string constructor but do not duplicate the string for
225 * internal storage. The given string must remain alive after the call to this
226 * constructor.
227 * Example of usage:
228 * \code
229 * Json::Value aValue( StaticString("some text") );
230 * \endcode
231 */
232 Value(const StaticString &value);
233 Value(const std::string &value);
234#ifdef JSON_USE_CPPTL
235 Value(const CppTL::ConstString &value);
236#endif
237 Value(bool value);
238 Value(const Value &other);
239 ~Value();
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000240
Billy Donahue45cd9492014-09-08 08:00:39 -0400241 Value &operator=(Value other);
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000242 /// Swap values.
243 /// \note Currently, comments are intentionally not swapped, for
244 /// both logic and efficiency.
245 void swap(Value &other);
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000246
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000247 ValueType type() const;
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000248
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000249 bool operator<(const Value &other) const;
250 bool operator<=(const Value &other) const;
251 bool operator>=(const Value &other) const;
252 bool operator>(const Value &other) const;
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000253
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000254 bool operator==(const Value &other) const;
255 bool operator!=(const Value &other) const;
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000256
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000257 int compare(const Value &other) const;
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000258
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000259 const char *asCString() const;
260 std::string asString() const;
261#ifdef JSON_USE_CPPTL
262 CppTL::ConstString asConstString() const;
263#endif
264 Int asInt() const;
265 UInt asUInt() const;
Aaron Jacobsf1053e72011-05-24 03:18:02 +0000266#if defined(JSON_HAS_INT64)
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000267 Int64 asInt64() const;
268 UInt64 asUInt64() const;
Aaron Jacobsf1053e72011-05-24 03:18:02 +0000269#endif // if defined(JSON_HAS_INT64)
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000270 LargestInt asLargestInt() const;
271 LargestUInt asLargestUInt() const;
272 float asFloat() const;
273 double asDouble() const;
274 bool asBool() const;
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000275
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000276 bool isNull() const;
277 bool isBool() const;
278 bool isInt() const;
279 bool isInt64() const;
280 bool isUInt() const;
281 bool isUInt64() const;
282 bool isIntegral() const;
283 bool isDouble() const;
284 bool isNumeric() const;
285 bool isString() const;
286 bool isArray() const;
287 bool isObject() const;
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000288
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000289 bool isConvertibleTo(ValueType other) const;
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000290
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000291 /// Number of values in array or object
292 ArrayIndex size() const;
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000293
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000294 /// \brief Return true if empty array, empty object, or null;
295 /// otherwise, false.
296 bool empty() const;
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000297
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000298 /// Return isNull()
299 bool operator!() const;
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000300
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000301 /// Remove all object members and array elements.
302 /// \pre type() is arrayValue, objectValue, or nullValue
303 /// \post type() is unchanged
304 void clear();
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000305
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000306 /// Resize the array to size elements.
307 /// New elements are initialized to null.
308 /// May only be called on nullValue or arrayValue.
309 /// \pre type() is arrayValue or nullValue
310 /// \post type() is arrayValue
311 void resize(ArrayIndex size);
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000312
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000313 /// Access an array element (zero based index ).
314 /// If the array contains less than index element, then null value are
315 /// inserted
316 /// in the array so that its size is index+1.
317 /// (You may need to say 'value[0u]' to get your compiler to distinguish
318 /// this from the operator[] which takes a string.)
319 Value &operator[](ArrayIndex index);
Baptiste Lepilleurfa130ef2010-12-24 12:47:14 +0000320
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000321 /// Access an array element (zero based index ).
322 /// If the array contains less than index element, then null value are
323 /// inserted
324 /// in the array so that its size is index+1.
325 /// (You may need to say 'value[0u]' to get your compiler to distinguish
326 /// this from the operator[] which takes a string.)
327 Value &operator[](int index);
Baptiste Lepilleurfa130ef2010-12-24 12:47:14 +0000328
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000329 /// Access an array element (zero based index )
330 /// (You may need to say 'value[0u]' to get your compiler to distinguish
331 /// this from the operator[] which takes a string.)
332 const Value &operator[](ArrayIndex index) const;
Baptiste Lepilleurfa130ef2010-12-24 12:47:14 +0000333
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000334 /// Access an array element (zero based index )
335 /// (You may need to say 'value[0u]' to get your compiler to distinguish
336 /// this from the operator[] which takes a string.)
337 const Value &operator[](int index) const;
Baptiste Lepilleurfa130ef2010-12-24 12:47:14 +0000338
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000339 /// If the array contains at least index+1 elements, returns the element
340 /// value,
341 /// otherwise returns defaultValue.
342 Value get(ArrayIndex index, const Value &defaultValue) const;
343 /// Return true if index < size().
344 bool isValidIndex(ArrayIndex index) const;
345 /// \brief Append value to array at the end.
346 ///
347 /// Equivalent to jsonvalue[jsonvalue.size()] = value;
348 Value &append(const Value &value);
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000349
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000350 /// Access an object value by name, create a null member if it does not exist.
351 Value &operator[](const char *key);
352 /// Access an object value by name, returns null if there is no member with
353 /// that name.
354 const Value &operator[](const char *key) const;
355 /// Access an object value by name, create a null member if it does not exist.
356 Value &operator[](const std::string &key);
357 /// Access an object value by name, returns null if there is no member with
358 /// that name.
359 const Value &operator[](const std::string &key) const;
360 /** \brief Access an object value by name, create a null member if it does not
361 exist.
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000362
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000363 * If the object as no entry for that name, then the member name used to store
364 * the new entry is not duplicated.
365 * Example of use:
366 * \code
367 * Json::Value object;
368 * static const StaticString code("code");
369 * object[code] = 1234;
370 * \endcode
371 */
372 Value &operator[](const StaticString &key);
373#ifdef JSON_USE_CPPTL
374 /// Access an object value by name, create a null member if it does not exist.
375 Value &operator[](const CppTL::ConstString &key);
376 /// Access an object value by name, returns null if there is no member with
377 /// that name.
378 const Value &operator[](const CppTL::ConstString &key) const;
379#endif
380 /// Return the member named key if it exist, defaultValue otherwise.
381 Value get(const char *key, const Value &defaultValue) const;
382 /// Return the member named key if it exist, defaultValue otherwise.
383 Value get(const std::string &key, const Value &defaultValue) const;
384#ifdef JSON_USE_CPPTL
385 /// Return the member named key if it exist, defaultValue otherwise.
386 Value get(const CppTL::ConstString &key, const Value &defaultValue) const;
387#endif
388 /// \brief Remove and return the named member.
389 ///
390 /// Do nothing if it did not exist.
391 /// \return the removed Value, or null.
392 /// \pre type() is objectValue or nullValue
393 /// \post type() is unchanged
394 Value removeMember(const char *key);
395 /// Same as removeMember(const char*)
396 Value removeMember(const std::string &key);
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000397
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000398 /// Return true if the object has a member named key.
399 bool isMember(const char *key) const;
400 /// Return true if the object has a member named key.
401 bool isMember(const std::string &key) const;
402#ifdef JSON_USE_CPPTL
403 /// Return true if the object has a member named key.
404 bool isMember(const CppTL::ConstString &key) const;
405#endif
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000406
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000407 /// \brief Return a list of the member names.
408 ///
409 /// If null, return an empty list.
410 /// \pre type() is objectValue or nullValue
411 /// \post if type() was nullValue, it remains nullValue
412 Members getMemberNames() const;
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000413
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000414 //# ifdef JSON_USE_CPPTL
415 // EnumMemberNames enumMemberNames() const;
416 // EnumValues enumValues() const;
417 //# endif
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000418
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000419 /// Comments must be //... or /* ... */
420 void setComment(const char *comment, CommentPlacement placement);
421 /// Comments must be //... or /* ... */
422 void setComment(const std::string &comment, CommentPlacement placement);
423 bool hasComment(CommentPlacement placement) const;
424 /// Include delimiters and embedded newlines.
425 std::string getComment(CommentPlacement placement) const;
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000426
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000427 std::string toStyledString() const;
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000428
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000429 const_iterator begin() const;
430 const_iterator end() const;
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000431
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000432 iterator begin();
433 iterator end();
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000434
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000435 // Accessors for the [start, limit) range of bytes within the JSON text from
436 // which this value was parsed, if any.
437 void setOffsetStart(size_t start);
438 void setOffsetLimit(size_t limit);
439 size_t getOffsetStart() const;
440 size_t getOffsetLimit() const;
Aaron Jacobs68db6552014-04-23 23:41:12 +0000441
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000442private:
443 Value &resolveReference(const char *key, bool isStatic);
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000444
445#ifdef JSON_VALUE_USE_INTERNAL_MAP
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000446 inline bool isItemAvailable() const { return itemIsUsed_ == 0; }
447
448 inline void setItemUsed(bool isUsed = true) { itemIsUsed_ = isUsed ? 1 : 0; }
449
450 inline bool isMemberNameStatic() const { return memberNameIsStatic_ == 0; }
451
452 inline void setMemberNameIsStatic(bool isStatic) {
453 memberNameIsStatic_ = isStatic ? 1 : 0;
454 }
455#endif // # ifdef JSON_VALUE_USE_INTERNAL_MAP
456
457private:
458 struct CommentInfo {
459 CommentInfo();
460 ~CommentInfo();
461
462 void setComment(const char *text);
463
464 char *comment_;
465 };
466
467 // struct MemberNamesTransform
468 //{
469 // typedef const char *result_type;
470 // const char *operator()( const CZString &name ) const
471 // {
472 // return name.c_str();
473 // }
474 //};
475
476 union ValueHolder {
477 LargestInt int_;
478 LargestUInt uint_;
479 double real_;
480 bool bool_;
481 char *string_;
482#ifdef JSON_VALUE_USE_INTERNAL_MAP
483 ValueInternalArray *array_;
484 ValueInternalMap *map_;
485#else
486 ObjectValues *map_;
487#endif
488 } value_;
489 ValueType type_ : 8;
490 int allocated_ : 1; // Notes: if declared as bool, bitfield is useless.
491#ifdef JSON_VALUE_USE_INTERNAL_MAP
492 unsigned int itemIsUsed_ : 1; // used by the ValueInternalMap container.
493 int memberNameIsStatic_ : 1; // used by the ValueInternalMap container.
494#endif
495 CommentInfo *comments_;
496
497 // [start, limit) byte offsets in the source JSON text from which this Value
498 // was extracted.
499 size_t start_;
500 size_t limit_;
501};
502
503/** \brief Experimental and untested: represents an element of the "path" to
504 * access a node.
505 */
506class JSON_API PathArgument {
507public:
508 friend class Path;
509
510 PathArgument();
511 PathArgument(ArrayIndex index);
512 PathArgument(const char *key);
513 PathArgument(const std::string &key);
514
515private:
516 enum Kind {
517 kindNone = 0,
518 kindIndex,
519 kindKey
520 };
521 std::string key_;
522 ArrayIndex index_;
523 Kind kind_;
524};
525
526/** \brief Experimental and untested: represents a "path" to access a node.
527 *
528 * Syntax:
529 * - "." => root node
530 * - ".[n]" => elements at index 'n' of root node (an array value)
531 * - ".name" => member named 'name' of root node (an object value)
532 * - ".name1.name2.name3"
533 * - ".[0][1][2].name1[3]"
534 * - ".%" => member name is provided as parameter
535 * - ".[%]" => index is provied as parameter
536 */
537class JSON_API Path {
538public:
539 Path(const std::string &path,
540 const PathArgument &a1 = PathArgument(),
541 const PathArgument &a2 = PathArgument(),
542 const PathArgument &a3 = PathArgument(),
543 const PathArgument &a4 = PathArgument(),
544 const PathArgument &a5 = PathArgument());
545
546 const Value &resolve(const Value &root) const;
547 Value resolve(const Value &root, const Value &defaultValue) const;
548 /// Creates the "path" to access the specified node and returns a reference on
549 /// the node.
550 Value &make(Value &root) const;
551
552private:
553 typedef std::vector<const PathArgument *> InArgs;
554 typedef std::vector<PathArgument> Args;
555
556 void makePath(const std::string &path, const InArgs &in);
557 void addPathInArg(const std::string &path,
558 const InArgs &in,
559 InArgs::const_iterator &itInArg,
560 PathArgument::Kind kind);
561 void invalidPath(const std::string &path, int location);
562
563 Args args_;
564};
565
566#ifdef JSON_VALUE_USE_INTERNAL_MAP
567/** \brief Allocator to customize Value internal map.
568 * Below is an example of a simple implementation (default implementation
569 actually
570 * use memory pool for speed).
571 * \code
572 class DefaultValueMapAllocator : public ValueMapAllocator
573 {
574 public: // overridden from ValueMapAllocator
575 virtual ValueInternalMap *newMap()
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000576 {
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000577 return new ValueInternalMap();
578 }
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000579
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000580 virtual ValueInternalMap *newMapCopy( const ValueInternalMap &other )
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000581 {
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000582 return new ValueInternalMap( other );
583 }
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000584
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000585 virtual void destructMap( ValueInternalMap *map )
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000586 {
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000587 delete map;
588 }
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000589
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000590 virtual ValueInternalLink *allocateMapBuckets( unsigned int size )
591 {
592 return new ValueInternalLink[size];
593 }
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000594
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000595 virtual void releaseMapBuckets( ValueInternalLink *links )
596 {
597 delete [] links;
598 }
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000599
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000600 virtual ValueInternalLink *allocateMapLink()
601 {
602 return new ValueInternalLink();
603 }
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000604
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000605 virtual void releaseMapLink( ValueInternalLink *link )
606 {
607 delete link;
608 }
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000609 };
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000610 * \endcode
611 */
612class JSON_API ValueMapAllocator {
613public:
614 virtual ~ValueMapAllocator();
615 virtual ValueInternalMap *newMap() = 0;
616 virtual ValueInternalMap *newMapCopy(const ValueInternalMap &other) = 0;
617 virtual void destructMap(ValueInternalMap *map) = 0;
618 virtual ValueInternalLink *allocateMapBuckets(unsigned int size) = 0;
619 virtual void releaseMapBuckets(ValueInternalLink *links) = 0;
620 virtual ValueInternalLink *allocateMapLink() = 0;
621 virtual void releaseMapLink(ValueInternalLink *link) = 0;
622};
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000623
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000624/** \brief ValueInternalMap hash-map bucket chain link (for internal use only).
625 * \internal previous_ & next_ allows for bidirectional traversal.
626 */
627class JSON_API ValueInternalLink {
628public:
629 enum {
630 itemPerLink = 6
631 }; // sizeof(ValueInternalLink) = 128 on 32 bits architecture.
632 enum InternalFlags {
633 flagAvailable = 0,
634 flagUsed = 1
635 };
636
637 ValueInternalLink();
638
639 ~ValueInternalLink();
640
641 Value items_[itemPerLink];
642 char *keys_[itemPerLink];
643 ValueInternalLink *previous_;
644 ValueInternalLink *next_;
645};
646
647/** \brief A linked page based hash-table implementation used internally by
648 *Value.
649 * \internal ValueInternalMap is a tradional bucket based hash-table, with a
650 *linked
651 * list in each bucket to handle collision. There is an addional twist in that
652 * each node of the collision linked list is a page containing a fixed amount of
653 * value. This provides a better compromise between memory usage and speed.
654 *
655 * Each bucket is made up of a chained list of ValueInternalLink. The last
656 * link of a given bucket can be found in the 'previous_' field of the following
657 *bucket.
658 * The last link of the last bucket is stored in tailLink_ as it has no
659 *following bucket.
660 * Only the last link of a bucket may contains 'available' item. The last link
661 *always
662 * contains at least one element unless is it the bucket one very first link.
663 */
664class JSON_API ValueInternalMap {
665 friend class ValueIteratorBase;
666 friend class Value;
667
668public:
669 typedef unsigned int HashKey;
670 typedef unsigned int BucketIndex;
671
672#ifndef JSONCPP_DOC_EXCLUDE_IMPLEMENTATION
673 struct IteratorState {
674 IteratorState() : map_(0), link_(0), itemIndex_(0), bucketIndex_(0) {}
675 ValueInternalMap *map_;
676 ValueInternalLink *link_;
677 BucketIndex itemIndex_;
678 BucketIndex bucketIndex_;
679 };
680#endif // ifndef JSONCPP_DOC_EXCLUDE_IMPLEMENTATION
681
682 ValueInternalMap();
683 ValueInternalMap(const ValueInternalMap &other);
Billy Donahue45cd9492014-09-08 08:00:39 -0400684 ValueInternalMap &operator=(ValueInternalMap other);
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000685 ~ValueInternalMap();
686
687 void swap(ValueInternalMap &other);
688
689 BucketIndex size() const;
690
691 void clear();
692
693 bool reserveDelta(BucketIndex growth);
694
695 bool reserve(BucketIndex newItemCount);
696
697 const Value *find(const char *key) const;
698
699 Value *find(const char *key);
700
701 Value &resolveReference(const char *key, bool isStatic);
702
703 void remove(const char *key);
704
705 void doActualRemove(ValueInternalLink *link,
706 BucketIndex index,
707 BucketIndex bucketIndex);
708
709 ValueInternalLink *&getLastLinkInBucket(BucketIndex bucketIndex);
710
711 Value &setNewItem(const char *key,
712 bool isStatic,
713 ValueInternalLink *link,
714 BucketIndex index);
715
716 Value &unsafeAdd(const char *key, bool isStatic, HashKey hashedKey);
717
718 HashKey hash(const char *key) const;
719
720 int compare(const ValueInternalMap &other) const;
721
722private:
723 void makeBeginIterator(IteratorState &it) const;
724 void makeEndIterator(IteratorState &it) const;
725 static bool equals(const IteratorState &x, const IteratorState &other);
726 static void increment(IteratorState &iterator);
727 static void incrementBucket(IteratorState &iterator);
728 static void decrement(IteratorState &iterator);
729 static const char *key(const IteratorState &iterator);
730 static const char *key(const IteratorState &iterator, bool &isStatic);
731 static Value &value(const IteratorState &iterator);
732 static int distance(const IteratorState &x, const IteratorState &y);
733
734private:
735 ValueInternalLink *buckets_;
736 ValueInternalLink *tailLink_;
737 BucketIndex bucketsSize_;
738 BucketIndex itemCount_;
739};
740
741/** \brief A simplified deque implementation used internally by Value.
742* \internal
743* It is based on a list of fixed "page", each page contains a fixed number of
744*items.
745* Instead of using a linked-list, a array of pointer is used for fast item
746*look-up.
747* Look-up for an element is as follow:
748* - compute page index: pageIndex = itemIndex / itemsPerPage
749* - look-up item in page: pages_[pageIndex][itemIndex % itemsPerPage]
750*
751* Insertion is amortized constant time (only the array containing the index of
752*pointers
753* need to be reallocated when items are appended).
754*/
755class JSON_API ValueInternalArray {
756 friend class Value;
757 friend class ValueIteratorBase;
758
759public:
760 enum {
761 itemsPerPage = 8
762 }; // should be a power of 2 for fast divide and modulo.
763 typedef Value::ArrayIndex ArrayIndex;
764 typedef unsigned int PageIndex;
765
766#ifndef JSONCPP_DOC_EXCLUDE_IMPLEMENTATION
767 struct IteratorState // Must be a POD
768 {
769 IteratorState() : array_(0), currentPageIndex_(0), currentItemIndex_(0) {}
770 ValueInternalArray *array_;
771 Value **currentPageIndex_;
772 unsigned int currentItemIndex_;
773 };
774#endif // ifndef JSONCPP_DOC_EXCLUDE_IMPLEMENTATION
775
776 ValueInternalArray();
777 ValueInternalArray(const ValueInternalArray &other);
Billy Donahue45cd9492014-09-08 08:00:39 -0400778 ValueInternalArray &operator=(ValueInternalArray other);
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000779 ~ValueInternalArray();
780 void swap(ValueInternalArray &other);
781
782 void clear();
783 void resize(ArrayIndex newSize);
784
785 Value &resolveReference(ArrayIndex index);
786
787 Value *find(ArrayIndex index) const;
788
789 ArrayIndex size() const;
790
791 int compare(const ValueInternalArray &other) const;
792
793private:
794 static bool equals(const IteratorState &x, const IteratorState &other);
795 static void increment(IteratorState &iterator);
796 static void decrement(IteratorState &iterator);
797 static Value &dereference(const IteratorState &iterator);
798 static Value &unsafeDereference(const IteratorState &iterator);
799 static int distance(const IteratorState &x, const IteratorState &y);
800 static ArrayIndex indexOf(const IteratorState &iterator);
801 void makeBeginIterator(IteratorState &it) const;
802 void makeEndIterator(IteratorState &it) const;
803 void makeIterator(IteratorState &it, ArrayIndex index) const;
804
805 void makeIndexValid(ArrayIndex index);
806
807 Value **pages_;
808 ArrayIndex size_;
809 PageIndex pageCount_;
810};
811
812/** \brief Experimental: do not use. Allocator to customize Value internal
813array.
814 * Below is an example of a simple implementation (actual implementation use
815 * memory pool).
816 \code
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000817class DefaultValueArrayAllocator : public ValueArrayAllocator
818{
819public: // overridden from ValueArrayAllocator
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000820virtual ~DefaultValueArrayAllocator()
821{
822}
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000823
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000824virtual ValueInternalArray *newArray()
825{
826 return new ValueInternalArray();
827}
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000828
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000829virtual ValueInternalArray *newArrayCopy( const ValueInternalArray &other )
830{
831 return new ValueInternalArray( other );
832}
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000833
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000834virtual void destruct( ValueInternalArray *array )
835{
836 delete array;
837}
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000838
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000839virtual void reallocateArrayPageIndex( Value **&indexes,
840 ValueInternalArray::PageIndex
841&indexCount,
842 ValueInternalArray::PageIndex
843minNewIndexCount )
844{
845 ValueInternalArray::PageIndex newIndexCount = (indexCount*3)/2 + 1;
846 if ( minNewIndexCount > newIndexCount )
847 newIndexCount = minNewIndexCount;
848 void *newIndexes = realloc( indexes, sizeof(Value*) * newIndexCount );
849 if ( !newIndexes )
850 throw std::bad_alloc();
851 indexCount = newIndexCount;
852 indexes = static_cast<Value **>( newIndexes );
853}
854virtual void releaseArrayPageIndex( Value **indexes,
855 ValueInternalArray::PageIndex indexCount )
856{
857 if ( indexes )
858 free( indexes );
859}
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000860
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000861virtual Value *allocateArrayPage()
862{
863 return static_cast<Value *>( malloc( sizeof(Value) *
864ValueInternalArray::itemsPerPage ) );
865}
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000866
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000867virtual void releaseArrayPage( Value *value )
868{
869 if ( value )
870 free( value );
871}
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000872};
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000873 \endcode
874 */
875class JSON_API ValueArrayAllocator {
876public:
877 virtual ~ValueArrayAllocator();
878 virtual ValueInternalArray *newArray() = 0;
879 virtual ValueInternalArray *newArrayCopy(const ValueInternalArray &other) = 0;
880 virtual void destructArray(ValueInternalArray *array) = 0;
881 /** \brief Reallocate array page index.
882 * Reallocates an array of pointer on each page.
883 * \param indexes [input] pointer on the current index. May be \c NULL.
884 * [output] pointer on the new index of at least
885 * \a minNewIndexCount pages.
886 * \param indexCount [input] current number of pages in the index.
887 * [output] number of page the reallocated index can handle.
888 * \b MUST be >= \a minNewIndexCount.
889 * \param minNewIndexCount Minimum number of page the new index must be able
890 * to
891 * handle.
892 */
893 virtual void
894 reallocateArrayPageIndex(Value **&indexes,
895 ValueInternalArray::PageIndex &indexCount,
896 ValueInternalArray::PageIndex minNewIndexCount) = 0;
897 virtual void
898 releaseArrayPageIndex(Value **indexes,
899 ValueInternalArray::PageIndex indexCount) = 0;
900 virtual Value *allocateArrayPage() = 0;
901 virtual void releaseArrayPage(Value *value) = 0;
902};
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000903#endif // #ifdef JSON_VALUE_USE_INTERNAL_MAP
904
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000905/** \brief base class for Value iterators.
906 *
907 */
908class JSON_API ValueIteratorBase {
909public:
910 typedef std::bidirectional_iterator_tag iterator_category;
911 typedef unsigned int size_t;
912 typedef int difference_type;
913 typedef ValueIteratorBase SelfType;
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000914
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000915 ValueIteratorBase();
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000916#ifndef JSON_VALUE_USE_INTERNAL_MAP
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000917 explicit ValueIteratorBase(const Value::ObjectValues::iterator &current);
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000918#else
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000919 ValueIteratorBase(const ValueInternalArray::IteratorState &state);
920 ValueIteratorBase(const ValueInternalMap::IteratorState &state);
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000921#endif
922
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000923 bool operator==(const SelfType &other) const { return isEqual(other); }
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000924
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000925 bool operator!=(const SelfType &other) const { return !isEqual(other); }
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000926
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000927 difference_type operator-(const SelfType &other) const {
928 return computeDistance(other);
929 }
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000930
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000931 /// Return either the index or the member name of the referenced value as a
932 /// Value.
933 Value key() const;
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000934
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000935 /// Return the index of the referenced Value. -1 if it is not an arrayValue.
936 UInt index() const;
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000937
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000938 /// Return the member name of the referenced Value. "" if it is not an
939 /// objectValue.
940 const char *memberName() const;
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000941
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000942protected:
943 Value &deref() const;
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000944
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000945 void increment();
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000946
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000947 void decrement();
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000948
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000949 difference_type computeDistance(const SelfType &other) const;
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000950
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000951 bool isEqual(const SelfType &other) const;
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000952
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000953 void copy(const SelfType &other);
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000954
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000955private:
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000956#ifndef JSON_VALUE_USE_INTERNAL_MAP
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000957 Value::ObjectValues::iterator current_;
958 // Indicates that iterator is for a null value.
959 bool isNull_;
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000960#else
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000961 union {
962 ValueInternalArray::IteratorState array_;
963 ValueInternalMap::IteratorState map_;
964 } iterator_;
965 bool isArray_;
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000966#endif
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000967};
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000968
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000969/** \brief const iterator for object and array value.
970 *
971 */
972class JSON_API ValueConstIterator : public ValueIteratorBase {
973 friend class Value;
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000974
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000975public:
976 typedef const Value value_type;
977 typedef unsigned int size_t;
978 typedef int difference_type;
979 typedef const Value &reference;
980 typedef const Value *pointer;
981 typedef ValueConstIterator SelfType;
982
983 ValueConstIterator();
984
985private:
986/*! \internal Use by Value to create an iterator.
987 */
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000988#ifndef JSON_VALUE_USE_INTERNAL_MAP
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000989 explicit ValueConstIterator(const Value::ObjectValues::iterator &current);
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000990#else
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000991 ValueConstIterator(const ValueInternalArray::IteratorState &state);
992 ValueConstIterator(const ValueInternalMap::IteratorState &state);
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000993#endif
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000994public:
995 SelfType &operator=(const ValueIteratorBase &other);
Christopher Dunn6d135cb2007-06-13 15:51:04 +0000996
Aaron Jacobs9fa4e842014-07-01 08:48:54 +1000997 SelfType operator++(int) {
998 SelfType temp(*this);
999 ++*this;
1000 return temp;
1001 }
Christopher Dunn6d135cb2007-06-13 15:51:04 +00001002
Aaron Jacobs9fa4e842014-07-01 08:48:54 +10001003 SelfType operator--(int) {
1004 SelfType temp(*this);
1005 --*this;
1006 return temp;
1007 }
Christopher Dunn6d135cb2007-06-13 15:51:04 +00001008
Aaron Jacobs9fa4e842014-07-01 08:48:54 +10001009 SelfType &operator--() {
1010 decrement();
1011 return *this;
1012 }
Christopher Dunn6d135cb2007-06-13 15:51:04 +00001013
Aaron Jacobs9fa4e842014-07-01 08:48:54 +10001014 SelfType &operator++() {
1015 increment();
1016 return *this;
1017 }
Christopher Dunn6d135cb2007-06-13 15:51:04 +00001018
Aaron Jacobs9fa4e842014-07-01 08:48:54 +10001019 reference operator*() const { return deref(); }
1020};
Christopher Dunn6d135cb2007-06-13 15:51:04 +00001021
Aaron Jacobs9fa4e842014-07-01 08:48:54 +10001022/** \brief Iterator for object and array value.
1023 */
1024class JSON_API ValueIterator : public ValueIteratorBase {
1025 friend class Value;
Christopher Dunn6d135cb2007-06-13 15:51:04 +00001026
Aaron Jacobs9fa4e842014-07-01 08:48:54 +10001027public:
1028 typedef Value value_type;
1029 typedef unsigned int size_t;
1030 typedef int difference_type;
1031 typedef Value &reference;
1032 typedef Value *pointer;
1033 typedef ValueIterator SelfType;
Christopher Dunn6d135cb2007-06-13 15:51:04 +00001034
Aaron Jacobs9fa4e842014-07-01 08:48:54 +10001035 ValueIterator();
1036 ValueIterator(const ValueConstIterator &other);
1037 ValueIterator(const ValueIterator &other);
1038
1039private:
1040/*! \internal Use by Value to create an iterator.
1041 */
Christopher Dunn6d135cb2007-06-13 15:51:04 +00001042#ifndef JSON_VALUE_USE_INTERNAL_MAP
Aaron Jacobs9fa4e842014-07-01 08:48:54 +10001043 explicit ValueIterator(const Value::ObjectValues::iterator &current);
Christopher Dunn6d135cb2007-06-13 15:51:04 +00001044#else
Aaron Jacobs9fa4e842014-07-01 08:48:54 +10001045 ValueIterator(const ValueInternalArray::IteratorState &state);
1046 ValueIterator(const ValueInternalMap::IteratorState &state);
Christopher Dunn6d135cb2007-06-13 15:51:04 +00001047#endif
Aaron Jacobs9fa4e842014-07-01 08:48:54 +10001048public:
1049 SelfType &operator=(const SelfType &other);
Christopher Dunn6d135cb2007-06-13 15:51:04 +00001050
Aaron Jacobs9fa4e842014-07-01 08:48:54 +10001051 SelfType operator++(int) {
1052 SelfType temp(*this);
1053 ++*this;
1054 return temp;
1055 }
Christopher Dunn6d135cb2007-06-13 15:51:04 +00001056
Aaron Jacobs9fa4e842014-07-01 08:48:54 +10001057 SelfType operator--(int) {
1058 SelfType temp(*this);
1059 --*this;
1060 return temp;
1061 }
Christopher Dunn6d135cb2007-06-13 15:51:04 +00001062
Aaron Jacobs9fa4e842014-07-01 08:48:54 +10001063 SelfType &operator--() {
1064 decrement();
1065 return *this;
1066 }
Christopher Dunn6d135cb2007-06-13 15:51:04 +00001067
Aaron Jacobs9fa4e842014-07-01 08:48:54 +10001068 SelfType &operator++() {
1069 increment();
1070 return *this;
1071 }
Christopher Dunn6d135cb2007-06-13 15:51:04 +00001072
Aaron Jacobs9fa4e842014-07-01 08:48:54 +10001073 reference operator*() const { return deref(); }
1074};
Christopher Dunn6d135cb2007-06-13 15:51:04 +00001075
1076} // namespace Json
1077
Baptiste Lepilleureafd7022013-05-08 20:21:11 +00001078#if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)
Aaron Jacobs9fa4e842014-07-01 08:48:54 +10001079#pragma warning(pop)
Baptiste Lepilleureafd7022013-05-08 20:21:11 +00001080#endif // if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)
1081
Christopher Dunn6d135cb2007-06-13 15:51:04 +00001082#endif // CPPTL_JSON_H_INCLUDED