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