pointer.h

Engine/source/persistence/rapidjson/pointer.h

More...

Classes:

class

Represents a JSON Pointer. Use Pointer for UTF8 encoding and default allocator.

class

A helper stream to encode character (UTF-8 code unit) into percent-encoded sequence.

class

A token is the basic units of internal representation.

Helper functions for GenericPointer

DocumentType::ValueType &
CreateValueByPointer(DocumentType & document, const CharType(&) source)
DocumentType::ValueType &
CreateValueByPointer(DocumentType & document, const GenericPointer< typename DocumentType::ValueType > & pointer)
T::ValueType &
CreateValueByPointer(T & root, const CharType(&) source, typename T::AllocatorType & a)
T::ValueType &
CreateValueByPointer(T & root, const GenericPointer< typename T::ValueType > & pointer, typename T::AllocatorType & a)
bool
EraseValueByPointer(T & root, const CharType(&) source)
bool
EraseValueByPointer(T & root, const GenericPointer< typename T::ValueType > & pointer)
const T::ValueType *
GetValueByPointer(const T & root, const CharType(&) source, size_t * unresolvedTokenIndex)
const T::ValueType *
GetValueByPointer(const T & root, const GenericPointer< typename T::ValueType > & pointer, size_t * unresolvedTokenIndex)
T::ValueType *
GetValueByPointer(T & root, const CharType(&) source, size_t * unresolvedTokenIndex)
T::ValueType *
GetValueByPointer(T & root, const GenericPointer< typename T::ValueType > & pointer, size_t * unresolvedTokenIndex)
DocumentType::ValueType &
GetValueByPointerWithDefault(DocumentType & document, const CharType(&) source, const typename DocumentType::Ch * defaultValue)
DocumentType::ValueType &
GetValueByPointerWithDefault(DocumentType & document, const CharType(&) source, const typename DocumentType::ValueType & defaultValue)
DocumentType::ValueType &
GetValueByPointerWithDefault(DocumentType & document, const GenericPointer< typename DocumentType::ValueType > & pointer, const typename DocumentType::Ch * defaultValue)
DocumentType::ValueType &
GetValueByPointerWithDefault(DocumentType & document, const GenericPointer< typename DocumentType::ValueType > & pointer, const typename DocumentType::ValueType & defaultValue)
T::ValueType &
GetValueByPointerWithDefault(T & root, const CharType(&) source, const typename T::Ch * defaultValue, typename T::AllocatorType & a)
T::ValueType &
GetValueByPointerWithDefault(T & root, const CharType(&) source, const typename T::ValueType & defaultValue, typename T::AllocatorType & a)
T::ValueType &
GetValueByPointerWithDefault(T & root, const GenericPointer< typename T::ValueType > & pointer, const typename T::Ch * defaultValue, typename T::AllocatorType & a)
T::ValueType &
GetValueByPointerWithDefault(T & root, const GenericPointer< typename T::ValueType > & pointer, const typename T::ValueType & defaultValue, typename T::AllocatorType & a)
RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr< internal::IsPointer< T2 >, internal::IsGenericValue< T2 > >) , (typename DocumentType::ValueType &) )
RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr< internal::IsPointer< T2 >, internal::IsGenericValue< T2 > >) , (typename DocumentType::ValueType &) )
RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr< internal::IsPointer< T2 >, internal::IsGenericValue< T2 > >) , (typename T::ValueType &) )
RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr< internal::IsPointer< T2 >, internal::IsGenericValue< T2 > >) , (typename T::ValueType &) )
DocumentType::ValueType &
SetValueByPointer(DocumentType & document, const CharType(&) source, const typename DocumentType::Ch * value)
DocumentType::ValueType &
SetValueByPointer(DocumentType & document, const CharType(&) source, const typename DocumentType::ValueType & value)
DocumentType::ValueType &
SetValueByPointer(DocumentType & document, const CharType(&) source, typename DocumentType::ValueType & value)
DocumentType::ValueType &
SetValueByPointer(DocumentType & document, const GenericPointer< typename DocumentType::ValueType > & pointer, const typename DocumentType::Ch * value)
DocumentType::ValueType &
SetValueByPointer(DocumentType & document, const GenericPointer< typename DocumentType::ValueType > & pointer, const typename DocumentType::ValueType & value)
DocumentType::ValueType &
SetValueByPointer(DocumentType & document, const GenericPointer< typename DocumentType::ValueType > & pointer, typename DocumentType::ValueType & value)
T::ValueType &
SetValueByPointer(T & root, const CharType(&) source, const typename T::Ch * value, typename T::AllocatorType & a)
T::ValueType &
SetValueByPointer(T & root, const CharType(&) source, const typename T::ValueType & value, typename T::AllocatorType & a)
T::ValueType &
SetValueByPointer(T & root, const CharType(&) source, typename T::ValueType & value, typename T::AllocatorType & a)
T::ValueType &
SetValueByPointer(T & root, const GenericPointer< typename T::ValueType > & pointer, const typename T::Ch * value, typename T::AllocatorType & a)
T::ValueType &
SetValueByPointer(T & root, const GenericPointer< typename T::ValueType > & pointer, const typename T::ValueType & value, typename T::AllocatorType & a)
T::ValueType &
SetValueByPointer(T & root, const GenericPointer< typename T::ValueType > & pointer, typename T::ValueType & value, typename T::AllocatorType & a)
DocumentType::ValueType &
SwapValueByPointer(DocumentType & document, const CharType(&) source, typename DocumentType::ValueType & value)
DocumentType::ValueType &
SwapValueByPointer(DocumentType & document, const GenericPointer< typename DocumentType::ValueType > & pointer, typename DocumentType::ValueType & value)
T::ValueType &
SwapValueByPointer(T & root, const CharType(&) source, typename T::ValueType & value, typename T::AllocatorType & a)
T::ValueType &
SwapValueByPointer(T & root, const GenericPointer< typename T::ValueType > & pointer, typename T::ValueType & value, typename T::AllocatorType & a)
const GenericPointer< typename T::ValueType > T2 T::AllocatorType &
a 
const GenericPointer< typename T::ValueType > T2
const GenericPointer< typename T::ValueType > &
const CharType(&
source )[N]
const GenericPointer< typename T::ValueType > T2

Public Enumerations

enum
PointerParseErrorCode {
  kPointerParseErrorNone = 0
  kPointerParseErrorTokenMustBeginWithSolidus 
  kPointerParseErrorInvalidEscape 
  kPointerParseErrorInvalidPercentEncoding 
  kPointerParseErrorCharacterMustPercentEncode 
}

Error code of parsing.

Public Typedefs

Pointer 

GenericPointer for Value (UTF-8, default allocator).

Detailed Description

Helper functions for GenericPointer

CreateValueByPointer(DocumentType & document, const CharType(&) source)

CreateValueByPointer(DocumentType & document, const GenericPointer< typename DocumentType::ValueType > & pointer)

CreateValueByPointer(T & root, const CharType(&) source, typename T::AllocatorType & a)

CreateValueByPointer(T & root, const GenericPointer< typename T::ValueType > & pointer, typename T::AllocatorType & a)

EraseValueByPointer(T & root, const CharType(&) source)

EraseValueByPointer(T & root, const GenericPointer< typename T::ValueType > & pointer)

GetValueByPointer(const T & root, const CharType(&) source, size_t * unresolvedTokenIndex)

GetValueByPointer(const T & root, const GenericPointer< typename T::ValueType > & pointer, size_t * unresolvedTokenIndex)

GetValueByPointer(T & root, const CharType(&) source, size_t * unresolvedTokenIndex)

GetValueByPointer(T & root, const GenericPointer< typename T::ValueType > & pointer, size_t * unresolvedTokenIndex)

GetValueByPointerWithDefault(DocumentType & document, const CharType(&) source, const typename DocumentType::Ch * defaultValue)

GetValueByPointerWithDefault(DocumentType & document, const CharType(&) source, const typename DocumentType::ValueType & defaultValue)

GetValueByPointerWithDefault(DocumentType & document, const GenericPointer< typename DocumentType::ValueType > & pointer, const typename DocumentType::Ch * defaultValue)

GetValueByPointerWithDefault(DocumentType & document, const GenericPointer< typename DocumentType::ValueType > & pointer, const typename DocumentType::ValueType & defaultValue)

GetValueByPointerWithDefault(T & root, const CharType(&) source, const typename T::Ch * defaultValue, typename T::AllocatorType & a)

GetValueByPointerWithDefault(T & root, const CharType(&) source, const typename T::ValueType & defaultValue, typename T::AllocatorType & a)

GetValueByPointerWithDefault(T & root, const GenericPointer< typename T::ValueType > & pointer, const typename T::Ch * defaultValue, typename T::AllocatorType & a)

GetValueByPointerWithDefault(T & root, const GenericPointer< typename T::ValueType > & pointer, const typename T::ValueType & defaultValue, typename T::AllocatorType & a)

RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr< internal::IsPointer< T2 >, internal::IsGenericValue< T2 > >) , (typename DocumentType::ValueType &) )

RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr< internal::IsPointer< T2 >, internal::IsGenericValue< T2 > >) , (typename DocumentType::ValueType &) )

RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr< internal::IsPointer< T2 >, internal::IsGenericValue< T2 > >) , (typename T::ValueType &) )

RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr< internal::IsPointer< T2 >, internal::IsGenericValue< T2 > >) , (typename T::ValueType &) )

SetValueByPointer(DocumentType & document, const CharType(&) source, const typename DocumentType::Ch * value)

SetValueByPointer(DocumentType & document, const CharType(&) source, const typename DocumentType::ValueType & value)

SetValueByPointer(DocumentType & document, const CharType(&) source, typename DocumentType::ValueType & value)

SetValueByPointer(DocumentType & document, const GenericPointer< typename DocumentType::ValueType > & pointer, const typename DocumentType::Ch * value)

SetValueByPointer(DocumentType & document, const GenericPointer< typename DocumentType::ValueType > & pointer, const typename DocumentType::ValueType & value)

SetValueByPointer(DocumentType & document, const GenericPointer< typename DocumentType::ValueType > & pointer, typename DocumentType::ValueType & value)

SetValueByPointer(T & root, const CharType(&) source, const typename T::Ch * value, typename T::AllocatorType & a)

SetValueByPointer(T & root, const CharType(&) source, const typename T::ValueType & value, typename T::AllocatorType & a)

SetValueByPointer(T & root, const CharType(&) source, typename T::ValueType & value, typename T::AllocatorType & a)

SetValueByPointer(T & root, const GenericPointer< typename T::ValueType > & pointer, const typename T::Ch * value, typename T::AllocatorType & a)

SetValueByPointer(T & root, const GenericPointer< typename T::ValueType > & pointer, const typename T::ValueType & value, typename T::AllocatorType & a)

SetValueByPointer(T & root, const GenericPointer< typename T::ValueType > & pointer, typename T::ValueType & value, typename T::AllocatorType & a)

SwapValueByPointer(DocumentType & document, const CharType(&) source, typename DocumentType::ValueType & value)

SwapValueByPointer(DocumentType & document, const GenericPointer< typename DocumentType::ValueType > & pointer, typename DocumentType::ValueType & value)

SwapValueByPointer(T & root, const CharType(&) source, typename T::ValueType & value, typename T::AllocatorType & a)

SwapValueByPointer(T & root, const GenericPointer< typename T::ValueType > & pointer, typename T::ValueType & value, typename T::AllocatorType & a)

const GenericPointer< typename T::ValueType > T2 T::AllocatorType & a 
const GenericPointer< typename T::ValueType > T2 defaultValue 
const GenericPointer< typename T::ValueType > & pointer 
const CharType(& source )[N]
const GenericPointer< typename T::ValueType > T2 value 

Public Enumerations

PointerParseErrorCode

Enumerator

kPointerParseErrorNone = 0

The parse is successful.

kPointerParseErrorTokenMustBeginWithSolidus

A token must begin with a '/'.

kPointerParseErrorInvalidEscape

Invalid escape.

kPointerParseErrorInvalidPercentEncoding

Invalid percent encoding in URI fragment.

kPointerParseErrorCharacterMustPercentEncode

A character must percent encoded in URI fragment.

Error code of parsing.

see:

GenericPointer::GenericPointer, GenericPointer::GetParseErrorCode

Public Typedefs

typedef GenericPointer< Value > Pointer 

GenericPointer for Value (UTF-8, default allocator).

Public Variables

RAPIDJSON_NAMESPACE_BEGIN const SizeType kPointerInvalidIndex 

Represents an invalid index in GenericPointer::Token.

   1
   2// Tencent is pleased to support the open source community by making RapidJSON available.
   3// 
   4// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
   5//
   6// Licensed under the MIT License (the "License"); you may not use this file except
   7// in compliance with the License. You may obtain a copy of the License at
   8//
   9// http://opensource.org/licenses/MIT
  10//
  11// Unless required by applicable law or agreed to in writing, software distributed 
  12// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 
  13// CONDITIONS OF ANY KIND, either express or implied. See the License for the 
  14// specific language governing permissions and limitations under the License.
  15
  16#ifndef RAPIDJSON_POINTER_H_
  17#define RAPIDJSON_POINTER_H_
  18
  19#include "document.h"
  20#include "internal/itoa.h"
  21
  22#ifdef __clang__
  23RAPIDJSON_DIAG_PUSH
  24RAPIDJSON_DIAG_OFF(switch-enum)
  25#elif defined(_MSC_VER)
  26RAPIDJSON_DIAG_PUSH
  27RAPIDJSON_DIAG_OFF(4512) // assignment operator could not be generated
  28#endif
  29
  30RAPIDJSON_NAMESPACE_BEGIN
  31
  32static const SizeType kPointerInvalidIndex = ~<a href="/coding/file/rapidjson_8h/#rapidjson_8h_1a5ed6e6e67250fadbd041127e6386dcb5">SizeType</a>(0);  //!< Represents an invalid index in GenericPointer::Token
  33
  34//! Error code of parsing.
  35/*! \ingroup RAPIDJSON_ERRORS
  36    \see GenericPointer::GenericPointer, GenericPointer::GetParseErrorCode
  37*/
  38enum PointerParseErrorCode {
  39    kPointerParseErrorNone = 0,                     //!< The parse is successful
  40
  41    kPointerParseErrorTokenMustBeginWithSolidus,    //!< A token must begin with a '/'
  42    kPointerParseErrorInvalidEscape,                //!< Invalid escape
  43    kPointerParseErrorInvalidPercentEncoding,       //!< Invalid percent encoding in URI fragment
  44    kPointerParseErrorCharacterMustPercentEncode    //!< A character must percent encoded in URI fragment
  45};
  46
  47///////////////////////////////////////////////////////////////////////////////
  48// GenericPointer
  49
  50//! Represents a JSON Pointer. Use Pointer for UTF8 encoding and default allocator.
  51/*!
  52    This class implements RFC 6901 "JavaScript Object Notation (JSON) Pointer" 
  53    (https://tools.ietf.org/html/rfc6901).
  54
  55    A JSON pointer is for identifying a specific value in a JSON document
  56    (GenericDocument). It can simplify coding of DOM tree manipulation, because it
  57    can access multiple-level depth of DOM tree with single API call.
  58
  59    After it parses a string representation (e.g. "/foo/0" or URI fragment 
  60    representation (e.g. "#/foo/0") into its internal representation (tokens),
  61    it can be used to resolve a specific value in multiple documents, or sub-tree 
  62    of documents.
  63
  64    Contrary to GenericValue, Pointer can be copy constructed and copy assigned.
  65    Apart from assignment, a Pointer cannot be modified after construction.
  66
  67    Although Pointer is very convenient, please aware that constructing Pointer
  68    involves parsing and dynamic memory allocation. A special constructor with user-
  69    supplied tokens eliminates these.
  70
  71    GenericPointer depends on GenericDocument and GenericValue.
  72    
  73    \tparam ValueType The value type of the DOM tree. E.g. GenericValue<UTF8<> >
  74    \tparam Allocator The allocator type for allocating memory for internal representation.
  75    
  76    \note GenericPointer uses same encoding of ValueType.
  77    However, Allocator of GenericPointer is independent of Allocator of Value.
  78*/
  79template <typename ValueType, typename Allocator = CrtAllocator>
  80class GenericPointer {
  81public:
  82    typedef typename ValueType::EncodingType EncodingType;  //!< Encoding type from Value
  83    typedef typename ValueType::Ch Ch;                      //!< Character type from Value
  84
  85    //! A token is the basic units of internal representation.
  86    /*!
  87        A JSON pointer string representation "/foo/123" is parsed to two tokens: 
  88        "foo" and 123. 123 will be represented in both numeric form and string form.
  89        They are resolved according to the actual value type (object or array).
  90
  91        For token that are not numbers, or the numeric value is out of bound
  92        (greater than limits of SizeType), they are only treated as string form
  93        (i.e. the token's index will be equal to kPointerInvalidIndex).
  94
  95        This struct is public so that user can create a Pointer without parsing and 
  96        allocation, using a special constructor.
  97    */
  98    struct Token {
  99        const Ch* name;             //!< Name of the token. It has null character at the end but it can contain null character.
 100        SizeType length;            //!< Length of the name.
 101        SizeType index;             //!< A valid array index, if it is not equal to kPointerInvalidIndex.
 102    };
 103
 104    //!@name Constructors and destructor.
 105    //@{
 106
 107    //! Default constructor.
 108    GenericPointer(Allocator* allocator = 0) : allocator_(allocator), ownAllocator_(), nameBuffer_(), tokens_(), tokenCount_(), parseErrorOffset_(), parseErrorCode_(kPointerParseErrorNone) {}
 109
 110    //! Constructor that parses a string or URI fragment representation.
 111    /*!
 112        \param source A null-terminated, string or URI fragment representation of JSON pointer.
 113        \param allocator User supplied allocator for this pointer. If no allocator is provided, it creates a self-owned one.
 114    */
 115    explicit GenericPointer(const Ch* source, Allocator* allocator = 0) : allocator_(allocator), ownAllocator_(), nameBuffer_(), tokens_(), tokenCount_(), parseErrorOffset_(), parseErrorCode_(kPointerParseErrorNone) {
 116        Parse(source, internal::StrLen(source));
 117    }
 118
 119#if RAPIDJSON_HAS_STDSTRING
 120    //! Constructor that parses a string or URI fragment representation.
 121    /*!
 122        \param source A string or URI fragment representation of JSON pointer.
 123        \param allocator User supplied allocator for this pointer. If no allocator is provided, it creates a self-owned one.
 124        \note Requires the definition of the preprocessor symbol \ref RAPIDJSON_HAS_STDSTRING.
 125    */
 126    explicit GenericPointer(const std::basic_string<Ch>& source, Allocator* allocator = 0) : allocator_(allocator), ownAllocator_(), nameBuffer_(), tokens_(), tokenCount_(), parseErrorOffset_(), parseErrorCode_(kPointerParseErrorNone) {
 127        Parse(source.c_str(), source.size());
 128    }
 129#endif
 130
 131    //! Constructor that parses a string or URI fragment representation, with length of the source string.
 132    /*!
 133        \param source A string or URI fragment representation of JSON pointer.
 134        \param length Length of source.
 135        \param allocator User supplied allocator for this pointer. If no allocator is provided, it creates a self-owned one.
 136        \note Slightly faster than the overload without length.
 137    */
 138    GenericPointer(const Ch* source, size_t length, Allocator* allocator = 0) : allocator_(allocator), ownAllocator_(), nameBuffer_(), tokens_(), tokenCount_(), parseErrorOffset_(), parseErrorCode_(kPointerParseErrorNone) {
 139        Parse(source, length);
 140    }
 141
 142    //! Constructor with user-supplied tokens.
 143    /*!
 144        This constructor let user supplies const array of tokens.
 145        This prevents the parsing process and eliminates allocation.
 146        This is preferred for memory constrained environments.
 147
 148        \param tokens An constant array of tokens representing the JSON pointer.
 149        \param tokenCount Number of tokens.
 150
 151        \b Example
 152        \code
 153        #define NAME(s) { s, sizeof(s) / sizeof(s[0]) - 1, kPointerInvalidIndex }
 154        #define INDEX(i) { #i, sizeof(#i) - 1, i }
 155
 156        static const Pointer::Token kTokens[] = { NAME("foo"), INDEX(123) };
 157        static const Pointer p(kTokens, sizeof(kTokens) / sizeof(kTokens[0]));
 158        // Equivalent to static const Pointer p("/foo/123");
 159
 160        #undef NAME
 161        #undef INDEX
 162        \endcode
 163    */
 164    GenericPointer(const Token* tokens, size_t tokenCount) : allocator_(), ownAllocator_(), nameBuffer_(), tokens_(const_cast<Token*>(tokens)), tokenCount_(tokenCount), parseErrorOffset_(), parseErrorCode_(kPointerParseErrorNone) {}
 165
 166    //! Copy constructor.
 167    GenericPointer(const GenericPointer& rhs) : allocator_(rhs.allocator_), ownAllocator_(), nameBuffer_(), tokens_(), tokenCount_(), parseErrorOffset_(), parseErrorCode_(kPointerParseErrorNone) {
 168        *this = rhs;
 169    }
 170
 171    //! Copy constructor.
 172    GenericPointer(const GenericPointer& rhs, Allocator* allocator) : allocator_(allocator), ownAllocator_(), nameBuffer_(), tokens_(), tokenCount_(), parseErrorOffset_(), parseErrorCode_(kPointerParseErrorNone) {
 173        *this = rhs;
 174    }
 175
 176    //! Destructor.
 177    ~GenericPointer() {
 178        if (nameBuffer_)    // If user-supplied tokens constructor is used, nameBuffer_ is nullptr and tokens_ are not deallocated.
 179            Allocator::Free(tokens_);
 180        RAPIDJSON_DELETE(ownAllocator_);
 181    }
 182
 183    //! Assignment operator.
 184    GenericPointer& operator=(const GenericPointer& rhs) {
 185        if (this != &rhs) {
 186            // Do not delete ownAllcator
 187            if (nameBuffer_)
 188                Allocator::Free(tokens_);
 189
 190            tokenCount_ = rhs.tokenCount_;
 191            parseErrorOffset_ = rhs.parseErrorOffset_;
 192            parseErrorCode_ = rhs.parseErrorCode_;
 193
 194            if (rhs.nameBuffer_)
 195                CopyFromRaw(rhs); // Normally parsed tokens.
 196            else {
 197                tokens_ = rhs.tokens_; // User supplied const tokens.
 198                nameBuffer_ = 0;
 199            }
 200        }
 201        return *this;
 202    }
 203
 204    //! Swap the content of this pointer with an other.
 205    /*!
 206        \param other The pointer to swap with.
 207        \note Constant complexity.
 208    */
 209    GenericPointer& Swap(GenericPointer& other) RAPIDJSON_NOEXCEPT {
 210        internal::Swap(allocator_, other.allocator_);
 211        internal::Swap(ownAllocator_, other.ownAllocator_);
 212        internal::Swap(nameBuffer_, other.nameBuffer_);
 213        internal::Swap(tokens_, other.tokens_);
 214        internal::Swap(tokenCount_, other.tokenCount_);
 215        internal::Swap(parseErrorOffset_, other.parseErrorOffset_);
 216        internal::Swap(parseErrorCode_, other.parseErrorCode_);
 217        return *this;
 218    }
 219
 220    //! free-standing swap function helper
 221    /*!
 222        Helper function to enable support for common swap implementation pattern based on \c std::swap:
 223        \code
 224        void swap(MyClass& a, MyClass& b) {
 225            using std::swap;
 226            swap(a.pointer, b.pointer);
 227            // ...
 228        }
 229        \endcode
 230        \see Swap()
 231     */
 232    friend inline void swap(GenericPointer& a, GenericPointer& b) RAPIDJSON_NOEXCEPT { a.Swap(b); }
 233
 234    //@}
 235
 236    //!@name Append token
 237    //@{
 238
 239    //! Append a token and return a new Pointer
 240    /*!
 241        \param token Token to be appended.
 242        \param allocator Allocator for the newly return Pointer.
 243        \return A new Pointer with appended token.
 244    */
 245    GenericPointer Append(const Token& token, Allocator* allocator = 0) const {
 246        GenericPointer r;
 247        r.allocator_ = allocator;
 248        Ch *p = r.CopyFromRaw(*this, 1, token.length + 1);
 249        std::memcpy(p, token.name, (token.length + 1) * sizeof(Ch));
 250        r.tokens_[tokenCount_].name = p;
 251        r.tokens_[tokenCount_].length = token.length;
 252        r.tokens_[tokenCount_].index = token.index;
 253        return r;
 254    }
 255
 256    //! Append a name token with length, and return a new Pointer
 257    /*!
 258        \param name Name to be appended.
 259        \param length Length of name.
 260        \param allocator Allocator for the newly return Pointer.
 261        \return A new Pointer with appended token.
 262    */
 263    GenericPointer Append(const Ch* name, SizeType length, Allocator* allocator = 0) const {
 264        Token token = { name, length, kPointerInvalidIndex };
 265        return Append(token, allocator);
 266    }
 267
 268    //! Append a name token without length, and return a new Pointer
 269    /*!
 270        \param name Name (const Ch*) to be appended.
 271        \param allocator Allocator for the newly return Pointer.
 272        \return A new Pointer with appended token.
 273    */
 274    template <typename T>
 275    RAPIDJSON_DISABLEIF_RETURN((internal::NotExpr<internal::IsSame<typename internal::RemoveConst<T>::Type, Ch> >), (GenericPointer))
 276    Append(T* name, Allocator* allocator = 0) const {
 277        return Append(name, internal::StrLen(name), allocator);
 278    }
 279
 280#if RAPIDJSON_HAS_STDSTRING
 281    //! Append a name token, and return a new Pointer
 282    /*!
 283        \param name Name to be appended.
 284        \param allocator Allocator for the newly return Pointer.
 285        \return A new Pointer with appended token.
 286    */
 287    GenericPointer Append(const std::basic_string<Ch>& name, Allocator* allocator = 0) const {
 288        return Append(name.c_str(), static_cast<SizeType>(name.size()), allocator);
 289    }
 290#endif
 291
 292    //! Append a index token, and return a new Pointer
 293    /*!
 294        \param index Index to be appended.
 295        \param allocator Allocator for the newly return Pointer.
 296        \return A new Pointer with appended token.
 297    */
 298    GenericPointer Append(SizeType index, Allocator* allocator = 0) const {
 299        char buffer[21];
 300        char* end = sizeof(SizeType) == 4 ? internal::u32toa(index, buffer) : internal::u64toa(index, buffer);
 301        SizeType length = static_cast<SizeType>(end - buffer);
 302        buffer[length] = '\0';
 303
 304        if (sizeof(Ch) == 1) {
 305            Token token = { reinterpret_cast<Ch*>(buffer), length, index };
 306            return Append(token, allocator);
 307        }
 308        else {
 309            Ch name[21];
 310            for (size_t i = 0; i <= length; i++)
 311                name[i] = static_cast<Ch>(buffer[i]);
 312            Token token = { name, length, index };
 313            return Append(token, allocator);
 314        }
 315    }
 316
 317    //! Append a token by value, and return a new Pointer
 318    /*!
 319        \param token token to be appended.
 320        \param allocator Allocator for the newly return Pointer.
 321        \return A new Pointer with appended token.
 322    */
 323    GenericPointer Append(const ValueType& token, Allocator* allocator = 0) const {
 324        if (token.IsString())
 325            return Append(token.GetString(), token.GetStringLength(), allocator);
 326        else {
 327            RAPIDJSON_ASSERT(token.IsUint64());
 328            RAPIDJSON_ASSERT(token.GetUint64() <= SizeType(~0));
 329            return Append(static_cast<SizeType>(token.GetUint64()), allocator);
 330        }
 331    }
 332
 333    //!@name Handling Parse Error
 334    //@{
 335
 336    //! Check whether this is a valid pointer.
 337    bool IsValid() const { return parseErrorCode_ == kPointerParseErrorNone; }
 338
 339    //! Get the parsing error offset in code unit.
 340    size_t GetParseErrorOffset() const { return parseErrorOffset_; }
 341
 342    //! Get the parsing error code.
 343    PointerParseErrorCode GetParseErrorCode() const { return parseErrorCode_; }
 344
 345    //@}
 346
 347    //! Get the allocator of this pointer.
 348    Allocator& GetAllocator() { return *allocator_; }
 349
 350    //!@name Tokens
 351    //@{
 352
 353    //! Get the token array (const version only).
 354    const Token* GetTokens() const { return tokens_; }
 355
 356    //! Get the number of tokens.
 357    size_t GetTokenCount() const { return tokenCount_; }
 358
 359    //@}
 360
 361    //!@name Equality/inequality operators
 362    //@{
 363
 364    //! Equality operator.
 365    /*!
 366        \note When any pointers are invalid, always returns false.
 367    */
 368    bool operator==(const GenericPointer& rhs) const {
 369        if (!IsValid() || !rhs.IsValid() || tokenCount_ != rhs.tokenCount_)
 370            return false;
 371
 372        for (size_t i = 0; i < tokenCount_; i++) {
 373            if (tokens_[i].index != rhs.tokens_[i].index ||
 374                tokens_[i].length != rhs.tokens_[i].length || 
 375                (tokens_[i].length != 0 && std::memcmp(tokens_[i].name, rhs.tokens_[i].name, sizeof(Ch)* tokens_[i].length) != 0))
 376            {
 377                return false;
 378            }
 379        }
 380
 381        return true;
 382    }
 383
 384    //! Inequality operator.
 385    /*!
 386        \note When any pointers are invalid, always returns true.
 387    */
 388    bool operator!=(const GenericPointer& rhs) const { return !(*this == rhs); }
 389
 390    //! Less than operator.
 391    /*!
 392        \note Invalid pointers are always greater than valid ones.
 393    */
 394    bool operator<(const GenericPointer& rhs) const {
 395        if (!IsValid())
 396            return false;
 397        if (!rhs.IsValid())
 398            return true;
 399
 400        if (tokenCount_ != rhs.tokenCount_)
 401            return tokenCount_ < rhs.tokenCount_;
 402
 403        for (size_t i = 0; i < tokenCount_; i++) {
 404            if (tokens_[i].index != rhs.tokens_[i].index)
 405                return tokens_[i].index < rhs.tokens_[i].index;
 406
 407            if (tokens_[i].length != rhs.tokens_[i].length)
 408                return tokens_[i].length < rhs.tokens_[i].length;
 409
 410            if (int cmp = std::memcmp(tokens_[i].name, rhs.tokens_[i].name, sizeof(Ch) * tokens_[i].length))
 411                return cmp < 0;
 412        }
 413
 414        return false;
 415    }
 416
 417    //@}
 418
 419    //!@name Stringify
 420    //@{
 421
 422    //! Stringify the pointer into string representation.
 423    /*!
 424        \tparam OutputStream Type of output stream.
 425        \param os The output stream.
 426    */
 427    template<typename OutputStream>
 428    bool Stringify(OutputStream& os) const {
 429        return Stringify<false, OutputStream>(os);
 430    }
 431
 432    //! Stringify the pointer into URI fragment representation.
 433    /*!
 434        \tparam OutputStream Type of output stream.
 435        \param os The output stream.
 436    */
 437    template<typename OutputStream>
 438    bool StringifyUriFragment(OutputStream& os) const {
 439        return Stringify<true, OutputStream>(os);
 440    }
 441
 442    //@}
 443
 444    //!@name Create value
 445    //@{
 446
 447    //! Create a value in a subtree.
 448    /*!
 449        If the value is not exist, it creates all parent values and a JSON Null value.
 450        So it always succeed and return the newly created or existing value.
 451
 452        Remind that it may change types of parents according to tokens, so it 
 453        potentially removes previously stored values. For example, if a document 
 454        was an array, and "/foo" is used to create a value, then the document 
 455        will be changed to an object, and all existing array elements are lost.
 456
 457        \param root Root value of a DOM subtree to be resolved. It can be any value other than document root.
 458        \param allocator Allocator for creating the values if the specified value or its parents are not exist.
 459        \param alreadyExist If non-null, it stores whether the resolved value is already exist.
 460        \return The resolved newly created (a JSON Null value), or already exists value.
 461    */
 462    ValueType& Create(ValueType& root, typename ValueType::AllocatorType& allocator, bool* alreadyExist = 0) const {
 463        RAPIDJSON_ASSERT(IsValid());
 464        ValueType* v = &root;
 465        bool exist = true;
 466        for (const Token *t = tokens_; t != tokens_ + tokenCount_; ++t) {
 467            if (v->IsArray() && t->name[0] == '-' && t->length == 1) {
 468                v->PushBack(ValueType().Move(), allocator);
 469                v = &((*v)[v->Size() - 1]);
 470                exist = false;
 471            }
 472            else {
 473                if (t->index == kPointerInvalidIndex) { // must be object name
 474                    if (!v->IsObject())
 475                        v->SetObject(); // Change to Object
 476                }
 477                else { // object name or array index
 478                    if (!v->IsArray() && !v->IsObject())
 479                        v->SetArray(); // Change to Array
 480                }
 481
 482                if (v->IsArray()) {
 483                    if (t->index >= v->Size()) {
 484                        v->Reserve(t->index + 1, allocator);
 485                        while (t->index >= v->Size())
 486                            v->PushBack(ValueType().Move(), allocator);
 487                        exist = false;
 488                    }
 489                    v = &((*v)[t->index]);
 490                }
 491                else {
 492                    typename ValueType::MemberIterator m = v->FindMember(GenericStringRef<Ch>(t->name, t->length));
 493                    if (m == v->MemberEnd()) {
 494                        v->AddMember(ValueType(t->name, t->length, allocator).Move(), ValueType().Move(), allocator);
 495                        v = &(--v->MemberEnd())->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(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(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
 812private:
 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).
1110typedef GenericPointer<Value> Pointer;
1111
1112//!@name Helper functions for GenericPointer
1113//@{
1114
1115//////////////////////////////////////////////////////////////////////////////
1116
1117template <typename T>
1118typename T::ValueType& CreateValueByPointer(T& root, const GenericPointer<typename T::ValueType>& pointer, typename T::AllocatorType& a) {
1119    return pointer.Create(root, a);
1120}
1121
1122template <typename T, typename CharType, size_t N>
1123typename 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
1129template <typename DocumentType>
1130typename DocumentType::ValueType& CreateValueByPointer(DocumentType& document, const GenericPointer<typename DocumentType::ValueType>& pointer) {
1131    return pointer.Create(document);
1132}
1133
1134template <typename DocumentType, typename CharType, size_t N>
1135typename DocumentType::ValueType& CreateValueByPointer(DocumentType& document, const CharType(&source)[N]) {
1136    return GenericPointer<typename DocumentType::ValueType>(source, N - 1).Create(document);
1137}
1138
1139//////////////////////////////////////////////////////////////////////////////
1140
1141template <typename T>
1142typename T::ValueType* GetValueByPointer(T& root, const GenericPointer<typename T::ValueType>& pointer, size_t* unresolvedTokenIndex = 0) {
1143    return pointer.Get(root, unresolvedTokenIndex);
1144}
1145
1146template <typename T>
1147const 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
1151template <typename T, typename CharType, size_t N>
1152typename 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
1156template <typename T, typename CharType, size_t N>
1157const 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
1163template <typename T>
1164typename 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
1168template <typename T>
1169typename 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
1174template <typename T>
1175typename 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
1180template <typename T, typename T2>
1181RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T2>, internal::IsGenericValue<T2> >), (typename T::ValueType&))
1182GetValueByPointerWithDefault(T& root, const GenericPointer<typename T::ValueType>& pointer, T2 defaultValue, typename T::AllocatorType& a) {
1183    return pointer.GetWithDefault(root, defaultValue, a);
1184}
1185
1186template <typename T, typename CharType, size_t N>
1187typename 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
1191template <typename T, typename CharType, size_t N>
1192typename 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
1197template <typename T, typename CharType, size_t N>
1198typename 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
1203template <typename T, typename CharType, size_t N, typename T2>
1204RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T2>, internal::IsGenericValue<T2> >), (typename T::ValueType&))
1205GetValueByPointerWithDefault(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
1211template <typename DocumentType>
1212typename DocumentType::ValueType& GetValueByPointerWithDefault(DocumentType& document, const GenericPointer<typename DocumentType::ValueType>& pointer, const typename DocumentType::ValueType& defaultValue) {
1213    return pointer.GetWithDefault(document, defaultValue);
1214}
1215
1216template <typename DocumentType>
1217typename 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
1222template <typename DocumentType>
1223typename 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
1228template <typename DocumentType, typename T2>
1229RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T2>, internal::IsGenericValue<T2> >), (typename DocumentType::ValueType&))
1230GetValueByPointerWithDefault(DocumentType& document, const GenericPointer<typename DocumentType::ValueType>& pointer, T2 defaultValue) {
1231    return pointer.GetWithDefault(document, defaultValue);
1232}
1233
1234template <typename DocumentType, typename CharType, size_t N>
1235typename 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
1239template <typename DocumentType, typename CharType, size_t N>
1240typename 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
1245template <typename DocumentType, typename CharType, size_t N>
1246typename 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
1251template <typename DocumentType, typename CharType, size_t N, typename T2>
1252RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T2>, internal::IsGenericValue<T2> >), (typename DocumentType::ValueType&))
1253GetValueByPointerWithDefault(DocumentType& document, const CharType(&source)[N], T2 defaultValue) {
1254    return GenericPointer<typename DocumentType::ValueType>(source, N - 1).GetWithDefault(document, defaultValue);
1255}
1256
1257//////////////////////////////////////////////////////////////////////////////
1258
1259template <typename T>
1260typename 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
1264template <typename T>
1265typename 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
1269template <typename T>
1270typename 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
1275template <typename T>
1276typename 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
1281template <typename T, typename T2>
1282RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T2>, internal::IsGenericValue<T2> >), (typename T::ValueType&))
1283SetValueByPointer(T& root, const GenericPointer<typename T::ValueType>& pointer, T2 value, typename T::AllocatorType& a) {
1284    return pointer.Set(root, value, a);
1285}
1286
1287template <typename T, typename CharType, size_t N>
1288typename 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
1292template <typename T, typename CharType, size_t N>
1293typename 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
1297template <typename T, typename CharType, size_t N>
1298typename 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
1303template <typename T, typename CharType, size_t N>
1304typename 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
1309template <typename T, typename CharType, size_t N, typename T2>
1310RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T2>, internal::IsGenericValue<T2> >), (typename T::ValueType&))
1311SetValueByPointer(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
1317template <typename DocumentType>
1318typename DocumentType::ValueType& SetValueByPointer(DocumentType& document, const GenericPointer<typename DocumentType::ValueType>& pointer, typename DocumentType::ValueType& value) {
1319    return pointer.Set(document, value);
1320}
1321
1322template <typename DocumentType>
1323typename DocumentType::ValueType& SetValueByPointer(DocumentType& document, const GenericPointer<typename DocumentType::ValueType>& pointer, const typename DocumentType::ValueType& value) {
1324    return pointer.Set(document, value);
1325}
1326
1327template <typename DocumentType>
1328typename 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
1333template <typename DocumentType>
1334typename 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
1339template <typename DocumentType, typename T2>
1340RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T2>, internal::IsGenericValue<T2> >), (typename DocumentType::ValueType&))
1341SetValueByPointer(DocumentType& document, const GenericPointer<typename DocumentType::ValueType>& pointer, T2 value) {
1342    return pointer.Set(document, value);
1343}
1344
1345template <typename DocumentType, typename CharType, size_t N>
1346typename 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
1350template <typename DocumentType, typename CharType, size_t N>
1351typename 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
1355template <typename DocumentType, typename CharType, size_t N>
1356typename 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
1361template <typename DocumentType, typename CharType, size_t N>
1362typename 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
1367template <typename DocumentType, typename CharType, size_t N, typename T2>
1368RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T2>, internal::IsGenericValue<T2> >), (typename DocumentType::ValueType&))
1369SetValueByPointer(DocumentType& document, const CharType(&source)[N], T2 value) {
1370    return GenericPointer<typename DocumentType::ValueType>(source, N - 1).Set(document, value);
1371}
1372
1373//////////////////////////////////////////////////////////////////////////////
1374
1375template <typename T>
1376typename 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
1380template <typename T, typename CharType, size_t N>
1381typename 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
1385template <typename DocumentType>
1386typename DocumentType::ValueType& SwapValueByPointer(DocumentType& document, const GenericPointer<typename DocumentType::ValueType>& pointer, typename DocumentType::ValueType& value) {
1387    return pointer.Swap(document, value);
1388}
1389
1390template <typename DocumentType, typename CharType, size_t N>
1391typename 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
1397template <typename T>
1398bool EraseValueByPointer(T& root, const GenericPointer<typename T::ValueType>& pointer) {
1399    return pointer.Erase(root);
1400}
1401
1402template <typename T, typename CharType, size_t N>
1403bool EraseValueByPointer(T& root, const CharType(&source)[N]) {
1404    return GenericPointer<typename T::ValueType>(source, N - 1).Erase(root);
1405}
1406
1407//@}
1408
1409RAPIDJSON_NAMESPACE_END
1410
1411#if defined(__clang__) || defined(_MSC_VER)
1412RAPIDJSON_DIAG_POP
1413#endif
1414
1415#endif // RAPIDJSON_POINTER_H_
1416