Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2021-02-14 13:26:26

0001 #ifndef CPPTL_JSON_H_INCLUDED
0002 #define CPPTL_JSON_H_INCLUDED
0003 
0004 #include "forwards.h"
0005 #include <string>
0006 #include <vector>
0007 
0008 #ifndef JSON_USE_CPPTL_SMALLMAP
0009 #include <map>
0010 #else
0011 #include <cpptl/smallmap.h>
0012 #endif
0013 #ifdef JSON_USE_CPPTL
0014 #include <cpptl/forwards.h>
0015 #endif
0016 
0017 /** \brief JSON (JavaScript Object Notation).
0018  */
0019 namespace Json {
0020 
0021   /** \brief Type of the value held by a Value object.
0022     */
0023   enum ValueType {
0024     nullValue = 0,  ///< 'null' value
0025     intValue,       ///< signed integer value
0026     uintValue,      ///< unsigned integer value
0027     realValue,      ///< double value
0028     stringValue,    ///< UTF-8 string value
0029     booleanValue,   ///< bool value
0030     arrayValue,     ///< array value (ordered list)
0031     objectValue     ///< object value (collection of name/value pairs).
0032   };
0033 
0034   enum CommentPlacement {
0035     commentBefore = 0,       ///< a comment placed on the line before a value
0036     commentAfterOnSameLine,  ///< a comment just after a value on the same line
0037     commentAfter,            ///< a comment on the line after a value (only make sense for root value)
0038     numberOfCommentPlacement
0039   };
0040 
0041   //# ifdef JSON_USE_CPPTL
0042   //   typedef CppTL::AnyEnumerator<const char *> EnumMemberNames;
0043   //   typedef CppTL::AnyEnumerator<const Value &> EnumValues;
0044   //# endif
0045 
0046   /** \brief Lightweight wrapper to tag static string.
0047     *
0048     * Value constructor and objectValue member assignement takes advantage of the
0049     * StaticString and avoid the cost of string duplication when storing the
0050     * string or the member name.
0051     *
0052     * Example of usage:
0053     * \code
0054     * Json::Value aValue( StaticString("some text") );
0055     * Json::Value object;
0056     * static const StaticString code("code");
0057     * object[code] = 1234;
0058     * \endcode
0059     */
0060   class JSON_API StaticString {
0061   public:
0062     explicit StaticString(const char *czstring) : str_(czstring) {}
0063 
0064     operator const char *() const { return str_; }
0065 
0066     const char *c_str() const { return str_; }
0067 
0068   private:
0069     const char *str_;
0070   };
0071 
0072   /** \brief Represents a <a HREF="http://www.json.org">JSON</a> value.
0073     *
0074     * This class is a discriminated union wrapper that can represents a:
0075     * - signed integer [range: Value::minInt - Value::maxInt]
0076     * - unsigned integer (range: 0 - Value::maxUInt)
0077     * - double
0078     * - UTF-8 string
0079     * - boolean
0080     * - 'null'
0081     * - an ordered list of Value
0082     * - collection of name/value pairs (javascript object)
0083     *
0084     * The type of the held value is represented by a #ValueType and 
0085     * can be obtained using type().
0086     *
0087     * values of an #objectValue or #arrayValue can be accessed using operator[]() methods. 
0088     * Non const methods will automatically create the a #nullValue element 
0089     * if it does not exist. 
0090     * The sequence of an #arrayValue will be automatically resize and initialized 
0091     * with #nullValue. resize() can be used to enlarge or truncate an #arrayValue.
0092     *
0093     * The get() methods can be used to obtanis default value in the case the required element
0094     * does not exist.
0095     *
0096     * It is possible to iterate over the list of a #objectValue values using 
0097     * the getMemberNames() method.
0098     */
0099   class JSON_API Value {
0100     friend class ValueIteratorBase;
0101 #ifdef JSON_VALUE_USE_INTERNAL_MAP
0102     friend class ValueInternalLink;
0103     friend class ValueInternalMap;
0104 #endif
0105   public:
0106     typedef std::vector<std::string> Members;
0107     typedef ValueIterator iterator;
0108     typedef ValueConstIterator const_iterator;
0109     typedef Json::UInt UInt;
0110     typedef Json::Int Int;
0111     typedef UInt ArrayIndex;
0112 
0113     static const Value null;
0114     static const Int minInt;
0115     static const Int maxInt;
0116     static const UInt maxUInt;
0117 
0118   private:
0119 #ifndef JSONCPP_DOC_EXCLUDE_IMPLEMENTATION
0120 #ifndef JSON_VALUE_USE_INTERNAL_MAP
0121     class CZString {
0122     public:
0123       enum DuplicationPolicy { noDuplication = 0, duplicate, duplicateOnCopy };
0124       CZString(int index);
0125       CZString(const char *cstr, DuplicationPolicy allocate);
0126       CZString(const CZString &other);
0127       ~CZString();
0128       CZString &operator=(const CZString &other);
0129       bool operator<(const CZString &other) const;
0130       bool operator==(const CZString &other) const;
0131       int index() const;
0132       const char *c_str() const;
0133       bool isStaticString() const;
0134 
0135     private:
0136       void swap(CZString &other);
0137       const char *cstr_;
0138       int index_;
0139     };
0140 
0141   public:
0142 #ifndef JSON_USE_CPPTL_SMALLMAP
0143     typedef std::map<CZString, Value> ObjectValues;
0144 #else
0145     typedef CppTL::SmallMap<CZString, Value> ObjectValues;
0146 #endif  // ifndef JSON_USE_CPPTL_SMALLMAP
0147 #endif  // ifndef JSON_VALUE_USE_INTERNAL_MAP
0148 #endif  // ifndef JSONCPP_DOC_EXCLUDE_IMPLEMENTATION
0149 
0150   public:
0151     /** \brief Create a default Value of the given type.
0152 
0153         This is a very useful constructor.
0154         To create an empty array, pass arrayValue.
0155         To create an empty object, pass objectValue.
0156         Another Value can then be set to this one by assignment.
0157     This is useful since clear() and resize() will not alter types.
0158 
0159         Examples:
0160     \code
0161     Json::Value null_value; // null
0162     Json::Value arr_value(Json::arrayValue); // []
0163     Json::Value obj_value(Json::objectValue); // {}
0164     \endcode
0165       */
0166     Value(ValueType type = nullValue);
0167     Value(Int value);
0168     Value(UInt value);
0169     Value(double value);
0170     Value(const char *value);
0171     Value(const char *beginValue, const char *endValue);
0172     /** \brief Constructs a value from a static string.
0173 
0174        * Like other value string constructor but do not duplicate the string for
0175        * internal storage. The given string must remain alive after the call to this
0176        * constructor.
0177        * Example of usage:
0178        * \code
0179        * Json::Value aValue( StaticString("some text") );
0180        * \endcode
0181        */
0182     Value(const StaticString &value);
0183     Value(const std::string &value);
0184 #ifdef JSON_USE_CPPTL
0185     Value(const CppTL::ConstString &value);
0186 #endif
0187     Value(bool value);
0188     Value(const Value &other);
0189     ~Value();
0190 
0191     Value &operator=(const Value &other);
0192     /// Swap values.
0193     /// \note Currently, comments are intentionally not swapped, for
0194     /// both logic and efficiency.
0195     void swap(Value &other);
0196 
0197     ValueType type() const;
0198 
0199     bool operator<(const Value &other) const;
0200     bool operator<=(const Value &other) const;
0201     bool operator>=(const Value &other) const;
0202     bool operator>(const Value &other) const;
0203 
0204     bool operator==(const Value &other) const;
0205     bool operator!=(const Value &other) const;
0206 
0207     int compare(const Value &other);
0208 
0209     const char *asCString() const;
0210     std::string asString() const;
0211 #ifdef JSON_USE_CPPTL
0212     CppTL::ConstString asConstString() const;
0213 #endif
0214     Int asInt() const;
0215     UInt asUInt() const;
0216     double asDouble() const;
0217     bool asBool() const;
0218 
0219     bool isNull() const;
0220     bool isBool() const;
0221     bool isInt() const;
0222     bool isUInt() const;
0223     bool isIntegral() const;
0224     bool isDouble() const;
0225     bool isNumeric() const;
0226     bool isString() const;
0227     bool isArray() const;
0228     bool isObject() const;
0229 
0230     bool isConvertibleTo(ValueType other) const;
0231 
0232     /// Number of values in array or object
0233     UInt size() const;
0234 
0235     /// \brief Return true if empty array, empty object, or null;
0236     /// otherwise, false.
0237     bool empty() const;
0238 
0239     /// Return isNull()
0240     bool operator!() const;
0241 
0242     /// Remove all object members and array elements.
0243     /// \pre type() is arrayValue, objectValue, or nullValue
0244     /// \post type() is unchanged
0245     void clear();
0246 
0247     /// Resize the array to size elements.
0248     /// New elements are initialized to null.
0249     /// May only be called on nullValue or arrayValue.
0250     /// \pre type() is arrayValue or nullValue
0251     /// \post type() is arrayValue
0252     void resize(UInt size);
0253 
0254     /// Access an array element (zero based index ).
0255     /// If the array contains less than index element, then null value are inserted
0256     /// in the array so that its size is index+1.
0257     /// (You may need to say 'value[0u]' to get your compiler to distinguish
0258     ///  this from the operator[] which takes a string.)
0259     Value &operator[](UInt index);
0260     /// Access an array element (zero based index )
0261     /// (You may need to say 'value[0u]' to get your compiler to distinguish
0262     ///  this from the operator[] which takes a string.)
0263     const Value &operator[](UInt index) const;
0264     /// If the array contains at least index+1 elements, returns the element value,
0265     /// otherwise returns defaultValue.
0266     Value get(UInt index, const Value &defaultValue) const;
0267     /// Return true if index < size().
0268     bool isValidIndex(UInt index) const;
0269     /// \brief Append value to array at the end.
0270     ///
0271     /// Equivalent to jsonvalue[jsonvalue.size()] = value;
0272     Value &append(const Value &value);
0273 
0274     /// Access an object value by name, create a null member if it does not exist.
0275     Value &operator[](const char *key);
0276     /// Access an object value by name, returns null if there is no member with that name.
0277     const Value &operator[](const char *key) const;
0278     /// Access an object value by name, create a null member if it does not exist.
0279     Value &operator[](const std::string &key);
0280     /// Access an object value by name, returns null if there is no member with that name.
0281     const Value &operator[](const std::string &key) const;
0282     /** \brief Access an object value by name, create a null member if it does not exist.
0283 
0284        * If the object as no entry for that name, then the member name used to store
0285        * the new entry is not duplicated.
0286        * Example of use:
0287        * \code
0288        * Json::Value object;
0289        * static const StaticString code("code");
0290        * object[code] = 1234;
0291        * \endcode
0292        */
0293     Value &operator[](const StaticString &key);
0294 #ifdef JSON_USE_CPPTL
0295     /// Access an object value by name, create a null member if it does not exist.
0296     Value &operator[](const CppTL::ConstString &key);
0297     /// Access an object value by name, returns null if there is no member with that name.
0298     const Value &operator[](const CppTL::ConstString &key) const;
0299 #endif
0300     /// Return the member named key if it exist, defaultValue otherwise.
0301     Value get(const char *key, const Value &defaultValue) const;
0302     /// Return the member named key if it exist, defaultValue otherwise.
0303     Value get(const std::string &key, const Value &defaultValue) const;
0304 #ifdef JSON_USE_CPPTL
0305     /// Return the member named key if it exist, defaultValue otherwise.
0306     Value get(const CppTL::ConstString &key, const Value &defaultValue) const;
0307 #endif
0308     /// \brief Remove and return the named member.
0309     ///
0310     /// Do nothing if it did not exist.
0311     /// \return the removed Value, or null.
0312     /// \pre type() is objectValue or nullValue
0313     /// \post type() is unchanged
0314     Value removeMember(const char *key);
0315     /// Same as removeMember(const char*)
0316     Value removeMember(const std::string &key);
0317 
0318     /// Return true if the object has a member named key.
0319     bool isMember(const char *key) const;
0320     /// Return true if the object has a member named key.
0321     bool isMember(const std::string &key) const;
0322 #ifdef JSON_USE_CPPTL
0323     /// Return true if the object has a member named key.
0324     bool isMember(const CppTL::ConstString &key) const;
0325 #endif
0326 
0327     /// \brief Return a list of the member names.
0328     ///
0329     /// If null, return an empty list.
0330     /// \pre type() is objectValue or nullValue
0331     /// \post if type() was nullValue, it remains nullValue
0332     Members getMemberNames() const;
0333 
0334     //# ifdef JSON_USE_CPPTL
0335     //      EnumMemberNames enumMemberNames() const;
0336     //      EnumValues enumValues() const;
0337     //# endif
0338 
0339     /// Comments must be //... or /* ... */
0340     void setComment(const char *comment, CommentPlacement placement);
0341     /// Comments must be //... or /* ... */
0342     void setComment(const std::string &comment, CommentPlacement placement);
0343     bool hasComment(CommentPlacement placement) const;
0344     /// Include delimiters and embedded newlines.
0345     std::string getComment(CommentPlacement placement) const;
0346 
0347     std::string toStyledString() const;
0348 
0349     const_iterator begin() const;
0350     const_iterator end() const;
0351 
0352     iterator begin();
0353     iterator end();
0354 
0355   private:
0356     Value &resolveReference(const char *key, bool isStatic);
0357 
0358 #ifdef JSON_VALUE_USE_INTERNAL_MAP
0359     inline bool isItemAvailable() const { return itemIsUsed_ == 0; }
0360 
0361     inline void setItemUsed(bool isUsed = true) { itemIsUsed_ = isUsed ? 1 : 0; }
0362 
0363     inline bool isMemberNameStatic() const { return memberNameIsStatic_ == 0; }
0364 
0365     inline void setMemberNameIsStatic(bool isStatic) { memberNameIsStatic_ = isStatic ? 1 : 0; }
0366 #endif  // # ifdef JSON_VALUE_USE_INTERNAL_MAP
0367 
0368   private:
0369     struct CommentInfo {
0370       CommentInfo();
0371       ~CommentInfo();
0372 
0373       void setComment(const char *text);
0374 
0375       char *comment_;
0376     };
0377 
0378     //struct MemberNamesTransform
0379     //{
0380     //   typedef const char *result_type;
0381     //   const char *operator()( const CZString &name ) const
0382     //   {
0383     //      return name.c_str();
0384     //   }
0385     //};
0386 
0387     union ValueHolder {
0388       Int int_;
0389       UInt uint_;
0390       double real_;
0391       bool bool_;
0392       char *string_;
0393 #ifdef JSON_VALUE_USE_INTERNAL_MAP
0394       ValueInternalArray *array_;
0395       ValueInternalMap *map_;
0396 #else
0397       ObjectValues *map_;
0398 #endif
0399     } value_;
0400     ValueType type_ : 8;
0401     int allocated_ : 1;  // Notes: if declared as bool, bitfield is useless.
0402 #ifdef JSON_VALUE_USE_INTERNAL_MAP
0403     unsigned int itemIsUsed_ : 1;  // used by the ValueInternalMap container.
0404     int memberNameIsStatic_ : 1;   // used by the ValueInternalMap container.
0405 #endif
0406     CommentInfo *comments_;
0407   };
0408 
0409   /** \brief Experimental and untested: represents an element of the "path" to access a node.
0410     */
0411   class PathArgument {
0412   public:
0413     friend class Path;
0414 
0415     PathArgument();
0416     PathArgument(UInt index);
0417     PathArgument(const char *key);
0418     PathArgument(const std::string &key);
0419 
0420   private:
0421     enum Kind { kindNone = 0, kindIndex, kindKey };
0422     std::string key_;
0423     UInt index_;
0424     Kind kind_;
0425   };
0426 
0427   /** \brief Experimental and untested: represents a "path" to access a node.
0428     *
0429     * Syntax:
0430     * - "." => root node
0431     * - ".[n]" => elements at index 'n' of root node (an array value)
0432     * - ".name" => member named 'name' of root node (an object value)
0433     * - ".name1.name2.name3"
0434     * - ".[0][1][2].name1[3]"
0435     * - ".%" => member name is provided as parameter
0436     * - ".[%]" => index is provied as parameter
0437     */
0438   class Path {
0439   public:
0440     Path(const std::string &path,
0441          const PathArgument &a1 = PathArgument(),
0442          const PathArgument &a2 = PathArgument(),
0443          const PathArgument &a3 = PathArgument(),
0444          const PathArgument &a4 = PathArgument(),
0445          const PathArgument &a5 = PathArgument());
0446 
0447     const Value &resolve(const Value &root) const;
0448     Value resolve(const Value &root, const Value &defaultValue) const;
0449     /// Creates the "path" to access the specified node and returns a reference on the node.
0450     Value &make(Value &root) const;
0451 
0452   private:
0453     typedef std::vector<const PathArgument *> InArgs;
0454     typedef std::vector<PathArgument> Args;
0455 
0456     void makePath(const std::string &path, const InArgs &in);
0457     void addPathInArg(const std::string &path,
0458                       const InArgs &in,
0459                       InArgs::const_iterator &itInArg,
0460                       PathArgument::Kind kind);
0461     void invalidPath(const std::string &path, int location);
0462 
0463     Args args_;
0464   };
0465 
0466   /** \brief Experimental do not use: Allocator to customize member name and string value memory management done by Value.
0467     *
0468     * - makeMemberName() and releaseMemberName() are called to respectively duplicate and
0469     *   free an Json::objectValue member name.
0470     * - duplicateStringValue() and releaseStringValue() are called similarly to
0471     *   duplicate and free a Json::stringValue value.
0472     */
0473   class ValueAllocator {
0474   public:
0475     enum { unknown = (unsigned)-1 };
0476 
0477     virtual ~ValueAllocator();
0478 
0479     virtual char *makeMemberName(const char *memberName) const = 0;
0480     virtual void releaseMemberName(char *memberName) const = 0;
0481     virtual char *duplicateStringValue(const char *value, unsigned int length = unknown) const = 0;
0482     virtual void releaseStringValue(char *value) const = 0;
0483   };
0484 
0485 #ifdef JSON_VALUE_USE_INTERNAL_MAP
0486   /** \brief Allocator to customize Value internal map.
0487     * Below is an example of a simple implementation (default implementation actually
0488     * use memory pool for speed).
0489     * \code
0490       class DefaultValueMapAllocator : public ValueMapAllocator
0491       {
0492       public: // overridden from ValueMapAllocator
0493          virtual ValueInternalMap *newMap()
0494          {
0495             return new ValueInternalMap();
0496          }
0497 
0498          virtual ValueInternalMap *newMapCopy( const ValueInternalMap &other )
0499          {
0500             return new ValueInternalMap( other );
0501          }
0502 
0503          virtual void destructMap( ValueInternalMap *map )
0504          {
0505             delete map;
0506          }
0507 
0508          virtual ValueInternalLink *allocateMapBuckets( unsigned int size )
0509          {
0510             return new ValueInternalLink[size];
0511          }
0512 
0513          virtual void releaseMapBuckets( ValueInternalLink *links )
0514          {
0515             delete [] links;
0516          }
0517 
0518          virtual ValueInternalLink *allocateMapLink()
0519          {
0520             return new ValueInternalLink();
0521          }
0522 
0523          virtual void releaseMapLink( ValueInternalLink *link )
0524          {
0525             delete link;
0526          }
0527       };
0528     * \endcode
0529     */
0530   class JSON_API ValueMapAllocator {
0531   public:
0532     virtual ~ValueMapAllocator();
0533     virtual ValueInternalMap *newMap() = 0;
0534     virtual ValueInternalMap *newMapCopy(const ValueInternalMap &other) = 0;
0535     virtual void destructMap(ValueInternalMap *map) = 0;
0536     virtual ValueInternalLink *allocateMapBuckets(unsigned int size) = 0;
0537     virtual void releaseMapBuckets(ValueInternalLink *links) = 0;
0538     virtual ValueInternalLink *allocateMapLink() = 0;
0539     virtual void releaseMapLink(ValueInternalLink *link) = 0;
0540   };
0541 
0542   /** \brief ValueInternalMap hash-map bucket chain link (for internal use only).
0543     * \internal previous_ & next_ allows for bidirectional traversal.
0544     */
0545   class JSON_API ValueInternalLink {
0546   public:
0547     enum { itemPerLink = 6 };  // sizeof(ValueInternalLink) = 128 on 32 bits architecture.
0548     enum InternalFlags { flagAvailable = 0, flagUsed = 1 };
0549 
0550     ValueInternalLink();
0551 
0552     ~ValueInternalLink();
0553 
0554     Value items_[itemPerLink];
0555     char *keys_[itemPerLink];
0556     ValueInternalLink *previous_;
0557     ValueInternalLink *next_;
0558   };
0559 
0560   /** \brief A linked page based hash-table implementation used internally by Value.
0561     * \internal ValueInternalMap is a tradional bucket based hash-table, with a linked
0562     * list in each bucket to handle collision. There is an addional twist in that
0563     * each node of the collision linked list is a page containing a fixed amount of
0564     * value. This provides a better compromise between memory usage and speed.
0565     * 
0566     * Each bucket is made up of a chained list of ValueInternalLink. The last
0567     * link of a given bucket can be found in the 'previous_' field of the following bucket.
0568     * The last link of the last bucket is stored in tailLink_ as it has no following bucket.
0569     * Only the last link of a bucket may contains 'available' item. The last link always
0570     * contains at least one element unless is it the bucket one very first link.
0571     */
0572   class JSON_API ValueInternalMap {
0573     friend class ValueIteratorBase;
0574     friend class Value;
0575 
0576   public:
0577     typedef unsigned int HashKey;
0578     typedef unsigned int BucketIndex;
0579 
0580 #ifndef JSONCPP_DOC_EXCLUDE_IMPLEMENTATION
0581     struct IteratorState {
0582       IteratorState() : map_(0), link_(0), itemIndex_(0), bucketIndex_(0) {}
0583       ValueInternalMap *map_;
0584       ValueInternalLink *link_;
0585       BucketIndex itemIndex_;
0586       BucketIndex bucketIndex_;
0587     };
0588 #endif  // ifndef JSONCPP_DOC_EXCLUDE_IMPLEMENTATION
0589 
0590     ValueInternalMap();
0591     ValueInternalMap(const ValueInternalMap &other);
0592     ValueInternalMap &operator=(const ValueInternalMap &other);
0593     ~ValueInternalMap();
0594 
0595     void swap(ValueInternalMap &other);
0596 
0597     BucketIndex size() const;
0598 
0599     void clear();
0600 
0601     bool reserveDelta(BucketIndex growth);
0602 
0603     bool reserve(BucketIndex newItemCount);
0604 
0605     const Value *find(const char *key) const;
0606 
0607     Value *find(const char *key);
0608 
0609     Value &resolveReference(const char *key, bool isStatic);
0610 
0611     void remove(const char *key);
0612 
0613     void doActualRemove(ValueInternalLink *link, BucketIndex index, BucketIndex bucketIndex);
0614 
0615     ValueInternalLink *&getLastLinkInBucket(BucketIndex bucketIndex);
0616 
0617     Value &setNewItem(const char *key, bool isStatic, ValueInternalLink *link, BucketIndex index);
0618 
0619     Value &unsafeAdd(const char *key, bool isStatic, HashKey hashedKey);
0620 
0621     HashKey hash(const char *key) const;
0622 
0623     int compare(const ValueInternalMap &other) const;
0624 
0625   private:
0626     void makeBeginIterator(IteratorState &it) const;
0627     void makeEndIterator(IteratorState &it) const;
0628     static bool equals(const IteratorState &x, const IteratorState &other);
0629     static void increment(IteratorState &iterator);
0630     static void incrementBucket(IteratorState &iterator);
0631     static void decrement(IteratorState &iterator);
0632     static const char *key(const IteratorState &iterator);
0633     static const char *key(const IteratorState &iterator, bool &isStatic);
0634     static Value &value(const IteratorState &iterator);
0635     static int distance(const IteratorState &x, const IteratorState &y);
0636 
0637   private:
0638     ValueInternalLink *buckets_;
0639     ValueInternalLink *tailLink_;
0640     BucketIndex bucketsSize_;
0641     BucketIndex itemCount_;
0642   };
0643 
0644   /** \brief A simplified deque implementation used internally by Value.
0645    * \internal
0646    * It is based on a list of fixed "page", each page contains a fixed number of items.
0647    * Instead of using a linked-list, a array of pointer is used for fast item look-up.
0648    * Look-up for an element is as follow:
0649    * - compute page index: pageIndex = itemIndex / itemsPerPage
0650    * - look-up item in page: pages_[pageIndex][itemIndex % itemsPerPage]
0651    *
0652    * Insertion is amortized constant time (only the array containing the index of pointers
0653    * need to be reallocated when items are appended).
0654    */
0655   class JSON_API ValueInternalArray {
0656     friend class Value;
0657     friend class ValueIteratorBase;
0658 
0659   public:
0660     enum { itemsPerPage = 8 };  // should be a power of 2 for fast divide and modulo.
0661     typedef Value::ArrayIndex ArrayIndex;
0662     typedef unsigned int PageIndex;
0663 
0664 #ifndef JSONCPP_DOC_EXCLUDE_IMPLEMENTATION
0665     struct IteratorState  // Must be a POD
0666     {
0667       IteratorState() : array_(0), currentPageIndex_(0), currentItemIndex_(0) {}
0668       ValueInternalArray *array_;
0669       Value **currentPageIndex_;
0670       unsigned int currentItemIndex_;
0671     };
0672 #endif  // ifndef JSONCPP_DOC_EXCLUDE_IMPLEMENTATION
0673 
0674     ValueInternalArray();
0675     ValueInternalArray(const ValueInternalArray &other);
0676     ValueInternalArray &operator=(const ValueInternalArray &other);
0677     ~ValueInternalArray();
0678     void swap(ValueInternalArray &other);
0679 
0680     void clear();
0681     void resize(ArrayIndex newSize);
0682 
0683     Value &resolveReference(ArrayIndex index);
0684 
0685     Value *find(ArrayIndex index) const;
0686 
0687     ArrayIndex size() const;
0688 
0689     int compare(const ValueInternalArray &other) const;
0690 
0691   private:
0692     static bool equals(const IteratorState &x, const IteratorState &other);
0693     static void increment(IteratorState &iterator);
0694     static void decrement(IteratorState &iterator);
0695     static Value &dereference(const IteratorState &iterator);
0696     static Value &unsafeDereference(const IteratorState &iterator);
0697     static int distance(const IteratorState &x, const IteratorState &y);
0698     static ArrayIndex indexOf(const IteratorState &iterator);
0699     void makeBeginIterator(IteratorState &it) const;
0700     void makeEndIterator(IteratorState &it) const;
0701     void makeIterator(IteratorState &it, ArrayIndex index) const;
0702 
0703     void makeIndexValid(ArrayIndex index);
0704 
0705     Value **pages_;
0706     ArrayIndex size_;
0707     PageIndex pageCount_;
0708   };
0709 
0710   /** \brief Experimental: do not use. Allocator to customize Value internal array.
0711     * Below is an example of a simple implementation (actual implementation use
0712     * memory pool).
0713       \code
0714 class DefaultValueArrayAllocator : public ValueArrayAllocator
0715 {
0716 public: // overridden from ValueArrayAllocator
0717    virtual ~DefaultValueArrayAllocator()
0718    {
0719    }
0720 
0721    virtual ValueInternalArray *newArray()
0722    {
0723       return new ValueInternalArray();
0724    }
0725 
0726    virtual ValueInternalArray *newArrayCopy( const ValueInternalArray &other )
0727    {
0728       return new ValueInternalArray( other );
0729    }
0730 
0731    virtual void destruct( ValueInternalArray *array )
0732    {
0733       delete array;
0734    }
0735 
0736    virtual void reallocateArrayPageIndex( Value **&indexes, 
0737                                           ValueInternalArray::PageIndex &indexCount,
0738                                           ValueInternalArray::PageIndex minNewIndexCount )
0739    {
0740       ValueInternalArray::PageIndex newIndexCount = (indexCount*3)/2 + 1;
0741       if ( minNewIndexCount > newIndexCount )
0742          newIndexCount = minNewIndexCount;
0743       void *newIndexes = realloc( indexes, sizeof(Value*) * newIndexCount );
0744       if ( !newIndexes )
0745          throw std::bad_alloc();
0746       indexCount = newIndexCount;
0747       indexes = static_cast<Value **>( newIndexes );
0748    }
0749    virtual void releaseArrayPageIndex( Value **indexes, 
0750                                        ValueInternalArray::PageIndex indexCount )
0751    {
0752       if ( indexes )
0753          free( indexes );
0754    }
0755 
0756    virtual Value *allocateArrayPage()
0757    {
0758       return static_cast<Value *>( malloc( sizeof(Value) * ValueInternalArray::itemsPerPage ) );
0759    }
0760 
0761    virtual void releaseArrayPage( Value *value )
0762    {
0763       if ( value )
0764          free( value );
0765    }
0766 };
0767       \endcode
0768     */
0769   class JSON_API ValueArrayAllocator {
0770   public:
0771     virtual ~ValueArrayAllocator();
0772     virtual ValueInternalArray *newArray() = 0;
0773     virtual ValueInternalArray *newArrayCopy(const ValueInternalArray &other) = 0;
0774     virtual void destructArray(ValueInternalArray *array) = 0;
0775     /** \brief Reallocate array page index.
0776        * Reallocates an array of pointer on each page.
0777        * \param indexes [input] pointer on the current index. May be \c NULL.
0778        *                [output] pointer on the new index of at least 
0779        *                         \a minNewIndexCount pages. 
0780        * \param indexCount [input] current number of pages in the index.
0781        *                   [output] number of page the reallocated index can handle.
0782        *                            \b MUST be >= \a minNewIndexCount.
0783        * \param minNewIndexCount Minimum number of page the new index must be able to
0784        *                         handle.
0785        */
0786     virtual void reallocateArrayPageIndex(Value **&indexes,
0787                                           ValueInternalArray::PageIndex &indexCount,
0788                                           ValueInternalArray::PageIndex minNewIndexCount) = 0;
0789     virtual void releaseArrayPageIndex(Value **indexes, ValueInternalArray::PageIndex indexCount) = 0;
0790     virtual Value *allocateArrayPage() = 0;
0791     virtual void releaseArrayPage(Value *value) = 0;
0792   };
0793 #endif  // #ifdef JSON_VALUE_USE_INTERNAL_MAP
0794 
0795   /** \brief base class for Value iterators.
0796     *
0797     */
0798   class ValueIteratorBase {
0799   public:
0800     typedef unsigned int size_t;
0801     typedef int difference_type;
0802     typedef ValueIteratorBase SelfType;
0803 
0804     ValueIteratorBase();
0805 #ifndef JSON_VALUE_USE_INTERNAL_MAP
0806     explicit ValueIteratorBase(const Value::ObjectValues::iterator &current);
0807 #else
0808     ValueIteratorBase(const ValueInternalArray::IteratorState &state);
0809     ValueIteratorBase(const ValueInternalMap::IteratorState &state);
0810 #endif
0811 
0812     bool operator==(const SelfType &other) const { return isEqual(other); }
0813 
0814     bool operator!=(const SelfType &other) const { return !isEqual(other); }
0815 
0816     difference_type operator-(const SelfType &other) const { return computeDistance(other); }
0817 
0818     /// Return either the index or the member name of the referenced value as a Value.
0819     Value key() const;
0820 
0821     /// Return the index of the referenced Value. -1 if it is not an arrayValue.
0822     UInt index() const;
0823 
0824     /// Return the member name of the referenced Value. "" if it is not an objectValue.
0825     const char *memberName() const;
0826 
0827   protected:
0828     Value &deref() const;
0829 
0830     void increment();
0831 
0832     void decrement();
0833 
0834     difference_type computeDistance(const SelfType &other) const;
0835 
0836     bool isEqual(const SelfType &other) const;
0837 
0838     void copy(const SelfType &other);
0839 
0840   private:
0841 #ifndef JSON_VALUE_USE_INTERNAL_MAP
0842     Value::ObjectValues::iterator current_;
0843     // Indicates that iterator is for a null value.
0844     bool isNull_;
0845 #else
0846     union {
0847       ValueInternalArray::IteratorState array_;
0848       ValueInternalMap::IteratorState map_;
0849     } iterator_;
0850     bool isArray_;
0851 #endif
0852   };
0853 
0854   /** \brief const iterator for object and array value.
0855     *
0856     */
0857   class ValueConstIterator : public ValueIteratorBase {
0858     friend class Value;
0859 
0860   public:
0861     typedef unsigned int size_t;
0862     typedef int difference_type;
0863     typedef const Value &reference;
0864     typedef const Value *pointer;
0865     typedef ValueConstIterator SelfType;
0866 
0867     ValueConstIterator();
0868 
0869   private:
0870     /*! \internal Use by Value to create an iterator.
0871        */
0872 #ifndef JSON_VALUE_USE_INTERNAL_MAP
0873     explicit ValueConstIterator(const Value::ObjectValues::iterator &current);
0874 #else
0875     ValueConstIterator(const ValueInternalArray::IteratorState &state);
0876     ValueConstIterator(const ValueInternalMap::IteratorState &state);
0877 #endif
0878   public:
0879     SelfType &operator=(const ValueIteratorBase &other);
0880 
0881     SelfType operator++(int) {
0882       SelfType temp(*this);
0883       ++*this;
0884       return temp;
0885     }
0886 
0887     SelfType operator--(int) {
0888       SelfType temp(*this);
0889       --*this;
0890       return temp;
0891     }
0892 
0893     SelfType &operator--() {
0894       decrement();
0895       return *this;
0896     }
0897 
0898     SelfType &operator++() {
0899       increment();
0900       return *this;
0901     }
0902 
0903     reference operator*() const { return deref(); }
0904   };
0905 
0906   /** \brief Iterator for object and array value.
0907     */
0908   class ValueIterator : public ValueIteratorBase {
0909     friend class Value;
0910 
0911   public:
0912     typedef unsigned int size_t;
0913     typedef int difference_type;
0914     typedef Value &reference;
0915     typedef Value *pointer;
0916     typedef ValueIterator SelfType;
0917 
0918     ValueIterator();
0919     ValueIterator(const ValueConstIterator &other);
0920     ValueIterator(const ValueIterator &other);
0921 
0922   private:
0923     /*! \internal Use by Value to create an iterator.
0924        */
0925 #ifndef JSON_VALUE_USE_INTERNAL_MAP
0926     explicit ValueIterator(const Value::ObjectValues::iterator &current);
0927 #else
0928     ValueIterator(const ValueInternalArray::IteratorState &state);
0929     ValueIterator(const ValueInternalMap::IteratorState &state);
0930 #endif
0931   public:
0932     SelfType &operator=(const SelfType &other);
0933 
0934     SelfType operator++(int) {
0935       SelfType temp(*this);
0936       ++*this;
0937       return temp;
0938     }
0939 
0940     SelfType operator--(int) {
0941       SelfType temp(*this);
0942       --*this;
0943       return temp;
0944     }
0945 
0946     SelfType &operator--() {
0947       decrement();
0948       return *this;
0949     }
0950 
0951     SelfType &operator++() {
0952       increment();
0953       return *this;
0954     }
0955 
0956     reference operator*() const { return deref(); }
0957   };
0958 
0959 }  // namespace Json
0960 
0961 #endif  // CPPTL_JSON_H_INCLUDED