Ran clang-format over all .h and .cpp files.
clang-format -i $(find . -name '*.h' -or -name '*.cpp')
diff --git a/include/json/value.h b/include/json/value.h
index f18457a..09db289 100644
--- a/include/json/value.h
+++ b/include/json/value.h
@@ -4,1133 +4,1079 @@
// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE
#ifndef CPPTL_JSON_H_INCLUDED
-# define CPPTL_JSON_H_INCLUDED
+#define CPPTL_JSON_H_INCLUDED
#if !defined(JSON_IS_AMALGAMATION)
-# include "forwards.h"
+#include "forwards.h"
#endif // if !defined(JSON_IS_AMALGAMATION)
-# include <string>
-# include <vector>
+#include <string>
+#include <vector>
-# ifndef JSON_USE_CPPTL_SMALLMAP
-# include <map>
-# else
-# include <cpptl/smallmap.h>
-# endif
-# ifdef JSON_USE_CPPTL
-# include <cpptl/forwards.h>
-# endif
+#ifndef JSON_USE_CPPTL_SMALLMAP
+#include <map>
+#else
+#include <cpptl/smallmap.h>
+#endif
+#ifdef JSON_USE_CPPTL
+#include <cpptl/forwards.h>
+#endif
-// Disable warning C4251: <data member>: <type> needs to have dll-interface to be used by...
+// Disable warning C4251: <data member>: <type> needs to have dll-interface to
+// be used by...
#if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)
-# pragma warning(push)
-# pragma warning(disable:4251)
+#pragma warning(push)
+#pragma warning(disable : 4251)
#endif // if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)
-
/** \brief JSON (JavaScript Object Notation).
*/
namespace Json {
- /** \brief Type of the value held by a Value object.
- */
- enum ValueType
- {
- nullValue = 0, ///< 'null' value
- intValue, ///< signed integer value
- uintValue, ///< unsigned integer value
- realValue, ///< double value
- stringValue, ///< UTF-8 string value
- booleanValue, ///< bool value
- arrayValue, ///< array value (ordered list)
- objectValue ///< object value (collection of name/value pairs).
- };
+/** \brief Type of the value held by a Value object.
+ */
+enum ValueType {
+ nullValue = 0, ///< 'null' value
+ intValue, ///< signed integer value
+ uintValue, ///< unsigned integer value
+ realValue, ///< double value
+ stringValue, ///< UTF-8 string value
+ booleanValue, ///< bool value
+ arrayValue, ///< array value (ordered list)
+ objectValue ///< object value (collection of name/value pairs).
+};
- enum CommentPlacement
- {
- commentBefore = 0, ///< a comment placed on the line before a value
- commentAfterOnSameLine, ///< a comment just after a value on the same line
- commentAfter, ///< a comment on the line after a value (only make sense for root value)
- numberOfCommentPlacement
- };
+enum CommentPlacement {
+ commentBefore = 0, ///< a comment placed on the line before a value
+ commentAfterOnSameLine, ///< a comment just after a value on the same line
+ commentAfter, ///< a comment on the line after a value (only make sense for
+ ///root value)
+ numberOfCommentPlacement
+};
//# ifdef JSON_USE_CPPTL
// typedef CppTL::AnyEnumerator<const char *> EnumMemberNames;
// typedef CppTL::AnyEnumerator<const Value &> EnumValues;
//# endif
- /** \brief Lightweight wrapper to tag static string.
- *
- * Value constructor and objectValue member assignement takes advantage of the
- * StaticString and avoid the cost of string duplication when storing the
- * string or the member name.
- *
- * Example of usage:
- * \code
- * Json::Value aValue( StaticString("some text") );
- * Json::Value object;
- * static const StaticString code("code");
- * object[code] = 1234;
- * \endcode
- */
- class JSON_API StaticString
- {
- public:
- explicit StaticString( const char *czstring )
- : str_( czstring )
- {
- }
+/** \brief Lightweight wrapper to tag static string.
+ *
+ * Value constructor and objectValue member assignement takes advantage of the
+ * StaticString and avoid the cost of string duplication when storing the
+ * string or the member name.
+ *
+ * Example of usage:
+ * \code
+ * Json::Value aValue( StaticString("some text") );
+ * Json::Value object;
+ * static const StaticString code("code");
+ * object[code] = 1234;
+ * \endcode
+ */
+class JSON_API StaticString {
+public:
+ explicit StaticString(const char *czstring) : str_(czstring) {}
- operator const char *() const
- {
- return str_;
- }
+ operator const char *() const { return str_; }
- const char *c_str() const
- {
- return str_;
- }
+ const char *c_str() const { return str_; }
- private:
- const char *str_;
- };
+private:
+ const char *str_;
+};
- /** \brief Represents a <a HREF="http://www.json.org">JSON</a> value.
- *
- * This class is a discriminated union wrapper that can represents a:
- * - signed integer [range: Value::minInt - Value::maxInt]
- * - unsigned integer (range: 0 - Value::maxUInt)
- * - double
- * - UTF-8 string
- * - boolean
- * - 'null'
- * - an ordered list of Value
- * - collection of name/value pairs (javascript object)
- *
- * The type of the held value is represented by a #ValueType and
- * can be obtained using type().
- *
- * values of an #objectValue or #arrayValue can be accessed using operator[]() methods.
- * Non const methods will automatically create the a #nullValue element
- * if it does not exist.
- * The sequence of an #arrayValue will be automatically resize and initialized
- * with #nullValue. resize() can be used to enlarge or truncate an #arrayValue.
- *
- * The get() methods can be used to obtanis default value in the case the required element
- * does not exist.
- *
- * It is possible to iterate over the list of a #objectValue values using
- * the getMemberNames() method.
- */
- class JSON_API Value
- {
- friend class ValueIteratorBase;
-# ifdef JSON_VALUE_USE_INTERNAL_MAP
- friend class ValueInternalLink;
- friend class ValueInternalMap;
-# endif
- public:
- typedef std::vector<std::string> Members;
- typedef ValueIterator iterator;
- typedef ValueConstIterator const_iterator;
- typedef Json::UInt UInt;
- typedef Json::Int Int;
-# if defined(JSON_HAS_INT64)
- typedef Json::UInt64 UInt64;
- typedef Json::Int64 Int64;
+/** \brief Represents a <a HREF="http://www.json.org">JSON</a> value.
+ *
+ * This class is a discriminated union wrapper that can represents a:
+ * - signed integer [range: Value::minInt - Value::maxInt]
+ * - unsigned integer (range: 0 - Value::maxUInt)
+ * - double
+ * - UTF-8 string
+ * - boolean
+ * - 'null'
+ * - an ordered list of Value
+ * - collection of name/value pairs (javascript object)
+ *
+ * The type of the held value is represented by a #ValueType and
+ * can be obtained using type().
+ *
+ * values of an #objectValue or #arrayValue can be accessed using operator[]()
+ *methods.
+ * Non const methods will automatically create the a #nullValue element
+ * if it does not exist.
+ * The sequence of an #arrayValue will be automatically resize and initialized
+ * with #nullValue. resize() can be used to enlarge or truncate an #arrayValue.
+ *
+ * The get() methods can be used to obtanis default value in the case the
+ *required element
+ * does not exist.
+ *
+ * It is possible to iterate over the list of a #objectValue values using
+ * the getMemberNames() method.
+ */
+class JSON_API Value {
+ friend class ValueIteratorBase;
+#ifdef JSON_VALUE_USE_INTERNAL_MAP
+ friend class ValueInternalLink;
+ friend class ValueInternalMap;
+#endif
+public:
+ typedef std::vector<std::string> Members;
+ typedef ValueIterator iterator;
+ typedef ValueConstIterator const_iterator;
+ typedef Json::UInt UInt;
+ typedef Json::Int Int;
+#if defined(JSON_HAS_INT64)
+ typedef Json::UInt64 UInt64;
+ typedef Json::Int64 Int64;
#endif // defined(JSON_HAS_INT64)
- typedef Json::LargestInt LargestInt;
- typedef Json::LargestUInt LargestUInt;
- typedef Json::ArrayIndex ArrayIndex;
+ typedef Json::LargestInt LargestInt;
+ typedef Json::LargestUInt LargestUInt;
+ typedef Json::ArrayIndex ArrayIndex;
- static const Value null;
- /// Minimum signed integer value that can be stored in a Json::Value.
- static const LargestInt minLargestInt;
- /// Maximum signed integer value that can be stored in a Json::Value.
- static const LargestInt maxLargestInt;
- /// Maximum unsigned integer value that can be stored in a Json::Value.
- static const LargestUInt maxLargestUInt;
+ static const Value null;
+ /// Minimum signed integer value that can be stored in a Json::Value.
+ static const LargestInt minLargestInt;
+ /// Maximum signed integer value that can be stored in a Json::Value.
+ static const LargestInt maxLargestInt;
+ /// Maximum unsigned integer value that can be stored in a Json::Value.
+ static const LargestUInt maxLargestUInt;
- /// Minimum signed int value that can be stored in a Json::Value.
- static const Int minInt;
- /// Maximum signed int value that can be stored in a Json::Value.
- static const Int maxInt;
- /// Maximum unsigned int value that can be stored in a Json::Value.
- static const UInt maxUInt;
+ /// Minimum signed int value that can be stored in a Json::Value.
+ static const Int minInt;
+ /// Maximum signed int value that can be stored in a Json::Value.
+ static const Int maxInt;
+ /// Maximum unsigned int value that can be stored in a Json::Value.
+ static const UInt maxUInt;
-# if defined(JSON_HAS_INT64)
- /// Minimum signed 64 bits int value that can be stored in a Json::Value.
- static const Int64 minInt64;
- /// Maximum signed 64 bits int value that can be stored in a Json::Value.
- static const Int64 maxInt64;
- /// Maximum unsigned 64 bits int value that can be stored in a Json::Value.
- static const UInt64 maxUInt64;
+#if defined(JSON_HAS_INT64)
+ /// Minimum signed 64 bits int value that can be stored in a Json::Value.
+ static const Int64 minInt64;
+ /// Maximum signed 64 bits int value that can be stored in a Json::Value.
+ static const Int64 maxInt64;
+ /// Maximum unsigned 64 bits int value that can be stored in a Json::Value.
+ static const UInt64 maxUInt64;
#endif // defined(JSON_HAS_INT64)
- private:
+private:
#ifndef JSONCPP_DOC_EXCLUDE_IMPLEMENTATION
-# ifndef JSON_VALUE_USE_INTERNAL_MAP
- class CZString
- {
- public:
- enum DuplicationPolicy
- {
- noDuplication = 0,
- duplicate,
- duplicateOnCopy
- };
- CZString( ArrayIndex index );
- CZString( const char *cstr, DuplicationPolicy allocate );
- CZString( const CZString &other );
- ~CZString();
- CZString &operator =( const CZString &other );
- bool operator<( const CZString &other ) const;
- bool operator==( const CZString &other ) const;
- ArrayIndex index() const;
- const char *c_str() const;
- bool isStaticString() const;
- private:
- void swap( CZString &other );
- const char *cstr_;
- ArrayIndex index_;
- };
+#ifndef JSON_VALUE_USE_INTERNAL_MAP
+ class CZString {
+ public:
+ enum DuplicationPolicy {
+ noDuplication = 0,
+ duplicate,
+ duplicateOnCopy
+ };
+ CZString(ArrayIndex index);
+ CZString(const char *cstr, DuplicationPolicy allocate);
+ CZString(const CZString &other);
+ ~CZString();
+ CZString &operator=(const CZString &other);
+ bool operator<(const CZString &other) const;
+ bool operator==(const CZString &other) const;
+ ArrayIndex index() const;
+ const char *c_str() const;
+ bool isStaticString() const;
- public:
-# ifndef JSON_USE_CPPTL_SMALLMAP
- typedef std::map<CZString, Value> ObjectValues;
-# else
- typedef CppTL::SmallMap<CZString, Value> ObjectValues;
-# endif // ifndef JSON_USE_CPPTL_SMALLMAP
-# endif // ifndef JSON_VALUE_USE_INTERNAL_MAP
+ private:
+ void swap(CZString &other);
+ const char *cstr_;
+ ArrayIndex index_;
+ };
+
+public:
+#ifndef JSON_USE_CPPTL_SMALLMAP
+ typedef std::map<CZString, Value> ObjectValues;
+#else
+ typedef CppTL::SmallMap<CZString, Value> ObjectValues;
+#endif // ifndef JSON_USE_CPPTL_SMALLMAP
+#endif // ifndef JSON_VALUE_USE_INTERNAL_MAP
#endif // ifndef JSONCPP_DOC_EXCLUDE_IMPLEMENTATION
- public:
- /** \brief Create a default Value of the given type.
+public:
+ /** \brief Create a default Value of the given type.
- This is a very useful constructor.
- To create an empty array, pass arrayValue.
- To create an empty object, pass objectValue.
- Another Value can then be set to this one by assignment.
- This is useful since clear() and resize() will not alter types.
+ This is a very useful constructor.
+ To create an empty array, pass arrayValue.
+ To create an empty object, pass objectValue.
+ Another Value can then be set to this one by assignment.
+This is useful since clear() and resize() will not alter types.
- Examples:
- \code
- Json::Value null_value; // null
- Json::Value arr_value(Json::arrayValue); // []
- Json::Value obj_value(Json::objectValue); // {}
- \endcode
- */
- Value( ValueType type = nullValue );
- Value( Int value );
- Value( UInt value );
+ Examples:
+\code
+Json::Value null_value; // null
+Json::Value arr_value(Json::arrayValue); // []
+Json::Value obj_value(Json::objectValue); // {}
+\endcode
+ */
+ Value(ValueType type = nullValue);
+ Value(Int value);
+ Value(UInt value);
#if defined(JSON_HAS_INT64)
- Value( Int64 value );
- Value( UInt64 value );
+ Value(Int64 value);
+ Value(UInt64 value);
#endif // if defined(JSON_HAS_INT64)
- Value( double value );
- Value( const char *value );
- Value( const char *beginValue, const char *endValue );
- /** \brief Constructs a value from a static string.
+ Value(double value);
+ Value(const char *value);
+ Value(const char *beginValue, const char *endValue);
+ /** \brief Constructs a value from a static string.
- * Like other value string constructor but do not duplicate the string for
- * internal storage. The given string must remain alive after the call to this
- * constructor.
- * Example of usage:
- * \code
- * Json::Value aValue( StaticString("some text") );
- * \endcode
- */
- Value( const StaticString &value );
- Value( const std::string &value );
-# ifdef JSON_USE_CPPTL
- Value( const CppTL::ConstString &value );
-# endif
- Value( bool value );
- Value( const Value &other );
- ~Value();
+ * Like other value string constructor but do not duplicate the string for
+ * internal storage. The given string must remain alive after the call to this
+ * constructor.
+ * Example of usage:
+ * \code
+ * Json::Value aValue( StaticString("some text") );
+ * \endcode
+ */
+ Value(const StaticString &value);
+ Value(const std::string &value);
+#ifdef JSON_USE_CPPTL
+ Value(const CppTL::ConstString &value);
+#endif
+ Value(bool value);
+ Value(const Value &other);
+ ~Value();
- Value &operator=( const Value &other );
- /// Swap values.
- /// \note Currently, comments are intentionally not swapped, for
- /// both logic and efficiency.
- void swap( Value &other );
+ Value &operator=(const Value &other);
+ /// Swap values.
+ /// \note Currently, comments are intentionally not swapped, for
+ /// both logic and efficiency.
+ void swap(Value &other);
- ValueType type() const;
+ ValueType type() const;
- bool operator <( const Value &other ) const;
- bool operator <=( const Value &other ) const;
- bool operator >=( const Value &other ) const;
- bool operator >( const Value &other ) const;
+ bool operator<(const Value &other) const;
+ bool operator<=(const Value &other) const;
+ bool operator>=(const Value &other) const;
+ bool operator>(const Value &other) const;
- bool operator ==( const Value &other ) const;
- bool operator !=( const Value &other ) const;
+ bool operator==(const Value &other) const;
+ bool operator!=(const Value &other) const;
- int compare( const Value &other ) const;
+ int compare(const Value &other) const;
- const char *asCString() const;
- std::string asString() const;
-# ifdef JSON_USE_CPPTL
- CppTL::ConstString asConstString() const;
-# endif
- Int asInt() const;
- UInt asUInt() const;
+ const char *asCString() const;
+ std::string asString() const;
+#ifdef JSON_USE_CPPTL
+ CppTL::ConstString asConstString() const;
+#endif
+ Int asInt() const;
+ UInt asUInt() const;
#if defined(JSON_HAS_INT64)
- Int64 asInt64() const;
- UInt64 asUInt64() const;
+ Int64 asInt64() const;
+ UInt64 asUInt64() const;
#endif // if defined(JSON_HAS_INT64)
- LargestInt asLargestInt() const;
- LargestUInt asLargestUInt() const;
- float asFloat() const;
- double asDouble() const;
- bool asBool() const;
+ LargestInt asLargestInt() const;
+ LargestUInt asLargestUInt() const;
+ float asFloat() const;
+ double asDouble() const;
+ bool asBool() const;
- bool isNull() const;
- bool isBool() const;
- bool isInt() const;
- bool isInt64() const;
- bool isUInt() const;
- bool isUInt64() const;
- bool isIntegral() const;
- bool isDouble() const;
- bool isNumeric() const;
- bool isString() const;
- bool isArray() const;
- bool isObject() const;
+ bool isNull() const;
+ bool isBool() const;
+ bool isInt() const;
+ bool isInt64() const;
+ bool isUInt() const;
+ bool isUInt64() const;
+ bool isIntegral() const;
+ bool isDouble() const;
+ bool isNumeric() const;
+ bool isString() const;
+ bool isArray() const;
+ bool isObject() const;
- bool isConvertibleTo( ValueType other ) const;
+ bool isConvertibleTo(ValueType other) const;
- /// Number of values in array or object
- ArrayIndex size() const;
+ /// Number of values in array or object
+ ArrayIndex size() const;
- /// \brief Return true if empty array, empty object, or null;
- /// otherwise, false.
- bool empty() const;
+ /// \brief Return true if empty array, empty object, or null;
+ /// otherwise, false.
+ bool empty() const;
- /// Return isNull()
- bool operator!() const;
+ /// Return isNull()
+ bool operator!() const;
- /// Remove all object members and array elements.
- /// \pre type() is arrayValue, objectValue, or nullValue
- /// \post type() is unchanged
- void clear();
+ /// Remove all object members and array elements.
+ /// \pre type() is arrayValue, objectValue, or nullValue
+ /// \post type() is unchanged
+ void clear();
- /// Resize the array to size elements.
- /// New elements are initialized to null.
- /// May only be called on nullValue or arrayValue.
- /// \pre type() is arrayValue or nullValue
- /// \post type() is arrayValue
- void resize( ArrayIndex size );
+ /// Resize the array to size elements.
+ /// New elements are initialized to null.
+ /// May only be called on nullValue or arrayValue.
+ /// \pre type() is arrayValue or nullValue
+ /// \post type() is arrayValue
+ void resize(ArrayIndex size);
- /// Access an array element (zero based index ).
- /// If the array contains less than index element, then null value are inserted
- /// in the array so that its size is index+1.
- /// (You may need to say 'value[0u]' to get your compiler to distinguish
- /// this from the operator[] which takes a string.)
- Value &operator[]( ArrayIndex index );
+ /// Access an array element (zero based index ).
+ /// If the array contains less than index element, then null value are
+ /// inserted
+ /// in the array so that its size is index+1.
+ /// (You may need to say 'value[0u]' to get your compiler to distinguish
+ /// this from the operator[] which takes a string.)
+ Value &operator[](ArrayIndex index);
- /// Access an array element (zero based index ).
- /// If the array contains less than index element, then null value are inserted
- /// in the array so that its size is index+1.
- /// (You may need to say 'value[0u]' to get your compiler to distinguish
- /// this from the operator[] which takes a string.)
- Value &operator[]( int index );
+ /// Access an array element (zero based index ).
+ /// If the array contains less than index element, then null value are
+ /// inserted
+ /// in the array so that its size is index+1.
+ /// (You may need to say 'value[0u]' to get your compiler to distinguish
+ /// this from the operator[] which takes a string.)
+ Value &operator[](int index);
- /// Access an array element (zero based index )
- /// (You may need to say 'value[0u]' to get your compiler to distinguish
- /// this from the operator[] which takes a string.)
- const Value &operator[]( ArrayIndex index ) const;
+ /// Access an array element (zero based index )
+ /// (You may need to say 'value[0u]' to get your compiler to distinguish
+ /// this from the operator[] which takes a string.)
+ const Value &operator[](ArrayIndex index) const;
- /// Access an array element (zero based index )
- /// (You may need to say 'value[0u]' to get your compiler to distinguish
- /// this from the operator[] which takes a string.)
- const Value &operator[]( int index ) const;
+ /// Access an array element (zero based index )
+ /// (You may need to say 'value[0u]' to get your compiler to distinguish
+ /// this from the operator[] which takes a string.)
+ const Value &operator[](int index) const;
- /// If the array contains at least index+1 elements, returns the element value,
- /// otherwise returns defaultValue.
- Value get( ArrayIndex index,
- const Value &defaultValue ) const;
- /// Return true if index < size().
- bool isValidIndex( ArrayIndex index ) const;
- /// \brief Append value to array at the end.
- ///
- /// Equivalent to jsonvalue[jsonvalue.size()] = value;
- Value &append( const Value &value );
+ /// If the array contains at least index+1 elements, returns the element
+ /// value,
+ /// otherwise returns defaultValue.
+ Value get(ArrayIndex index, const Value &defaultValue) const;
+ /// Return true if index < size().
+ bool isValidIndex(ArrayIndex index) const;
+ /// \brief Append value to array at the end.
+ ///
+ /// Equivalent to jsonvalue[jsonvalue.size()] = value;
+ Value &append(const Value &value);
- /// Access an object value by name, create a null member if it does not exist.
- Value &operator[]( const char *key );
- /// Access an object value by name, returns null if there is no member with that name.
- const Value &operator[]( const char *key ) const;
- /// Access an object value by name, create a null member if it does not exist.
- Value &operator[]( const std::string &key );
- /// Access an object value by name, returns null if there is no member with that name.
- const Value &operator[]( const std::string &key ) const;
- /** \brief Access an object value by name, create a null member if it does not exist.
+ /// Access an object value by name, create a null member if it does not exist.
+ Value &operator[](const char *key);
+ /// Access an object value by name, returns null if there is no member with
+ /// that name.
+ const Value &operator[](const char *key) const;
+ /// Access an object value by name, create a null member if it does not exist.
+ Value &operator[](const std::string &key);
+ /// Access an object value by name, returns null if there is no member with
+ /// that name.
+ const Value &operator[](const std::string &key) const;
+ /** \brief Access an object value by name, create a null member if it does not
+ exist.
- * If the object as no entry for that name, then the member name used to store
- * the new entry is not duplicated.
- * Example of use:
- * \code
- * Json::Value object;
- * static const StaticString code("code");
- * object[code] = 1234;
- * \endcode
- */
- Value &operator[]( const StaticString &key );
-# ifdef JSON_USE_CPPTL
- /// Access an object value by name, create a null member if it does not exist.
- Value &operator[]( const CppTL::ConstString &key );
- /// Access an object value by name, returns null if there is no member with that name.
- const Value &operator[]( const CppTL::ConstString &key ) const;
-# endif
- /// Return the member named key if it exist, defaultValue otherwise.
- Value get( const char *key,
- const Value &defaultValue ) const;
- /// Return the member named key if it exist, defaultValue otherwise.
- Value get( const std::string &key,
- const Value &defaultValue ) const;
-# ifdef JSON_USE_CPPTL
- /// Return the member named key if it exist, defaultValue otherwise.
- Value get( const CppTL::ConstString &key,
- const Value &defaultValue ) const;
-# endif
- /// \brief Remove and return the named member.
- ///
- /// Do nothing if it did not exist.
- /// \return the removed Value, or null.
- /// \pre type() is objectValue or nullValue
- /// \post type() is unchanged
- Value removeMember( const char* key );
- /// Same as removeMember(const char*)
- Value removeMember( const std::string &key );
+ * If the object as no entry for that name, then the member name used to store
+ * the new entry is not duplicated.
+ * Example of use:
+ * \code
+ * Json::Value object;
+ * static const StaticString code("code");
+ * object[code] = 1234;
+ * \endcode
+ */
+ Value &operator[](const StaticString &key);
+#ifdef JSON_USE_CPPTL
+ /// Access an object value by name, create a null member if it does not exist.
+ Value &operator[](const CppTL::ConstString &key);
+ /// Access an object value by name, returns null if there is no member with
+ /// that name.
+ const Value &operator[](const CppTL::ConstString &key) const;
+#endif
+ /// Return the member named key if it exist, defaultValue otherwise.
+ Value get(const char *key, const Value &defaultValue) const;
+ /// Return the member named key if it exist, defaultValue otherwise.
+ Value get(const std::string &key, const Value &defaultValue) const;
+#ifdef JSON_USE_CPPTL
+ /// Return the member named key if it exist, defaultValue otherwise.
+ Value get(const CppTL::ConstString &key, const Value &defaultValue) const;
+#endif
+ /// \brief Remove and return the named member.
+ ///
+ /// Do nothing if it did not exist.
+ /// \return the removed Value, or null.
+ /// \pre type() is objectValue or nullValue
+ /// \post type() is unchanged
+ Value removeMember(const char *key);
+ /// Same as removeMember(const char*)
+ Value removeMember(const std::string &key);
- /// Return true if the object has a member named key.
- bool isMember( const char *key ) const;
- /// Return true if the object has a member named key.
- bool isMember( const std::string &key ) const;
-# ifdef JSON_USE_CPPTL
- /// Return true if the object has a member named key.
- bool isMember( const CppTL::ConstString &key ) const;
-# endif
+ /// Return true if the object has a member named key.
+ bool isMember(const char *key) const;
+ /// Return true if the object has a member named key.
+ bool isMember(const std::string &key) const;
+#ifdef JSON_USE_CPPTL
+ /// Return true if the object has a member named key.
+ bool isMember(const CppTL::ConstString &key) const;
+#endif
- /// \brief Return a list of the member names.
- ///
- /// If null, return an empty list.
- /// \pre type() is objectValue or nullValue
- /// \post if type() was nullValue, it remains nullValue
- Members getMemberNames() const;
+ /// \brief Return a list of the member names.
+ ///
+ /// If null, return an empty list.
+ /// \pre type() is objectValue or nullValue
+ /// \post if type() was nullValue, it remains nullValue
+ Members getMemberNames() const;
-//# ifdef JSON_USE_CPPTL
-// EnumMemberNames enumMemberNames() const;
-// EnumValues enumValues() const;
-//# endif
+ //# ifdef JSON_USE_CPPTL
+ // EnumMemberNames enumMemberNames() const;
+ // EnumValues enumValues() const;
+ //# endif
- /// Comments must be //... or /* ... */
- void setComment( const char *comment,
- CommentPlacement placement );
- /// Comments must be //... or /* ... */
- void setComment( const std::string &comment,
- CommentPlacement placement );
- bool hasComment( CommentPlacement placement ) const;
- /// Include delimiters and embedded newlines.
- std::string getComment( CommentPlacement placement ) const;
+ /// Comments must be //... or /* ... */
+ void setComment(const char *comment, CommentPlacement placement);
+ /// Comments must be //... or /* ... */
+ void setComment(const std::string &comment, CommentPlacement placement);
+ bool hasComment(CommentPlacement placement) const;
+ /// Include delimiters and embedded newlines.
+ std::string getComment(CommentPlacement placement) const;
- std::string toStyledString() const;
+ std::string toStyledString() const;
- const_iterator begin() const;
- const_iterator end() const;
+ const_iterator begin() const;
+ const_iterator end() const;
- iterator begin();
- iterator end();
+ iterator begin();
+ iterator end();
- // Accessors for the [start, limit) range of bytes within the JSON text from
- // which this value was parsed, if any.
- void setOffsetStart( size_t start );
- void setOffsetLimit( size_t limit );
- size_t getOffsetStart() const;
- size_t getOffsetLimit() const;
+ // Accessors for the [start, limit) range of bytes within the JSON text from
+ // which this value was parsed, if any.
+ void setOffsetStart(size_t start);
+ void setOffsetLimit(size_t limit);
+ size_t getOffsetStart() const;
+ size_t getOffsetLimit() const;
- private:
- Value &resolveReference( const char *key,
- bool isStatic );
-
-# ifdef JSON_VALUE_USE_INTERNAL_MAP
- inline bool isItemAvailable() const
- {
- return itemIsUsed_ == 0;
- }
-
- inline void setItemUsed( bool isUsed = true )
- {
- itemIsUsed_ = isUsed ? 1 : 0;
- }
-
- inline bool isMemberNameStatic() const
- {
- return memberNameIsStatic_ == 0;
- }
-
- inline void setMemberNameIsStatic( bool isStatic )
- {
- memberNameIsStatic_ = isStatic ? 1 : 0;
- }
-# endif // # ifdef JSON_VALUE_USE_INTERNAL_MAP
-
- private:
- struct CommentInfo
- {
- CommentInfo();
- ~CommentInfo();
-
- void setComment( const char *text );
-
- char *comment_;
- };
-
- //struct MemberNamesTransform
- //{
- // typedef const char *result_type;
- // const char *operator()( const CZString &name ) const
- // {
- // return name.c_str();
- // }
- //};
-
- union ValueHolder
- {
- LargestInt int_;
- LargestUInt uint_;
- double real_;
- bool bool_;
- char *string_;
-# ifdef JSON_VALUE_USE_INTERNAL_MAP
- ValueInternalArray *array_;
- ValueInternalMap *map_;
-#else
- ObjectValues *map_;
-# endif
- } value_;
- ValueType type_ : 8;
- int allocated_ : 1; // Notes: if declared as bool, bitfield is useless.
-# ifdef JSON_VALUE_USE_INTERNAL_MAP
- unsigned int itemIsUsed_ : 1; // used by the ValueInternalMap container.
- int memberNameIsStatic_ : 1; // used by the ValueInternalMap container.
-# endif
- CommentInfo *comments_;
-
- // [start, limit) byte offsets in the source JSON text from which this Value
- // was extracted.
- size_t start_;
- size_t limit_;
- };
-
-
- /** \brief Experimental and untested: represents an element of the "path" to access a node.
- */
- class JSON_API PathArgument
- {
- public:
- friend class Path;
-
- PathArgument();
- PathArgument( ArrayIndex index );
- PathArgument( const char *key );
- PathArgument( const std::string &key );
-
- private:
- enum Kind
- {
- kindNone = 0,
- kindIndex,
- kindKey
- };
- std::string key_;
- ArrayIndex index_;
- Kind kind_;
- };
-
- /** \brief Experimental and untested: represents a "path" to access a node.
- *
- * Syntax:
- * - "." => root node
- * - ".[n]" => elements at index 'n' of root node (an array value)
- * - ".name" => member named 'name' of root node (an object value)
- * - ".name1.name2.name3"
- * - ".[0][1][2].name1[3]"
- * - ".%" => member name is provided as parameter
- * - ".[%]" => index is provied as parameter
- */
- class JSON_API Path
- {
- public:
- Path( const std::string &path,
- const PathArgument &a1 = PathArgument(),
- const PathArgument &a2 = PathArgument(),
- const PathArgument &a3 = PathArgument(),
- const PathArgument &a4 = PathArgument(),
- const PathArgument &a5 = PathArgument() );
-
- const Value &resolve( const Value &root ) const;
- Value resolve( const Value &root,
- const Value &defaultValue ) const;
- /// Creates the "path" to access the specified node and returns a reference on the node.
- Value &make( Value &root ) const;
-
- private:
- typedef std::vector<const PathArgument *> InArgs;
- typedef std::vector<PathArgument> Args;
-
- void makePath( const std::string &path,
- const InArgs &in );
- void addPathInArg( const std::string &path,
- const InArgs &in,
- InArgs::const_iterator &itInArg,
- PathArgument::Kind kind );
- void invalidPath( const std::string &path,
- int location );
-
- Args args_;
- };
-
-
+private:
+ Value &resolveReference(const char *key, bool isStatic);
#ifdef JSON_VALUE_USE_INTERNAL_MAP
- /** \brief Allocator to customize Value internal map.
- * Below is an example of a simple implementation (default implementation actually
- * use memory pool for speed).
- * \code
- class DefaultValueMapAllocator : public ValueMapAllocator
+ inline bool isItemAvailable() const { return itemIsUsed_ == 0; }
+
+ inline void setItemUsed(bool isUsed = true) { itemIsUsed_ = isUsed ? 1 : 0; }
+
+ inline bool isMemberNameStatic() const { return memberNameIsStatic_ == 0; }
+
+ inline void setMemberNameIsStatic(bool isStatic) {
+ memberNameIsStatic_ = isStatic ? 1 : 0;
+ }
+#endif // # ifdef JSON_VALUE_USE_INTERNAL_MAP
+
+private:
+ struct CommentInfo {
+ CommentInfo();
+ ~CommentInfo();
+
+ void setComment(const char *text);
+
+ char *comment_;
+ };
+
+ // struct MemberNamesTransform
+ //{
+ // typedef const char *result_type;
+ // const char *operator()( const CZString &name ) const
+ // {
+ // return name.c_str();
+ // }
+ //};
+
+ union ValueHolder {
+ LargestInt int_;
+ LargestUInt uint_;
+ double real_;
+ bool bool_;
+ char *string_;
+#ifdef JSON_VALUE_USE_INTERNAL_MAP
+ ValueInternalArray *array_;
+ ValueInternalMap *map_;
+#else
+ ObjectValues *map_;
+#endif
+ } value_;
+ ValueType type_ : 8;
+ int allocated_ : 1; // Notes: if declared as bool, bitfield is useless.
+#ifdef JSON_VALUE_USE_INTERNAL_MAP
+ unsigned int itemIsUsed_ : 1; // used by the ValueInternalMap container.
+ int memberNameIsStatic_ : 1; // used by the ValueInternalMap container.
+#endif
+ CommentInfo *comments_;
+
+ // [start, limit) byte offsets in the source JSON text from which this Value
+ // was extracted.
+ size_t start_;
+ size_t limit_;
+};
+
+/** \brief Experimental and untested: represents an element of the "path" to
+ * access a node.
+ */
+class JSON_API PathArgument {
+public:
+ friend class Path;
+
+ PathArgument();
+ PathArgument(ArrayIndex index);
+ PathArgument(const char *key);
+ PathArgument(const std::string &key);
+
+private:
+ enum Kind {
+ kindNone = 0,
+ kindIndex,
+ kindKey
+ };
+ std::string key_;
+ ArrayIndex index_;
+ Kind kind_;
+};
+
+/** \brief Experimental and untested: represents a "path" to access a node.
+ *
+ * Syntax:
+ * - "." => root node
+ * - ".[n]" => elements at index 'n' of root node (an array value)
+ * - ".name" => member named 'name' of root node (an object value)
+ * - ".name1.name2.name3"
+ * - ".[0][1][2].name1[3]"
+ * - ".%" => member name is provided as parameter
+ * - ".[%]" => index is provied as parameter
+ */
+class JSON_API Path {
+public:
+ Path(const std::string &path,
+ const PathArgument &a1 = PathArgument(),
+ const PathArgument &a2 = PathArgument(),
+ const PathArgument &a3 = PathArgument(),
+ const PathArgument &a4 = PathArgument(),
+ const PathArgument &a5 = PathArgument());
+
+ const Value &resolve(const Value &root) const;
+ Value resolve(const Value &root, const Value &defaultValue) const;
+ /// Creates the "path" to access the specified node and returns a reference on
+ /// the node.
+ Value &make(Value &root) const;
+
+private:
+ typedef std::vector<const PathArgument *> InArgs;
+ typedef std::vector<PathArgument> Args;
+
+ void makePath(const std::string &path, const InArgs &in);
+ void addPathInArg(const std::string &path,
+ const InArgs &in,
+ InArgs::const_iterator &itInArg,
+ PathArgument::Kind kind);
+ void invalidPath(const std::string &path, int location);
+
+ Args args_;
+};
+
+#ifdef JSON_VALUE_USE_INTERNAL_MAP
+/** \brief Allocator to customize Value internal map.
+ * Below is an example of a simple implementation (default implementation
+ actually
+ * use memory pool for speed).
+ * \code
+ class DefaultValueMapAllocator : public ValueMapAllocator
+ {
+ public: // overridden from ValueMapAllocator
+ virtual ValueInternalMap *newMap()
{
- public: // overridden from ValueMapAllocator
- virtual ValueInternalMap *newMap()
- {
- return new ValueInternalMap();
- }
+ return new ValueInternalMap();
+ }
- virtual ValueInternalMap *newMapCopy( const ValueInternalMap &other )
- {
- return new ValueInternalMap( other );
- }
-
- virtual void destructMap( ValueInternalMap *map )
- {
- delete map;
- }
-
- virtual ValueInternalLink *allocateMapBuckets( unsigned int size )
- {
- return new ValueInternalLink[size];
- }
-
- virtual void releaseMapBuckets( ValueInternalLink *links )
- {
- delete [] links;
- }
-
- virtual ValueInternalLink *allocateMapLink()
- {
- return new ValueInternalLink();
- }
-
- virtual void releaseMapLink( ValueInternalLink *link )
- {
- delete link;
- }
- };
- * \endcode
- */
- class JSON_API ValueMapAllocator
- {
- public:
- virtual ~ValueMapAllocator();
- virtual ValueInternalMap *newMap() = 0;
- virtual ValueInternalMap *newMapCopy( const ValueInternalMap &other ) = 0;
- virtual void destructMap( ValueInternalMap *map ) = 0;
- virtual ValueInternalLink *allocateMapBuckets( unsigned int size ) = 0;
- virtual void releaseMapBuckets( ValueInternalLink *links ) = 0;
- virtual ValueInternalLink *allocateMapLink() = 0;
- virtual void releaseMapLink( ValueInternalLink *link ) = 0;
- };
-
- /** \brief ValueInternalMap hash-map bucket chain link (for internal use only).
- * \internal previous_ & next_ allows for bidirectional traversal.
- */
- class JSON_API ValueInternalLink
- {
- public:
- enum { itemPerLink = 6 }; // sizeof(ValueInternalLink) = 128 on 32 bits architecture.
- enum InternalFlags {
- flagAvailable = 0,
- flagUsed = 1
- };
-
- ValueInternalLink();
-
- ~ValueInternalLink();
-
- Value items_[itemPerLink];
- char *keys_[itemPerLink];
- ValueInternalLink *previous_;
- ValueInternalLink *next_;
- };
-
-
- /** \brief A linked page based hash-table implementation used internally by Value.
- * \internal ValueInternalMap is a tradional bucket based hash-table, with a linked
- * list in each bucket to handle collision. There is an addional twist in that
- * each node of the collision linked list is a page containing a fixed amount of
- * value. This provides a better compromise between memory usage and speed.
- *
- * Each bucket is made up of a chained list of ValueInternalLink. The last
- * link of a given bucket can be found in the 'previous_' field of the following bucket.
- * The last link of the last bucket is stored in tailLink_ as it has no following bucket.
- * Only the last link of a bucket may contains 'available' item. The last link always
- * contains at least one element unless is it the bucket one very first link.
- */
- class JSON_API ValueInternalMap
- {
- friend class ValueIteratorBase;
- friend class Value;
- public:
- typedef unsigned int HashKey;
- typedef unsigned int BucketIndex;
-
-# ifndef JSONCPP_DOC_EXCLUDE_IMPLEMENTATION
- struct IteratorState
+ virtual ValueInternalMap *newMapCopy( const ValueInternalMap &other )
{
- IteratorState()
- : map_(0)
- , link_(0)
- , itemIndex_(0)
- , bucketIndex_(0)
- {
- }
- ValueInternalMap *map_;
- ValueInternalLink *link_;
- BucketIndex itemIndex_;
- BucketIndex bucketIndex_;
- };
-# endif // ifndef JSONCPP_DOC_EXCLUDE_IMPLEMENTATION
+ return new ValueInternalMap( other );
+ }
- ValueInternalMap();
- ValueInternalMap( const ValueInternalMap &other );
- ValueInternalMap &operator =( const ValueInternalMap &other );
- ~ValueInternalMap();
-
- void swap( ValueInternalMap &other );
-
- BucketIndex size() const;
-
- void clear();
-
- bool reserveDelta( BucketIndex growth );
-
- bool reserve( BucketIndex newItemCount );
-
- const Value *find( const char *key ) const;
-
- Value *find( const char *key );
-
- Value &resolveReference( const char *key,
- bool isStatic );
-
- void remove( const char *key );
-
- void doActualRemove( ValueInternalLink *link,
- BucketIndex index,
- BucketIndex bucketIndex );
-
- ValueInternalLink *&getLastLinkInBucket( BucketIndex bucketIndex );
-
- Value &setNewItem( const char *key,
- bool isStatic,
- ValueInternalLink *link,
- BucketIndex index );
-
- Value &unsafeAdd( const char *key,
- bool isStatic,
- HashKey hashedKey );
-
- HashKey hash( const char *key ) const;
-
- int compare( const ValueInternalMap &other ) const;
-
- private:
- void makeBeginIterator( IteratorState &it ) const;
- void makeEndIterator( IteratorState &it ) const;
- static bool equals( const IteratorState &x, const IteratorState &other );
- static void increment( IteratorState &iterator );
- static void incrementBucket( IteratorState &iterator );
- static void decrement( IteratorState &iterator );
- static const char *key( const IteratorState &iterator );
- static const char *key( const IteratorState &iterator, bool &isStatic );
- static Value &value( const IteratorState &iterator );
- static int distance( const IteratorState &x, const IteratorState &y );
-
- private:
- ValueInternalLink *buckets_;
- ValueInternalLink *tailLink_;
- BucketIndex bucketsSize_;
- BucketIndex itemCount_;
- };
-
- /** \brief A simplified deque implementation used internally by Value.
- * \internal
- * It is based on a list of fixed "page", each page contains a fixed number of items.
- * Instead of using a linked-list, a array of pointer is used for fast item look-up.
- * Look-up for an element is as follow:
- * - compute page index: pageIndex = itemIndex / itemsPerPage
- * - look-up item in page: pages_[pageIndex][itemIndex % itemsPerPage]
- *
- * Insertion is amortized constant time (only the array containing the index of pointers
- * need to be reallocated when items are appended).
- */
- class JSON_API ValueInternalArray
- {
- friend class Value;
- friend class ValueIteratorBase;
- public:
- enum { itemsPerPage = 8 }; // should be a power of 2 for fast divide and modulo.
- typedef Value::ArrayIndex ArrayIndex;
- typedef unsigned int PageIndex;
-
-# ifndef JSONCPP_DOC_EXCLUDE_IMPLEMENTATION
- struct IteratorState // Must be a POD
+ virtual void destructMap( ValueInternalMap *map )
{
- IteratorState()
- : array_(0)
- , currentPageIndex_(0)
- , currentItemIndex_(0)
- {
- }
- ValueInternalArray *array_;
- Value **currentPageIndex_;
- unsigned int currentItemIndex_;
- };
-# endif // ifndef JSONCPP_DOC_EXCLUDE_IMPLEMENTATION
+ delete map;
+ }
- ValueInternalArray();
- ValueInternalArray( const ValueInternalArray &other );
- ValueInternalArray &operator =( const ValueInternalArray &other );
- ~ValueInternalArray();
- void swap( ValueInternalArray &other );
+ virtual ValueInternalLink *allocateMapBuckets( unsigned int size )
+ {
+ return new ValueInternalLink[size];
+ }
- void clear();
- void resize( ArrayIndex newSize );
+ virtual void releaseMapBuckets( ValueInternalLink *links )
+ {
+ delete [] links;
+ }
- Value &resolveReference( ArrayIndex index );
+ virtual ValueInternalLink *allocateMapLink()
+ {
+ return new ValueInternalLink();
+ }
- Value *find( ArrayIndex index ) const;
-
- ArrayIndex size() const;
-
- int compare( const ValueInternalArray &other ) const;
-
- private:
- static bool equals( const IteratorState &x, const IteratorState &other );
- static void increment( IteratorState &iterator );
- static void decrement( IteratorState &iterator );
- static Value &dereference( const IteratorState &iterator );
- static Value &unsafeDereference( const IteratorState &iterator );
- static int distance( const IteratorState &x, const IteratorState &y );
- static ArrayIndex indexOf( const IteratorState &iterator );
- void makeBeginIterator( IteratorState &it ) const;
- void makeEndIterator( IteratorState &it ) const;
- void makeIterator( IteratorState &it, ArrayIndex index ) const;
-
- void makeIndexValid( ArrayIndex index );
-
- Value **pages_;
- ArrayIndex size_;
- PageIndex pageCount_;
+ virtual void releaseMapLink( ValueInternalLink *link )
+ {
+ delete link;
+ }
};
+ * \endcode
+ */
+class JSON_API ValueMapAllocator {
+public:
+ virtual ~ValueMapAllocator();
+ virtual ValueInternalMap *newMap() = 0;
+ virtual ValueInternalMap *newMapCopy(const ValueInternalMap &other) = 0;
+ virtual void destructMap(ValueInternalMap *map) = 0;
+ virtual ValueInternalLink *allocateMapBuckets(unsigned int size) = 0;
+ virtual void releaseMapBuckets(ValueInternalLink *links) = 0;
+ virtual ValueInternalLink *allocateMapLink() = 0;
+ virtual void releaseMapLink(ValueInternalLink *link) = 0;
+};
- /** \brief Experimental: do not use. Allocator to customize Value internal array.
- * Below is an example of a simple implementation (actual implementation use
- * memory pool).
- \code
+/** \brief ValueInternalMap hash-map bucket chain link (for internal use only).
+ * \internal previous_ & next_ allows for bidirectional traversal.
+ */
+class JSON_API ValueInternalLink {
+public:
+ enum {
+ itemPerLink = 6
+ }; // sizeof(ValueInternalLink) = 128 on 32 bits architecture.
+ enum InternalFlags {
+ flagAvailable = 0,
+ flagUsed = 1
+ };
+
+ ValueInternalLink();
+
+ ~ValueInternalLink();
+
+ Value items_[itemPerLink];
+ char *keys_[itemPerLink];
+ ValueInternalLink *previous_;
+ ValueInternalLink *next_;
+};
+
+/** \brief A linked page based hash-table implementation used internally by
+ *Value.
+ * \internal ValueInternalMap is a tradional bucket based hash-table, with a
+ *linked
+ * list in each bucket to handle collision. There is an addional twist in that
+ * each node of the collision linked list is a page containing a fixed amount of
+ * value. This provides a better compromise between memory usage and speed.
+ *
+ * Each bucket is made up of a chained list of ValueInternalLink. The last
+ * link of a given bucket can be found in the 'previous_' field of the following
+ *bucket.
+ * The last link of the last bucket is stored in tailLink_ as it has no
+ *following bucket.
+ * Only the last link of a bucket may contains 'available' item. The last link
+ *always
+ * contains at least one element unless is it the bucket one very first link.
+ */
+class JSON_API ValueInternalMap {
+ friend class ValueIteratorBase;
+ friend class Value;
+
+public:
+ typedef unsigned int HashKey;
+ typedef unsigned int BucketIndex;
+
+#ifndef JSONCPP_DOC_EXCLUDE_IMPLEMENTATION
+ struct IteratorState {
+ IteratorState() : map_(0), link_(0), itemIndex_(0), bucketIndex_(0) {}
+ ValueInternalMap *map_;
+ ValueInternalLink *link_;
+ BucketIndex itemIndex_;
+ BucketIndex bucketIndex_;
+ };
+#endif // ifndef JSONCPP_DOC_EXCLUDE_IMPLEMENTATION
+
+ ValueInternalMap();
+ ValueInternalMap(const ValueInternalMap &other);
+ ValueInternalMap &operator=(const ValueInternalMap &other);
+ ~ValueInternalMap();
+
+ void swap(ValueInternalMap &other);
+
+ BucketIndex size() const;
+
+ void clear();
+
+ bool reserveDelta(BucketIndex growth);
+
+ bool reserve(BucketIndex newItemCount);
+
+ const Value *find(const char *key) const;
+
+ Value *find(const char *key);
+
+ Value &resolveReference(const char *key, bool isStatic);
+
+ void remove(const char *key);
+
+ void doActualRemove(ValueInternalLink *link,
+ BucketIndex index,
+ BucketIndex bucketIndex);
+
+ ValueInternalLink *&getLastLinkInBucket(BucketIndex bucketIndex);
+
+ Value &setNewItem(const char *key,
+ bool isStatic,
+ ValueInternalLink *link,
+ BucketIndex index);
+
+ Value &unsafeAdd(const char *key, bool isStatic, HashKey hashedKey);
+
+ HashKey hash(const char *key) const;
+
+ int compare(const ValueInternalMap &other) const;
+
+private:
+ void makeBeginIterator(IteratorState &it) const;
+ void makeEndIterator(IteratorState &it) const;
+ static bool equals(const IteratorState &x, const IteratorState &other);
+ static void increment(IteratorState &iterator);
+ static void incrementBucket(IteratorState &iterator);
+ static void decrement(IteratorState &iterator);
+ static const char *key(const IteratorState &iterator);
+ static const char *key(const IteratorState &iterator, bool &isStatic);
+ static Value &value(const IteratorState &iterator);
+ static int distance(const IteratorState &x, const IteratorState &y);
+
+private:
+ ValueInternalLink *buckets_;
+ ValueInternalLink *tailLink_;
+ BucketIndex bucketsSize_;
+ BucketIndex itemCount_;
+};
+
+/** \brief A simplified deque implementation used internally by Value.
+* \internal
+* It is based on a list of fixed "page", each page contains a fixed number of
+*items.
+* Instead of using a linked-list, a array of pointer is used for fast item
+*look-up.
+* Look-up for an element is as follow:
+* - compute page index: pageIndex = itemIndex / itemsPerPage
+* - look-up item in page: pages_[pageIndex][itemIndex % itemsPerPage]
+*
+* Insertion is amortized constant time (only the array containing the index of
+*pointers
+* need to be reallocated when items are appended).
+*/
+class JSON_API ValueInternalArray {
+ friend class Value;
+ friend class ValueIteratorBase;
+
+public:
+ enum {
+ itemsPerPage = 8
+ }; // should be a power of 2 for fast divide and modulo.
+ typedef Value::ArrayIndex ArrayIndex;
+ typedef unsigned int PageIndex;
+
+#ifndef JSONCPP_DOC_EXCLUDE_IMPLEMENTATION
+ struct IteratorState // Must be a POD
+ {
+ IteratorState() : array_(0), currentPageIndex_(0), currentItemIndex_(0) {}
+ ValueInternalArray *array_;
+ Value **currentPageIndex_;
+ unsigned int currentItemIndex_;
+ };
+#endif // ifndef JSONCPP_DOC_EXCLUDE_IMPLEMENTATION
+
+ ValueInternalArray();
+ ValueInternalArray(const ValueInternalArray &other);
+ ValueInternalArray &operator=(const ValueInternalArray &other);
+ ~ValueInternalArray();
+ void swap(ValueInternalArray &other);
+
+ void clear();
+ void resize(ArrayIndex newSize);
+
+ Value &resolveReference(ArrayIndex index);
+
+ Value *find(ArrayIndex index) const;
+
+ ArrayIndex size() const;
+
+ int compare(const ValueInternalArray &other) const;
+
+private:
+ static bool equals(const IteratorState &x, const IteratorState &other);
+ static void increment(IteratorState &iterator);
+ static void decrement(IteratorState &iterator);
+ static Value &dereference(const IteratorState &iterator);
+ static Value &unsafeDereference(const IteratorState &iterator);
+ static int distance(const IteratorState &x, const IteratorState &y);
+ static ArrayIndex indexOf(const IteratorState &iterator);
+ void makeBeginIterator(IteratorState &it) const;
+ void makeEndIterator(IteratorState &it) const;
+ void makeIterator(IteratorState &it, ArrayIndex index) const;
+
+ void makeIndexValid(ArrayIndex index);
+
+ Value **pages_;
+ ArrayIndex size_;
+ PageIndex pageCount_;
+};
+
+/** \brief Experimental: do not use. Allocator to customize Value internal
+array.
+ * Below is an example of a simple implementation (actual implementation use
+ * memory pool).
+ \code
class DefaultValueArrayAllocator : public ValueArrayAllocator
{
public: // overridden from ValueArrayAllocator
- virtual ~DefaultValueArrayAllocator()
- {
- }
+virtual ~DefaultValueArrayAllocator()
+{
+}
- virtual ValueInternalArray *newArray()
- {
- return new ValueInternalArray();
- }
+virtual ValueInternalArray *newArray()
+{
+ return new ValueInternalArray();
+}
- virtual ValueInternalArray *newArrayCopy( const ValueInternalArray &other )
- {
- return new ValueInternalArray( other );
- }
+virtual ValueInternalArray *newArrayCopy( const ValueInternalArray &other )
+{
+ return new ValueInternalArray( other );
+}
- virtual void destruct( ValueInternalArray *array )
- {
- delete array;
- }
+virtual void destruct( ValueInternalArray *array )
+{
+ delete array;
+}
- virtual void reallocateArrayPageIndex( Value **&indexes,
- ValueInternalArray::PageIndex &indexCount,
- ValueInternalArray::PageIndex minNewIndexCount )
- {
- ValueInternalArray::PageIndex newIndexCount = (indexCount*3)/2 + 1;
- if ( minNewIndexCount > newIndexCount )
- newIndexCount = minNewIndexCount;
- void *newIndexes = realloc( indexes, sizeof(Value*) * newIndexCount );
- if ( !newIndexes )
- throw std::bad_alloc();
- indexCount = newIndexCount;
- indexes = static_cast<Value **>( newIndexes );
- }
- virtual void releaseArrayPageIndex( Value **indexes,
- ValueInternalArray::PageIndex indexCount )
- {
- if ( indexes )
- free( indexes );
- }
+virtual void reallocateArrayPageIndex( Value **&indexes,
+ ValueInternalArray::PageIndex
+&indexCount,
+ ValueInternalArray::PageIndex
+minNewIndexCount )
+{
+ ValueInternalArray::PageIndex newIndexCount = (indexCount*3)/2 + 1;
+ if ( minNewIndexCount > newIndexCount )
+ newIndexCount = minNewIndexCount;
+ void *newIndexes = realloc( indexes, sizeof(Value*) * newIndexCount );
+ if ( !newIndexes )
+ throw std::bad_alloc();
+ indexCount = newIndexCount;
+ indexes = static_cast<Value **>( newIndexes );
+}
+virtual void releaseArrayPageIndex( Value **indexes,
+ ValueInternalArray::PageIndex indexCount )
+{
+ if ( indexes )
+ free( indexes );
+}
- virtual Value *allocateArrayPage()
- {
- return static_cast<Value *>( malloc( sizeof(Value) * ValueInternalArray::itemsPerPage ) );
- }
+virtual Value *allocateArrayPage()
+{
+ return static_cast<Value *>( malloc( sizeof(Value) *
+ValueInternalArray::itemsPerPage ) );
+}
- virtual void releaseArrayPage( Value *value )
- {
- if ( value )
- free( value );
- }
+virtual void releaseArrayPage( Value *value )
+{
+ if ( value )
+ free( value );
+}
};
- \endcode
- */
- class JSON_API ValueArrayAllocator
- {
- public:
- virtual ~ValueArrayAllocator();
- virtual ValueInternalArray *newArray() = 0;
- virtual ValueInternalArray *newArrayCopy( const ValueInternalArray &other ) = 0;
- virtual void destructArray( ValueInternalArray *array ) = 0;
- /** \brief Reallocate array page index.
- * Reallocates an array of pointer on each page.
- * \param indexes [input] pointer on the current index. May be \c NULL.
- * [output] pointer on the new index of at least
- * \a minNewIndexCount pages.
- * \param indexCount [input] current number of pages in the index.
- * [output] number of page the reallocated index can handle.
- * \b MUST be >= \a minNewIndexCount.
- * \param minNewIndexCount Minimum number of page the new index must be able to
- * handle.
- */
- virtual void reallocateArrayPageIndex( Value **&indexes,
- ValueInternalArray::PageIndex &indexCount,
- ValueInternalArray::PageIndex minNewIndexCount ) = 0;
- virtual void releaseArrayPageIndex( Value **indexes,
- ValueInternalArray::PageIndex indexCount ) = 0;
- virtual Value *allocateArrayPage() = 0;
- virtual void releaseArrayPage( Value *value ) = 0;
- };
+ \endcode
+ */
+class JSON_API ValueArrayAllocator {
+public:
+ virtual ~ValueArrayAllocator();
+ virtual ValueInternalArray *newArray() = 0;
+ virtual ValueInternalArray *newArrayCopy(const ValueInternalArray &other) = 0;
+ virtual void destructArray(ValueInternalArray *array) = 0;
+ /** \brief Reallocate array page index.
+ * Reallocates an array of pointer on each page.
+ * \param indexes [input] pointer on the current index. May be \c NULL.
+ * [output] pointer on the new index of at least
+ * \a minNewIndexCount pages.
+ * \param indexCount [input] current number of pages in the index.
+ * [output] number of page the reallocated index can handle.
+ * \b MUST be >= \a minNewIndexCount.
+ * \param minNewIndexCount Minimum number of page the new index must be able
+ * to
+ * handle.
+ */
+ virtual void
+ reallocateArrayPageIndex(Value **&indexes,
+ ValueInternalArray::PageIndex &indexCount,
+ ValueInternalArray::PageIndex minNewIndexCount) = 0;
+ virtual void
+ releaseArrayPageIndex(Value **indexes,
+ ValueInternalArray::PageIndex indexCount) = 0;
+ virtual Value *allocateArrayPage() = 0;
+ virtual void releaseArrayPage(Value *value) = 0;
+};
#endif // #ifdef JSON_VALUE_USE_INTERNAL_MAP
+/** \brief base class for Value iterators.
+ *
+ */
+class JSON_API ValueIteratorBase {
+public:
+ typedef std::bidirectional_iterator_tag iterator_category;
+ typedef unsigned int size_t;
+ typedef int difference_type;
+ typedef ValueIteratorBase SelfType;
- /** \brief base class for Value iterators.
- *
- */
- class JSON_API ValueIteratorBase
- {
- public:
- typedef std::bidirectional_iterator_tag iterator_category;
- typedef unsigned int size_t;
- typedef int difference_type;
- typedef ValueIteratorBase SelfType;
-
- ValueIteratorBase();
+ ValueIteratorBase();
#ifndef JSON_VALUE_USE_INTERNAL_MAP
- explicit ValueIteratorBase( const Value::ObjectValues::iterator ¤t );
+ explicit ValueIteratorBase(const Value::ObjectValues::iterator ¤t);
#else
- ValueIteratorBase( const ValueInternalArray::IteratorState &state );
- ValueIteratorBase( const ValueInternalMap::IteratorState &state );
+ ValueIteratorBase(const ValueInternalArray::IteratorState &state);
+ ValueIteratorBase(const ValueInternalMap::IteratorState &state);
#endif
- bool operator ==( const SelfType &other ) const
- {
- return isEqual( other );
- }
+ bool operator==(const SelfType &other) const { return isEqual(other); }
- bool operator !=( const SelfType &other ) const
- {
- return !isEqual( other );
- }
+ bool operator!=(const SelfType &other) const { return !isEqual(other); }
- difference_type operator -( const SelfType &other ) const
- {
- return computeDistance( other );
- }
+ difference_type operator-(const SelfType &other) const {
+ return computeDistance(other);
+ }
- /// Return either the index or the member name of the referenced value as a Value.
- Value key() const;
+ /// Return either the index or the member name of the referenced value as a
+ /// Value.
+ Value key() const;
- /// Return the index of the referenced Value. -1 if it is not an arrayValue.
- UInt index() const;
+ /// Return the index of the referenced Value. -1 if it is not an arrayValue.
+ UInt index() const;
- /// Return the member name of the referenced Value. "" if it is not an objectValue.
- const char *memberName() const;
+ /// Return the member name of the referenced Value. "" if it is not an
+ /// objectValue.
+ const char *memberName() const;
- protected:
- Value &deref() const;
+protected:
+ Value &deref() const;
- void increment();
+ void increment();
- void decrement();
+ void decrement();
- difference_type computeDistance( const SelfType &other ) const;
+ difference_type computeDistance(const SelfType &other) const;
- bool isEqual( const SelfType &other ) const;
+ bool isEqual(const SelfType &other) const;
- void copy( const SelfType &other );
+ void copy(const SelfType &other);
- private:
+private:
#ifndef JSON_VALUE_USE_INTERNAL_MAP
- Value::ObjectValues::iterator current_;
- // Indicates that iterator is for a null value.
- bool isNull_;
+ Value::ObjectValues::iterator current_;
+ // Indicates that iterator is for a null value.
+ bool isNull_;
#else
- union
- {
- ValueInternalArray::IteratorState array_;
- ValueInternalMap::IteratorState map_;
- } iterator_;
- bool isArray_;
+ union {
+ ValueInternalArray::IteratorState array_;
+ ValueInternalMap::IteratorState map_;
+ } iterator_;
+ bool isArray_;
#endif
- };
+};
- /** \brief const iterator for object and array value.
- *
- */
- class JSON_API ValueConstIterator : public ValueIteratorBase
- {
- friend class Value;
- public:
- typedef const Value value_type;
- typedef unsigned int size_t;
- typedef int difference_type;
- typedef const Value &reference;
- typedef const Value *pointer;
- typedef ValueConstIterator SelfType;
+/** \brief const iterator for object and array value.
+ *
+ */
+class JSON_API ValueConstIterator : public ValueIteratorBase {
+ friend class Value;
- ValueConstIterator();
- private:
- /*! \internal Use by Value to create an iterator.
- */
+public:
+ typedef const Value value_type;
+ typedef unsigned int size_t;
+ typedef int difference_type;
+ typedef const Value &reference;
+ typedef const Value *pointer;
+ typedef ValueConstIterator SelfType;
+
+ ValueConstIterator();
+
+private:
+/*! \internal Use by Value to create an iterator.
+ */
#ifndef JSON_VALUE_USE_INTERNAL_MAP
- explicit ValueConstIterator( const Value::ObjectValues::iterator ¤t );
+ explicit ValueConstIterator(const Value::ObjectValues::iterator ¤t);
#else
- ValueConstIterator( const ValueInternalArray::IteratorState &state );
- ValueConstIterator( const ValueInternalMap::IteratorState &state );
+ ValueConstIterator(const ValueInternalArray::IteratorState &state);
+ ValueConstIterator(const ValueInternalMap::IteratorState &state);
#endif
- public:
- SelfType &operator =( const ValueIteratorBase &other );
+public:
+ SelfType &operator=(const ValueIteratorBase &other);
- SelfType operator++( int )
- {
- SelfType temp( *this );
- ++*this;
- return temp;
- }
+ SelfType operator++(int) {
+ SelfType temp(*this);
+ ++*this;
+ return temp;
+ }
- SelfType operator--( int )
- {
- SelfType temp( *this );
- --*this;
- return temp;
- }
+ SelfType operator--(int) {
+ SelfType temp(*this);
+ --*this;
+ return temp;
+ }
- SelfType &operator--()
- {
- decrement();
- return *this;
- }
+ SelfType &operator--() {
+ decrement();
+ return *this;
+ }
- SelfType &operator++()
- {
- increment();
- return *this;
- }
+ SelfType &operator++() {
+ increment();
+ return *this;
+ }
- reference operator *() const
- {
- return deref();
- }
- };
+ reference operator*() const { return deref(); }
+};
+/** \brief Iterator for object and array value.
+ */
+class JSON_API ValueIterator : public ValueIteratorBase {
+ friend class Value;
- /** \brief Iterator for object and array value.
- */
- class JSON_API ValueIterator : public ValueIteratorBase
- {
- friend class Value;
- public:
- typedef Value value_type;
- typedef unsigned int size_t;
- typedef int difference_type;
- typedef Value &reference;
- typedef Value *pointer;
- typedef ValueIterator SelfType;
+public:
+ typedef Value value_type;
+ typedef unsigned int size_t;
+ typedef int difference_type;
+ typedef Value &reference;
+ typedef Value *pointer;
+ typedef ValueIterator SelfType;
- ValueIterator();
- ValueIterator( const ValueConstIterator &other );
- ValueIterator( const ValueIterator &other );
- private:
- /*! \internal Use by Value to create an iterator.
- */
+ ValueIterator();
+ ValueIterator(const ValueConstIterator &other);
+ ValueIterator(const ValueIterator &other);
+
+private:
+/*! \internal Use by Value to create an iterator.
+ */
#ifndef JSON_VALUE_USE_INTERNAL_MAP
- explicit ValueIterator( const Value::ObjectValues::iterator ¤t );
+ explicit ValueIterator(const Value::ObjectValues::iterator ¤t);
#else
- ValueIterator( const ValueInternalArray::IteratorState &state );
- ValueIterator( const ValueInternalMap::IteratorState &state );
+ ValueIterator(const ValueInternalArray::IteratorState &state);
+ ValueIterator(const ValueInternalMap::IteratorState &state);
#endif
- public:
+public:
+ SelfType &operator=(const SelfType &other);
- SelfType &operator =( const SelfType &other );
+ SelfType operator++(int) {
+ SelfType temp(*this);
+ ++*this;
+ return temp;
+ }
- SelfType operator++( int )
- {
- SelfType temp( *this );
- ++*this;
- return temp;
- }
+ SelfType operator--(int) {
+ SelfType temp(*this);
+ --*this;
+ return temp;
+ }
- SelfType operator--( int )
- {
- SelfType temp( *this );
- --*this;
- return temp;
- }
+ SelfType &operator--() {
+ decrement();
+ return *this;
+ }
- SelfType &operator--()
- {
- decrement();
- return *this;
- }
+ SelfType &operator++() {
+ increment();
+ return *this;
+ }
- SelfType &operator++()
- {
- increment();
- return *this;
- }
-
- reference operator *() const
- {
- return deref();
- }
- };
-
+ reference operator*() const { return deref(); }
+};
} // namespace Json
-
#if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)
-# pragma warning(pop)
+#pragma warning(pop)
#endif // if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)
-
#endif // CPPTL_JSON_H_INCLUDED