rlottie/rapidjson: updated to latest rapidjson
[platform/core/uifw/lottie-player.git] / src / lottie / rapidjson / pointer.h
1 // Tencent is pleased to support the open source community by making RapidJSON available.
2 // 
3 // Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
4 //
5 // Licensed under the MIT License (the "License"); you may not use this file except
6 // in compliance with the License. You may obtain a copy of the License at
7 //
8 // http://opensource.org/licenses/MIT
9 //
10 // Unless required by applicable law or agreed to in writing, software distributed 
11 // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 
12 // CONDITIONS OF ANY KIND, either express or implied. See the License for the 
13 // specific language governing permissions and limitations under the License.
14
15 #ifndef RAPIDJSON_POINTER_H_
16 #define RAPIDJSON_POINTER_H_
17
18 #include "document.h"
19 #include "internal/itoa.h"
20
21 #ifdef __clang__
22 RAPIDJSON_DIAG_PUSH
23 RAPIDJSON_DIAG_OFF(switch-enum)
24 #elif defined(_MSC_VER)
25 RAPIDJSON_DIAG_PUSH
26 RAPIDJSON_DIAG_OFF(4512) // assignment operator could not be generated
27 #endif
28
29 RAPIDJSON_NAMESPACE_BEGIN
30
31 static const SizeType kPointerInvalidIndex = ~SizeType(0);  //!< Represents an invalid index in GenericPointer::Token
32
33 //! Error code of parsing.
34 /*! \ingroup RAPIDJSON_ERRORS
35     \see GenericPointer::GenericPointer, GenericPointer::GetParseErrorCode
36 */
37 enum PointerParseErrorCode {
38     kPointerParseErrorNone = 0,                     //!< The parse is successful
39
40     kPointerParseErrorTokenMustBeginWithSolidus,    //!< A token must begin with a '/'
41     kPointerParseErrorInvalidEscape,                //!< Invalid escape
42     kPointerParseErrorInvalidPercentEncoding,       //!< Invalid percent encoding in URI fragment
43     kPointerParseErrorCharacterMustPercentEncode    //!< A character must percent encoded in URI fragment
44 };
45
46 ///////////////////////////////////////////////////////////////////////////////
47 // GenericPointer
48
49 //! Represents a JSON Pointer. Use Pointer for UTF8 encoding and default allocator.
50 /*!
51     This class implements RFC 6901 "JavaScript Object Notation (JSON) Pointer" 
52     (https://tools.ietf.org/html/rfc6901).
53
54     A JSON pointer is for identifying a specific value in a JSON document
55     (GenericDocument). It can simplify coding of DOM tree manipulation, because it
56     can access multiple-level depth of DOM tree with single API call.
57
58     After it parses a string representation (e.g. "/foo/0" or URI fragment 
59     representation (e.g. "#/foo/0") into its internal representation (tokens),
60     it can be used to resolve a specific value in multiple documents, or sub-tree 
61     of documents.
62
63     Contrary to GenericValue, Pointer can be copy constructed and copy assigned.
64     Apart from assignment, a Pointer cannot be modified after construction.
65
66     Although Pointer is very convenient, please aware that constructing Pointer
67     involves parsing and dynamic memory allocation. A special constructor with user-
68     supplied tokens eliminates these.
69
70     GenericPointer depends on GenericDocument and GenericValue.
71     
72     \tparam ValueType The value type of the DOM tree. E.g. GenericValue<UTF8<> >
73     \tparam Allocator The allocator type for allocating memory for internal representation.
74     
75     \note GenericPointer uses same encoding of ValueType.
76     However, Allocator of GenericPointer is independent of Allocator of Value.
77 */
78 template <typename ValueType, typename Allocator = CrtAllocator>
79 class GenericPointer {
80 public:
81     typedef typename ValueType::EncodingType EncodingType;  //!< Encoding type from Value
82     typedef typename ValueType::Ch Ch;                      //!< Character type from Value
83
84     //! A token is the basic units of internal representation.
85     /*!
86         A JSON pointer string representation "/foo/123" is parsed to two tokens: 
87         "foo" and 123. 123 will be represented in both numeric form and string form.
88         They are resolved according to the actual value type (object or array).
89
90         For token that are not numbers, or the numeric value is out of bound
91         (greater than limits of SizeType), they are only treated as string form
92         (i.e. the token's index will be equal to kPointerInvalidIndex).
93
94         This struct is public so that user can create a Pointer without parsing and 
95         allocation, using a special constructor.
96     */
97     struct Token {
98         const Ch* name;             //!< Name of the token. It has null character at the end but it can contain null character.
99         SizeType length;            //!< Length of the name.
100         SizeType index;             //!< A valid array index, if it is not equal to kPointerInvalidIndex.
101     };
102
103     //!@name Constructors and destructor.
104     //@{
105
106     //! Default constructor.
107     GenericPointer(Allocator* allocator = 0) : allocator_(allocator), ownAllocator_(), nameBuffer_(), tokens_(), tokenCount_(), parseErrorOffset_(), parseErrorCode_(kPointerParseErrorNone) {}
108
109     //! Constructor that parses a string or URI fragment representation.
110     /*!
111         \param source A null-terminated, string or URI fragment representation of JSON pointer.
112         \param allocator User supplied allocator for this pointer. If no allocator is provided, it creates a self-owned one.
113     */
114     explicit GenericPointer(const Ch* source, Allocator* allocator = 0) : allocator_(allocator), ownAllocator_(), nameBuffer_(), tokens_(), tokenCount_(), parseErrorOffset_(), parseErrorCode_(kPointerParseErrorNone) {
115         Parse(source, internal::StrLen(source));
116     }
117
118 #if RAPIDJSON_HAS_STDSTRING
119     //! Constructor that parses a string or URI fragment representation.
120     /*!
121         \param source A string or URI fragment representation of JSON pointer.
122         \param allocator User supplied allocator for this pointer. If no allocator is provided, it creates a self-owned one.
123         \note Requires the definition of the preprocessor symbol \ref RAPIDJSON_HAS_STDSTRING.
124     */
125     explicit GenericPointer(const std::basic_string<Ch>& source, Allocator* allocator = 0) : allocator_(allocator), ownAllocator_(), nameBuffer_(), tokens_(), tokenCount_(), parseErrorOffset_(), parseErrorCode_(kPointerParseErrorNone) {
126         Parse(source.c_str(), source.size());
127     }
128 #endif
129
130     //! Constructor that parses a string or URI fragment representation, with length of the source string.
131     /*!
132         \param source A string or URI fragment representation of JSON pointer.
133         \param length Length of source.
134         \param allocator User supplied allocator for this pointer. If no allocator is provided, it creates a self-owned one.
135         \note Slightly faster than the overload without length.
136     */
137     GenericPointer(const Ch* source, size_t length, Allocator* allocator = 0) : allocator_(allocator), ownAllocator_(), nameBuffer_(), tokens_(), tokenCount_(), parseErrorOffset_(), parseErrorCode_(kPointerParseErrorNone) {
138         Parse(source, length);
139     }
140
141     //! Constructor with user-supplied tokens.
142     /*!
143         This constructor let user supplies const array of tokens.
144         This prevents the parsing process and eliminates allocation.
145         This is preferred for memory constrained environments.
146
147         \param tokens An constant array of tokens representing the JSON pointer.
148         \param tokenCount Number of tokens.
149
150         \b Example
151         \code
152         #define NAME(s) { s, sizeof(s) / sizeof(s[0]) - 1, kPointerInvalidIndex }
153         #define INDEX(i) { #i, sizeof(#i) - 1, i }
154
155         static const Pointer::Token kTokens[] = { NAME("foo"), INDEX(123) };
156         static const Pointer p(kTokens, sizeof(kTokens) / sizeof(kTokens[0]));
157         // Equivalent to static const Pointer p("/foo/123");
158
159         #undef NAME
160         #undef INDEX
161         \endcode
162     */
163     GenericPointer(const Token* tokens, size_t tokenCount) : allocator_(), ownAllocator_(), nameBuffer_(), tokens_(const_cast<Token*>(tokens)), tokenCount_(tokenCount), parseErrorOffset_(), parseErrorCode_(kPointerParseErrorNone) {}
164
165     //! Copy constructor.
166     GenericPointer(const GenericPointer& rhs) : allocator_(rhs.allocator_), ownAllocator_(), nameBuffer_(), tokens_(), tokenCount_(), parseErrorOffset_(), parseErrorCode_(kPointerParseErrorNone) {
167         *this = rhs;
168     }
169
170     //! Copy constructor.
171     GenericPointer(const GenericPointer& rhs, Allocator* allocator) : allocator_(allocator), ownAllocator_(), nameBuffer_(), tokens_(), tokenCount_(), parseErrorOffset_(), parseErrorCode_(kPointerParseErrorNone) {
172         *this = rhs;
173     }
174
175     //! Destructor.
176     ~GenericPointer() {
177         if (nameBuffer_)    // If user-supplied tokens constructor is used, nameBuffer_ is nullptr and tokens_ are not deallocated.
178             Allocator::Free(tokens_);
179         RAPIDJSON_DELETE(ownAllocator_);
180     }
181
182     //! Assignment operator.
183     GenericPointer& operator=(const GenericPointer& rhs) {
184         if (this != &rhs) {
185             // Do not delete ownAllcator
186             if (nameBuffer_)
187                 Allocator::Free(tokens_);
188
189             tokenCount_ = rhs.tokenCount_;
190             parseErrorOffset_ = rhs.parseErrorOffset_;
191             parseErrorCode_ = rhs.parseErrorCode_;
192
193             if (rhs.nameBuffer_)
194                 CopyFromRaw(rhs); // Normally parsed tokens.
195             else {
196                 tokens_ = rhs.tokens_; // User supplied const tokens.
197                 nameBuffer_ = 0;
198             }
199         }
200         return *this;
201     }
202
203     //! Swap the content of this pointer with an other.
204     /*!
205         \param other The pointer to swap with.
206         \note Constant complexity.
207     */
208     GenericPointer& Swap(GenericPointer& other) RAPIDJSON_NOEXCEPT {
209         internal::Swap(allocator_, other.allocator_);
210         internal::Swap(ownAllocator_, other.ownAllocator_);
211         internal::Swap(nameBuffer_, other.nameBuffer_);
212         internal::Swap(tokens_, other.tokens_);
213         internal::Swap(tokenCount_, other.tokenCount_);
214         internal::Swap(parseErrorOffset_, other.parseErrorOffset_);
215         internal::Swap(parseErrorCode_, other.parseErrorCode_);
216         return *this;
217     }
218
219     //! free-standing swap function helper
220     /*!
221         Helper function to enable support for common swap implementation pattern based on \c std::swap:
222         \code
223         void swap(MyClass& a, MyClass& b) {
224             using std::swap;
225             swap(a.pointer, b.pointer);
226             // ...
227         }
228         \endcode
229         \see Swap()
230      */
231     friend inline void swap(GenericPointer& a, GenericPointer& b) RAPIDJSON_NOEXCEPT { a.Swap(b); }
232
233     //@}
234
235     //!@name Append token
236     //@{
237
238     //! Append a token and return a new Pointer
239     /*!
240         \param token Token to be appended.
241         \param allocator Allocator for the newly return Pointer.
242         \return A new Pointer with appended token.
243     */
244     GenericPointer Append(const Token& token, Allocator* allocator = 0) const {
245         GenericPointer r;
246         r.allocator_ = allocator;
247         Ch *p = r.CopyFromRaw(*this, 1, token.length + 1);
248         std::memcpy(p, token.name, (token.length + 1) * sizeof(Ch));
249         r.tokens_[tokenCount_].name = p;
250         r.tokens_[tokenCount_].length = token.length;
251         r.tokens_[tokenCount_].index = token.index;
252         return r;
253     }
254
255     //! Append a name token with length, and return a new Pointer
256     /*!
257         \param name Name to be appended.
258         \param length Length of name.
259         \param allocator Allocator for the newly return Pointer.
260         \return A new Pointer with appended token.
261     */
262     GenericPointer Append(const Ch* name, SizeType length, Allocator* allocator = 0) const {
263         Token token = { name, length, kPointerInvalidIndex };
264         return Append(token, allocator);
265     }
266
267     //! Append a name token without length, and return a new Pointer
268     /*!
269         \param name Name (const Ch*) to be appended.
270         \param allocator Allocator for the newly return Pointer.
271         \return A new Pointer with appended token.
272     */
273     template <typename T>
274     RAPIDJSON_DISABLEIF_RETURN((internal::NotExpr<internal::IsSame<typename internal::RemoveConst<T>::Type, Ch> >), (GenericPointer))
275     Append(T* name, Allocator* allocator = 0) const {
276         return Append(name, internal::StrLen(name), allocator);
277     }
278
279 #if RAPIDJSON_HAS_STDSTRING
280     //! Append a name token, and return a new Pointer
281     /*!
282         \param name Name to be appended.
283         \param allocator Allocator for the newly return Pointer.
284         \return A new Pointer with appended token.
285     */
286     GenericPointer Append(const std::basic_string<Ch>& name, Allocator* allocator = 0) const {
287         return Append(name.c_str(), static_cast<SizeType>(name.size()), allocator);
288     }
289 #endif
290
291     //! Append a index token, and return a new Pointer
292     /*!
293         \param index Index to be appended.
294         \param allocator Allocator for the newly return Pointer.
295         \return A new Pointer with appended token.
296     */
297     GenericPointer Append(SizeType index, Allocator* allocator = 0) const {
298         char buffer[21];
299         char* end = sizeof(SizeType) == 4 ? internal::u32toa(index, buffer) : internal::u64toa(index, buffer);
300         SizeType length = static_cast<SizeType>(end - buffer);
301         buffer[length] = '\0';
302
303         if (sizeof(Ch) == 1) {
304             Token token = { reinterpret_cast<Ch*>(buffer), length, index };
305             return Append(token, allocator);
306         }
307         else {
308             Ch name[21];
309             for (size_t i = 0; i <= length; i++)
310                 name[i] = static_cast<Ch>(buffer[i]);
311             Token token = { name, length, index };
312             return Append(token, allocator);
313         }
314     }
315
316     //! Append a token by value, and return a new Pointer
317     /*!
318         \param token token to be appended.
319         \param allocator Allocator for the newly return Pointer.
320         \return A new Pointer with appended token.
321     */
322     GenericPointer Append(const ValueType& token, Allocator* allocator = 0) const {
323         if (token.IsString())
324             return Append(token.GetString(), token.GetStringLength(), allocator);
325         else {
326             RAPIDJSON_ASSERT(token.IsUint64());
327             RAPIDJSON_ASSERT(token.GetUint64() <= SizeType(~0));
328             return Append(static_cast<SizeType>(token.GetUint64()), allocator);
329         }
330     }
331
332     //!@name Handling Parse Error
333     //@{
334
335     //! Check whether this is a valid pointer.
336     bool IsValid() const { return parseErrorCode_ == kPointerParseErrorNone; }
337
338     //! Get the parsing error offset in code unit.
339     size_t GetParseErrorOffset() const { return parseErrorOffset_; }
340
341     //! Get the parsing error code.
342     PointerParseErrorCode GetParseErrorCode() const { return parseErrorCode_; }
343
344     //@}
345
346     //! Get the allocator of this pointer.
347     Allocator& GetAllocator() { return *allocator_; }
348
349     //!@name Tokens
350     //@{
351
352     //! Get the token array (const version only).
353     const Token* GetTokens() const { return tokens_; }
354
355     //! Get the number of tokens.
356     size_t GetTokenCount() const { return tokenCount_; }
357
358     //@}
359
360     //!@name Equality/inequality operators
361     //@{
362
363     //! Equality operator.
364     /*!
365         \note When any pointers are invalid, always returns false.
366     */
367     bool operator==(const GenericPointer& rhs) const {
368         if (!IsValid() || !rhs.IsValid() || tokenCount_ != rhs.tokenCount_)
369             return false;
370
371         for (size_t i = 0; i < tokenCount_; i++) {
372             if (tokens_[i].index != rhs.tokens_[i].index ||
373                 tokens_[i].length != rhs.tokens_[i].length || 
374                 (tokens_[i].length != 0 && std::memcmp(tokens_[i].name, rhs.tokens_[i].name, sizeof(Ch)* tokens_[i].length) != 0))
375             {
376                 return false;
377             }
378         }
379
380         return true;
381     }
382
383     //! Inequality operator.
384     /*!
385         \note When any pointers are invalid, always returns true.
386     */
387     bool operator!=(const GenericPointer& rhs) const { return !(*this == rhs); }
388
389     //! Less than operator.
390     /*!
391         \note Invalid pointers are always greater than valid ones.
392     */
393     bool operator<(const GenericPointer& rhs) const {
394         if (!IsValid())
395             return false;
396         if (!rhs.IsValid())
397             return true;
398
399         if (tokenCount_ != rhs.tokenCount_)
400             return tokenCount_ < rhs.tokenCount_;
401
402         for (size_t i = 0; i < tokenCount_; i++) {
403             if (tokens_[i].index != rhs.tokens_[i].index)
404                 return tokens_[i].index < rhs.tokens_[i].index;
405
406             if (tokens_[i].length != rhs.tokens_[i].length)
407                 return tokens_[i].length < rhs.tokens_[i].length;
408
409             if (int cmp = std::memcmp(tokens_[i].name, rhs.tokens_[i].name, sizeof(Ch) * tokens_[i].length))
410                 return cmp < 0;
411         }
412
413         return false;
414     }
415
416     //@}
417
418     //!@name Stringify
419     //@{
420
421     //! Stringify the pointer into string representation.
422     /*!
423         \tparam OutputStream Type of output stream.
424         \param os The output stream.
425     */
426     template<typename OutputStream>
427     bool Stringify(OutputStream& os) const {
428         return Stringify<false, OutputStream>(os);
429     }
430
431     //! Stringify the pointer into URI fragment representation.
432     /*!
433         \tparam OutputStream Type of output stream.
434         \param os The output stream.
435     */
436     template<typename OutputStream>
437     bool StringifyUriFragment(OutputStream& os) const {
438         return Stringify<true, OutputStream>(os);
439     }
440
441     //@}
442
443     //!@name Create value
444     //@{
445
446     //! Create a value in a subtree.
447     /*!
448         If the value is not exist, it creates all parent values and a JSON Null value.
449         So it always succeed and return the newly created or existing value.
450
451         Remind that it may change types of parents according to tokens, so it 
452         potentially removes previously stored values. For example, if a document 
453         was an array, and "/foo" is used to create a value, then the document 
454         will be changed to an object, and all existing array elements are lost.
455
456         \param root Root value of a DOM subtree to be resolved. It can be any value other than document root.
457         \param allocator Allocator for creating the values if the specified value or its parents are not exist.
458         \param alreadyExist If non-null, it stores whether the resolved value is already exist.
459         \return The resolved newly created (a JSON Null value), or already exists value.
460     */
461     ValueType& Create(ValueType& root, typename ValueType::AllocatorType& allocator, bool* alreadyExist = 0) const {
462         RAPIDJSON_ASSERT(IsValid());
463         ValueType* v = &root;
464         bool exist = true;
465         for (const Token *t = tokens_; t != tokens_ + tokenCount_; ++t) {
466             if (v->IsArray() && t->name[0] == '-' && t->length == 1) {
467                 v->PushBack(ValueType().Move(), allocator);
468                 v = &((*v)[v->Size() - 1]);
469                 exist = false;
470             }
471             else {
472                 if (t->index == kPointerInvalidIndex) { // must be object name
473                     if (!v->IsObject())
474                         v->SetObject(); // Change to Object
475                 }
476                 else { // object name or array index
477                     if (!v->IsArray() && !v->IsObject())
478                         v->SetArray(); // Change to Array
479                 }
480
481                 if (v->IsArray()) {
482                     if (t->index >= v->Size()) {
483                         v->Reserve(t->index + 1, allocator);
484                         while (t->index >= v->Size())
485                             v->PushBack(ValueType().Move(), allocator);
486                         exist = false;
487                     }
488                     v = &((*v)[t->index]);
489                 }
490                 else {
491                     typename ValueType::MemberIterator m = v->FindMember(GenericValue<EncodingType>(GenericStringRef<Ch>(t->name, t->length)));
492                     if (m == v->MemberEnd()) {
493                         v->AddMember(ValueType(t->name, t->length, allocator).Move(), ValueType().Move(), allocator);
494                         m = v->MemberEnd();
495                         v = &(--m)->value; // Assumes AddMember() appends at the end
496                         exist = false;
497                     }
498                     else
499                         v = &m->value;
500                 }
501             }
502         }
503
504         if (alreadyExist)
505             *alreadyExist = exist;
506
507         return *v;
508     }
509
510     //! Creates a value in a document.
511     /*!
512         \param document A document to be resolved.
513         \param alreadyExist If non-null, it stores whether the resolved value is already exist.
514         \return The resolved newly created, or already exists value.
515     */
516     template <typename stackAllocator>
517     ValueType& Create(GenericDocument<EncodingType, typename ValueType::AllocatorType, stackAllocator>& document, bool* alreadyExist = 0) const {
518         return Create(document, document.GetAllocator(), alreadyExist);
519     }
520
521     //@}
522
523     //!@name Query value
524     //@{
525
526     //! Query a value in a subtree.
527     /*!
528         \param root Root value of a DOM sub-tree to be resolved. It can be any value other than document root.
529         \param unresolvedTokenIndex If the pointer cannot resolve a token in the pointer, this parameter can obtain the index of unresolved token.
530         \return Pointer to the value if it can be resolved. Otherwise null.
531
532         \note
533         There are only 3 situations when a value cannot be resolved:
534         1. A value in the path is not an array nor object.
535         2. An object value does not contain the token.
536         3. A token is out of range of an array value.
537
538         Use unresolvedTokenIndex to retrieve the token index.
539     */
540     ValueType* Get(ValueType& root, size_t* unresolvedTokenIndex = 0) const {
541         RAPIDJSON_ASSERT(IsValid());
542         ValueType* v = &root;
543         for (const Token *t = tokens_; t != tokens_ + tokenCount_; ++t) {
544             switch (v->GetType()) {
545             case kObjectType:
546                 {
547                     typename ValueType::MemberIterator m = v->FindMember(GenericValue<EncodingType>(GenericStringRef<Ch>(t->name, t->length)));
548                     if (m == v->MemberEnd())
549                         break;
550                     v = &m->value;
551                 }
552                 continue;
553             case kArrayType:
554                 if (t->index == kPointerInvalidIndex || t->index >= v->Size())
555                     break;
556                 v = &((*v)[t->index]);
557                 continue;
558             default:
559                 break;
560             }
561
562             // Error: unresolved token
563             if (unresolvedTokenIndex)
564                 *unresolvedTokenIndex = static_cast<size_t>(t - tokens_);
565             return 0;
566         }
567         return v;
568     }
569
570     //! Query a const value in a const subtree.
571     /*!
572         \param root Root value of a DOM sub-tree to be resolved. It can be any value other than document root.
573         \return Pointer to the value if it can be resolved. Otherwise null.
574     */
575     const ValueType* Get(const ValueType& root, size_t* unresolvedTokenIndex = 0) const { 
576         return Get(const_cast<ValueType&>(root), unresolvedTokenIndex);
577     }
578
579     //@}
580
581     //!@name Query a value with default
582     //@{
583
584     //! Query a value in a subtree with default value.
585     /*!
586         Similar to Get(), but if the specified value do not exists, it creates all parents and clone the default value.
587         So that this function always succeed.
588
589         \param root Root value of a DOM sub-tree to be resolved. It can be any value other than document root.
590         \param defaultValue Default value to be cloned if the value was not exists.
591         \param allocator Allocator for creating the values if the specified value or its parents are not exist.
592         \see Create()
593     */
594     ValueType& GetWithDefault(ValueType& root, const ValueType& defaultValue, typename ValueType::AllocatorType& allocator) const {
595         bool alreadyExist;
596         ValueType& v = Create(root, allocator, &alreadyExist);
597         return alreadyExist ? v : v.CopyFrom(defaultValue, allocator);
598     }
599
600     //! Query a value in a subtree with default null-terminated string.
601     ValueType& GetWithDefault(ValueType& root, const Ch* defaultValue, typename ValueType::AllocatorType& allocator) const {
602         bool alreadyExist;
603         ValueType& v = Create(root, allocator, &alreadyExist);
604         return alreadyExist ? v : v.SetString(defaultValue, allocator);
605     }
606
607 #if RAPIDJSON_HAS_STDSTRING
608     //! Query a value in a subtree with default std::basic_string.
609     ValueType& GetWithDefault(ValueType& root, const std::basic_string<Ch>& defaultValue, typename ValueType::AllocatorType& allocator) const {
610         bool alreadyExist;
611         ValueType& v = Create(root, allocator, &alreadyExist);
612         return alreadyExist ? v : v.SetString(defaultValue, allocator);
613     }
614 #endif
615
616     //! Query a value in a subtree with default primitive value.
617     /*!
618         \tparam T Either \ref Type, \c int, \c unsigned, \c int64_t, \c uint64_t, \c bool
619     */
620     template <typename T>
621     RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>, internal::IsGenericValue<T> >), (ValueType&))
622     GetWithDefault(ValueType& root, T defaultValue, typename ValueType::AllocatorType& allocator) const {
623         return GetWithDefault(root, ValueType(defaultValue).Move(), allocator);
624     }
625
626     //! Query a value in a document with default value.
627     template <typename stackAllocator>
628     ValueType& GetWithDefault(GenericDocument<EncodingType, typename ValueType::AllocatorType, stackAllocator>& document, const ValueType& defaultValue) const {
629         return GetWithDefault(document, defaultValue, document.GetAllocator());
630     }
631
632     //! Query a value in a document with default null-terminated string.
633     template <typename stackAllocator>
634     ValueType& GetWithDefault(GenericDocument<EncodingType, typename ValueType::AllocatorType, stackAllocator>& document, const Ch* defaultValue) const {
635         return GetWithDefault(document, defaultValue, document.GetAllocator());
636     }
637     
638 #if RAPIDJSON_HAS_STDSTRING
639     //! Query a value in a document with default std::basic_string.
640     template <typename stackAllocator>
641     ValueType& GetWithDefault(GenericDocument<EncodingType, typename ValueType::AllocatorType, stackAllocator>& document, const std::basic_string<Ch>& defaultValue) const {
642         return GetWithDefault(document, defaultValue, document.GetAllocator());
643     }
644 #endif
645
646     //! Query a value in a document with default primitive value.
647     /*!
648         \tparam T Either \ref Type, \c int, \c unsigned, \c int64_t, \c uint64_t, \c bool
649     */
650     template <typename T, typename stackAllocator>
651     RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>, internal::IsGenericValue<T> >), (ValueType&))
652     GetWithDefault(GenericDocument<EncodingType, typename ValueType::AllocatorType, stackAllocator>& document, T defaultValue) const {
653         return GetWithDefault(document, defaultValue, document.GetAllocator());
654     }
655
656     //@}
657
658     //!@name Set a value
659     //@{
660
661     //! Set a value in a subtree, with move semantics.
662     /*!
663         It creates all parents if they are not exist or types are different to the tokens.
664         So this function always succeeds but potentially remove existing values.
665
666         \param root Root value of a DOM sub-tree to be resolved. It can be any value other than document root.
667         \param value Value to be set.
668         \param allocator Allocator for creating the values if the specified value or its parents are not exist.
669         \see Create()
670     */
671     ValueType& Set(ValueType& root, ValueType& value, typename ValueType::AllocatorType& allocator) const {
672         return Create(root, allocator) = value;
673     }
674
675     //! Set a value in a subtree, with copy semantics.
676     ValueType& Set(ValueType& root, const ValueType& value, typename ValueType::AllocatorType& allocator) const {
677         return Create(root, allocator).CopyFrom(value, allocator);
678     }
679
680     //! Set a null-terminated string in a subtree.
681     ValueType& Set(ValueType& root, const Ch* value, typename ValueType::AllocatorType& allocator) const {
682         return Create(root, allocator) = ValueType(value, allocator).Move();
683     }
684
685 #if RAPIDJSON_HAS_STDSTRING
686     //! Set a std::basic_string in a subtree.
687     ValueType& Set(ValueType& root, const std::basic_string<Ch>& value, typename ValueType::AllocatorType& allocator) const {
688         return Create(root, allocator) = ValueType(value, allocator).Move();
689     }
690 #endif
691
692     //! Set a primitive value in a subtree.
693     /*!
694         \tparam T Either \ref Type, \c int, \c unsigned, \c int64_t, \c uint64_t, \c bool
695     */
696     template <typename T>
697     RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>, internal::IsGenericValue<T> >), (ValueType&))
698     Set(ValueType& root, T value, typename ValueType::AllocatorType& allocator) const {
699         return Create(root, allocator) = ValueType(value).Move();
700     }
701
702     //! Set a value in a document, with move semantics.
703     template <typename stackAllocator>
704     ValueType& Set(GenericDocument<EncodingType, typename ValueType::AllocatorType, stackAllocator>& document, ValueType& value) const {
705         return Create(document) = value;
706     }
707
708     //! Set a value in a document, with copy semantics.
709     template <typename stackAllocator>
710     ValueType& Set(GenericDocument<EncodingType, typename ValueType::AllocatorType, stackAllocator>& document, const ValueType& value) const {
711         return Create(document).CopyFrom(value, document.GetAllocator());
712     }
713
714     //! Set a null-terminated string in a document.
715     template <typename stackAllocator>
716     ValueType& Set(GenericDocument<EncodingType, typename ValueType::AllocatorType, stackAllocator>& document, const Ch* value) const {
717         return Create(document) = ValueType(value, document.GetAllocator()).Move();
718     }
719
720 #if RAPIDJSON_HAS_STDSTRING
721     //! Sets a std::basic_string in a document.
722     template <typename stackAllocator>
723     ValueType& Set(GenericDocument<EncodingType, typename ValueType::AllocatorType, stackAllocator>& document, const std::basic_string<Ch>& value) const {
724         return Create(document) = ValueType(value, document.GetAllocator()).Move();
725     }
726 #endif
727
728     //! Set a primitive value in a document.
729     /*!
730     \tparam T Either \ref Type, \c int, \c unsigned, \c int64_t, \c uint64_t, \c bool
731     */
732     template <typename T, typename stackAllocator>
733     RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>, internal::IsGenericValue<T> >), (ValueType&))
734         Set(GenericDocument<EncodingType, typename ValueType::AllocatorType, stackAllocator>& document, T value) const {
735             return Create(document) = value;
736     }
737
738     //@}
739
740     //!@name Swap a value
741     //@{
742
743     //! Swap a value with a value in a subtree.
744     /*!
745         It creates all parents if they are not exist or types are different to the tokens.
746         So this function always succeeds but potentially remove existing values.
747
748         \param root Root value of a DOM sub-tree to be resolved. It can be any value other than document root.
749         \param value Value to be swapped.
750         \param allocator Allocator for creating the values if the specified value or its parents are not exist.
751         \see Create()
752     */
753     ValueType& Swap(ValueType& root, ValueType& value, typename ValueType::AllocatorType& allocator) const {
754         return Create(root, allocator).Swap(value);
755     }
756
757     //! Swap a value with a value in a document.
758     template <typename stackAllocator>
759     ValueType& Swap(GenericDocument<EncodingType, typename ValueType::AllocatorType, stackAllocator>& document, ValueType& value) const {
760         return Create(document).Swap(value);
761     }
762
763     //@}
764
765     //! Erase a value in a subtree.
766     /*!
767         \param root Root value of a DOM sub-tree to be resolved. It can be any value other than document root.
768         \return Whether the resolved value is found and erased.
769
770         \note Erasing with an empty pointer \c Pointer(""), i.e. the root, always fail and return false.
771     */
772     bool Erase(ValueType& root) const {
773         RAPIDJSON_ASSERT(IsValid());
774         if (tokenCount_ == 0) // Cannot erase the root
775             return false;
776
777         ValueType* v = &root;
778         const Token* last = tokens_ + (tokenCount_ - 1);
779         for (const Token *t = tokens_; t != last; ++t) {
780             switch (v->GetType()) {
781             case kObjectType:
782                 {
783                     typename ValueType::MemberIterator m = v->FindMember(GenericValue<EncodingType>(GenericStringRef<Ch>(t->name, t->length)));
784                     if (m == v->MemberEnd())
785                         return false;
786                     v = &m->value;
787                 }
788                 break;
789             case kArrayType:
790                 if (t->index == kPointerInvalidIndex || t->index >= v->Size())
791                     return false;
792                 v = &((*v)[t->index]);
793                 break;
794             default:
795                 return false;
796             }
797         }
798
799         switch (v->GetType()) {
800         case kObjectType:
801             return v->EraseMember(GenericStringRef<Ch>(last->name, last->length));
802         case kArrayType:
803             if (last->index == kPointerInvalidIndex || last->index >= v->Size())
804                 return false;
805             v->Erase(v->Begin() + last->index);
806             return true;
807         default:
808             return false;
809         }
810     }
811
812 private:
813     //! Clone the content from rhs to this.
814     /*!
815         \param rhs Source pointer.
816         \param extraToken Extra tokens to be allocated.
817         \param extraNameBufferSize Extra name buffer size (in number of Ch) to be allocated.
818         \return Start of non-occupied name buffer, for storing extra names.
819     */
820     Ch* CopyFromRaw(const GenericPointer& rhs, size_t extraToken = 0, size_t extraNameBufferSize = 0) {
821         if (!allocator_) // allocator is independently owned.
822             ownAllocator_ = allocator_ = RAPIDJSON_NEW(Allocator)();
823
824         size_t nameBufferSize = rhs.tokenCount_; // null terminators for tokens
825         for (Token *t = rhs.tokens_; t != rhs.tokens_ + rhs.tokenCount_; ++t)
826             nameBufferSize += t->length;
827
828         tokenCount_ = rhs.tokenCount_ + extraToken;
829         tokens_ = static_cast<Token *>(allocator_->Malloc(tokenCount_ * sizeof(Token) + (nameBufferSize + extraNameBufferSize) * sizeof(Ch)));
830         nameBuffer_ = reinterpret_cast<Ch *>(tokens_ + tokenCount_);
831         if (rhs.tokenCount_ > 0) {
832             std::memcpy(tokens_, rhs.tokens_, rhs.tokenCount_ * sizeof(Token));
833         }
834         if (nameBufferSize > 0) {
835             std::memcpy(nameBuffer_, rhs.nameBuffer_, nameBufferSize * sizeof(Ch));
836         }
837
838         // Adjust pointers to name buffer
839         std::ptrdiff_t diff = nameBuffer_ - rhs.nameBuffer_;
840         for (Token *t = tokens_; t != tokens_ + rhs.tokenCount_; ++t)
841             t->name += diff;
842
843         return nameBuffer_ + nameBufferSize;
844     }
845
846     //! Check whether a character should be percent-encoded.
847     /*!
848         According to RFC 3986 2.3 Unreserved Characters.
849         \param c The character (code unit) to be tested.
850     */
851     bool NeedPercentEncode(Ch c) const {
852         return !((c >= '0' && c <= '9') || (c >= 'A' && c <='Z') || (c >= 'a' && c <= 'z') || c == '-' || c == '.' || c == '_' || c =='~');
853     }
854
855     //! Parse a JSON String or its URI fragment representation into tokens.
856 #ifndef __clang__ // -Wdocumentation
857     /*!
858         \param source Either a JSON Pointer string, or its URI fragment representation. Not need to be null terminated.
859         \param length Length of the source string.
860         \note Source cannot be JSON String Representation of JSON Pointer, e.g. In "/\u0000", \u0000 will not be unescaped.
861     */
862 #endif
863     void Parse(const Ch* source, size_t length) {
864         RAPIDJSON_ASSERT(source != NULL);
865         RAPIDJSON_ASSERT(nameBuffer_ == 0);
866         RAPIDJSON_ASSERT(tokens_ == 0);
867
868         // Create own allocator if user did not supply.
869         if (!allocator_)
870             ownAllocator_ = allocator_ = RAPIDJSON_NEW(Allocator)();
871
872         // Count number of '/' as tokenCount
873         tokenCount_ = 0;
874         for (const Ch* s = source; s != source + length; s++) 
875             if (*s == '/')
876                 tokenCount_++;
877
878         Token* token = tokens_ = static_cast<Token *>(allocator_->Malloc(tokenCount_ * sizeof(Token) + length * sizeof(Ch)));
879         Ch* name = nameBuffer_ = reinterpret_cast<Ch *>(tokens_ + tokenCount_);
880         size_t i = 0;
881
882         // Detect if it is a URI fragment
883         bool uriFragment = false;
884         if (source[i] == '#') {
885             uriFragment = true;
886             i++;
887         }
888
889         if (i != length && source[i] != '/') {
890             parseErrorCode_ = kPointerParseErrorTokenMustBeginWithSolidus;
891             goto error;
892         }
893
894         while (i < length) {
895             RAPIDJSON_ASSERT(source[i] == '/');
896             i++; // consumes '/'
897
898             token->name = name;
899             bool isNumber = true;
900
901             while (i < length && source[i] != '/') {
902                 Ch c = source[i];
903                 if (uriFragment) {
904                     // Decoding percent-encoding for URI fragment
905                     if (c == '%') {
906                         PercentDecodeStream is(&source[i], source + length);
907                         GenericInsituStringStream<EncodingType> os(name);
908                         Ch* begin = os.PutBegin();
909                         if (!Transcoder<UTF8<>, EncodingType>().Validate(is, os) || !is.IsValid()) {
910                             parseErrorCode_ = kPointerParseErrorInvalidPercentEncoding;
911                             goto error;
912                         }
913                         size_t len = os.PutEnd(begin);
914                         i += is.Tell() - 1;
915                         if (len == 1)
916                             c = *name;
917                         else {
918                             name += len;
919                             isNumber = false;
920                             i++;
921                             continue;
922                         }
923                     }
924                     else if (NeedPercentEncode(c)) {
925                         parseErrorCode_ = kPointerParseErrorCharacterMustPercentEncode;
926                         goto error;
927                     }
928                 }
929
930                 i++;
931                 
932                 // Escaping "~0" -> '~', "~1" -> '/'
933                 if (c == '~') {
934                     if (i < length) {
935                         c = source[i];
936                         if (c == '0')       c = '~';
937                         else if (c == '1')  c = '/';
938                         else {
939                             parseErrorCode_ = kPointerParseErrorInvalidEscape;
940                             goto error;
941                         }
942                         i++;
943                     }
944                     else {
945                         parseErrorCode_ = kPointerParseErrorInvalidEscape;
946                         goto error;
947                     }
948                 }
949
950                 // First check for index: all of characters are digit
951                 if (c < '0' || c > '9')
952                     isNumber = false;
953
954                 *name++ = c;
955             }
956             token->length = static_cast<SizeType>(name - token->name);
957             if (token->length == 0)
958                 isNumber = false;
959             *name++ = '\0'; // Null terminator
960
961             // Second check for index: more than one digit cannot have leading zero
962             if (isNumber && token->length > 1 && token->name[0] == '0')
963                 isNumber = false;
964
965             // String to SizeType conversion
966             SizeType n = 0;
967             if (isNumber) {
968                 for (size_t j = 0; j < token->length; j++) {
969                     SizeType m = n * 10 + static_cast<SizeType>(token->name[j] - '0');
970                     if (m < n) {   // overflow detection
971                         isNumber = false;
972                         break;
973                     }
974                     n = m;
975                 }
976             }
977
978             token->index = isNumber ? n : kPointerInvalidIndex;
979             token++;
980         }
981
982         RAPIDJSON_ASSERT(name <= nameBuffer_ + length); // Should not overflow buffer
983         parseErrorCode_ = kPointerParseErrorNone;
984         return;
985
986     error:
987         Allocator::Free(tokens_);
988         nameBuffer_ = 0;
989         tokens_ = 0;
990         tokenCount_ = 0;
991         parseErrorOffset_ = i;
992         return;
993     }
994
995     //! Stringify to string or URI fragment representation.
996     /*!
997         \tparam uriFragment True for stringifying to URI fragment representation. False for string representation.
998         \tparam OutputStream type of output stream.
999         \param os The output stream.
1000     */
1001     template<bool uriFragment, typename OutputStream>
1002     bool Stringify(OutputStream& os) const {
1003         RAPIDJSON_ASSERT(IsValid());
1004
1005         if (uriFragment)
1006             os.Put('#');
1007
1008         for (Token *t = tokens_; t != tokens_ + tokenCount_; ++t) {
1009             os.Put('/');
1010             for (size_t j = 0; j < t->length; j++) {
1011                 Ch c = t->name[j];
1012                 if (c == '~') {
1013                     os.Put('~');
1014                     os.Put('0');
1015                 }
1016                 else if (c == '/') {
1017                     os.Put('~');
1018                     os.Put('1');
1019                 }
1020                 else if (uriFragment && NeedPercentEncode(c)) { 
1021                     // Transcode to UTF8 sequence
1022                     GenericStringStream<typename ValueType::EncodingType> source(&t->name[j]);
1023                     PercentEncodeStream<OutputStream> target(os);
1024                     if (!Transcoder<EncodingType, UTF8<> >().Validate(source, target))
1025                         return false;
1026                     j += source.Tell() - 1;
1027                 }
1028                 else
1029                     os.Put(c);
1030             }
1031         }
1032         return true;
1033     }
1034
1035     //! A helper stream for decoding a percent-encoded sequence into code unit.
1036     /*!
1037         This stream decodes %XY triplet into code unit (0-255).
1038         If it encounters invalid characters, it sets output code unit as 0 and 
1039         mark invalid, and to be checked by IsValid().
1040     */
1041     class PercentDecodeStream {
1042     public:
1043         typedef typename ValueType::Ch Ch;
1044
1045         //! Constructor
1046         /*!
1047             \param source Start of the stream
1048             \param end Past-the-end of the stream.
1049         */
1050         PercentDecodeStream(const Ch* source, const Ch* end) : src_(source), head_(source), end_(end), valid_(true) {}
1051
1052         Ch Take() {
1053             if (*src_ != '%' || src_ + 3 > end_) { // %XY triplet
1054                 valid_ = false;
1055                 return 0;
1056             }
1057             src_++;
1058             Ch c = 0;
1059             for (int j = 0; j < 2; j++) {
1060                 c = static_cast<Ch>(c << 4);
1061                 Ch h = *src_;
1062                 if      (h >= '0' && h <= '9') c = static_cast<Ch>(c + h - '0');
1063                 else if (h >= 'A' && h <= 'F') c = static_cast<Ch>(c + h - 'A' + 10);
1064                 else if (h >= 'a' && h <= 'f') c = static_cast<Ch>(c + h - 'a' + 10);
1065                 else {
1066                     valid_ = false;
1067                     return 0;
1068                 }
1069                 src_++;
1070             }
1071             return c;
1072         }
1073
1074         size_t Tell() const { return static_cast<size_t>(src_ - head_); }
1075         bool IsValid() const { return valid_; }
1076
1077     private:
1078         const Ch* src_;     //!< Current read position.
1079         const Ch* head_;    //!< Original head of the string.
1080         const Ch* end_;     //!< Past-the-end position.
1081         bool valid_;        //!< Whether the parsing is valid.
1082     };
1083
1084     //! A helper stream to encode character (UTF-8 code unit) into percent-encoded sequence.
1085     template <typename OutputStream>
1086     class PercentEncodeStream {
1087     public:
1088         PercentEncodeStream(OutputStream& os) : os_(os) {}
1089         void Put(char c) { // UTF-8 must be byte
1090             unsigned char u = static_cast<unsigned char>(c);
1091             static const char hexDigits[16] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
1092             os_.Put('%');
1093             os_.Put(static_cast<typename OutputStream::Ch>(hexDigits[u >> 4]));
1094             os_.Put(static_cast<typename OutputStream::Ch>(hexDigits[u & 15]));
1095         }
1096     private:
1097         OutputStream& os_;
1098     };
1099
1100     Allocator* allocator_;                  //!< The current allocator. It is either user-supplied or equal to ownAllocator_.
1101     Allocator* ownAllocator_;               //!< Allocator owned by this Pointer.
1102     Ch* nameBuffer_;                        //!< A buffer containing all names in tokens.
1103     Token* tokens_;                         //!< A list of tokens.
1104     size_t tokenCount_;                     //!< Number of tokens in tokens_.
1105     size_t parseErrorOffset_;               //!< Offset in code unit when parsing fail.
1106     PointerParseErrorCode parseErrorCode_;  //!< Parsing error code.
1107 };
1108
1109 //! GenericPointer for Value (UTF-8, default allocator).
1110 typedef GenericPointer<Value> Pointer;
1111
1112 //!@name Helper functions for GenericPointer
1113 //@{
1114
1115 //////////////////////////////////////////////////////////////////////////////
1116
1117 template <typename T>
1118 typename T::ValueType& CreateValueByPointer(T& root, const GenericPointer<typename T::ValueType>& pointer, typename T::AllocatorType& a) {
1119     return pointer.Create(root, a);
1120 }
1121
1122 template <typename T, typename CharType, size_t N>
1123 typename T::ValueType& CreateValueByPointer(T& root, const CharType(&source)[N], typename T::AllocatorType& a) {
1124     return GenericPointer<typename T::ValueType>(source, N - 1).Create(root, a);
1125 }
1126
1127 // No allocator parameter
1128
1129 template <typename DocumentType>
1130 typename DocumentType::ValueType& CreateValueByPointer(DocumentType& document, const GenericPointer<typename DocumentType::ValueType>& pointer) {
1131     return pointer.Create(document);
1132 }
1133
1134 template <typename DocumentType, typename CharType, size_t N>
1135 typename DocumentType::ValueType& CreateValueByPointer(DocumentType& document, const CharType(&source)[N]) {
1136     return GenericPointer<typename DocumentType::ValueType>(source, N - 1).Create(document);
1137 }
1138
1139 //////////////////////////////////////////////////////////////////////////////
1140
1141 template <typename T>
1142 typename T::ValueType* GetValueByPointer(T& root, const GenericPointer<typename T::ValueType>& pointer, size_t* unresolvedTokenIndex = 0) {
1143     return pointer.Get(root, unresolvedTokenIndex);
1144 }
1145
1146 template <typename T>
1147 const typename T::ValueType* GetValueByPointer(const T& root, const GenericPointer<typename T::ValueType>& pointer, size_t* unresolvedTokenIndex = 0) {
1148     return pointer.Get(root, unresolvedTokenIndex);
1149 }
1150
1151 template <typename T, typename CharType, size_t N>
1152 typename T::ValueType* GetValueByPointer(T& root, const CharType (&source)[N], size_t* unresolvedTokenIndex = 0) {
1153     return GenericPointer<typename T::ValueType>(source, N - 1).Get(root, unresolvedTokenIndex);
1154 }
1155
1156 template <typename T, typename CharType, size_t N>
1157 const typename T::ValueType* GetValueByPointer(const T& root, const CharType(&source)[N], size_t* unresolvedTokenIndex = 0) {
1158     return GenericPointer<typename T::ValueType>(source, N - 1).Get(root, unresolvedTokenIndex);
1159 }
1160
1161 //////////////////////////////////////////////////////////////////////////////
1162
1163 template <typename T>
1164 typename T::ValueType& GetValueByPointerWithDefault(T& root, const GenericPointer<typename T::ValueType>& pointer, const typename T::ValueType& defaultValue, typename T::AllocatorType& a) {
1165     return pointer.GetWithDefault(root, defaultValue, a);
1166 }
1167
1168 template <typename T>
1169 typename T::ValueType& GetValueByPointerWithDefault(T& root, const GenericPointer<typename T::ValueType>& pointer, const typename T::Ch* defaultValue, typename T::AllocatorType& a) {
1170     return pointer.GetWithDefault(root, defaultValue, a);
1171 }
1172
1173 #if RAPIDJSON_HAS_STDSTRING
1174 template <typename T>
1175 typename T::ValueType& GetValueByPointerWithDefault(T& root, const GenericPointer<typename T::ValueType>& pointer, const std::basic_string<typename T::Ch>& defaultValue, typename T::AllocatorType& a) {
1176     return pointer.GetWithDefault(root, defaultValue, a);
1177 }
1178 #endif
1179
1180 template <typename T, typename T2>
1181 RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T2>, internal::IsGenericValue<T2> >), (typename T::ValueType&))
1182 GetValueByPointerWithDefault(T& root, const GenericPointer<typename T::ValueType>& pointer, T2 defaultValue, typename T::AllocatorType& a) {
1183     return pointer.GetWithDefault(root, defaultValue, a);
1184 }
1185
1186 template <typename T, typename CharType, size_t N>
1187 typename T::ValueType& GetValueByPointerWithDefault(T& root, const CharType(&source)[N], const typename T::ValueType& defaultValue, typename T::AllocatorType& a) {
1188     return GenericPointer<typename T::ValueType>(source, N - 1).GetWithDefault(root, defaultValue, a);
1189 }
1190
1191 template <typename T, typename CharType, size_t N>
1192 typename T::ValueType& GetValueByPointerWithDefault(T& root, const CharType(&source)[N], const typename T::Ch* defaultValue, typename T::AllocatorType& a) {
1193     return GenericPointer<typename T::ValueType>(source, N - 1).GetWithDefault(root, defaultValue, a);
1194 }
1195
1196 #if RAPIDJSON_HAS_STDSTRING
1197 template <typename T, typename CharType, size_t N>
1198 typename T::ValueType& GetValueByPointerWithDefault(T& root, const CharType(&source)[N], const std::basic_string<typename T::Ch>& defaultValue, typename T::AllocatorType& a) {
1199     return GenericPointer<typename T::ValueType>(source, N - 1).GetWithDefault(root, defaultValue, a);
1200 }
1201 #endif
1202
1203 template <typename T, typename CharType, size_t N, typename T2>
1204 RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T2>, internal::IsGenericValue<T2> >), (typename T::ValueType&))
1205 GetValueByPointerWithDefault(T& root, const CharType(&source)[N], T2 defaultValue, typename T::AllocatorType& a) {
1206     return GenericPointer<typename T::ValueType>(source, N - 1).GetWithDefault(root, defaultValue, a);
1207 }
1208
1209 // No allocator parameter
1210
1211 template <typename DocumentType>
1212 typename DocumentType::ValueType& GetValueByPointerWithDefault(DocumentType& document, const GenericPointer<typename DocumentType::ValueType>& pointer, const typename DocumentType::ValueType& defaultValue) {
1213     return pointer.GetWithDefault(document, defaultValue);
1214 }
1215
1216 template <typename DocumentType>
1217 typename DocumentType::ValueType& GetValueByPointerWithDefault(DocumentType& document, const GenericPointer<typename DocumentType::ValueType>& pointer, const typename DocumentType::Ch* defaultValue) {
1218     return pointer.GetWithDefault(document, defaultValue);
1219 }
1220
1221 #if RAPIDJSON_HAS_STDSTRING
1222 template <typename DocumentType>
1223 typename DocumentType::ValueType& GetValueByPointerWithDefault(DocumentType& document, const GenericPointer<typename DocumentType::ValueType>& pointer, const std::basic_string<typename DocumentType::Ch>& defaultValue) {
1224     return pointer.GetWithDefault(document, defaultValue);
1225 }
1226 #endif
1227
1228 template <typename DocumentType, typename T2>
1229 RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T2>, internal::IsGenericValue<T2> >), (typename DocumentType::ValueType&))
1230 GetValueByPointerWithDefault(DocumentType& document, const GenericPointer<typename DocumentType::ValueType>& pointer, T2 defaultValue) {
1231     return pointer.GetWithDefault(document, defaultValue);
1232 }
1233
1234 template <typename DocumentType, typename CharType, size_t N>
1235 typename DocumentType::ValueType& GetValueByPointerWithDefault(DocumentType& document, const CharType(&source)[N], const typename DocumentType::ValueType& defaultValue) {
1236     return GenericPointer<typename DocumentType::ValueType>(source, N - 1).GetWithDefault(document, defaultValue);
1237 }
1238
1239 template <typename DocumentType, typename CharType, size_t N>
1240 typename DocumentType::ValueType& GetValueByPointerWithDefault(DocumentType& document, const CharType(&source)[N], const typename DocumentType::Ch* defaultValue) {
1241     return GenericPointer<typename DocumentType::ValueType>(source, N - 1).GetWithDefault(document, defaultValue);
1242 }
1243
1244 #if RAPIDJSON_HAS_STDSTRING
1245 template <typename DocumentType, typename CharType, size_t N>
1246 typename DocumentType::ValueType& GetValueByPointerWithDefault(DocumentType& document, const CharType(&source)[N], const std::basic_string<typename DocumentType::Ch>& defaultValue) {
1247     return GenericPointer<typename DocumentType::ValueType>(source, N - 1).GetWithDefault(document, defaultValue);
1248 }
1249 #endif
1250
1251 template <typename DocumentType, typename CharType, size_t N, typename T2>
1252 RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T2>, internal::IsGenericValue<T2> >), (typename DocumentType::ValueType&))
1253 GetValueByPointerWithDefault(DocumentType& document, const CharType(&source)[N], T2 defaultValue) {
1254     return GenericPointer<typename DocumentType::ValueType>(source, N - 1).GetWithDefault(document, defaultValue);
1255 }
1256
1257 //////////////////////////////////////////////////////////////////////////////
1258
1259 template <typename T>
1260 typename T::ValueType& SetValueByPointer(T& root, const GenericPointer<typename T::ValueType>& pointer, typename T::ValueType& value, typename T::AllocatorType& a) {
1261     return pointer.Set(root, value, a);
1262 }
1263
1264 template <typename T>
1265 typename T::ValueType& SetValueByPointer(T& root, const GenericPointer<typename T::ValueType>& pointer, const typename T::ValueType& value, typename T::AllocatorType& a) {
1266     return pointer.Set(root, value, a);
1267 }
1268
1269 template <typename T>
1270 typename T::ValueType& SetValueByPointer(T& root, const GenericPointer<typename T::ValueType>& pointer, const typename T::Ch* value, typename T::AllocatorType& a) {
1271     return pointer.Set(root, value, a);
1272 }
1273
1274 #if RAPIDJSON_HAS_STDSTRING
1275 template <typename T>
1276 typename T::ValueType& SetValueByPointer(T& root, const GenericPointer<typename T::ValueType>& pointer, const std::basic_string<typename T::Ch>& value, typename T::AllocatorType& a) {
1277     return pointer.Set(root, value, a);
1278 }
1279 #endif
1280
1281 template <typename T, typename T2>
1282 RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T2>, internal::IsGenericValue<T2> >), (typename T::ValueType&))
1283 SetValueByPointer(T& root, const GenericPointer<typename T::ValueType>& pointer, T2 value, typename T::AllocatorType& a) {
1284     return pointer.Set(root, value, a);
1285 }
1286
1287 template <typename T, typename CharType, size_t N>
1288 typename T::ValueType& SetValueByPointer(T& root, const CharType(&source)[N], typename T::ValueType& value, typename T::AllocatorType& a) {
1289     return GenericPointer<typename T::ValueType>(source, N - 1).Set(root, value, a);
1290 }
1291
1292 template <typename T, typename CharType, size_t N>
1293 typename T::ValueType& SetValueByPointer(T& root, const CharType(&source)[N], const typename T::ValueType& value, typename T::AllocatorType& a) {
1294     return GenericPointer<typename T::ValueType>(source, N - 1).Set(root, value, a);
1295 }
1296
1297 template <typename T, typename CharType, size_t N>
1298 typename T::ValueType& SetValueByPointer(T& root, const CharType(&source)[N], const typename T::Ch* value, typename T::AllocatorType& a) {
1299     return GenericPointer<typename T::ValueType>(source, N - 1).Set(root, value, a);
1300 }
1301
1302 #if RAPIDJSON_HAS_STDSTRING
1303 template <typename T, typename CharType, size_t N>
1304 typename T::ValueType& SetValueByPointer(T& root, const CharType(&source)[N], const std::basic_string<typename T::Ch>& value, typename T::AllocatorType& a) {
1305     return GenericPointer<typename T::ValueType>(source, N - 1).Set(root, value, a);
1306 }
1307 #endif
1308
1309 template <typename T, typename CharType, size_t N, typename T2>
1310 RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T2>, internal::IsGenericValue<T2> >), (typename T::ValueType&))
1311 SetValueByPointer(T& root, const CharType(&source)[N], T2 value, typename T::AllocatorType& a) {
1312     return GenericPointer<typename T::ValueType>(source, N - 1).Set(root, value, a);
1313 }
1314
1315 // No allocator parameter
1316
1317 template <typename DocumentType>
1318 typename DocumentType::ValueType& SetValueByPointer(DocumentType& document, const GenericPointer<typename DocumentType::ValueType>& pointer, typename DocumentType::ValueType& value) {
1319     return pointer.Set(document, value);
1320 }
1321
1322 template <typename DocumentType>
1323 typename DocumentType::ValueType& SetValueByPointer(DocumentType& document, const GenericPointer<typename DocumentType::ValueType>& pointer, const typename DocumentType::ValueType& value) {
1324     return pointer.Set(document, value);
1325 }
1326
1327 template <typename DocumentType>
1328 typename DocumentType::ValueType& SetValueByPointer(DocumentType& document, const GenericPointer<typename DocumentType::ValueType>& pointer, const typename DocumentType::Ch* value) {
1329     return pointer.Set(document, value);
1330 }
1331
1332 #if RAPIDJSON_HAS_STDSTRING
1333 template <typename DocumentType>
1334 typename DocumentType::ValueType& SetValueByPointer(DocumentType& document, const GenericPointer<typename DocumentType::ValueType>& pointer, const std::basic_string<typename DocumentType::Ch>& value) {
1335     return pointer.Set(document, value);
1336 }
1337 #endif
1338
1339 template <typename DocumentType, typename T2>
1340 RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T2>, internal::IsGenericValue<T2> >), (typename DocumentType::ValueType&))
1341 SetValueByPointer(DocumentType& document, const GenericPointer<typename DocumentType::ValueType>& pointer, T2 value) {
1342     return pointer.Set(document, value);
1343 }
1344
1345 template <typename DocumentType, typename CharType, size_t N>
1346 typename DocumentType::ValueType& SetValueByPointer(DocumentType& document, const CharType(&source)[N], typename DocumentType::ValueType& value) {
1347     return GenericPointer<typename DocumentType::ValueType>(source, N - 1).Set(document, value);
1348 }
1349
1350 template <typename DocumentType, typename CharType, size_t N>
1351 typename DocumentType::ValueType& SetValueByPointer(DocumentType& document, const CharType(&source)[N], const typename DocumentType::ValueType& value) {
1352     return GenericPointer<typename DocumentType::ValueType>(source, N - 1).Set(document, value);
1353 }
1354
1355 template <typename DocumentType, typename CharType, size_t N>
1356 typename DocumentType::ValueType& SetValueByPointer(DocumentType& document, const CharType(&source)[N], const typename DocumentType::Ch* value) {
1357     return GenericPointer<typename DocumentType::ValueType>(source, N - 1).Set(document, value);
1358 }
1359
1360 #if RAPIDJSON_HAS_STDSTRING
1361 template <typename DocumentType, typename CharType, size_t N>
1362 typename DocumentType::ValueType& SetValueByPointer(DocumentType& document, const CharType(&source)[N], const std::basic_string<typename DocumentType::Ch>& value) {
1363     return GenericPointer<typename DocumentType::ValueType>(source, N - 1).Set(document, value);
1364 }
1365 #endif
1366
1367 template <typename DocumentType, typename CharType, size_t N, typename T2>
1368 RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T2>, internal::IsGenericValue<T2> >), (typename DocumentType::ValueType&))
1369 SetValueByPointer(DocumentType& document, const CharType(&source)[N], T2 value) {
1370     return GenericPointer<typename DocumentType::ValueType>(source, N - 1).Set(document, value);
1371 }
1372
1373 //////////////////////////////////////////////////////////////////////////////
1374
1375 template <typename T>
1376 typename T::ValueType& SwapValueByPointer(T& root, const GenericPointer<typename T::ValueType>& pointer, typename T::ValueType& value, typename T::AllocatorType& a) {
1377     return pointer.Swap(root, value, a);
1378 }
1379
1380 template <typename T, typename CharType, size_t N>
1381 typename T::ValueType& SwapValueByPointer(T& root, const CharType(&source)[N], typename T::ValueType& value, typename T::AllocatorType& a) {
1382     return GenericPointer<typename T::ValueType>(source, N - 1).Swap(root, value, a);
1383 }
1384
1385 template <typename DocumentType>
1386 typename DocumentType::ValueType& SwapValueByPointer(DocumentType& document, const GenericPointer<typename DocumentType::ValueType>& pointer, typename DocumentType::ValueType& value) {
1387     return pointer.Swap(document, value);
1388 }
1389
1390 template <typename DocumentType, typename CharType, size_t N>
1391 typename DocumentType::ValueType& SwapValueByPointer(DocumentType& document, const CharType(&source)[N], typename DocumentType::ValueType& value) {
1392     return GenericPointer<typename DocumentType::ValueType>(source, N - 1).Swap(document, value);
1393 }
1394
1395 //////////////////////////////////////////////////////////////////////////////
1396
1397 template <typename T>
1398 bool EraseValueByPointer(T& root, const GenericPointer<typename T::ValueType>& pointer) {
1399     return pointer.Erase(root);
1400 }
1401
1402 template <typename T, typename CharType, size_t N>
1403 bool EraseValueByPointer(T& root, const CharType(&source)[N]) {
1404     return GenericPointer<typename T::ValueType>(source, N - 1).Erase(root);
1405 }
1406
1407 //@}
1408
1409 RAPIDJSON_NAMESPACE_END
1410
1411 #if defined(__clang__) || defined(_MSC_VER)
1412 RAPIDJSON_DIAG_POP
1413 #endif
1414
1415 #endif // RAPIDJSON_POINTER_H_