value.h revision f59fb0e83fd0a4b41700d3f5eebdc8d21b173c2e
1// Copyright 2007-2010 Baptiste Lepilleur
2// Distributed under MIT license, or public domain if desired and
3// recognized in your jurisdiction.
4// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE
5
6#ifndef CPPTL_JSON_H_INCLUDED
7# define CPPTL_JSON_H_INCLUDED
8
9#if !defined(JSON_IS_AMALGAMATION)
10# include "forwards.h"
11#endif // if !defined(JSON_IS_AMALGAMATION)
12# include <string>
13# include <vector>
14
15# ifndef JSON_USE_CPPTL_SMALLMAP
16#  include <map>
17# else
18#  include <cpptl/smallmap.h>
19# endif
20# ifdef JSON_USE_CPPTL
21#  include <cpptl/forwards.h>
22# endif
23
24/** \brief JSON (JavaScript Object Notation).
25 */
26namespace Json {
27
28   /** \brief Type of the value held by a Value object.
29    */
30   enum ValueType
31   {
32      nullValue = 0, ///< 'null' value
33      intValue,      ///< signed integer value
34      uintValue,     ///< unsigned integer value
35      realValue,     ///< double value
36      stringValue,   ///< UTF-8 string value
37      booleanValue,  ///< bool value
38      arrayValue,    ///< array value (ordered list)
39      objectValue    ///< object value (collection of name/value pairs).
40   };
41
42   enum CommentPlacement
43   {
44      commentBefore = 0,        ///< a comment placed on the line before a value
45      commentAfterOnSameLine,   ///< a comment just after a value on the same line
46      commentAfter,             ///< a comment on the line after a value (only make sense for root value)
47      numberOfCommentPlacement
48   };
49
50//# ifdef JSON_USE_CPPTL
51//   typedef CppTL::AnyEnumerator<const char *> EnumMemberNames;
52//   typedef CppTL::AnyEnumerator<const Value &> EnumValues;
53//# endif
54
55   /** \brief Lightweight wrapper to tag static string.
56    *
57    * Value constructor and objectValue member assignement takes advantage of the
58    * StaticString and avoid the cost of string duplication when storing the
59    * string or the member name.
60    *
61    * Example of usage:
62    * \code
63    * Json::Value aValue( StaticString("some text") );
64    * Json::Value object;
65    * static const StaticString code("code");
66    * object[code] = 1234;
67    * \endcode
68    */
69   class JSON_API StaticString
70   {
71   public:
72      explicit StaticString( const char *czstring )
73         : str_( czstring )
74      {
75      }
76
77      operator const char *() const
78      {
79         return str_;
80      }
81
82      const char *c_str() const
83      {
84         return str_;
85      }
86
87   private:
88      const char *str_;
89   };
90
91   /** \brief Represents a <a HREF="http://www.json.org">JSON</a> value.
92    *
93    * This class is a discriminated union wrapper that can represents a:
94    * - signed integer [range: Value::minInt - Value::maxInt]
95    * - unsigned integer (range: 0 - Value::maxUInt)
96    * - double
97    * - UTF-8 string
98    * - boolean
99    * - 'null'
100    * - an ordered list of Value
101    * - collection of name/value pairs (javascript object)
102    *
103    * The type of the held value is represented by a #ValueType and
104    * can be obtained using type().
105    *
106    * values of an #objectValue or #arrayValue can be accessed using operator[]() methods.
107    * Non const methods will automatically create the a #nullValue element
108    * if it does not exist.
109    * The sequence of an #arrayValue will be automatically resize and initialized
110    * with #nullValue. resize() can be used to enlarge or truncate an #arrayValue.
111    *
112    * The get() methods can be used to obtanis default value in the case the required element
113    * does not exist.
114    *
115    * It is possible to iterate over the list of a #objectValue values using
116    * the getMemberNames() method.
117    */
118   class JSON_API Value
119   {
120      friend class ValueIteratorBase;
121# ifdef JSON_VALUE_USE_INTERNAL_MAP
122      friend class ValueInternalLink;
123      friend class ValueInternalMap;
124# endif
125   public:
126      typedef std::vector<std::string> Members;
127      typedef ValueIterator iterator;
128      typedef ValueConstIterator const_iterator;
129      typedef Json::UInt UInt;
130      typedef Json::Int Int;
131# if defined(JSON_HAS_INT64)
132      typedef Json::UInt64 UInt64;
133      typedef Json::Int64 Int64;
134#endif // defined(JSON_HAS_INT64)
135      typedef Json::LargestInt LargestInt;
136      typedef Json::LargestUInt LargestUInt;
137      typedef Json::ArrayIndex ArrayIndex;
138
139      static const Value null;
140      /// Minimum signed integer value that can be stored in a Json::Value.
141      static const LargestInt minLargestInt;
142      /// Maximum signed integer value that can be stored in a Json::Value.
143      static const LargestInt maxLargestInt;
144      /// Maximum unsigned integer value that can be stored in a Json::Value.
145      static const LargestUInt maxLargestUInt;
146
147      /// Minimum signed int value that can be stored in a Json::Value.
148      static const Int minInt;
149      /// Maximum signed int value that can be stored in a Json::Value.
150      static const Int maxInt;
151      /// Maximum unsigned int value that can be stored in a Json::Value.
152      static const UInt maxUInt;
153
154# if defined(JSON_HAS_INT64)
155      /// Minimum signed 64 bits int value that can be stored in a Json::Value.
156      static const Int64 minInt64;
157      /// Maximum signed 64 bits int value that can be stored in a Json::Value.
158      static const Int64 maxInt64;
159      /// Maximum unsigned 64 bits int value that can be stored in a Json::Value.
160      static const UInt64 maxUInt64;
161#endif // defined(JSON_HAS_INT64)
162
163   private:
164#ifndef JSONCPP_DOC_EXCLUDE_IMPLEMENTATION
165# ifndef JSON_VALUE_USE_INTERNAL_MAP
166      class CZString
167      {
168      public:
169         enum DuplicationPolicy
170         {
171            noDuplication = 0,
172            duplicate,
173            duplicateOnCopy
174         };
175         CZString( ArrayIndex index );
176         CZString( const char *cstr, DuplicationPolicy allocate );
177         CZString( const CZString &other );
178         ~CZString();
179         CZString &operator =( const CZString &other );
180         bool operator<( const CZString &other ) const;
181         bool operator==( const CZString &other ) const;
182         ArrayIndex index() const;
183         const char *c_str() const;
184         bool isStaticString() const;
185      private:
186         void swap( CZString &other );
187         const char *cstr_;
188         ArrayIndex index_;
189      };
190
191   public:
192#  ifndef JSON_USE_CPPTL_SMALLMAP
193      typedef std::map<CZString, Value> ObjectValues;
194#  else
195      typedef CppTL::SmallMap<CZString, Value> ObjectValues;
196#  endif // ifndef JSON_USE_CPPTL_SMALLMAP
197# endif // ifndef JSON_VALUE_USE_INTERNAL_MAP
198#endif // ifndef JSONCPP_DOC_EXCLUDE_IMPLEMENTATION
199
200   public:
201      /** \brief Create a default Value of the given type.
202
203        This is a very useful constructor.
204        To create an empty array, pass arrayValue.
205        To create an empty object, pass objectValue.
206        Another Value can then be set to this one by assignment.
207    This is useful since clear() and resize() will not alter types.
208
209        Examples:
210    \code
211    Json::Value null_value; // null
212    Json::Value arr_value(Json::arrayValue); // []
213    Json::Value obj_value(Json::objectValue); // {}
214    \endcode
215      */
216      Value( ValueType type = nullValue );
217      Value( Int value );
218      Value( UInt value );
219#if defined(JSON_HAS_INT64)
220      Value( Int64 value );
221      Value( UInt64 value );
222#endif // if defined(JSON_HAS_INT64)
223      Value( double value );
224      Value( const char *value );
225      Value( const char *beginValue, const char *endValue );
226      /** \brief Constructs a value from a static string.
227
228       * Like other value string constructor but do not duplicate the string for
229       * internal storage. The given string must remain alive after the call to this
230       * constructor.
231       * Example of usage:
232       * \code
233       * Json::Value aValue( StaticString("some text") );
234       * \endcode
235       */
236      Value( const StaticString &value );
237      Value( const std::string &value );
238# ifdef JSON_USE_CPPTL
239      Value( const CppTL::ConstString &value );
240# endif
241      Value( bool value );
242      Value( const Value &other );
243      ~Value();
244
245      Value &operator=( const Value &other );
246      /// Swap values.
247      /// \note Currently, comments are intentionally not swapped, for
248      /// both logic and efficiency.
249      void swap( Value &other );
250
251      ValueType type() const;
252
253      bool operator <( const Value &other ) const;
254      bool operator <=( const Value &other ) const;
255      bool operator >=( const Value &other ) const;
256      bool operator >( const Value &other ) const;
257
258      bool operator ==( const Value &other ) const;
259      bool operator !=( const Value &other ) const;
260
261      int compare( const Value &other ) const;
262
263      const char *asCString() const;
264      std::string asString() const;
265# ifdef JSON_USE_CPPTL
266      CppTL::ConstString asConstString() const;
267# endif
268      Int asInt() const;
269      UInt asUInt() const;
270#if defined(JSON_HAS_INT64)
271      Int64 asInt64() const;
272      UInt64 asUInt64() const;
273#endif // if defined(JSON_HAS_INT64)
274      LargestInt asLargestInt() const;
275      LargestUInt asLargestUInt() const;
276      float asFloat() const;
277      double asDouble() const;
278      bool asBool() const;
279
280      bool isNull() const;
281      bool isBool() const;
282      bool isInt() const;
283      bool isInt64() const;
284      bool isUInt() const;
285      bool isUInt64() const;
286      bool isIntegral() const;
287      bool isDouble() const;
288      bool isNumeric() const;
289      bool isString() const;
290      bool isArray() const;
291      bool isObject() const;
292
293      bool isConvertibleTo( ValueType other ) const;
294
295      /// Number of values in array or object
296      ArrayIndex size() const;
297
298      /// \brief Return true if empty array, empty object, or null;
299      /// otherwise, false.
300      bool empty() const;
301
302      /// Return isNull()
303      bool operator!() const;
304
305      /// Remove all object members and array elements.
306      /// \pre type() is arrayValue, objectValue, or nullValue
307      /// \post type() is unchanged
308      void clear();
309
310      /// Resize the array to size elements.
311      /// New elements are initialized to null.
312      /// May only be called on nullValue or arrayValue.
313      /// \pre type() is arrayValue or nullValue
314      /// \post type() is arrayValue
315      void resize( ArrayIndex size );
316
317      /// Access an array element (zero based index ).
318      /// If the array contains less than index element, then null value are inserted
319      /// in the array so that its size is index+1.
320      /// (You may need to say 'value[0u]' to get your compiler to distinguish
321      ///  this from the operator[] which takes a string.)
322      Value &operator[]( ArrayIndex index );
323
324      /// Access an array element (zero based index ).
325      /// If the array contains less than index element, then null value are inserted
326      /// in the array so that its size is index+1.
327      /// (You may need to say 'value[0u]' to get your compiler to distinguish
328      ///  this from the operator[] which takes a string.)
329      Value &operator[]( int index );
330
331      /// Access an array element (zero based index )
332      /// (You may need to say 'value[0u]' to get your compiler to distinguish
333      ///  this from the operator[] which takes a string.)
334      const Value &operator[]( ArrayIndex index ) const;
335
336      /// Access an array element (zero based index )
337      /// (You may need to say 'value[0u]' to get your compiler to distinguish
338      ///  this from the operator[] which takes a string.)
339      const Value &operator[]( int index ) const;
340
341      /// If the array contains at least index+1 elements, returns the element value,
342      /// otherwise returns defaultValue.
343      Value get( ArrayIndex index,
344                 const Value &defaultValue ) const;
345      /// Return true if index < size().
346      bool isValidIndex( ArrayIndex index ) const;
347      /// \brief Append value to array at the end.
348      ///
349      /// Equivalent to jsonvalue[jsonvalue.size()] = value;
350      Value &append( const Value &value );
351
352      /// Access an object value by name, create a null member if it does not exist.
353      Value &operator[]( const char *key );
354      /// Access an object value by name, returns null if there is no member with that name.
355      const Value &operator[]( const char *key ) const;
356      /// Access an object value by name, create a null member if it does not exist.
357      Value &operator[]( const std::string &key );
358      /// Access an object value by name, returns null if there is no member with that name.
359      const Value &operator[]( const std::string &key ) const;
360      /** \brief Access an object value by name, create a null member if it does not exist.
361
362       * If the object as no entry for that name, then the member name used to store
363       * the new entry is not duplicated.
364       * Example of use:
365       * \code
366       * Json::Value object;
367       * static const StaticString code("code");
368       * object[code] = 1234;
369       * \endcode
370       */
371      Value &operator[]( const StaticString &key );
372# ifdef JSON_USE_CPPTL
373      /// Access an object value by name, create a null member if it does not exist.
374      Value &operator[]( const CppTL::ConstString &key );
375      /// Access an object value by name, returns null if there is no member with that name.
376      const Value &operator[]( const CppTL::ConstString &key ) const;
377# endif
378      /// Return the member named key if it exist, defaultValue otherwise.
379      Value get( const char *key,
380                 const Value &defaultValue ) const;
381      /// Return the member named key if it exist, defaultValue otherwise.
382      Value get( const std::string &key,
383                 const Value &defaultValue ) const;
384# ifdef JSON_USE_CPPTL
385      /// Return the member named key if it exist, defaultValue otherwise.
386      Value get( const CppTL::ConstString &key,
387                 const Value &defaultValue ) const;
388# endif
389      /// \brief Remove and return the named member.
390      ///
391      /// Do nothing if it did not exist.
392      /// \return the removed Value, or null.
393      /// \pre type() is objectValue or nullValue
394      /// \post type() is unchanged
395      Value removeMember( const char* key );
396      /// Same as removeMember(const char*)
397      Value removeMember( const std::string &key );
398
399      /// Return true if the object has a member named key.
400      bool isMember( const char *key ) const;
401      /// Return true if the object has a member named key.
402      bool isMember( const std::string &key ) const;
403# ifdef JSON_USE_CPPTL
404      /// Return true if the object has a member named key.
405      bool isMember( const CppTL::ConstString &key ) const;
406# endif
407
408      /// \brief Return a list of the member names.
409      ///
410      /// If null, return an empty list.
411      /// \pre type() is objectValue or nullValue
412      /// \post if type() was nullValue, it remains nullValue
413      Members getMemberNames() const;
414
415//# ifdef JSON_USE_CPPTL
416//      EnumMemberNames enumMemberNames() const;
417//      EnumValues enumValues() const;
418//# endif
419
420      /// Comments must be //... or /* ... */
421      void setComment( const char *comment,
422                       CommentPlacement placement );
423      /// Comments must be //... or /* ... */
424      void setComment( const std::string &comment,
425                       CommentPlacement placement );
426      bool hasComment( CommentPlacement placement ) const;
427      /// Include delimiters and embedded newlines.
428      std::string getComment( CommentPlacement placement ) const;
429
430      std::string toStyledString() const;
431
432      const_iterator begin() const;
433      const_iterator end() const;
434
435      iterator begin();
436      iterator end();
437
438   private:
439      Value &resolveReference( const char *key,
440                               bool isStatic );
441
442# ifdef JSON_VALUE_USE_INTERNAL_MAP
443      inline bool isItemAvailable() const
444      {
445         return itemIsUsed_ == 0;
446      }
447
448      inline void setItemUsed( bool isUsed = true )
449      {
450         itemIsUsed_ = isUsed ? 1 : 0;
451      }
452
453      inline bool isMemberNameStatic() const
454      {
455         return memberNameIsStatic_ == 0;
456      }
457
458      inline void setMemberNameIsStatic( bool isStatic )
459      {
460         memberNameIsStatic_ = isStatic ? 1 : 0;
461      }
462# endif // # ifdef JSON_VALUE_USE_INTERNAL_MAP
463
464   private:
465      struct CommentInfo
466      {
467         CommentInfo();
468         ~CommentInfo();
469
470         void setComment( const char *text );
471
472         char *comment_;
473      };
474
475      //struct MemberNamesTransform
476      //{
477      //   typedef const char *result_type;
478      //   const char *operator()( const CZString &name ) const
479      //   {
480      //      return name.c_str();
481      //   }
482      //};
483
484      union ValueHolder
485      {
486         LargestInt int_;
487         LargestUInt uint_;
488         double real_;
489         bool bool_;
490         char *string_;
491# ifdef JSON_VALUE_USE_INTERNAL_MAP
492         ValueInternalArray *array_;
493         ValueInternalMap *map_;
494#else
495         ObjectValues *map_;
496# endif
497      } value_;
498      ValueType type_ : 8;
499      int allocated_ : 1;     // Notes: if declared as bool, bitfield is useless.
500# ifdef JSON_VALUE_USE_INTERNAL_MAP
501      unsigned int itemIsUsed_ : 1;      // used by the ValueInternalMap container.
502      int memberNameIsStatic_ : 1;       // used by the ValueInternalMap container.
503# endif
504      CommentInfo *comments_;
505   };
506
507
508   /** \brief Experimental and untested: represents an element of the "path" to access a node.
509    */
510   class PathArgument
511   {
512   public:
513      friend class Path;
514
515      PathArgument();
516      PathArgument( ArrayIndex index );
517      PathArgument( const char *key );
518      PathArgument( const std::string &key );
519
520   private:
521      enum Kind
522      {
523         kindNone = 0,
524         kindIndex,
525         kindKey
526      };
527      std::string key_;
528      ArrayIndex index_;
529      Kind kind_;
530   };
531
532   /** \brief Experimental and untested: represents a "path" to access a node.
533    *
534    * Syntax:
535    * - "." => root node
536    * - ".[n]" => elements at index 'n' of root node (an array value)
537    * - ".name" => member named 'name' of root node (an object value)
538    * - ".name1.name2.name3"
539    * - ".[0][1][2].name1[3]"
540    * - ".%" => member name is provided as parameter
541    * - ".[%]" => index is provied as parameter
542    */
543   class Path
544   {
545   public:
546      Path( const std::string &path,
547            const PathArgument &a1 = PathArgument(),
548            const PathArgument &a2 = PathArgument(),
549            const PathArgument &a3 = PathArgument(),
550            const PathArgument &a4 = PathArgument(),
551            const PathArgument &a5 = PathArgument() );
552
553      const Value &resolve( const Value &root ) const;
554      Value resolve( const Value &root,
555                     const Value &defaultValue ) const;
556      /// Creates the "path" to access the specified node and returns a reference on the node.
557      Value &make( Value &root ) const;
558
559   private:
560      typedef std::vector<const PathArgument *> InArgs;
561      typedef std::vector<PathArgument> Args;
562
563      void makePath( const std::string &path,
564                     const InArgs &in );
565      void addPathInArg( const std::string &path,
566                         const InArgs &in,
567                         InArgs::const_iterator &itInArg,
568                         PathArgument::Kind kind );
569      void invalidPath( const std::string &path,
570                        int location );
571
572      Args args_;
573   };
574
575
576
577#ifdef JSON_VALUE_USE_INTERNAL_MAP
578   /** \brief Allocator to customize Value internal map.
579    * Below is an example of a simple implementation (default implementation actually
580    * use memory pool for speed).
581    * \code
582      class DefaultValueMapAllocator : public ValueMapAllocator
583      {
584      public: // overridden from ValueMapAllocator
585         virtual ValueInternalMap *newMap()
586         {
587            return new ValueInternalMap();
588         }
589
590         virtual ValueInternalMap *newMapCopy( const ValueInternalMap &other )
591         {
592            return new ValueInternalMap( other );
593         }
594
595         virtual void destructMap( ValueInternalMap *map )
596         {
597            delete map;
598         }
599
600         virtual ValueInternalLink *allocateMapBuckets( unsigned int size )
601         {
602            return new ValueInternalLink[size];
603         }
604
605         virtual void releaseMapBuckets( ValueInternalLink *links )
606         {
607            delete [] links;
608         }
609
610         virtual ValueInternalLink *allocateMapLink()
611         {
612            return new ValueInternalLink();
613         }
614
615         virtual void releaseMapLink( ValueInternalLink *link )
616         {
617            delete link;
618         }
619      };
620    * \endcode
621    */
622   class JSON_API ValueMapAllocator
623   {
624   public:
625      virtual ~ValueMapAllocator();
626      virtual ValueInternalMap *newMap() = 0;
627      virtual ValueInternalMap *newMapCopy( const ValueInternalMap &other ) = 0;
628      virtual void destructMap( ValueInternalMap *map ) = 0;
629      virtual ValueInternalLink *allocateMapBuckets( unsigned int size ) = 0;
630      virtual void releaseMapBuckets( ValueInternalLink *links ) = 0;
631      virtual ValueInternalLink *allocateMapLink() = 0;
632      virtual void releaseMapLink( ValueInternalLink *link ) = 0;
633   };
634
635   /** \brief ValueInternalMap hash-map bucket chain link (for internal use only).
636    * \internal previous_ & next_ allows for bidirectional traversal.
637    */
638   class JSON_API ValueInternalLink
639   {
640   public:
641      enum { itemPerLink = 6 };  // sizeof(ValueInternalLink) = 128 on 32 bits architecture.
642      enum InternalFlags {
643         flagAvailable = 0,
644         flagUsed = 1
645      };
646
647      ValueInternalLink();
648
649      ~ValueInternalLink();
650
651      Value items_[itemPerLink];
652      char *keys_[itemPerLink];
653      ValueInternalLink *previous_;
654      ValueInternalLink *next_;
655   };
656
657
658   /** \brief A linked page based hash-table implementation used internally by Value.
659    * \internal ValueInternalMap is a tradional bucket based hash-table, with a linked
660    * list in each bucket to handle collision. There is an addional twist in that
661    * each node of the collision linked list is a page containing a fixed amount of
662    * value. This provides a better compromise between memory usage and speed.
663    *
664    * Each bucket is made up of a chained list of ValueInternalLink. The last
665    * link of a given bucket can be found in the 'previous_' field of the following bucket.
666    * The last link of the last bucket is stored in tailLink_ as it has no following bucket.
667    * Only the last link of a bucket may contains 'available' item. The last link always
668    * contains at least one element unless is it the bucket one very first link.
669    */
670   class JSON_API ValueInternalMap
671   {
672      friend class ValueIteratorBase;
673      friend class Value;
674   public:
675      typedef unsigned int HashKey;
676      typedef unsigned int BucketIndex;
677
678# ifndef JSONCPP_DOC_EXCLUDE_IMPLEMENTATION
679      struct IteratorState
680      {
681         IteratorState()
682            : map_(0)
683            , link_(0)
684            , itemIndex_(0)
685            , bucketIndex_(0)
686         {
687         }
688         ValueInternalMap *map_;
689         ValueInternalLink *link_;
690         BucketIndex itemIndex_;
691         BucketIndex bucketIndex_;
692      };
693# endif // ifndef JSONCPP_DOC_EXCLUDE_IMPLEMENTATION
694
695      ValueInternalMap();
696      ValueInternalMap( const ValueInternalMap &other );
697      ValueInternalMap &operator =( const ValueInternalMap &other );
698      ~ValueInternalMap();
699
700      void swap( ValueInternalMap &other );
701
702      BucketIndex size() const;
703
704      void clear();
705
706      bool reserveDelta( BucketIndex growth );
707
708      bool reserve( BucketIndex newItemCount );
709
710      const Value *find( const char *key ) const;
711
712      Value *find( const char *key );
713
714      Value &resolveReference( const char *key,
715                               bool isStatic );
716
717      void remove( const char *key );
718
719      void doActualRemove( ValueInternalLink *link,
720                           BucketIndex index,
721                           BucketIndex bucketIndex );
722
723      ValueInternalLink *&getLastLinkInBucket( BucketIndex bucketIndex );
724
725      Value &setNewItem( const char *key,
726                         bool isStatic,
727                         ValueInternalLink *link,
728                         BucketIndex index );
729
730      Value &unsafeAdd( const char *key,
731                        bool isStatic,
732                        HashKey hashedKey );
733
734      HashKey hash( const char *key ) const;
735
736      int compare( const ValueInternalMap &other ) const;
737
738   private:
739      void makeBeginIterator( IteratorState &it ) const;
740      void makeEndIterator( IteratorState &it ) const;
741      static bool equals( const IteratorState &x, const IteratorState &other );
742      static void increment( IteratorState &iterator );
743      static void incrementBucket( IteratorState &iterator );
744      static void decrement( IteratorState &iterator );
745      static const char *key( const IteratorState &iterator );
746      static const char *key( const IteratorState &iterator, bool &isStatic );
747      static Value &value( const IteratorState &iterator );
748      static int distance( const IteratorState &x, const IteratorState &y );
749
750   private:
751      ValueInternalLink *buckets_;
752      ValueInternalLink *tailLink_;
753      BucketIndex bucketsSize_;
754      BucketIndex itemCount_;
755   };
756
757   /** \brief A simplified deque implementation used internally by Value.
758   * \internal
759   * It is based on a list of fixed "page", each page contains a fixed number of items.
760   * Instead of using a linked-list, a array of pointer is used for fast item look-up.
761   * Look-up for an element is as follow:
762   * - compute page index: pageIndex = itemIndex / itemsPerPage
763   * - look-up item in page: pages_[pageIndex][itemIndex % itemsPerPage]
764   *
765   * Insertion is amortized constant time (only the array containing the index of pointers
766   * need to be reallocated when items are appended).
767   */
768   class JSON_API ValueInternalArray
769   {
770      friend class Value;
771      friend class ValueIteratorBase;
772   public:
773      enum { itemsPerPage = 8 };    // should be a power of 2 for fast divide and modulo.
774      typedef Value::ArrayIndex ArrayIndex;
775      typedef unsigned int PageIndex;
776
777# ifndef JSONCPP_DOC_EXCLUDE_IMPLEMENTATION
778      struct IteratorState // Must be a POD
779      {
780         IteratorState()
781            : array_(0)
782            , currentPageIndex_(0)
783            , currentItemIndex_(0)
784         {
785         }
786         ValueInternalArray *array_;
787         Value **currentPageIndex_;
788         unsigned int currentItemIndex_;
789      };
790# endif // ifndef JSONCPP_DOC_EXCLUDE_IMPLEMENTATION
791
792      ValueInternalArray();
793      ValueInternalArray( const ValueInternalArray &other );
794      ValueInternalArray &operator =( const ValueInternalArray &other );
795      ~ValueInternalArray();
796      void swap( ValueInternalArray &other );
797
798      void clear();
799      void resize( ArrayIndex newSize );
800
801      Value &resolveReference( ArrayIndex index );
802
803      Value *find( ArrayIndex index ) const;
804
805      ArrayIndex size() const;
806
807      int compare( const ValueInternalArray &other ) const;
808
809   private:
810      static bool equals( const IteratorState &x, const IteratorState &other );
811      static void increment( IteratorState &iterator );
812      static void decrement( IteratorState &iterator );
813      static Value &dereference( const IteratorState &iterator );
814      static Value &unsafeDereference( const IteratorState &iterator );
815      static int distance( const IteratorState &x, const IteratorState &y );
816      static ArrayIndex indexOf( const IteratorState &iterator );
817      void makeBeginIterator( IteratorState &it ) const;
818      void makeEndIterator( IteratorState &it ) const;
819      void makeIterator( IteratorState &it, ArrayIndex index ) const;
820
821      void makeIndexValid( ArrayIndex index );
822
823      Value **pages_;
824      ArrayIndex size_;
825      PageIndex pageCount_;
826   };
827
828   /** \brief Experimental: do not use. Allocator to customize Value internal array.
829    * Below is an example of a simple implementation (actual implementation use
830    * memory pool).
831      \code
832class DefaultValueArrayAllocator : public ValueArrayAllocator
833{
834public: // overridden from ValueArrayAllocator
835   virtual ~DefaultValueArrayAllocator()
836   {
837   }
838
839   virtual ValueInternalArray *newArray()
840   {
841      return new ValueInternalArray();
842   }
843
844   virtual ValueInternalArray *newArrayCopy( const ValueInternalArray &other )
845   {
846      return new ValueInternalArray( other );
847   }
848
849   virtual void destruct( ValueInternalArray *array )
850   {
851      delete array;
852   }
853
854   virtual void reallocateArrayPageIndex( Value **&indexes,
855                                          ValueInternalArray::PageIndex &indexCount,
856                                          ValueInternalArray::PageIndex minNewIndexCount )
857   {
858      ValueInternalArray::PageIndex newIndexCount = (indexCount*3)/2 + 1;
859      if ( minNewIndexCount > newIndexCount )
860         newIndexCount = minNewIndexCount;
861      void *newIndexes = realloc( indexes, sizeof(Value*) * newIndexCount );
862      if ( !newIndexes )
863         throw std::bad_alloc();
864      indexCount = newIndexCount;
865      indexes = static_cast<Value **>( newIndexes );
866   }
867   virtual void releaseArrayPageIndex( Value **indexes,
868                                       ValueInternalArray::PageIndex indexCount )
869   {
870      if ( indexes )
871         free( indexes );
872   }
873
874   virtual Value *allocateArrayPage()
875   {
876      return static_cast<Value *>( malloc( sizeof(Value) * ValueInternalArray::itemsPerPage ) );
877   }
878
879   virtual void releaseArrayPage( Value *value )
880   {
881      if ( value )
882         free( value );
883   }
884};
885      \endcode
886    */
887   class JSON_API ValueArrayAllocator
888   {
889   public:
890      virtual ~ValueArrayAllocator();
891      virtual ValueInternalArray *newArray() = 0;
892      virtual ValueInternalArray *newArrayCopy( const ValueInternalArray &other ) = 0;
893      virtual void destructArray( ValueInternalArray *array ) = 0;
894      /** \brief Reallocate array page index.
895       * Reallocates an array of pointer on each page.
896       * \param indexes [input] pointer on the current index. May be \c NULL.
897       *                [output] pointer on the new index of at least
898       *                         \a minNewIndexCount pages.
899       * \param indexCount [input] current number of pages in the index.
900       *                   [output] number of page the reallocated index can handle.
901       *                            \b MUST be >= \a minNewIndexCount.
902       * \param minNewIndexCount Minimum number of page the new index must be able to
903       *                         handle.
904       */
905      virtual void reallocateArrayPageIndex( Value **&indexes,
906                                             ValueInternalArray::PageIndex &indexCount,
907                                             ValueInternalArray::PageIndex minNewIndexCount ) = 0;
908      virtual void releaseArrayPageIndex( Value **indexes,
909                                          ValueInternalArray::PageIndex indexCount ) = 0;
910      virtual Value *allocateArrayPage() = 0;
911      virtual void releaseArrayPage( Value *value ) = 0;
912   };
913#endif // #ifdef JSON_VALUE_USE_INTERNAL_MAP
914
915
916   /** \brief base class for Value iterators.
917    *
918    */
919   class ValueIteratorBase
920   {
921   public:
922      typedef unsigned int size_t;
923      typedef int difference_type;
924      typedef ValueIteratorBase SelfType;
925
926      ValueIteratorBase();
927#ifndef JSON_VALUE_USE_INTERNAL_MAP
928      explicit ValueIteratorBase( const Value::ObjectValues::iterator &current );
929#else
930      ValueIteratorBase( const ValueInternalArray::IteratorState &state );
931      ValueIteratorBase( const ValueInternalMap::IteratorState &state );
932#endif
933
934      bool operator ==( const SelfType &other ) const
935      {
936         return isEqual( other );
937      }
938
939      bool operator !=( const SelfType &other ) const
940      {
941         return !isEqual( other );
942      }
943
944      difference_type operator -( const SelfType &other ) const
945      {
946         return computeDistance( other );
947      }
948
949      /// Return either the index or the member name of the referenced value as a Value.
950      Value key() const;
951
952      /// Return the index of the referenced Value. -1 if it is not an arrayValue.
953      UInt index() const;
954
955      /// Return the member name of the referenced Value. "" if it is not an objectValue.
956      const char *memberName() const;
957
958   protected:
959      Value &deref() const;
960
961      void increment();
962
963      void decrement();
964
965      difference_type computeDistance( const SelfType &other ) const;
966
967      bool isEqual( const SelfType &other ) const;
968
969      void copy( const SelfType &other );
970
971   private:
972#ifndef JSON_VALUE_USE_INTERNAL_MAP
973      Value::ObjectValues::iterator current_;
974      // Indicates that iterator is for a null value.
975      bool isNull_;
976#else
977      union
978      {
979         ValueInternalArray::IteratorState array_;
980         ValueInternalMap::IteratorState map_;
981      } iterator_;
982      bool isArray_;
983#endif
984   };
985
986   /** \brief const iterator for object and array value.
987    *
988    */
989   class ValueConstIterator : public ValueIteratorBase
990   {
991      friend class Value;
992   public:
993      typedef unsigned int size_t;
994      typedef int difference_type;
995      typedef const Value &reference;
996      typedef const Value *pointer;
997      typedef ValueConstIterator SelfType;
998
999      ValueConstIterator();
1000   private:
1001      /*! \internal Use by Value to create an iterator.
1002       */
1003#ifndef JSON_VALUE_USE_INTERNAL_MAP
1004      explicit ValueConstIterator( const Value::ObjectValues::iterator &current );
1005#else
1006      ValueConstIterator( const ValueInternalArray::IteratorState &state );
1007      ValueConstIterator( const ValueInternalMap::IteratorState &state );
1008#endif
1009   public:
1010      SelfType &operator =( const ValueIteratorBase &other );
1011
1012      SelfType operator++( int )
1013      {
1014         SelfType temp( *this );
1015         ++*this;
1016         return temp;
1017      }
1018
1019      SelfType operator--( int )
1020      {
1021         SelfType temp( *this );
1022         --*this;
1023         return temp;
1024      }
1025
1026      SelfType &operator--()
1027      {
1028         decrement();
1029         return *this;
1030      }
1031
1032      SelfType &operator++()
1033      {
1034         increment();
1035         return *this;
1036      }
1037
1038      reference operator *() const
1039      {
1040         return deref();
1041      }
1042   };
1043
1044
1045   /** \brief Iterator for object and array value.
1046    */
1047   class ValueIterator : public ValueIteratorBase
1048   {
1049      friend class Value;
1050   public:
1051      typedef unsigned int size_t;
1052      typedef int difference_type;
1053      typedef Value &reference;
1054      typedef Value *pointer;
1055      typedef ValueIterator SelfType;
1056
1057      ValueIterator();
1058      ValueIterator( const ValueConstIterator &other );
1059      ValueIterator( const ValueIterator &other );
1060   private:
1061      /*! \internal Use by Value to create an iterator.
1062       */
1063#ifndef JSON_VALUE_USE_INTERNAL_MAP
1064      explicit ValueIterator( const Value::ObjectValues::iterator &current );
1065#else
1066      ValueIterator( const ValueInternalArray::IteratorState &state );
1067      ValueIterator( const ValueInternalMap::IteratorState &state );
1068#endif
1069   public:
1070
1071      SelfType &operator =( const SelfType &other );
1072
1073      SelfType operator++( int )
1074      {
1075         SelfType temp( *this );
1076         ++*this;
1077         return temp;
1078      }
1079
1080      SelfType operator--( int )
1081      {
1082         SelfType temp( *this );
1083         --*this;
1084         return temp;
1085      }
1086
1087      SelfType &operator--()
1088      {
1089         decrement();
1090         return *this;
1091      }
1092
1093      SelfType &operator++()
1094      {
1095         increment();
1096         return *this;
1097      }
1098
1099      reference operator *() const
1100      {
1101         return deref();
1102      }
1103   };
1104
1105
1106} // namespace Json
1107
1108
1109#endif // CPPTL_JSON_H_INCLUDED
1110