blob: 197a85614df1cea8be8637ed6ba042766ebb71c4 [file] [log] [blame]
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -04001// 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
6#ifndef CPPTL_JSON_H_INCLUDED
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -05007#define CPPTL_JSON_H_INCLUDED
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -04008
9#if !defined(JSON_IS_AMALGAMATION)
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -050010#include "forwards.h"
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -040011#endif // if !defined(JSON_IS_AMALGAMATION)
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -050012#include <string>
13#include <vector>
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -040014
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -050015#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
23
24// Disable warning C4251: <data member>: <type> needs to have dll-interface to
25// be used by...
26#if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)
27#pragma warning(push)
28#pragma warning(disable : 4251)
29#endif // if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -040030
31/** \brief JSON (JavaScript Object Notation).
32 */
33namespace Json {
34
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -050035/** \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};
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -040047
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -050048enum 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
52 /// root value)
53 numberOfCommentPlacement
54};
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -040055
56//# ifdef JSON_USE_CPPTL
57// typedef CppTL::AnyEnumerator<const char *> EnumMemberNames;
58// typedef CppTL::AnyEnumerator<const Value &> EnumValues;
59//# endif
60
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -050061/** \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) {}
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -040078
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -050079 operator const char*() const { return str_; }
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -040080
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -050081 const char* c_str() const { return str_; }
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -040082
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -050083private:
84 const char* str_;
85};
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -040086
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -050087/** \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;
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -0400131#endif // defined(JSON_HAS_INT64)
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500132 typedef Json::LargestInt LargestInt;
133 typedef Json::LargestUInt LargestUInt;
134 typedef Json::ArrayIndex ArrayIndex;
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -0400135
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500136 static const Value& null;
137 /// 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;
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -0400143
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500144 /// 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;
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -0400150
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500151#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;
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -0400158#endif // defined(JSON_HAS_INT64)
159
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500160private:
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -0400161#ifndef JSONCPP_DOC_EXCLUDE_IMPLEMENTATION
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500162#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();
174 CZString& operator=(CZString other);
175 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;
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -0400180
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500181 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
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -0400194#endif // ifndef JSONCPP_DOC_EXCLUDE_IMPLEMENTATION
195
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500196public:
197 /** \brief Create a default Value of the given type.
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -0400198
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500199 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.
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -0400204
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500205 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);
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -0400215#if defined(JSON_HAS_INT64)
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500216 Value(Int64 value);
217 Value(UInt64 value);
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -0400218#endif // if defined(JSON_HAS_INT64)
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500219 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.
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -0400223
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500224 * 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();
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -0400240
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500241 Value& operator=(Value other);
242 /// Swap values.
243 /// \note Currently, comments are intentionally not swapped, for
244 /// both logic and efficiency.
245 void swap(Value& other);
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -0400246
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500247 ValueType type() const;
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -0400248
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500249 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;
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -0400253
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500254 bool operator==(const Value& other) const;
255 bool operator!=(const Value& other) const;
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -0400256
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500257 int compare(const Value& other) const;
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -0400258
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500259 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;
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -0400266#if defined(JSON_HAS_INT64)
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500267 Int64 asInt64() const;
268 UInt64 asUInt64() const;
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -0400269#endif // if defined(JSON_HAS_INT64)
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500270 LargestInt asLargestInt() const;
271 LargestUInt asLargestUInt() const;
272 float asFloat() const;
273 double asDouble() const;
274 bool asBool() const;
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -0400275
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500276 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;
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -0400288
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500289 bool isConvertibleTo(ValueType other) const;
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -0400290
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500291 /// Number of values in array or object
292 ArrayIndex size() const;
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -0400293
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500294 /// \brief Return true if empty array, empty object, or null;
295 /// otherwise, false.
296 bool empty() const;
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -0400297
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500298 /// Return isNull()
299 bool operator!() const;
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -0400300
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500301 /// Remove all object members and array elements.
302 /// \pre type() is arrayValue, objectValue, or nullValue
303 /// \post type() is unchanged
304 void clear();
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -0400305
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500306 /// 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);
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -0400312
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500313 /// 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);
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -0400320
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500321 /// 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);
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -0400328
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500329 /// 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;
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -0400333
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500334 /// 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;
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -0400338
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500339 /// 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);
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -0400349
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500350 /// 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.
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -0400362
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500363 * 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);
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -0400397
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500398 /// 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
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -0400406
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500407 /// \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;
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -0400413
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500414 //# ifdef JSON_USE_CPPTL
415 // EnumMemberNames enumMemberNames() const;
416 // EnumValues enumValues() const;
417 //# endif
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -0400418
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500419 /// 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;
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -0400426
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500427 std::string toStyledString() const;
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -0400428
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500429 const_iterator begin() const;
430 const_iterator end() const;
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -0400431
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500432 iterator begin();
433 iterator end();
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -0400434
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500435 // 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;
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -0400441
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500442private:
443 void initBasic(ValueType type, bool allocated = false);
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -0400444
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500445 Value& resolveReference(const char* key, bool isStatic);
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -0400446
447#ifdef JSON_VALUE_USE_INTERNAL_MAP
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500448 inline bool isItemAvailable() const { return itemIsUsed_ == 0; }
449
450 inline void setItemUsed(bool isUsed = true) { itemIsUsed_ = isUsed ? 1 : 0; }
451
452 inline bool isMemberNameStatic() const { return memberNameIsStatic_ == 0; }
453
454 inline void setMemberNameIsStatic(bool isStatic) {
455 memberNameIsStatic_ = isStatic ? 1 : 0;
456 }
457#endif // # ifdef JSON_VALUE_USE_INTERNAL_MAP
458
459private:
460 struct CommentInfo {
461 CommentInfo();
462 ~CommentInfo();
463
464 void setComment(const char* text);
465
466 char* comment_;
467 };
468
469 // struct MemberNamesTransform
470 //{
471 // typedef const char *result_type;
472 // const char *operator()( const CZString &name ) const
473 // {
474 // return name.c_str();
475 // }
476 //};
477
478 union ValueHolder {
479 LargestInt int_;
480 LargestUInt uint_;
481 double real_;
482 bool bool_;
483 char* string_;
484#ifdef JSON_VALUE_USE_INTERNAL_MAP
485 ValueInternalArray* array_;
486 ValueInternalMap* map_;
487#else
488 ObjectValues* map_;
489#endif
490 } value_;
491 ValueType type_ : 8;
492 int allocated_ : 1; // Notes: if declared as bool, bitfield is useless.
493#ifdef JSON_VALUE_USE_INTERNAL_MAP
494 unsigned int itemIsUsed_ : 1; // used by the ValueInternalMap container.
495 int memberNameIsStatic_ : 1; // used by the ValueInternalMap container.
496#endif
497 CommentInfo* comments_;
498
499 // [start, limit) byte offsets in the source JSON text from which this Value
500 // was extracted.
501 size_t start_;
502 size_t limit_;
503};
504
505/** \brief Experimental and untested: represents an element of the "path" to
506 * access a node.
507 */
508class JSON_API PathArgument {
509public:
510 friend class Path;
511
512 PathArgument();
513 PathArgument(ArrayIndex index);
514 PathArgument(const char* key);
515 PathArgument(const std::string& key);
516
517private:
518 enum Kind {
519 kindNone = 0,
520 kindIndex,
521 kindKey
522 };
523 std::string key_;
524 ArrayIndex index_;
525 Kind kind_;
526};
527
528/** \brief Experimental and untested: represents a "path" to access a node.
529 *
530 * Syntax:
531 * - "." => root node
532 * - ".[n]" => elements at index 'n' of root node (an array value)
533 * - ".name" => member named 'name' of root node (an object value)
534 * - ".name1.name2.name3"
535 * - ".[0][1][2].name1[3]"
536 * - ".%" => member name is provided as parameter
537 * - ".[%]" => index is provied as parameter
538 */
539class JSON_API Path {
540public:
541 Path(const std::string& path,
542 const PathArgument& a1 = PathArgument(),
543 const PathArgument& a2 = PathArgument(),
544 const PathArgument& a3 = PathArgument(),
545 const PathArgument& a4 = PathArgument(),
546 const PathArgument& a5 = PathArgument());
547
548 const Value& resolve(const Value& root) const;
549 Value resolve(const Value& root, const Value& defaultValue) const;
550 /// Creates the "path" to access the specified node and returns a reference on
551 /// the node.
552 Value& make(Value& root) const;
553
554private:
555 typedef std::vector<const PathArgument*> InArgs;
556 typedef std::vector<PathArgument> Args;
557
558 void makePath(const std::string& path, const InArgs& in);
559 void addPathInArg(const std::string& path,
560 const InArgs& in,
561 InArgs::const_iterator& itInArg,
562 PathArgument::Kind kind);
563 void invalidPath(const std::string& path, int location);
564
565 Args args_;
566};
567
568#ifdef JSON_VALUE_USE_INTERNAL_MAP
569/** \brief Allocator to customize Value internal map.
570 * Below is an example of a simple implementation (default implementation
571 actually
572 * use memory pool for speed).
573 * \code
574 class DefaultValueMapAllocator : public ValueMapAllocator
575 {
576 public: // overridden from ValueMapAllocator
577 virtual ValueInternalMap *newMap()
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -0400578 {
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500579 return new ValueInternalMap();
580 }
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -0400581
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500582 virtual ValueInternalMap *newMapCopy( const ValueInternalMap &other )
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -0400583 {
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500584 return new ValueInternalMap( other );
585 }
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -0400586
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500587 virtual void destructMap( ValueInternalMap *map )
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -0400588 {
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500589 delete map;
590 }
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -0400591
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500592 virtual ValueInternalLink *allocateMapBuckets( unsigned int size )
593 {
594 return new ValueInternalLink[size];
595 }
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -0400596
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500597 virtual void releaseMapBuckets( ValueInternalLink *links )
598 {
599 delete [] links;
600 }
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -0400601
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500602 virtual ValueInternalLink *allocateMapLink()
603 {
604 return new ValueInternalLink();
605 }
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -0400606
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500607 virtual void releaseMapLink( ValueInternalLink *link )
608 {
609 delete link;
610 }
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -0400611 };
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500612 * \endcode
613 */
614class JSON_API ValueMapAllocator {
615public:
616 virtual ~ValueMapAllocator();
617 virtual ValueInternalMap* newMap() = 0;
618 virtual ValueInternalMap* newMapCopy(const ValueInternalMap& other) = 0;
619 virtual void destructMap(ValueInternalMap* map) = 0;
620 virtual ValueInternalLink* allocateMapBuckets(unsigned int size) = 0;
621 virtual void releaseMapBuckets(ValueInternalLink* links) = 0;
622 virtual ValueInternalLink* allocateMapLink() = 0;
623 virtual void releaseMapLink(ValueInternalLink* link) = 0;
624};
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -0400625
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500626/** \brief ValueInternalMap hash-map bucket chain link (for internal use only).
627 * \internal previous_ & next_ allows for bidirectional traversal.
628 */
629class JSON_API ValueInternalLink {
630public:
631 enum {
632 itemPerLink = 6
633 }; // sizeof(ValueInternalLink) = 128 on 32 bits architecture.
634 enum InternalFlags {
635 flagAvailable = 0,
636 flagUsed = 1
637 };
638
639 ValueInternalLink();
640
641 ~ValueInternalLink();
642
643 Value items_[itemPerLink];
644 char* keys_[itemPerLink];
645 ValueInternalLink* previous_;
646 ValueInternalLink* next_;
647};
648
649/** \brief A linked page based hash-table implementation used internally by
650 *Value.
651 * \internal ValueInternalMap is a tradional bucket based hash-table, with a
652 *linked
653 * list in each bucket to handle collision. There is an addional twist in that
654 * each node of the collision linked list is a page containing a fixed amount of
655 * value. This provides a better compromise between memory usage and speed.
656 *
657 * Each bucket is made up of a chained list of ValueInternalLink. The last
658 * link of a given bucket can be found in the 'previous_' field of the following
659 *bucket.
660 * The last link of the last bucket is stored in tailLink_ as it has no
661 *following bucket.
662 * Only the last link of a bucket may contains 'available' item. The last link
663 *always
664 * contains at least one element unless is it the bucket one very first link.
665 */
666class JSON_API ValueInternalMap {
667 friend class ValueIteratorBase;
668 friend class Value;
669
670public:
671 typedef unsigned int HashKey;
672 typedef unsigned int BucketIndex;
673
674#ifndef JSONCPP_DOC_EXCLUDE_IMPLEMENTATION
675 struct IteratorState {
676 IteratorState() : map_(0), link_(0), itemIndex_(0), bucketIndex_(0) {}
677 ValueInternalMap* map_;
678 ValueInternalLink* link_;
679 BucketIndex itemIndex_;
680 BucketIndex bucketIndex_;
681 };
682#endif // ifndef JSONCPP_DOC_EXCLUDE_IMPLEMENTATION
683
684 ValueInternalMap();
685 ValueInternalMap(const ValueInternalMap& other);
686 ValueInternalMap& operator=(ValueInternalMap other);
687 ~ValueInternalMap();
688
689 void swap(ValueInternalMap& other);
690
691 BucketIndex size() const;
692
693 void clear();
694
695 bool reserveDelta(BucketIndex growth);
696
697 bool reserve(BucketIndex newItemCount);
698
699 const Value* find(const char* key) const;
700
701 Value* find(const char* key);
702
703 Value& resolveReference(const char* key, bool isStatic);
704
705 void remove(const char* key);
706
707 void doActualRemove(ValueInternalLink* link,
708 BucketIndex index,
709 BucketIndex bucketIndex);
710
711 ValueInternalLink*& getLastLinkInBucket(BucketIndex bucketIndex);
712
713 Value& setNewItem(const char* key,
714 bool isStatic,
715 ValueInternalLink* link,
716 BucketIndex index);
717
718 Value& unsafeAdd(const char* key, bool isStatic, HashKey hashedKey);
719
720 HashKey hash(const char* key) const;
721
722 int compare(const ValueInternalMap& other) const;
723
724private:
725 void makeBeginIterator(IteratorState& it) const;
726 void makeEndIterator(IteratorState& it) const;
727 static bool equals(const IteratorState& x, const IteratorState& other);
728 static void increment(IteratorState& iterator);
729 static void incrementBucket(IteratorState& iterator);
730 static void decrement(IteratorState& iterator);
731 static const char* key(const IteratorState& iterator);
732 static const char* key(const IteratorState& iterator, bool& isStatic);
733 static Value& value(const IteratorState& iterator);
734 static int distance(const IteratorState& x, const IteratorState& y);
735
736private:
737 ValueInternalLink* buckets_;
738 ValueInternalLink* tailLink_;
739 BucketIndex bucketsSize_;
740 BucketIndex itemCount_;
741};
742
743/** \brief A simplified deque implementation used internally by Value.
744* \internal
745* It is based on a list of fixed "page", each page contains a fixed number of
746*items.
747* Instead of using a linked-list, a array of pointer is used for fast item
748*look-up.
749* Look-up for an element is as follow:
750* - compute page index: pageIndex = itemIndex / itemsPerPage
751* - look-up item in page: pages_[pageIndex][itemIndex % itemsPerPage]
752*
753* Insertion is amortized constant time (only the array containing the index of
754*pointers
755* need to be reallocated when items are appended).
756*/
757class JSON_API ValueInternalArray {
758 friend class Value;
759 friend class ValueIteratorBase;
760
761public:
762 enum {
763 itemsPerPage = 8
764 }; // should be a power of 2 for fast divide and modulo.
765 typedef Value::ArrayIndex ArrayIndex;
766 typedef unsigned int PageIndex;
767
768#ifndef JSONCPP_DOC_EXCLUDE_IMPLEMENTATION
769 struct IteratorState // Must be a POD
770 {
771 IteratorState() : array_(0), currentPageIndex_(0), currentItemIndex_(0) {}
772 ValueInternalArray* array_;
773 Value** currentPageIndex_;
774 unsigned int currentItemIndex_;
775 };
776#endif // ifndef JSONCPP_DOC_EXCLUDE_IMPLEMENTATION
777
778 ValueInternalArray();
779 ValueInternalArray(const ValueInternalArray& other);
780 ValueInternalArray& operator=(ValueInternalArray other);
781 ~ValueInternalArray();
782 void swap(ValueInternalArray& other);
783
784 void clear();
785 void resize(ArrayIndex newSize);
786
787 Value& resolveReference(ArrayIndex index);
788
789 Value* find(ArrayIndex index) const;
790
791 ArrayIndex size() const;
792
793 int compare(const ValueInternalArray& other) const;
794
795private:
796 static bool equals(const IteratorState& x, const IteratorState& other);
797 static void increment(IteratorState& iterator);
798 static void decrement(IteratorState& iterator);
799 static Value& dereference(const IteratorState& iterator);
800 static Value& unsafeDereference(const IteratorState& iterator);
801 static int distance(const IteratorState& x, const IteratorState& y);
802 static ArrayIndex indexOf(const IteratorState& iterator);
803 void makeBeginIterator(IteratorState& it) const;
804 void makeEndIterator(IteratorState& it) const;
805 void makeIterator(IteratorState& it, ArrayIndex index) const;
806
807 void makeIndexValid(ArrayIndex index);
808
809 Value** pages_;
810 ArrayIndex size_;
811 PageIndex pageCount_;
812};
813
814/** \brief Experimental: do not use. Allocator to customize Value internal
815array.
816 * Below is an example of a simple implementation (actual implementation use
817 * memory pool).
818 \code
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -0400819class DefaultValueArrayAllocator : public ValueArrayAllocator
820{
821public: // overridden from ValueArrayAllocator
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500822virtual ~DefaultValueArrayAllocator()
823{
824}
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -0400825
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500826virtual ValueInternalArray *newArray()
827{
828 return new ValueInternalArray();
829}
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -0400830
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500831virtual ValueInternalArray *newArrayCopy( const ValueInternalArray &other )
832{
833 return new ValueInternalArray( other );
834}
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -0400835
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500836virtual void destruct( ValueInternalArray *array )
837{
838 delete array;
839}
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -0400840
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500841virtual void reallocateArrayPageIndex( Value **&indexes,
842 ValueInternalArray::PageIndex
843&indexCount,
844 ValueInternalArray::PageIndex
845minNewIndexCount )
846{
847 ValueInternalArray::PageIndex newIndexCount = (indexCount*3)/2 + 1;
848 if ( minNewIndexCount > newIndexCount )
849 newIndexCount = minNewIndexCount;
850 void *newIndexes = realloc( indexes, sizeof(Value*) * newIndexCount );
851 if ( !newIndexes )
852 throw std::bad_alloc();
853 indexCount = newIndexCount;
854 indexes = static_cast<Value **>( newIndexes );
855}
856virtual void releaseArrayPageIndex( Value **indexes,
857 ValueInternalArray::PageIndex indexCount )
858{
859 if ( indexes )
860 free( indexes );
861}
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -0400862
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500863virtual Value *allocateArrayPage()
864{
865 return static_cast<Value *>( malloc( sizeof(Value) *
866ValueInternalArray::itemsPerPage ) );
867}
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -0400868
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500869virtual void releaseArrayPage( Value *value )
870{
871 if ( value )
872 free( value );
873}
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -0400874};
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500875 \endcode
876 */
877class JSON_API ValueArrayAllocator {
878public:
879 virtual ~ValueArrayAllocator();
880 virtual ValueInternalArray* newArray() = 0;
881 virtual ValueInternalArray* newArrayCopy(const ValueInternalArray& other) = 0;
882 virtual void destructArray(ValueInternalArray* array) = 0;
883 /** \brief Reallocate array page index.
884 * Reallocates an array of pointer on each page.
885 * \param indexes [input] pointer on the current index. May be \c NULL.
886 * [output] pointer on the new index of at least
887 * \a minNewIndexCount pages.
888 * \param indexCount [input] current number of pages in the index.
889 * [output] number of page the reallocated index can handle.
890 * \b MUST be >= \a minNewIndexCount.
891 * \param minNewIndexCount Minimum number of page the new index must be able
892 * to
893 * handle.
894 */
895 virtual void
896 reallocateArrayPageIndex(Value**& indexes,
897 ValueInternalArray::PageIndex& indexCount,
898 ValueInternalArray::PageIndex minNewIndexCount) = 0;
899 virtual void
900 releaseArrayPageIndex(Value** indexes,
901 ValueInternalArray::PageIndex indexCount) = 0;
902 virtual Value* allocateArrayPage() = 0;
903 virtual void releaseArrayPage(Value* value) = 0;
904};
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -0400905#endif // #ifdef JSON_VALUE_USE_INTERNAL_MAP
906
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500907/** \brief base class for Value iterators.
908 *
909 */
910class JSON_API ValueIteratorBase {
911public:
912 typedef std::bidirectional_iterator_tag iterator_category;
913 typedef unsigned int size_t;
914 typedef int difference_type;
915 typedef ValueIteratorBase SelfType;
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -0400916
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500917 ValueIteratorBase();
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -0400918#ifndef JSON_VALUE_USE_INTERNAL_MAP
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500919 explicit ValueIteratorBase(const Value::ObjectValues::iterator& current);
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -0400920#else
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500921 ValueIteratorBase(const ValueInternalArray::IteratorState& state);
922 ValueIteratorBase(const ValueInternalMap::IteratorState& state);
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -0400923#endif
924
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500925 bool operator==(const SelfType& other) const { return isEqual(other); }
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -0400926
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500927 bool operator!=(const SelfType& other) const { return !isEqual(other); }
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -0400928
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500929 difference_type operator-(const SelfType& other) const {
930 return computeDistance(other);
931 }
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -0400932
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500933 /// Return either the index or the member name of the referenced value as a
934 /// Value.
935 Value key() const;
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -0400936
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500937 /// Return the index of the referenced Value. -1 if it is not an arrayValue.
938 UInt index() const;
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -0400939
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500940 /// Return the member name of the referenced Value. "" if it is not an
941 /// objectValue.
942 const char* memberName() const;
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -0400943
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500944protected:
945 Value& deref() const;
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -0400946
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500947 void increment();
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -0400948
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500949 void decrement();
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -0400950
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500951 difference_type computeDistance(const SelfType& other) const;
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -0400952
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500953 bool isEqual(const SelfType& other) const;
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -0400954
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500955 void copy(const SelfType& other);
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -0400956
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500957private:
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -0400958#ifndef JSON_VALUE_USE_INTERNAL_MAP
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500959 Value::ObjectValues::iterator current_;
960 // Indicates that iterator is for a null value.
961 bool isNull_;
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -0400962#else
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500963 union {
964 ValueInternalArray::IteratorState array_;
965 ValueInternalMap::IteratorState map_;
966 } iterator_;
967 bool isArray_;
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -0400968#endif
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500969};
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -0400970
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500971/** \brief const iterator for object and array value.
972 *
973 */
974class JSON_API ValueConstIterator : public ValueIteratorBase {
975 friend class Value;
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -0400976
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500977public:
978 typedef const Value value_type;
979 typedef unsigned int size_t;
980 typedef int difference_type;
981 typedef const Value& reference;
982 typedef const Value* pointer;
983 typedef ValueConstIterator SelfType;
984
985 ValueConstIterator();
986
987private:
988/*! \internal Use by Value to create an iterator.
989 */
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -0400990#ifndef JSON_VALUE_USE_INTERNAL_MAP
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500991 explicit ValueConstIterator(const Value::ObjectValues::iterator& current);
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -0400992#else
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500993 ValueConstIterator(const ValueInternalArray::IteratorState& state);
994 ValueConstIterator(const ValueInternalMap::IteratorState& state);
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -0400995#endif
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500996public:
997 SelfType& operator=(const ValueIteratorBase& other);
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -0400998
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -0500999 SelfType operator++(int) {
1000 SelfType temp(*this);
1001 ++*this;
1002 return temp;
1003 }
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -04001004
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -05001005 SelfType operator--(int) {
1006 SelfType temp(*this);
1007 --*this;
1008 return temp;
1009 }
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -04001010
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -05001011 SelfType& operator--() {
1012 decrement();
1013 return *this;
1014 }
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -04001015
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -05001016 SelfType& operator++() {
1017 increment();
1018 return *this;
1019 }
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -04001020
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -05001021 reference operator*() const { return deref(); }
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -04001022
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -05001023 pointer operator->() const { return &deref(); }
1024};
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -04001025
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -05001026/** \brief Iterator for object and array value.
1027 */
1028class JSON_API ValueIterator : public ValueIteratorBase {
1029 friend class Value;
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -04001030
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -05001031public:
1032 typedef Value value_type;
1033 typedef unsigned int size_t;
1034 typedef int difference_type;
1035 typedef Value& reference;
1036 typedef Value* pointer;
1037 typedef ValueIterator SelfType;
1038
1039 ValueIterator();
1040 ValueIterator(const ValueConstIterator& other);
1041 ValueIterator(const ValueIterator& other);
1042
1043private:
1044/*! \internal Use by Value to create an iterator.
1045 */
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -04001046#ifndef JSON_VALUE_USE_INTERNAL_MAP
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -05001047 explicit ValueIterator(const Value::ObjectValues::iterator& current);
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -04001048#else
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -05001049 ValueIterator(const ValueInternalArray::IteratorState& state);
1050 ValueIterator(const ValueInternalMap::IteratorState& state);
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -04001051#endif
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -05001052public:
1053 SelfType& operator=(const SelfType& other);
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -04001054
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -05001055 SelfType operator++(int) {
1056 SelfType temp(*this);
1057 ++*this;
1058 return temp;
1059 }
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -04001060
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -05001061 SelfType operator--(int) {
1062 SelfType temp(*this);
1063 --*this;
1064 return temp;
1065 }
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -04001066
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -05001067 SelfType& operator--() {
1068 decrement();
1069 return *this;
1070 }
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -04001071
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -05001072 SelfType& operator++() {
1073 increment();
1074 return *this;
1075 }
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -04001076
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -05001077 reference operator*() const { return deref(); }
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -04001078
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -05001079 pointer operator->() const { return &deref(); }
1080};
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -04001081
1082} // namespace Json
1083
Derek Sollenberger2eb3b4d2016-01-11 14:41:40 -05001084#if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)
1085#pragma warning(pop)
1086#endif // if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)
Leon Scroggins IIIf59fb0e2014-05-28 15:19:42 -04001087
1088#endif // CPPTL_JSON_H_INCLUDED