git repos / blockattack-game

blame: source/code/Libs/include/cereal/external/rapidjson/document.h

normal view · raw

6c5f2c01 sago007 2017-03-15 17:56 1
// Tencent is pleased to support the open source community by making RapidJSON available.
6c5f2c01 sago007 2017-03-15 17:56 2
// 
6c5f2c01 sago007 2017-03-15 17:56 3
// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
6c5f2c01 sago007 2017-03-15 17:56 4
//
6c5f2c01 sago007 2017-03-15 17:56 5
// Licensed under the MIT License (the "License"); you may not use this file except
6c5f2c01 sago007 2017-03-15 17:56 6
// in compliance with the License. You may obtain a copy of the License at
6c5f2c01 sago007 2017-03-15 17:56 7
//
6c5f2c01 sago007 2017-03-15 17:56 8
// http://opensource.org/licenses/MIT
6c5f2c01 sago007 2017-03-15 17:56 9
//
6c5f2c01 sago007 2017-03-15 17:56 10
// Unless required by applicable law or agreed to in writing, software distributed 
6c5f2c01 sago007 2017-03-15 17:56 11
// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 
6c5f2c01 sago007 2017-03-15 17:56 12
// CONDITIONS OF ANY KIND, either express or implied. See the License for the 
6c5f2c01 sago007 2017-03-15 17:56 13
// specific language governing permissions and limitations under the License.
6c5f2c01 sago007 2017-03-15 17:56 14
6c5f2c01 sago007 2017-03-15 17:56 15
#ifndef CEREAL_RAPIDJSON_DOCUMENT_H_
6c5f2c01 sago007 2017-03-15 17:56 16
#define CEREAL_RAPIDJSON_DOCUMENT_H_
6c5f2c01 sago007 2017-03-15 17:56 17
6c5f2c01 sago007 2017-03-15 17:56 18
/*! \file document.h */
7a956470 sago007 2016-02-14 17:09 19
7a956470 sago007 2016-02-14 17:09 20
#include "reader.h"
6c5f2c01 sago007 2017-03-15 17:56 21
#include "internal/meta.h"
7a956470 sago007 2016-02-14 17:09 22
#include "internal/strfunc.h"
6c5f2c01 sago007 2017-03-15 17:56 23
#include "memorystream.h"
6c5f2c01 sago007 2017-03-15 17:56 24
#include "encodedstream.h"
6c5f2c01 sago007 2017-03-15 17:56 25
#include <new>      // placement new
6c5f2c01 sago007 2017-03-15 17:56 26
#include <limits>
7a956470 sago007 2016-02-14 17:09 27
6c5f2c01 sago007 2017-03-15 17:56 28
CEREAL_RAPIDJSON_DIAG_PUSH
7a956470 sago007 2016-02-14 17:09 29
#ifdef _MSC_VER
6c5f2c01 sago007 2017-03-15 17:56 30
CEREAL_RAPIDJSON_DIAG_OFF(4127) // conditional expression is constant
6c5f2c01 sago007 2017-03-15 17:56 31
CEREAL_RAPIDJSON_DIAG_OFF(4244) // conversion from kXxxFlags to 'uint16_t', possible loss of data
7a956470 sago007 2016-02-14 17:09 32
#endif
7a956470 sago007 2016-02-14 17:09 33
6c5f2c01 sago007 2017-03-15 17:56 34
#ifdef __clang__
6c5f2c01 sago007 2017-03-15 17:56 35
CEREAL_RAPIDJSON_DIAG_OFF(padded)
6c5f2c01 sago007 2017-03-15 17:56 36
CEREAL_RAPIDJSON_DIAG_OFF(switch-enum)
6c5f2c01 sago007 2017-03-15 17:56 37
CEREAL_RAPIDJSON_DIAG_OFF(c++98-compat)
6c5f2c01 sago007 2017-03-15 17:56 38
#endif
6c5f2c01 sago007 2017-03-15 17:56 39
6c5f2c01 sago007 2017-03-15 17:56 40
#ifdef __GNUC__
6c5f2c01 sago007 2017-03-15 17:56 41
CEREAL_RAPIDJSON_DIAG_OFF(effc++)
6c5f2c01 sago007 2017-03-15 17:56 42
#if __GNUC__ >= 6
6c5f2c01 sago007 2017-03-15 17:56 43
CEREAL_RAPIDJSON_DIAG_OFF(terminate) // ignore throwing CEREAL_RAPIDJSON_ASSERT in CEREAL_RAPIDJSON_NOEXCEPT functions
6c5f2c01 sago007 2017-03-15 17:56 44
#endif
6c5f2c01 sago007 2017-03-15 17:56 45
#endif // __GNUC__
6c5f2c01 sago007 2017-03-15 17:56 46
6c5f2c01 sago007 2017-03-15 17:56 47
#ifndef CEREAL_RAPIDJSON_NOMEMBERITERATORCLASS
6c5f2c01 sago007 2017-03-15 17:56 48
#include <iterator> // std::iterator, std::random_access_iterator_tag
6c5f2c01 sago007 2017-03-15 17:56 49
#endif
6c5f2c01 sago007 2017-03-15 17:56 50
6c5f2c01 sago007 2017-03-15 17:56 51
#if CEREAL_RAPIDJSON_HAS_CXX11_RVALUE_REFS
6c5f2c01 sago007 2017-03-15 17:56 52
#include <utility> // std::move
6c5f2c01 sago007 2017-03-15 17:56 53
#endif
6c5f2c01 sago007 2017-03-15 17:56 54
6c5f2c01 sago007 2017-03-15 17:56 55
CEREAL_RAPIDJSON_NAMESPACE_BEGIN
6c5f2c01 sago007 2017-03-15 17:56 56
6c5f2c01 sago007 2017-03-15 17:56 57
// Forward declaration.
6c5f2c01 sago007 2017-03-15 17:56 58
template <typename Encoding, typename Allocator>
6c5f2c01 sago007 2017-03-15 17:56 59
class GenericValue;
6c5f2c01 sago007 2017-03-15 17:56 60
6c5f2c01 sago007 2017-03-15 17:56 61
template <typename Encoding, typename Allocator, typename StackAllocator>
6c5f2c01 sago007 2017-03-15 17:56 62
class GenericDocument;
6c5f2c01 sago007 2017-03-15 17:56 63
6c5f2c01 sago007 2017-03-15 17:56 64
//! Name-value pair in a JSON object value.
6c5f2c01 sago007 2017-03-15 17:56 65
/*!
6c5f2c01 sago007 2017-03-15 17:56 66
    This class was internal to GenericValue. It used to be a inner struct.
6c5f2c01 sago007 2017-03-15 17:56 67
    But a compiler (IBM XL C/C++ for AIX) have reported to have problem with that so it moved as a namespace scope struct.
6c5f2c01 sago007 2017-03-15 17:56 68
    https://code.google.com/p/rapidjson/issues/detail?id=64
6c5f2c01 sago007 2017-03-15 17:56 69
*/
6c5f2c01 sago007 2017-03-15 17:56 70
template <typename Encoding, typename Allocator> 
6c5f2c01 sago007 2017-03-15 17:56 71
struct GenericMember { 
6c5f2c01 sago007 2017-03-15 17:56 72
    GenericValue<Encoding, Allocator> name;     //!< name of member (must be a string)
6c5f2c01 sago007 2017-03-15 17:56 73
    GenericValue<Encoding, Allocator> value;    //!< value of member.
6c5f2c01 sago007 2017-03-15 17:56 74
};
6c5f2c01 sago007 2017-03-15 17:56 75
6c5f2c01 sago007 2017-03-15 17:56 76
///////////////////////////////////////////////////////////////////////////////
6c5f2c01 sago007 2017-03-15 17:56 77
// GenericMemberIterator
6c5f2c01 sago007 2017-03-15 17:56 78
6c5f2c01 sago007 2017-03-15 17:56 79
#ifndef CEREAL_RAPIDJSON_NOMEMBERITERATORCLASS
6c5f2c01 sago007 2017-03-15 17:56 80
6c5f2c01 sago007 2017-03-15 17:56 81
//! (Constant) member iterator for a JSON object value
6c5f2c01 sago007 2017-03-15 17:56 82
/*!
6c5f2c01 sago007 2017-03-15 17:56 83
    \tparam Const Is this a constant iterator?
6c5f2c01 sago007 2017-03-15 17:56 84
    \tparam Encoding    Encoding of the value. (Even non-string values need to have the same encoding in a document)
6c5f2c01 sago007 2017-03-15 17:56 85
    \tparam Allocator   Allocator type for allocating memory of object, array and string.
6c5f2c01 sago007 2017-03-15 17:56 86
6c5f2c01 sago007 2017-03-15 17:56 87
    This class implements a Random Access Iterator for GenericMember elements
6c5f2c01 sago007 2017-03-15 17:56 88
    of a GenericValue, see ISO/IEC 14882:2003(E) C++ standard, 24.1 [lib.iterator.requirements].
6c5f2c01 sago007 2017-03-15 17:56 89
6c5f2c01 sago007 2017-03-15 17:56 90
    \note This iterator implementation is mainly intended to avoid implicit
6c5f2c01 sago007 2017-03-15 17:56 91
        conversions from iterator values to \c NULL,
6c5f2c01 sago007 2017-03-15 17:56 92
        e.g. from GenericValue::FindMember.
6c5f2c01 sago007 2017-03-15 17:56 93
6c5f2c01 sago007 2017-03-15 17:56 94
    \note Define \c CEREAL_RAPIDJSON_NOMEMBERITERATORCLASS to fall back to a
6c5f2c01 sago007 2017-03-15 17:56 95
        pointer-based implementation, if your platform doesn't provide
6c5f2c01 sago007 2017-03-15 17:56 96
        the C++ <iterator> header.
6c5f2c01 sago007 2017-03-15 17:56 97
6c5f2c01 sago007 2017-03-15 17:56 98
    \see GenericMember, GenericValue::MemberIterator, GenericValue::ConstMemberIterator
6c5f2c01 sago007 2017-03-15 17:56 99
 */
6c5f2c01 sago007 2017-03-15 17:56 100
template <bool Const, typename Encoding, typename Allocator>
6c5f2c01 sago007 2017-03-15 17:56 101
class GenericMemberIterator
6c5f2c01 sago007 2017-03-15 17:56 102
    : public std::iterator<std::random_access_iterator_tag
6c5f2c01 sago007 2017-03-15 17:56 103
        , typename internal::MaybeAddConst<Const,GenericMember<Encoding,Allocator> >::Type> {
6c5f2c01 sago007 2017-03-15 17:56 104
6c5f2c01 sago007 2017-03-15 17:56 105
    friend class GenericValue<Encoding,Allocator>;
6c5f2c01 sago007 2017-03-15 17:56 106
    template <bool, typename, typename> friend class GenericMemberIterator;
6c5f2c01 sago007 2017-03-15 17:56 107
6c5f2c01 sago007 2017-03-15 17:56 108
    typedef GenericMember<Encoding,Allocator> PlainType;
6c5f2c01 sago007 2017-03-15 17:56 109
    typedef typename internal::MaybeAddConst<Const,PlainType>::Type ValueType;
6c5f2c01 sago007 2017-03-15 17:56 110
    typedef std::iterator<std::random_access_iterator_tag,ValueType> BaseType;
6c5f2c01 sago007 2017-03-15 17:56 111
6c5f2c01 sago007 2017-03-15 17:56 112
public:
6c5f2c01 sago007 2017-03-15 17:56 113
    //! Iterator type itself
6c5f2c01 sago007 2017-03-15 17:56 114
    typedef GenericMemberIterator Iterator;
6c5f2c01 sago007 2017-03-15 17:56 115
    //! Constant iterator type
6c5f2c01 sago007 2017-03-15 17:56 116
    typedef GenericMemberIterator<true,Encoding,Allocator>  ConstIterator;
6c5f2c01 sago007 2017-03-15 17:56 117
    //! Non-constant iterator type
6c5f2c01 sago007 2017-03-15 17:56 118
    typedef GenericMemberIterator<false,Encoding,Allocator> NonConstIterator;
6c5f2c01 sago007 2017-03-15 17:56 119
6c5f2c01 sago007 2017-03-15 17:56 120
    //! Pointer to (const) GenericMember
6c5f2c01 sago007 2017-03-15 17:56 121
    typedef typename BaseType::pointer         Pointer;
6c5f2c01 sago007 2017-03-15 17:56 122
    //! Reference to (const) GenericMember
6c5f2c01 sago007 2017-03-15 17:56 123
    typedef typename BaseType::reference       Reference;
6c5f2c01 sago007 2017-03-15 17:56 124
    //! Signed integer type (e.g. \c ptrdiff_t)
6c5f2c01 sago007 2017-03-15 17:56 125
    typedef typename BaseType::difference_type DifferenceType;
6c5f2c01 sago007 2017-03-15 17:56 126
6c5f2c01 sago007 2017-03-15 17:56 127
    //! Default constructor (singular value)
6c5f2c01 sago007 2017-03-15 17:56 128
    /*! Creates an iterator pointing to no element.
6c5f2c01 sago007 2017-03-15 17:56 129
        \note All operations, except for comparisons, are undefined on such values.
6c5f2c01 sago007 2017-03-15 17:56 130
     */
6c5f2c01 sago007 2017-03-15 17:56 131
    GenericMemberIterator() : ptr_() {}
6c5f2c01 sago007 2017-03-15 17:56 132
6c5f2c01 sago007 2017-03-15 17:56 133
    //! Iterator conversions to more const
6c5f2c01 sago007 2017-03-15 17:56 134
    /*!
6c5f2c01 sago007 2017-03-15 17:56 135
        \param it (Non-const) iterator to copy from
6c5f2c01 sago007 2017-03-15 17:56 136
6c5f2c01 sago007 2017-03-15 17:56 137
        Allows the creation of an iterator from another GenericMemberIterator
6c5f2c01 sago007 2017-03-15 17:56 138
        that is "less const".  Especially, creating a non-constant iterator
6c5f2c01 sago007 2017-03-15 17:56 139
        from a constant iterator are disabled:
6c5f2c01 sago007 2017-03-15 17:56 140
        \li const -> non-const (not ok)
6c5f2c01 sago007 2017-03-15 17:56 141
        \li const -> const (ok)
6c5f2c01 sago007 2017-03-15 17:56 142
        \li non-const -> const (ok)
6c5f2c01 sago007 2017-03-15 17:56 143
        \li non-const -> non-const (ok)
6c5f2c01 sago007 2017-03-15 17:56 144
6c5f2c01 sago007 2017-03-15 17:56 145
        \note If the \c Const template parameter is already \c false, this
6c5f2c01 sago007 2017-03-15 17:56 146
            constructor effectively defines a regular copy-constructor.
6c5f2c01 sago007 2017-03-15 17:56 147
            Otherwise, the copy constructor is implicitly defined.
6c5f2c01 sago007 2017-03-15 17:56 148
    */
6c5f2c01 sago007 2017-03-15 17:56 149
    GenericMemberIterator(const NonConstIterator & it) : ptr_(it.ptr_) {}
6c5f2c01 sago007 2017-03-15 17:56 150
    Iterator& operator=(const NonConstIterator & it) { ptr_ = it.ptr_; return *this; }
6c5f2c01 sago007 2017-03-15 17:56 151
6c5f2c01 sago007 2017-03-15 17:56 152
    //! @name stepping
6c5f2c01 sago007 2017-03-15 17:56 153
    //@{
6c5f2c01 sago007 2017-03-15 17:56 154
    Iterator& operator++(){ ++ptr_; return *this; }
6c5f2c01 sago007 2017-03-15 17:56 155
    Iterator& operator--(){ --ptr_; return *this; }
6c5f2c01 sago007 2017-03-15 17:56 156
    Iterator  operator++(int){ Iterator old(*this); ++ptr_; return old; }
6c5f2c01 sago007 2017-03-15 17:56 157
    Iterator  operator--(int){ Iterator old(*this); --ptr_; return old; }
6c5f2c01 sago007 2017-03-15 17:56 158
    //@}
6c5f2c01 sago007 2017-03-15 17:56 159
6c5f2c01 sago007 2017-03-15 17:56 160
    //! @name increment/decrement
6c5f2c01 sago007 2017-03-15 17:56 161
    //@{
6c5f2c01 sago007 2017-03-15 17:56 162
    Iterator operator+(DifferenceType n) const { return Iterator(ptr_+n); }
6c5f2c01 sago007 2017-03-15 17:56 163
    Iterator operator-(DifferenceType n) const { return Iterator(ptr_-n); }
6c5f2c01 sago007 2017-03-15 17:56 164
6c5f2c01 sago007 2017-03-15 17:56 165
    Iterator& operator+=(DifferenceType n) { ptr_+=n; return *this; }
6c5f2c01 sago007 2017-03-15 17:56 166
    Iterator& operator-=(DifferenceType n) { ptr_-=n; return *this; }
6c5f2c01 sago007 2017-03-15 17:56 167
    //@}
6c5f2c01 sago007 2017-03-15 17:56 168
6c5f2c01 sago007 2017-03-15 17:56 169
    //! @name relations
6c5f2c01 sago007 2017-03-15 17:56 170
    //@{
6c5f2c01 sago007 2017-03-15 17:56 171
    bool operator==(ConstIterator that) const { return ptr_ == that.ptr_; }
6c5f2c01 sago007 2017-03-15 17:56 172
    bool operator!=(ConstIterator that) const { return ptr_ != that.ptr_; }
6c5f2c01 sago007 2017-03-15 17:56 173
    bool operator<=(ConstIterator that) const { return ptr_ <= that.ptr_; }
6c5f2c01 sago007 2017-03-15 17:56 174
    bool operator>=(ConstIterator that) const { return ptr_ >= that.ptr_; }
6c5f2c01 sago007 2017-03-15 17:56 175
    bool operator< (ConstIterator that) const { return ptr_ < that.ptr_; }
6c5f2c01 sago007 2017-03-15 17:56 176
    bool operator> (ConstIterator that) const { return ptr_ > that.ptr_; }
6c5f2c01 sago007 2017-03-15 17:56 177
    //@}
6c5f2c01 sago007 2017-03-15 17:56 178
6c5f2c01 sago007 2017-03-15 17:56 179
    //! @name dereference
6c5f2c01 sago007 2017-03-15 17:56 180
    //@{
6c5f2c01 sago007 2017-03-15 17:56 181
    Reference operator*() const { return *ptr_; }
6c5f2c01 sago007 2017-03-15 17:56 182
    Pointer   operator->() const { return ptr_; }
6c5f2c01 sago007 2017-03-15 17:56 183
    Reference operator[](DifferenceType n) const { return ptr_[n]; }
6c5f2c01 sago007 2017-03-15 17:56 184
    //@}
6c5f2c01 sago007 2017-03-15 17:56 185
6c5f2c01 sago007 2017-03-15 17:56 186
    //! Distance
6c5f2c01 sago007 2017-03-15 17:56 187
    DifferenceType operator-(ConstIterator that) const { return ptr_-that.ptr_; }
6c5f2c01 sago007 2017-03-15 17:56 188
6c5f2c01 sago007 2017-03-15 17:56 189
private:
6c5f2c01 sago007 2017-03-15 17:56 190
    //! Internal constructor from plain pointer
6c5f2c01 sago007 2017-03-15 17:56 191
    explicit GenericMemberIterator(Pointer p) : ptr_(p) {}
6c5f2c01 sago007 2017-03-15 17:56 192
6c5f2c01 sago007 2017-03-15 17:56 193
    Pointer ptr_; //!< raw pointer
6c5f2c01 sago007 2017-03-15 17:56 194
};
6c5f2c01 sago007 2017-03-15 17:56 195
6c5f2c01 sago007 2017-03-15 17:56 196
#else // CEREAL_RAPIDJSON_NOMEMBERITERATORCLASS
6c5f2c01 sago007 2017-03-15 17:56 197
6c5f2c01 sago007 2017-03-15 17:56 198
// class-based member iterator implementation disabled, use plain pointers
6c5f2c01 sago007 2017-03-15 17:56 199
6c5f2c01 sago007 2017-03-15 17:56 200
template <bool Const, typename Encoding, typename Allocator>
6c5f2c01 sago007 2017-03-15 17:56 201
struct GenericMemberIterator;
6c5f2c01 sago007 2017-03-15 17:56 202
6c5f2c01 sago007 2017-03-15 17:56 203
//! non-const GenericMemberIterator
6c5f2c01 sago007 2017-03-15 17:56 204
template <typename Encoding, typename Allocator>
6c5f2c01 sago007 2017-03-15 17:56 205
struct GenericMemberIterator<false,Encoding,Allocator> {
6c5f2c01 sago007 2017-03-15 17:56 206
    //! use plain pointer as iterator type
6c5f2c01 sago007 2017-03-15 17:56 207
    typedef GenericMember<Encoding,Allocator>* Iterator;
6c5f2c01 sago007 2017-03-15 17:56 208
};
6c5f2c01 sago007 2017-03-15 17:56 209
//! const GenericMemberIterator
6c5f2c01 sago007 2017-03-15 17:56 210
template <typename Encoding, typename Allocator>
6c5f2c01 sago007 2017-03-15 17:56 211
struct GenericMemberIterator<true,Encoding,Allocator> {
6c5f2c01 sago007 2017-03-15 17:56 212
    //! use plain const pointer as iterator type
6c5f2c01 sago007 2017-03-15 17:56 213
    typedef const GenericMember<Encoding,Allocator>* Iterator;
6c5f2c01 sago007 2017-03-15 17:56 214
};
6c5f2c01 sago007 2017-03-15 17:56 215
6c5f2c01 sago007 2017-03-15 17:56 216
#endif // CEREAL_RAPIDJSON_NOMEMBERITERATORCLASS
6c5f2c01 sago007 2017-03-15 17:56 217
6c5f2c01 sago007 2017-03-15 17:56 218
///////////////////////////////////////////////////////////////////////////////
6c5f2c01 sago007 2017-03-15 17:56 219
// GenericStringRef
6c5f2c01 sago007 2017-03-15 17:56 220
6c5f2c01 sago007 2017-03-15 17:56 221
//! Reference to a constant string (not taking a copy)
6c5f2c01 sago007 2017-03-15 17:56 222
/*!
6c5f2c01 sago007 2017-03-15 17:56 223
    \tparam CharType character type of the string
6c5f2c01 sago007 2017-03-15 17:56 224
6c5f2c01 sago007 2017-03-15 17:56 225
    This helper class is used to automatically infer constant string
6c5f2c01 sago007 2017-03-15 17:56 226
    references for string literals, especially from \c const \b (!)
6c5f2c01 sago007 2017-03-15 17:56 227
    character arrays.
6c5f2c01 sago007 2017-03-15 17:56 228
6c5f2c01 sago007 2017-03-15 17:56 229
    The main use is for creating JSON string values without copying the
6c5f2c01 sago007 2017-03-15 17:56 230
    source string via an \ref Allocator.  This requires that the referenced
6c5f2c01 sago007 2017-03-15 17:56 231
    string pointers have a sufficient lifetime, which exceeds the lifetime
6c5f2c01 sago007 2017-03-15 17:56 232
    of the associated GenericValue.
6c5f2c01 sago007 2017-03-15 17:56 233
6c5f2c01 sago007 2017-03-15 17:56 234
    \b Example
6c5f2c01 sago007 2017-03-15 17:56 235
    \code
6c5f2c01 sago007 2017-03-15 17:56 236
    Value v("foo");   // ok, no need to copy & calculate length
6c5f2c01 sago007 2017-03-15 17:56 237
    const char foo[] = "foo";
6c5f2c01 sago007 2017-03-15 17:56 238
    v.SetString(foo); // ok
6c5f2c01 sago007 2017-03-15 17:56 239
6c5f2c01 sago007 2017-03-15 17:56 240
    const char* bar = foo;
6c5f2c01 sago007 2017-03-15 17:56 241
    // Value x(bar); // not ok, can't rely on bar's lifetime
6c5f2c01 sago007 2017-03-15 17:56 242
    Value x(StringRef(bar)); // lifetime explicitly guaranteed by user
6c5f2c01 sago007 2017-03-15 17:56 243
    Value y(StringRef(bar, 3));  // ok, explicitly pass length
6c5f2c01 sago007 2017-03-15 17:56 244
    \endcode
6c5f2c01 sago007 2017-03-15 17:56 245
6c5f2c01 sago007 2017-03-15 17:56 246
    \see StringRef, GenericValue::SetString
6c5f2c01 sago007 2017-03-15 17:56 247
*/
6c5f2c01 sago007 2017-03-15 17:56 248
template<typename CharType>
6c5f2c01 sago007 2017-03-15 17:56 249
struct GenericStringRef {
6c5f2c01 sago007 2017-03-15 17:56 250
    typedef CharType Ch; //!< character type of the string
6c5f2c01 sago007 2017-03-15 17:56 251
6c5f2c01 sago007 2017-03-15 17:56 252
    //! Create string reference from \c const character array
6c5f2c01 sago007 2017-03-15 17:56 253
#ifndef __clang__ // -Wdocumentation
6c5f2c01 sago007 2017-03-15 17:56 254
    /*!
6c5f2c01 sago007 2017-03-15 17:56 255
        This constructor implicitly creates a constant string reference from
6c5f2c01 sago007 2017-03-15 17:56 256
        a \c const character array.  It has better performance than
6c5f2c01 sago007 2017-03-15 17:56 257
        \ref StringRef(const CharType*) by inferring the string \ref length
6c5f2c01 sago007 2017-03-15 17:56 258
        from the array length, and also supports strings containing null
6c5f2c01 sago007 2017-03-15 17:56 259
        characters.
6c5f2c01 sago007 2017-03-15 17:56 260
6c5f2c01 sago007 2017-03-15 17:56 261
        \tparam N length of the string, automatically inferred
6c5f2c01 sago007 2017-03-15 17:56 262
6c5f2c01 sago007 2017-03-15 17:56 263
        \param str Constant character array, lifetime assumed to be longer
6c5f2c01 sago007 2017-03-15 17:56 264
            than the use of the string in e.g. a GenericValue
6c5f2c01 sago007 2017-03-15 17:56 265
6c5f2c01 sago007 2017-03-15 17:56 266
        \post \ref s == str
6c5f2c01 sago007 2017-03-15 17:56 267
6c5f2c01 sago007 2017-03-15 17:56 268
        \note Constant complexity.
6c5f2c01 sago007 2017-03-15 17:56 269
        \note There is a hidden, private overload to disallow references to
6c5f2c01 sago007 2017-03-15 17:56 270
            non-const character arrays to be created via this constructor.
6c5f2c01 sago007 2017-03-15 17:56 271
            By this, e.g. function-scope arrays used to be filled via
6c5f2c01 sago007 2017-03-15 17:56 272
            \c snprintf are excluded from consideration.
6c5f2c01 sago007 2017-03-15 17:56 273
            In such cases, the referenced string should be \b copied to the
6c5f2c01 sago007 2017-03-15 17:56 274
            GenericValue instead.
6c5f2c01 sago007 2017-03-15 17:56 275
     */
6c5f2c01 sago007 2017-03-15 17:56 276
#endif
6c5f2c01 sago007 2017-03-15 17:56 277
    template<SizeType N>
6c5f2c01 sago007 2017-03-15 17:56 278
    GenericStringRef(const CharType (&str)[N]) CEREAL_RAPIDJSON_NOEXCEPT
6c5f2c01 sago007 2017-03-15 17:56 279
        : s(str), length(N-1) {}
6c5f2c01 sago007 2017-03-15 17:56 280
6c5f2c01 sago007 2017-03-15 17:56 281
    //! Explicitly create string reference from \c const character pointer
6c5f2c01 sago007 2017-03-15 17:56 282
#ifndef __clang__ // -Wdocumentation
6c5f2c01 sago007 2017-03-15 17:56 283
    /*!
6c5f2c01 sago007 2017-03-15 17:56 284
        This constructor can be used to \b explicitly  create a reference to
6c5f2c01 sago007 2017-03-15 17:56 285
        a constant string pointer.
6c5f2c01 sago007 2017-03-15 17:56 286
6c5f2c01 sago007 2017-03-15 17:56 287
        \see StringRef(const CharType*)
6c5f2c01 sago007 2017-03-15 17:56 288
6c5f2c01 sago007 2017-03-15 17:56 289
        \param str Constant character pointer, lifetime assumed to be longer
6c5f2c01 sago007 2017-03-15 17:56 290
            than the use of the string in e.g. a GenericValue
6c5f2c01 sago007 2017-03-15 17:56 291
6c5f2c01 sago007 2017-03-15 17:56 292
        \post \ref s == str
6c5f2c01 sago007 2017-03-15 17:56 293
6c5f2c01 sago007 2017-03-15 17:56 294
        \note There is a hidden, private overload to disallow references to
6c5f2c01 sago007 2017-03-15 17:56 295
            non-const character arrays to be created via this constructor.
6c5f2c01 sago007 2017-03-15 17:56 296
            By this, e.g. function-scope arrays used to be filled via
6c5f2c01 sago007 2017-03-15 17:56 297
            \c snprintf are excluded from consideration.
6c5f2c01 sago007 2017-03-15 17:56 298
            In such cases, the referenced string should be \b copied to the
6c5f2c01 sago007 2017-03-15 17:56 299
            GenericValue instead.
6c5f2c01 sago007 2017-03-15 17:56 300
     */
6c5f2c01 sago007 2017-03-15 17:56 301
#endif
6c5f2c01 sago007 2017-03-15 17:56 302
    explicit GenericStringRef(const CharType* str)
6c5f2c01 sago007 2017-03-15 17:56 303
        : s(str), length(internal::StrLen(str)){ CEREAL_RAPIDJSON_ASSERT(s != 0); }
6c5f2c01 sago007 2017-03-15 17:56 304
6c5f2c01 sago007 2017-03-15 17:56 305
    //! Create constant string reference from pointer and length
6c5f2c01 sago007 2017-03-15 17:56 306
#ifndef __clang__ // -Wdocumentation
6c5f2c01 sago007 2017-03-15 17:56 307
    /*! \param str constant string, lifetime assumed to be longer than the use of the string in e.g. a GenericValue
6c5f2c01 sago007 2017-03-15 17:56 308
        \param len length of the string, excluding the trailing NULL terminator
6c5f2c01 sago007 2017-03-15 17:56 309
6c5f2c01 sago007 2017-03-15 17:56 310
        \post \ref s == str && \ref length == len
6c5f2c01 sago007 2017-03-15 17:56 311
        \note Constant complexity.
6c5f2c01 sago007 2017-03-15 17:56 312
     */
6c5f2c01 sago007 2017-03-15 17:56 313
#endif
6c5f2c01 sago007 2017-03-15 17:56 314
    GenericStringRef(const CharType* str, SizeType len)
6c5f2c01 sago007 2017-03-15 17:56 315
        : s(str), length(len) { CEREAL_RAPIDJSON_ASSERT(s != 0); }
6c5f2c01 sago007 2017-03-15 17:56 316
6c5f2c01 sago007 2017-03-15 17:56 317
    GenericStringRef(const GenericStringRef& rhs) : s(rhs.s), length(rhs.length) {}
6c5f2c01 sago007 2017-03-15 17:56 318
6c5f2c01 sago007 2017-03-15 17:56 319
    GenericStringRef& operator=(const GenericStringRef& rhs) { s = rhs.s; length = rhs.length; }
6c5f2c01 sago007 2017-03-15 17:56 320
6c5f2c01 sago007 2017-03-15 17:56 321
    //! implicit conversion to plain CharType pointer
6c5f2c01 sago007 2017-03-15 17:56 322
    operator const Ch *() const { return s; }
6c5f2c01 sago007 2017-03-15 17:56 323
6c5f2c01 sago007 2017-03-15 17:56 324
    const Ch* const s; //!< plain CharType pointer
6c5f2c01 sago007 2017-03-15 17:56 325
    const SizeType length; //!< length of the string (excluding the trailing NULL terminator)
6c5f2c01 sago007 2017-03-15 17:56 326
6c5f2c01 sago007 2017-03-15 17:56 327
private:
6c5f2c01 sago007 2017-03-15 17:56 328
    //! Disallow construction from non-const array
6c5f2c01 sago007 2017-03-15 17:56 329
    template<SizeType N>
6c5f2c01 sago007 2017-03-15 17:56 330
    GenericStringRef(CharType (&str)[N]) /* = delete */;
6c5f2c01 sago007 2017-03-15 17:56 331
};
6c5f2c01 sago007 2017-03-15 17:56 332
6c5f2c01 sago007 2017-03-15 17:56 333
//! Mark a character pointer as constant string
6c5f2c01 sago007 2017-03-15 17:56 334
/*! Mark a plain character pointer as a "string literal".  This function
6c5f2c01 sago007 2017-03-15 17:56 335
    can be used to avoid copying a character string to be referenced as a
6c5f2c01 sago007 2017-03-15 17:56 336
    value in a JSON GenericValue object, if the string's lifetime is known
6c5f2c01 sago007 2017-03-15 17:56 337
    to be valid long enough.
6c5f2c01 sago007 2017-03-15 17:56 338
    \tparam CharType Character type of the string
6c5f2c01 sago007 2017-03-15 17:56 339
    \param str Constant string, lifetime assumed to be longer than the use of the string in e.g. a GenericValue
6c5f2c01 sago007 2017-03-15 17:56 340
    \return GenericStringRef string reference object
6c5f2c01 sago007 2017-03-15 17:56 341
    \relatesalso GenericStringRef
6c5f2c01 sago007 2017-03-15 17:56 342
6c5f2c01 sago007 2017-03-15 17:56 343
    \see GenericValue::GenericValue(StringRefType), GenericValue::operator=(StringRefType), GenericValue::SetString(StringRefType), GenericValue::PushBack(StringRefType, Allocator&), GenericValue::AddMember
6c5f2c01 sago007 2017-03-15 17:56 344
*/
6c5f2c01 sago007 2017-03-15 17:56 345
template<typename CharType>
6c5f2c01 sago007 2017-03-15 17:56 346
inline GenericStringRef<CharType> StringRef(const CharType* str) {
6c5f2c01 sago007 2017-03-15 17:56 347
    return GenericStringRef<CharType>(str, internal::StrLen(str));
6c5f2c01 sago007 2017-03-15 17:56 348
}
6c5f2c01 sago007 2017-03-15 17:56 349
6c5f2c01 sago007 2017-03-15 17:56 350
//! Mark a character pointer as constant string
6c5f2c01 sago007 2017-03-15 17:56 351
/*! Mark a plain character pointer as a "string literal".  This function
6c5f2c01 sago007 2017-03-15 17:56 352
    can be used to avoid copying a character string to be referenced as a
6c5f2c01 sago007 2017-03-15 17:56 353
    value in a JSON GenericValue object, if the string's lifetime is known
6c5f2c01 sago007 2017-03-15 17:56 354
    to be valid long enough.
6c5f2c01 sago007 2017-03-15 17:56 355
6c5f2c01 sago007 2017-03-15 17:56 356
    This version has better performance with supplied length, and also
6c5f2c01 sago007 2017-03-15 17:56 357
    supports string containing null characters.
6c5f2c01 sago007 2017-03-15 17:56 358
6c5f2c01 sago007 2017-03-15 17:56 359
    \tparam CharType character type of the string
6c5f2c01 sago007 2017-03-15 17:56 360
    \param str Constant string, lifetime assumed to be longer than the use of the string in e.g. a GenericValue
6c5f2c01 sago007 2017-03-15 17:56 361
    \param length The length of source string.
6c5f2c01 sago007 2017-03-15 17:56 362
    \return GenericStringRef string reference object
6c5f2c01 sago007 2017-03-15 17:56 363
    \relatesalso GenericStringRef
6c5f2c01 sago007 2017-03-15 17:56 364
*/
6c5f2c01 sago007 2017-03-15 17:56 365
template<typename CharType>
6c5f2c01 sago007 2017-03-15 17:56 366
inline GenericStringRef<CharType> StringRef(const CharType* str, size_t length) {
6c5f2c01 sago007 2017-03-15 17:56 367
    return GenericStringRef<CharType>(str, SizeType(length));
6c5f2c01 sago007 2017-03-15 17:56 368
}
6c5f2c01 sago007 2017-03-15 17:56 369
6c5f2c01 sago007 2017-03-15 17:56 370
#if CEREAL_RAPIDJSON_HAS_STDSTRING
6c5f2c01 sago007 2017-03-15 17:56 371
//! Mark a string object as constant string
6c5f2c01 sago007 2017-03-15 17:56 372
/*! Mark a string object (e.g. \c std::string) as a "string literal".
6c5f2c01 sago007 2017-03-15 17:56 373
    This function can be used to avoid copying a string to be referenced as a
6c5f2c01 sago007 2017-03-15 17:56 374
    value in a JSON GenericValue object, if the string's lifetime is known
6c5f2c01 sago007 2017-03-15 17:56 375
    to be valid long enough.
6c5f2c01 sago007 2017-03-15 17:56 376
6c5f2c01 sago007 2017-03-15 17:56 377
    \tparam CharType character type of the string
6c5f2c01 sago007 2017-03-15 17:56 378
    \param str Constant string, lifetime assumed to be longer than the use of the string in e.g. a GenericValue
6c5f2c01 sago007 2017-03-15 17:56 379
    \return GenericStringRef string reference object
6c5f2c01 sago007 2017-03-15 17:56 380
    \relatesalso GenericStringRef
6c5f2c01 sago007 2017-03-15 17:56 381
    \note Requires the definition of the preprocessor symbol \ref CEREAL_RAPIDJSON_HAS_STDSTRING.
6c5f2c01 sago007 2017-03-15 17:56 382
*/
6c5f2c01 sago007 2017-03-15 17:56 383
template<typename CharType>
6c5f2c01 sago007 2017-03-15 17:56 384
inline GenericStringRef<CharType> StringRef(const std::basic_string<CharType>& str) {
6c5f2c01 sago007 2017-03-15 17:56 385
    return GenericStringRef<CharType>(str.data(), SizeType(str.size()));
6c5f2c01 sago007 2017-03-15 17:56 386
}
6c5f2c01 sago007 2017-03-15 17:56 387
#endif
6c5f2c01 sago007 2017-03-15 17:56 388
6c5f2c01 sago007 2017-03-15 17:56 389
///////////////////////////////////////////////////////////////////////////////
6c5f2c01 sago007 2017-03-15 17:56 390
// GenericValue type traits
6c5f2c01 sago007 2017-03-15 17:56 391
namespace internal {
6c5f2c01 sago007 2017-03-15 17:56 392
6c5f2c01 sago007 2017-03-15 17:56 393
template <typename T, typename Encoding = void, typename Allocator = void>
6c5f2c01 sago007 2017-03-15 17:56 394
struct IsGenericValueImpl : FalseType {};
6c5f2c01 sago007 2017-03-15 17:56 395
6c5f2c01 sago007 2017-03-15 17:56 396
// select candidates according to nested encoding and allocator types
6c5f2c01 sago007 2017-03-15 17:56 397
template <typename T> struct IsGenericValueImpl<T, typename Void<typename T::EncodingType>::Type, typename Void<typename T::AllocatorType>::Type>
6c5f2c01 sago007 2017-03-15 17:56 398
    : IsBaseOf<GenericValue<typename T::EncodingType, typename T::AllocatorType>, T>::Type {};
6c5f2c01 sago007 2017-03-15 17:56 399
6c5f2c01 sago007 2017-03-15 17:56 400
// helper to match arbitrary GenericValue instantiations, including derived classes
6c5f2c01 sago007 2017-03-15 17:56 401
template <typename T> struct IsGenericValue : IsGenericValueImpl<T>::Type {};
6c5f2c01 sago007 2017-03-15 17:56 402
6c5f2c01 sago007 2017-03-15 17:56 403
} // namespace internal
6c5f2c01 sago007 2017-03-15 17:56 404
6c5f2c01 sago007 2017-03-15 17:56 405
///////////////////////////////////////////////////////////////////////////////
6c5f2c01 sago007 2017-03-15 17:56 406
// TypeHelper
6c5f2c01 sago007 2017-03-15 17:56 407
6c5f2c01 sago007 2017-03-15 17:56 408
namespace internal {
6c5f2c01 sago007 2017-03-15 17:56 409
6c5f2c01 sago007 2017-03-15 17:56 410
template <typename ValueType, typename T>
6c5f2c01 sago007 2017-03-15 17:56 411
struct TypeHelper {};
6c5f2c01 sago007 2017-03-15 17:56 412
6c5f2c01 sago007 2017-03-15 17:56 413
template<typename ValueType> 
6c5f2c01 sago007 2017-03-15 17:56 414
struct TypeHelper<ValueType, bool> {
6c5f2c01 sago007 2017-03-15 17:56 415
    static bool Is(const ValueType& v) { return v.IsBool(); }
6c5f2c01 sago007 2017-03-15 17:56 416
    static bool Get(const ValueType& v) { return v.GetBool(); }
6c5f2c01 sago007 2017-03-15 17:56 417
    static ValueType& Set(ValueType& v, bool data) { return v.SetBool(data); }
6c5f2c01 sago007 2017-03-15 17:56 418
    static ValueType& Set(ValueType& v, bool data, typename ValueType::AllocatorType&) { return v.SetBool(data); }
6c5f2c01 sago007 2017-03-15 17:56 419
};
6c5f2c01 sago007 2017-03-15 17:56 420
6c5f2c01 sago007 2017-03-15 17:56 421
template<typename ValueType> 
6c5f2c01 sago007 2017-03-15 17:56 422
struct TypeHelper<ValueType, int> {
6c5f2c01 sago007 2017-03-15 17:56 423
    static bool Is(const ValueType& v) { return v.IsInt(); }
6c5f2c01 sago007 2017-03-15 17:56 424
    static int Get(const ValueType& v) { return v.GetInt(); }
6c5f2c01 sago007 2017-03-15 17:56 425
    static ValueType& Set(ValueType& v, int data) { return v.SetInt(data); }
6c5f2c01 sago007 2017-03-15 17:56 426
    static ValueType& Set(ValueType& v, int data, typename ValueType::AllocatorType&) { return v.SetInt(data); }
6c5f2c01 sago007 2017-03-15 17:56 427
};
6c5f2c01 sago007 2017-03-15 17:56 428
6c5f2c01 sago007 2017-03-15 17:56 429
template<typename ValueType> 
6c5f2c01 sago007 2017-03-15 17:56 430
struct TypeHelper<ValueType, unsigned> {
6c5f2c01 sago007 2017-03-15 17:56 431
    static bool Is(const ValueType& v) { return v.IsUint(); }
6c5f2c01 sago007 2017-03-15 17:56 432
    static unsigned Get(const ValueType& v) { return v.GetUint(); }
6c5f2c01 sago007 2017-03-15 17:56 433
    static ValueType& Set(ValueType& v, unsigned data) { return v.SetUint(data); }
6c5f2c01 sago007 2017-03-15 17:56 434
    static ValueType& Set(ValueType& v, unsigned data, typename ValueType::AllocatorType&) { return v.SetUint(data); }
6c5f2c01 sago007 2017-03-15 17:56 435
};
6c5f2c01 sago007 2017-03-15 17:56 436
6c5f2c01 sago007 2017-03-15 17:56 437
template<typename ValueType> 
6c5f2c01 sago007 2017-03-15 17:56 438
struct TypeHelper<ValueType, int64_t> {
6c5f2c01 sago007 2017-03-15 17:56 439
    static bool Is(const ValueType& v) { return v.IsInt64(); }
6c5f2c01 sago007 2017-03-15 17:56 440
    static int64_t Get(const ValueType& v) { return v.GetInt64(); }
6c5f2c01 sago007 2017-03-15 17:56 441
    static ValueType& Set(ValueType& v, int64_t data) { return v.SetInt64(data); }
6c5f2c01 sago007 2017-03-15 17:56 442
    static ValueType& Set(ValueType& v, int64_t data, typename ValueType::AllocatorType&) { return v.SetInt64(data); }
6c5f2c01 sago007 2017-03-15 17:56 443
};
6c5f2c01 sago007 2017-03-15 17:56 444
6c5f2c01 sago007 2017-03-15 17:56 445
template<typename ValueType> 
6c5f2c01 sago007 2017-03-15 17:56 446
struct TypeHelper<ValueType, uint64_t> {
6c5f2c01 sago007 2017-03-15 17:56 447
    static bool Is(const ValueType& v) { return v.IsUint64(); }
6c5f2c01 sago007 2017-03-15 17:56 448
    static uint64_t Get(const ValueType& v) { return v.GetUint64(); }
6c5f2c01 sago007 2017-03-15 17:56 449
    static ValueType& Set(ValueType& v, uint64_t data) { return v.SetUint64(data); }
6c5f2c01 sago007 2017-03-15 17:56 450
    static ValueType& Set(ValueType& v, uint64_t data, typename ValueType::AllocatorType&) { return v.SetUint64(data); }
6c5f2c01 sago007 2017-03-15 17:56 451
};
6c5f2c01 sago007 2017-03-15 17:56 452
6c5f2c01 sago007 2017-03-15 17:56 453
template<typename ValueType> 
6c5f2c01 sago007 2017-03-15 17:56 454
struct TypeHelper<ValueType, double> {
6c5f2c01 sago007 2017-03-15 17:56 455
    static bool Is(const ValueType& v) { return v.IsDouble(); }
6c5f2c01 sago007 2017-03-15 17:56 456
    static double Get(const ValueType& v) { return v.GetDouble(); }
6c5f2c01 sago007 2017-03-15 17:56 457
    static ValueType& Set(ValueType& v, double data) { return v.SetDouble(data); }
6c5f2c01 sago007 2017-03-15 17:56 458
    static ValueType& Set(ValueType& v, double data, typename ValueType::AllocatorType&) { return v.SetDouble(data); }
6c5f2c01 sago007 2017-03-15 17:56 459
};
6c5f2c01 sago007 2017-03-15 17:56 460
6c5f2c01 sago007 2017-03-15 17:56 461
template<typename ValueType> 
6c5f2c01 sago007 2017-03-15 17:56 462
struct TypeHelper<ValueType, float> {
6c5f2c01 sago007 2017-03-15 17:56 463
    static bool Is(const ValueType& v) { return v.IsFloat(); }
6c5f2c01 sago007 2017-03-15 17:56 464
    static float Get(const ValueType& v) { return v.GetFloat(); }
6c5f2c01 sago007 2017-03-15 17:56 465
    static ValueType& Set(ValueType& v, float data) { return v.SetFloat(data); }
6c5f2c01 sago007 2017-03-15 17:56 466
    static ValueType& Set(ValueType& v, float data, typename ValueType::AllocatorType&) { return v.SetFloat(data); }
6c5f2c01 sago007 2017-03-15 17:56 467
};
6c5f2c01 sago007 2017-03-15 17:56 468
6c5f2c01 sago007 2017-03-15 17:56 469
template<typename ValueType> 
6c5f2c01 sago007 2017-03-15 17:56 470
struct TypeHelper<ValueType, const typename ValueType::Ch*> {
6c5f2c01 sago007 2017-03-15 17:56 471
    typedef const typename ValueType::Ch* StringType;
6c5f2c01 sago007 2017-03-15 17:56 472
    static bool Is(const ValueType& v) { return v.IsString(); }
6c5f2c01 sago007 2017-03-15 17:56 473
    static StringType Get(const ValueType& v) { return v.GetString(); }
6c5f2c01 sago007 2017-03-15 17:56 474
    static ValueType& Set(ValueType& v, const StringType data) { return v.SetString(typename ValueType::StringRefType(data)); }
6c5f2c01 sago007 2017-03-15 17:56 475
    static ValueType& Set(ValueType& v, const StringType data, typename ValueType::AllocatorType& a) { return v.SetString(data, a); }
6c5f2c01 sago007 2017-03-15 17:56 476
};
6c5f2c01 sago007 2017-03-15 17:56 477
6c5f2c01 sago007 2017-03-15 17:56 478
#if CEREAL_RAPIDJSON_HAS_STDSTRING
6c5f2c01 sago007 2017-03-15 17:56 479
template<typename ValueType> 
6c5f2c01 sago007 2017-03-15 17:56 480
struct TypeHelper<ValueType, std::basic_string<typename ValueType::Ch> > {
6c5f2c01 sago007 2017-03-15 17:56 481
    typedef std::basic_string<typename ValueType::Ch> StringType;
6c5f2c01 sago007 2017-03-15 17:56 482
    static bool Is(const ValueType& v) { return v.IsString(); }
6c5f2c01 sago007 2017-03-15 17:56 483
    static StringType Get(const ValueType& v) { return StringType(v.GetString(), v.GetStringLength()); }
6c5f2c01 sago007 2017-03-15 17:56 484
    static ValueType& Set(ValueType& v, const StringType& data, typename ValueType::AllocatorType& a) { return v.SetString(data, a); }
6c5f2c01 sago007 2017-03-15 17:56 485
};
6c5f2c01 sago007 2017-03-15 17:56 486
#endif
6c5f2c01 sago007 2017-03-15 17:56 487
6c5f2c01 sago007 2017-03-15 17:56 488
template<typename ValueType> 
6c5f2c01 sago007 2017-03-15 17:56 489
struct TypeHelper<ValueType, typename ValueType::Array> {
6c5f2c01 sago007 2017-03-15 17:56 490
    typedef typename ValueType::Array ArrayType;
6c5f2c01 sago007 2017-03-15 17:56 491
    static bool Is(const ValueType& v) { return v.IsArray(); }
6c5f2c01 sago007 2017-03-15 17:56 492
    static ArrayType Get(ValueType& v) { return v.GetArray(); }
6c5f2c01 sago007 2017-03-15 17:56 493
    static ValueType& Set(ValueType& v, ArrayType data) { return v = data; }
6c5f2c01 sago007 2017-03-15 17:56 494
    static ValueType& Set(ValueType& v, ArrayType data, typename ValueType::AllocatorType&) { return v = data; }
6c5f2c01 sago007 2017-03-15 17:56 495
};
6c5f2c01 sago007 2017-03-15 17:56 496
6c5f2c01 sago007 2017-03-15 17:56 497
template<typename ValueType> 
6c5f2c01 sago007 2017-03-15 17:56 498
struct TypeHelper<ValueType, typename ValueType::ConstArray> {
6c5f2c01 sago007 2017-03-15 17:56 499
    typedef typename ValueType::ConstArray ArrayType;
6c5f2c01 sago007 2017-03-15 17:56 500
    static bool Is(const ValueType& v) { return v.IsArray(); }
6c5f2c01 sago007 2017-03-15 17:56 501
    static ArrayType Get(const ValueType& v) { return v.GetArray(); }
6c5f2c01 sago007 2017-03-15 17:56 502
};
6c5f2c01 sago007 2017-03-15 17:56 503
6c5f2c01 sago007 2017-03-15 17:56 504
template<typename ValueType> 
6c5f2c01 sago007 2017-03-15 17:56 505
struct TypeHelper<ValueType, typename ValueType::Object> {
6c5f2c01 sago007 2017-03-15 17:56 506
    typedef typename ValueType::Object ObjectType;
6c5f2c01 sago007 2017-03-15 17:56 507
    static bool Is(const ValueType& v) { return v.IsObject(); }
6c5f2c01 sago007 2017-03-15 17:56 508
    static ObjectType Get(ValueType& v) { return v.GetObject(); }
6c5f2c01 sago007 2017-03-15 17:56 509
    static ValueType& Set(ValueType& v, ObjectType data) { return v = data; }
6c5f2c01 sago007 2017-03-15 17:56 510
    static ValueType& Set(ValueType& v, ObjectType data, typename ValueType::AllocatorType&) { v = data; }
6c5f2c01 sago007 2017-03-15 17:56 511
};
6c5f2c01 sago007 2017-03-15 17:56 512
6c5f2c01 sago007 2017-03-15 17:56 513
template<typename ValueType> 
6c5f2c01 sago007 2017-03-15 17:56 514
struct TypeHelper<ValueType, typename ValueType::ConstObject> {
6c5f2c01 sago007 2017-03-15 17:56 515
    typedef typename ValueType::ConstObject ObjectType;
6c5f2c01 sago007 2017-03-15 17:56 516
    static bool Is(const ValueType& v) { return v.IsObject(); }
6c5f2c01 sago007 2017-03-15 17:56 517
    static ObjectType Get(const ValueType& v) { return v.GetObject(); }
6c5f2c01 sago007 2017-03-15 17:56 518
};
6c5f2c01 sago007 2017-03-15 17:56 519
6c5f2c01 sago007 2017-03-15 17:56 520
} // namespace internal
6c5f2c01 sago007 2017-03-15 17:56 521
6c5f2c01 sago007 2017-03-15 17:56 522
// Forward declarations
6c5f2c01 sago007 2017-03-15 17:56 523
template <bool, typename> class GenericArray;
6c5f2c01 sago007 2017-03-15 17:56 524
template <bool, typename> class GenericObject;
7a956470 sago007 2016-02-14 17:09 525
7a956470 sago007 2016-02-14 17:09 526
///////////////////////////////////////////////////////////////////////////////
7a956470 sago007 2016-02-14 17:09 527
// GenericValue
7a956470 sago007 2016-02-14 17:09 528
7a956470 sago007 2016-02-14 17:09 529
//! Represents a JSON value. Use Value for UTF8 encoding and default allocator.
7a956470 sago007 2016-02-14 17:09 530
/*!
6c5f2c01 sago007 2017-03-15 17:56 531
    A JSON value can be one of 7 types. This class is a variant type supporting
6c5f2c01 sago007 2017-03-15 17:56 532
    these types.
7a956470 sago007 2016-02-14 17:09 533
6c5f2c01 sago007 2017-03-15 17:56 534
    Use the Value if UTF8 and default allocator
7a956470 sago007 2016-02-14 17:09 535
6c5f2c01 sago007 2017-03-15 17:56 536
    \tparam Encoding    Encoding of the value. (Even non-string values need to have the same encoding in a document)
6c5f2c01 sago007 2017-03-15 17:56 537
    \tparam Allocator   Allocator type for allocating memory of object, array and string.
7a956470 sago007 2016-02-14 17:09 538
*/
6c5f2c01 sago007 2017-03-15 17:56 539
template <typename Encoding, typename Allocator = MemoryPoolAllocator<> > 
7a956470 sago007 2016-02-14 17:09 540
class GenericValue {
7a956470 sago007 2016-02-14 17:09 541
public:
6c5f2c01 sago007 2017-03-15 17:56 542
    //! Name-value pair in an object.
6c5f2c01 sago007 2017-03-15 17:56 543
    typedef GenericMember<Encoding, Allocator> Member;
6c5f2c01 sago007 2017-03-15 17:56 544
    typedef Encoding EncodingType;                  //!< Encoding type from template parameter.
6c5f2c01 sago007 2017-03-15 17:56 545
    typedef Allocator AllocatorType;                //!< Allocator type from template parameter.
6c5f2c01 sago007 2017-03-15 17:56 546
    typedef typename Encoding::Ch Ch;               //!< Character type derived from Encoding.
6c5f2c01 sago007 2017-03-15 17:56 547
    typedef GenericStringRef<Ch> StringRefType;     //!< Reference to a constant string
6c5f2c01 sago007 2017-03-15 17:56 548
    typedef typename GenericMemberIterator<false,Encoding,Allocator>::Iterator MemberIterator;  //!< Member iterator for iterating in object.
6c5f2c01 sago007 2017-03-15 17:56 549
    typedef typename GenericMemberIterator<true,Encoding,Allocator>::Iterator ConstMemberIterator;  //!< Constant member iterator for iterating in object.
6c5f2c01 sago007 2017-03-15 17:56 550
    typedef GenericValue* ValueIterator;            //!< Value iterator for iterating in array.
6c5f2c01 sago007 2017-03-15 17:56 551
    typedef const GenericValue* ConstValueIterator; //!< Constant value iterator for iterating in array.
6c5f2c01 sago007 2017-03-15 17:56 552
    typedef GenericValue<Encoding, Allocator> ValueType;    //!< Value type of itself.
6c5f2c01 sago007 2017-03-15 17:56 553
    typedef GenericArray<false, ValueType> Array;
6c5f2c01 sago007 2017-03-15 17:56 554
    typedef GenericArray<true, ValueType> ConstArray;
6c5f2c01 sago007 2017-03-15 17:56 555
    typedef GenericObject<false, ValueType> Object;
6c5f2c01 sago007 2017-03-15 17:56 556
    typedef GenericObject<true, ValueType> ConstObject;
6c5f2c01 sago007 2017-03-15 17:56 557
6c5f2c01 sago007 2017-03-15 17:56 558
    //!@name Constructors and destructor.
6c5f2c01 sago007 2017-03-15 17:56 559
    //@{
6c5f2c01 sago007 2017-03-15 17:56 560
6c5f2c01 sago007 2017-03-15 17:56 561
    //! Default constructor creates a null value.
6c5f2c01 sago007 2017-03-15 17:56 562
    GenericValue() CEREAL_RAPIDJSON_NOEXCEPT : data_() { data_.f.flags = kNullFlag; }
6c5f2c01 sago007 2017-03-15 17:56 563
6c5f2c01 sago007 2017-03-15 17:56 564
#if CEREAL_RAPIDJSON_HAS_CXX11_RVALUE_REFS
6c5f2c01 sago007 2017-03-15 17:56 565
    //! Move constructor in C++11
6c5f2c01 sago007 2017-03-15 17:56 566
    GenericValue(GenericValue&& rhs) CEREAL_RAPIDJSON_NOEXCEPT : data_(rhs.data_) {
6c5f2c01 sago007 2017-03-15 17:56 567
        rhs.data_.f.flags = kNullFlag; // give up contents
6c5f2c01 sago007 2017-03-15 17:56 568
    }
6c5f2c01 sago007 2017-03-15 17:56 569
#endif
6c5f2c01 sago007 2017-03-15 17:56 570
7a956470 sago007 2016-02-14 17:09 571
private:
6c5f2c01 sago007 2017-03-15 17:56 572
    //! Copy constructor is not permitted.
6c5f2c01 sago007 2017-03-15 17:56 573
    GenericValue(const GenericValue& rhs);
6c5f2c01 sago007 2017-03-15 17:56 574
6c5f2c01 sago007 2017-03-15 17:56 575
#if CEREAL_RAPIDJSON_HAS_CXX11_RVALUE_REFS
6c5f2c01 sago007 2017-03-15 17:56 576
    //! Moving from a GenericDocument is not permitted.
6c5f2c01 sago007 2017-03-15 17:56 577
    template <typename StackAllocator>
6c5f2c01 sago007 2017-03-15 17:56 578
    GenericValue(GenericDocument<Encoding,Allocator,StackAllocator>&& rhs);
6c5f2c01 sago007 2017-03-15 17:56 579
6c5f2c01 sago007 2017-03-15 17:56 580
    //! Move assignment from a GenericDocument is not permitted.
6c5f2c01 sago007 2017-03-15 17:56 581
    template <typename StackAllocator>
6c5f2c01 sago007 2017-03-15 17:56 582
    GenericValue& operator=(GenericDocument<Encoding,Allocator,StackAllocator>&& rhs);
6c5f2c01 sago007 2017-03-15 17:56 583
#endif
7a956470 sago007 2016-02-14 17:09 584
7a956470 sago007 2016-02-14 17:09 585
public:
7a956470 sago007 2016-02-14 17:09 586
6c5f2c01 sago007 2017-03-15 17:56 587
    //! Constructor with JSON value type.
6c5f2c01 sago007 2017-03-15 17:56 588
    /*! This creates a Value of specified type with default content.
6c5f2c01 sago007 2017-03-15 17:56 589
        \param type Type of the value.
6c5f2c01 sago007 2017-03-15 17:56 590
        \note Default content for number is zero.
6c5f2c01 sago007 2017-03-15 17:56 591
    */
6c5f2c01 sago007 2017-03-15 17:56 592
    explicit GenericValue(Type type) CEREAL_RAPIDJSON_NOEXCEPT : data_() {
6c5f2c01 sago007 2017-03-15 17:56 593
        static const uint16_t defaultFlags[7] = {
6c5f2c01 sago007 2017-03-15 17:56 594
            kNullFlag, kFalseFlag, kTrueFlag, kObjectFlag, kArrayFlag, kShortStringFlag,
6c5f2c01 sago007 2017-03-15 17:56 595
            kNumberAnyFlag
6c5f2c01 sago007 2017-03-15 17:56 596
        };
6c5f2c01 sago007 2017-03-15 17:56 597
        CEREAL_RAPIDJSON_ASSERT(type <= kNumberType);
6c5f2c01 sago007 2017-03-15 17:56 598
        data_.f.flags = defaultFlags[type];
6c5f2c01 sago007 2017-03-15 17:56 599
6c5f2c01 sago007 2017-03-15 17:56 600
        // Use ShortString to store empty string.
6c5f2c01 sago007 2017-03-15 17:56 601
        if (type == kStringType)
6c5f2c01 sago007 2017-03-15 17:56 602
            data_.ss.SetLength(0);
6c5f2c01 sago007 2017-03-15 17:56 603
    }
6c5f2c01 sago007 2017-03-15 17:56 604
6c5f2c01 sago007 2017-03-15 17:56 605
    //! Explicit copy constructor (with allocator)
6c5f2c01 sago007 2017-03-15 17:56 606
    /*! Creates a copy of a Value by using the given Allocator
6c5f2c01 sago007 2017-03-15 17:56 607
        \tparam SourceAllocator allocator of \c rhs
6c5f2c01 sago007 2017-03-15 17:56 608
        \param rhs Value to copy from (read-only)
6c5f2c01 sago007 2017-03-15 17:56 609
        \param allocator Allocator for allocating copied elements and buffers. Commonly use GenericDocument::GetAllocator().
6c5f2c01 sago007 2017-03-15 17:56 610
        \see CopyFrom()
6c5f2c01 sago007 2017-03-15 17:56 611
    */
6c5f2c01 sago007 2017-03-15 17:56 612
    template< typename SourceAllocator >
6c5f2c01 sago007 2017-03-15 17:56 613
    GenericValue(const GenericValue<Encoding, SourceAllocator>& rhs, Allocator & allocator);
6c5f2c01 sago007 2017-03-15 17:56 614
6c5f2c01 sago007 2017-03-15 17:56 615
    //! Constructor for boolean value.
6c5f2c01 sago007 2017-03-15 17:56 616
    /*! \param b Boolean value
6c5f2c01 sago007 2017-03-15 17:56 617
        \note This constructor is limited to \em real boolean values and rejects
6c5f2c01 sago007 2017-03-15 17:56 618
            implicitly converted types like arbitrary pointers.  Use an explicit cast
6c5f2c01 sago007 2017-03-15 17:56 619
            to \c bool, if you want to construct a boolean JSON value in such cases.
6c5f2c01 sago007 2017-03-15 17:56 620
     */
6c5f2c01 sago007 2017-03-15 17:56 621
#ifndef CEREAL_RAPIDJSON_DOXYGEN_RUNNING // hide SFINAE from Doxygen
6c5f2c01 sago007 2017-03-15 17:56 622
    template <typename T>
6c5f2c01 sago007 2017-03-15 17:56 623
    explicit GenericValue(T b, CEREAL_RAPIDJSON_ENABLEIF((internal::IsSame<bool, T>))) CEREAL_RAPIDJSON_NOEXCEPT  // See #472
6c5f2c01 sago007 2017-03-15 17:56 624
#else
6c5f2c01 sago007 2017-03-15 17:56 625
    explicit GenericValue(bool b) CEREAL_RAPIDJSON_NOEXCEPT
6c5f2c01 sago007 2017-03-15 17:56 626
#endif
6c5f2c01 sago007 2017-03-15 17:56 627
        : data_() {
6c5f2c01 sago007 2017-03-15 17:56 628
            // safe-guard against failing SFINAE
6c5f2c01 sago007 2017-03-15 17:56 629
            CEREAL_RAPIDJSON_STATIC_ASSERT((internal::IsSame<bool,T>::Value));
6c5f2c01 sago007 2017-03-15 17:56 630
            data_.f.flags = b ? kTrueFlag : kFalseFlag;
6c5f2c01 sago007 2017-03-15 17:56 631
    }
6c5f2c01 sago007 2017-03-15 17:56 632
6c5f2c01 sago007 2017-03-15 17:56 633
    //! Constructor for int value.
6c5f2c01 sago007 2017-03-15 17:56 634
    explicit GenericValue(int i) CEREAL_RAPIDJSON_NOEXCEPT : data_() {
6c5f2c01 sago007 2017-03-15 17:56 635
        data_.n.i64 = i;
6c5f2c01 sago007 2017-03-15 17:56 636
        data_.f.flags = (i >= 0) ? (kNumberIntFlag | kUintFlag | kUint64Flag) : kNumberIntFlag;
6c5f2c01 sago007 2017-03-15 17:56 637
    }
6c5f2c01 sago007 2017-03-15 17:56 638
6c5f2c01 sago007 2017-03-15 17:56 639
    //! Constructor for unsigned value.
6c5f2c01 sago007 2017-03-15 17:56 640
    explicit GenericValue(unsigned u) CEREAL_RAPIDJSON_NOEXCEPT : data_() {
6c5f2c01 sago007 2017-03-15 17:56 641
        data_.n.u64 = u; 
6c5f2c01 sago007 2017-03-15 17:56 642
        data_.f.flags = (u & 0x80000000) ? kNumberUintFlag : (kNumberUintFlag | kIntFlag | kInt64Flag);
6c5f2c01 sago007 2017-03-15 17:56 643
    }
6c5f2c01 sago007 2017-03-15 17:56 644
6c5f2c01 sago007 2017-03-15 17:56 645
    //! Constructor for int64_t value.
6c5f2c01 sago007 2017-03-15 17:56 646
    explicit GenericValue(int64_t i64) CEREAL_RAPIDJSON_NOEXCEPT : data_() {
6c5f2c01 sago007 2017-03-15 17:56 647
        data_.n.i64 = i64;
6c5f2c01 sago007 2017-03-15 17:56 648
        data_.f.flags = kNumberInt64Flag;
6c5f2c01 sago007 2017-03-15 17:56 649
        if (i64 >= 0) {
6c5f2c01 sago007 2017-03-15 17:56 650
            data_.f.flags |= kNumberUint64Flag;
6c5f2c01 sago007 2017-03-15 17:56 651
            if (!(static_cast<uint64_t>(i64) & CEREAL_RAPIDJSON_UINT64_C2(0xFFFFFFFF, 0x00000000)))
6c5f2c01 sago007 2017-03-15 17:56 652
                data_.f.flags |= kUintFlag;
6c5f2c01 sago007 2017-03-15 17:56 653
            if (!(static_cast<uint64_t>(i64) & CEREAL_RAPIDJSON_UINT64_C2(0xFFFFFFFF, 0x80000000)))
6c5f2c01 sago007 2017-03-15 17:56 654
                data_.f.flags |= kIntFlag;
6c5f2c01 sago007 2017-03-15 17:56 655
        }
6c5f2c01 sago007 2017-03-15 17:56 656
        else if (i64 >= static_cast<int64_t>(CEREAL_RAPIDJSON_UINT64_C2(0xFFFFFFFF, 0x80000000)))
6c5f2c01 sago007 2017-03-15 17:56 657
            data_.f.flags |= kIntFlag;
6c5f2c01 sago007 2017-03-15 17:56 658
    }
6c5f2c01 sago007 2017-03-15 17:56 659
6c5f2c01 sago007 2017-03-15 17:56 660
    //! Constructor for uint64_t value.
6c5f2c01 sago007 2017-03-15 17:56 661
    explicit GenericValue(uint64_t u64) CEREAL_RAPIDJSON_NOEXCEPT : data_() {
6c5f2c01 sago007 2017-03-15 17:56 662
        data_.n.u64 = u64;
6c5f2c01 sago007 2017-03-15 17:56 663
        data_.f.flags = kNumberUint64Flag;
6c5f2c01 sago007 2017-03-15 17:56 664
        if (!(u64 & CEREAL_RAPIDJSON_UINT64_C2(0x80000000, 0x00000000)))
6c5f2c01 sago007 2017-03-15 17:56 665
            data_.f.flags |= kInt64Flag;
6c5f2c01 sago007 2017-03-15 17:56 666
        if (!(u64 & CEREAL_RAPIDJSON_UINT64_C2(0xFFFFFFFF, 0x00000000)))
6c5f2c01 sago007 2017-03-15 17:56 667
            data_.f.flags |= kUintFlag;
6c5f2c01 sago007 2017-03-15 17:56 668
        if (!(u64 & CEREAL_RAPIDJSON_UINT64_C2(0xFFFFFFFF, 0x80000000)))
6c5f2c01 sago007 2017-03-15 17:56 669
            data_.f.flags |= kIntFlag;
6c5f2c01 sago007 2017-03-15 17:56 670
    }
6c5f2c01 sago007 2017-03-15 17:56 671
6c5f2c01 sago007 2017-03-15 17:56 672
    //! Constructor for double value.
6c5f2c01 sago007 2017-03-15 17:56 673
    explicit GenericValue(double d) CEREAL_RAPIDJSON_NOEXCEPT : data_() { data_.n.d = d; data_.f.flags = kNumberDoubleFlag; }
6c5f2c01 sago007 2017-03-15 17:56 674
6c5f2c01 sago007 2017-03-15 17:56 675
    //! Constructor for constant string (i.e. do not make a copy of string)
6c5f2c01 sago007 2017-03-15 17:56 676
    GenericValue(const Ch* s, SizeType length) CEREAL_RAPIDJSON_NOEXCEPT : data_() { SetStringRaw(StringRef(s, length)); }
6c5f2c01 sago007 2017-03-15 17:56 677
6c5f2c01 sago007 2017-03-15 17:56 678
    //! Constructor for constant string (i.e. do not make a copy of string)
6c5f2c01 sago007 2017-03-15 17:56 679
    explicit GenericValue(StringRefType s) CEREAL_RAPIDJSON_NOEXCEPT : data_() { SetStringRaw(s); }
6c5f2c01 sago007 2017-03-15 17:56 680
6c5f2c01 sago007 2017-03-15 17:56 681
    //! Constructor for copy-string (i.e. do make a copy of string)
6c5f2c01 sago007 2017-03-15 17:56 682
    GenericValue(const Ch* s, SizeType length, Allocator& allocator) : data_() { SetStringRaw(StringRef(s, length), allocator); }
6c5f2c01 sago007 2017-03-15 17:56 683
6c5f2c01 sago007 2017-03-15 17:56 684
    //! Constructor for copy-string (i.e. do make a copy of string)
6c5f2c01 sago007 2017-03-15 17:56 685
    GenericValue(const Ch*s, Allocator& allocator) : data_() { SetStringRaw(StringRef(s), allocator); }
6c5f2c01 sago007 2017-03-15 17:56 686
6c5f2c01 sago007 2017-03-15 17:56 687
#if CEREAL_RAPIDJSON_HAS_STDSTRING
6c5f2c01 sago007 2017-03-15 17:56 688
    //! Constructor for copy-string from a string object (i.e. do make a copy of string)
6c5f2c01 sago007 2017-03-15 17:56 689
    /*! \note Requires the definition of the preprocessor symbol \ref CEREAL_RAPIDJSON_HAS_STDSTRING.
6c5f2c01 sago007 2017-03-15 17:56 690
     */
6c5f2c01 sago007 2017-03-15 17:56 691
    GenericValue(const std::basic_string<Ch>& s, Allocator& allocator) : data_() { SetStringRaw(StringRef(s), allocator); }
6c5f2c01 sago007 2017-03-15 17:56 692
#endif
6c5f2c01 sago007 2017-03-15 17:56 693
6c5f2c01 sago007 2017-03-15 17:56 694
    //! Constructor for Array.
6c5f2c01 sago007 2017-03-15 17:56 695
    /*!
6c5f2c01 sago007 2017-03-15 17:56 696
        \param a An array obtained by \c GetArray().
6c5f2c01 sago007 2017-03-15 17:56 697
        \note \c Array is always pass-by-value.
6c5f2c01 sago007 2017-03-15 17:56 698
        \note the source array is moved into this value and the sourec array becomes empty.
6c5f2c01 sago007 2017-03-15 17:56 699
    */
6c5f2c01 sago007 2017-03-15 17:56 700
    GenericValue(Array a) CEREAL_RAPIDJSON_NOEXCEPT : data_(a.value_.data_) {
6c5f2c01 sago007 2017-03-15 17:56 701
        a.value_.data_ = Data();
6c5f2c01 sago007 2017-03-15 17:56 702
        a.value_.data_.f.flags = kArrayFlag;
6c5f2c01 sago007 2017-03-15 17:56 703
    }
6c5f2c01 sago007 2017-03-15 17:56 704
6c5f2c01 sago007 2017-03-15 17:56 705
    //! Constructor for Object.
6c5f2c01 sago007 2017-03-15 17:56 706
    /*!
6c5f2c01 sago007 2017-03-15 17:56 707
        \param o An object obtained by \c GetObject().
6c5f2c01 sago007 2017-03-15 17:56 708
        \note \c Object is always pass-by-value.
6c5f2c01 sago007 2017-03-15 17:56 709
        \note the source object is moved into this value and the sourec object becomes empty.
6c5f2c01 sago007 2017-03-15 17:56 710
    */
6c5f2c01 sago007 2017-03-15 17:56 711
    GenericValue(Object o) CEREAL_RAPIDJSON_NOEXCEPT : data_(o.value_.data_) {
6c5f2c01 sago007 2017-03-15 17:56 712
        o.value_.data_ = Data();
6c5f2c01 sago007 2017-03-15 17:56 713
        o.value_.data_.f.flags = kObjectFlag;
6c5f2c01 sago007 2017-03-15 17:56 714
    }
6c5f2c01 sago007 2017-03-15 17:56 715
6c5f2c01 sago007 2017-03-15 17:56 716
    //! Destructor.
6c5f2c01 sago007 2017-03-15 17:56 717
    /*! Need to destruct elements of array, members of object, or copy-string.
6c5f2c01 sago007 2017-03-15 17:56 718
    */
6c5f2c01 sago007 2017-03-15 17:56 719
    ~GenericValue() {
6c5f2c01 sago007 2017-03-15 17:56 720
        if (Allocator::kNeedFree) { // Shortcut by Allocator's trait
6c5f2c01 sago007 2017-03-15 17:56 721
            switch(data_.f.flags) {
6c5f2c01 sago007 2017-03-15 17:56 722
            case kArrayFlag:
6c5f2c01 sago007 2017-03-15 17:56 723
                {
6c5f2c01 sago007 2017-03-15 17:56 724
                    GenericValue* e = GetElementsPointer();
6c5f2c01 sago007 2017-03-15 17:56 725
                    for (GenericValue* v = e; v != e + data_.a.size; ++v)
6c5f2c01 sago007 2017-03-15 17:56 726
                        v->~GenericValue();
6c5f2c01 sago007 2017-03-15 17:56 727
                    Allocator::Free(e);
6c5f2c01 sago007 2017-03-15 17:56 728
                }
6c5f2c01 sago007 2017-03-15 17:56 729
                break;
6c5f2c01 sago007 2017-03-15 17:56 730
6c5f2c01 sago007 2017-03-15 17:56 731
            case kObjectFlag:
6c5f2c01 sago007 2017-03-15 17:56 732
                for (MemberIterator m = MemberBegin(); m != MemberEnd(); ++m)
6c5f2c01 sago007 2017-03-15 17:56 733
                    m->~Member();
6c5f2c01 sago007 2017-03-15 17:56 734
                Allocator::Free(GetMembersPointer());
6c5f2c01 sago007 2017-03-15 17:56 735
                break;
6c5f2c01 sago007 2017-03-15 17:56 736
6c5f2c01 sago007 2017-03-15 17:56 737
            case kCopyStringFlag:
6c5f2c01 sago007 2017-03-15 17:56 738
                Allocator::Free(const_cast<Ch*>(GetStringPointer()));
6c5f2c01 sago007 2017-03-15 17:56 739
                break;
6c5f2c01 sago007 2017-03-15 17:56 740
6c5f2c01 sago007 2017-03-15 17:56 741
            default:
6c5f2c01 sago007 2017-03-15 17:56 742
                break;  // Do nothing for other types.
6c5f2c01 sago007 2017-03-15 17:56 743
            }
6c5f2c01 sago007 2017-03-15 17:56 744
        }
6c5f2c01 sago007 2017-03-15 17:56 745
    }
6c5f2c01 sago007 2017-03-15 17:56 746
6c5f2c01 sago007 2017-03-15 17:56 747
    //@}
6c5f2c01 sago007 2017-03-15 17:56 748
6c5f2c01 sago007 2017-03-15 17:56 749
    //!@name Assignment operators
6c5f2c01 sago007 2017-03-15 17:56 750
    //@{
6c5f2c01 sago007 2017-03-15 17:56 751
6c5f2c01 sago007 2017-03-15 17:56 752
    //! Assignment with move semantics.
6c5f2c01 sago007 2017-03-15 17:56 753
    /*! \param rhs Source of the assignment. It will become a null value after assignment.
6c5f2c01 sago007 2017-03-15 17:56 754
    */
6c5f2c01 sago007 2017-03-15 17:56 755
    GenericValue& operator=(GenericValue& rhs) CEREAL_RAPIDJSON_NOEXCEPT {
6c5f2c01 sago007 2017-03-15 17:56 756
        CEREAL_RAPIDJSON_ASSERT(this != &rhs);
6c5f2c01 sago007 2017-03-15 17:56 757
        this->~GenericValue();
6c5f2c01 sago007 2017-03-15 17:56 758
        RawAssign(rhs);
6c5f2c01 sago007 2017-03-15 17:56 759
        return *this;
6c5f2c01 sago007 2017-03-15 17:56 760
    }
6c5f2c01 sago007 2017-03-15 17:56 761
6c5f2c01 sago007 2017-03-15 17:56 762
#if CEREAL_RAPIDJSON_HAS_CXX11_RVALUE_REFS
6c5f2c01 sago007 2017-03-15 17:56 763
    //! Move assignment in C++11
6c5f2c01 sago007 2017-03-15 17:56 764
    GenericValue& operator=(GenericValue&& rhs) CEREAL_RAPIDJSON_NOEXCEPT {
6c5f2c01 sago007 2017-03-15 17:56 765
        return *this = rhs.Move();
6c5f2c01 sago007 2017-03-15 17:56 766
    }
6c5f2c01 sago007 2017-03-15 17:56 767
#endif
6c5f2c01 sago007 2017-03-15 17:56 768
6c5f2c01 sago007 2017-03-15 17:56 769
    //! Assignment of constant string reference (no copy)
6c5f2c01 sago007 2017-03-15 17:56 770
    /*! \param str Constant string reference to be assigned
6c5f2c01 sago007 2017-03-15 17:56 771
        \note This overload is needed to avoid clashes with the generic primitive type assignment overload below.
6c5f2c01 sago007 2017-03-15 17:56 772
        \see GenericStringRef, operator=(T)
6c5f2c01 sago007 2017-03-15 17:56 773
    */
6c5f2c01 sago007 2017-03-15 17:56 774
    GenericValue& operator=(StringRefType str) CEREAL_RAPIDJSON_NOEXCEPT {
6c5f2c01 sago007 2017-03-15 17:56 775
        GenericValue s(str);
6c5f2c01 sago007 2017-03-15 17:56 776
        return *this = s;
6c5f2c01 sago007 2017-03-15 17:56 777
    }
6c5f2c01 sago007 2017-03-15 17:56 778
6c5f2c01 sago007 2017-03-15 17:56 779
    //! Assignment with primitive types.
6c5f2c01 sago007 2017-03-15 17:56 780
    /*! \tparam T Either \ref Type, \c int, \c unsigned, \c int64_t, \c uint64_t
6c5f2c01 sago007 2017-03-15 17:56 781
        \param value The value to be assigned.
6c5f2c01 sago007 2017-03-15 17:56 782
6c5f2c01 sago007 2017-03-15 17:56 783
        \note The source type \c T explicitly disallows all pointer types,
6c5f2c01 sago007 2017-03-15 17:56 784
            especially (\c const) \ref Ch*.  This helps avoiding implicitly
6c5f2c01 sago007 2017-03-15 17:56 785
            referencing character strings with insufficient lifetime, use
6c5f2c01 sago007 2017-03-15 17:56 786
            \ref SetString(const Ch*, Allocator&) (for copying) or
6c5f2c01 sago007 2017-03-15 17:56 787
            \ref StringRef() (to explicitly mark the pointer as constant) instead.
6c5f2c01 sago007 2017-03-15 17:56 788
            All other pointer types would implicitly convert to \c bool,
6c5f2c01 sago007 2017-03-15 17:56 789
            use \ref SetBool() instead.
6c5f2c01 sago007 2017-03-15 17:56 790
    */
6c5f2c01 sago007 2017-03-15 17:56 791
    template <typename T>
6c5f2c01 sago007 2017-03-15 17:56 792
    CEREAL_RAPIDJSON_DISABLEIF_RETURN((internal::IsPointer<T>), (GenericValue&))
6c5f2c01 sago007 2017-03-15 17:56 793
    operator=(T value) {
6c5f2c01 sago007 2017-03-15 17:56 794
        GenericValue v(value);
6c5f2c01 sago007 2017-03-15 17:56 795
        return *this = v;
6c5f2c01 sago007 2017-03-15 17:56 796
    }
6c5f2c01 sago007 2017-03-15 17:56 797
6c5f2c01 sago007 2017-03-15 17:56 798
    //! Deep-copy assignment from Value
6c5f2c01 sago007 2017-03-15 17:56 799
    /*! Assigns a \b copy of the Value to the current Value object
6c5f2c01 sago007 2017-03-15 17:56 800
        \tparam SourceAllocator Allocator type of \c rhs
6c5f2c01 sago007 2017-03-15 17:56 801
        \param rhs Value to copy from (read-only)
6c5f2c01 sago007 2017-03-15 17:56 802
        \param allocator Allocator to use for copying
6c5f2c01 sago007 2017-03-15 17:56 803
     */
6c5f2c01 sago007 2017-03-15 17:56 804
    template <typename SourceAllocator>
6c5f2c01 sago007 2017-03-15 17:56 805
    GenericValue& CopyFrom(const GenericValue<Encoding, SourceAllocator>& rhs, Allocator& allocator) {
6c5f2c01 sago007 2017-03-15 17:56 806
        CEREAL_RAPIDJSON_ASSERT(static_cast<void*>(this) != static_cast<void const*>(&rhs));
6c5f2c01 sago007 2017-03-15 17:56 807
        this->~GenericValue();
6c5f2c01 sago007 2017-03-15 17:56 808
        new (this) GenericValue(rhs, allocator);
6c5f2c01 sago007 2017-03-15 17:56 809
        return *this;
6c5f2c01 sago007 2017-03-15 17:56 810
    }
6c5f2c01 sago007 2017-03-15 17:56 811
6c5f2c01 sago007 2017-03-15 17:56 812
    //! Exchange the contents of this value with those of other.
6c5f2c01 sago007 2017-03-15 17:56 813
    /*!
6c5f2c01 sago007 2017-03-15 17:56 814
        \param other Another value.
6c5f2c01 sago007 2017-03-15 17:56 815
        \note Constant complexity.
6c5f2c01 sago007 2017-03-15 17:56 816
    */
6c5f2c01 sago007 2017-03-15 17:56 817
    GenericValue& Swap(GenericValue& other) CEREAL_RAPIDJSON_NOEXCEPT {
6c5f2c01 sago007 2017-03-15 17:56 818
        GenericValue temp;
6c5f2c01 sago007 2017-03-15 17:56 819
        temp.RawAssign(*this);
6c5f2c01 sago007 2017-03-15 17:56 820
        RawAssign(other);
6c5f2c01 sago007 2017-03-15 17:56 821
        other.RawAssign(temp);
6c5f2c01 sago007 2017-03-15 17:56 822
        return *this;
6c5f2c01 sago007 2017-03-15 17:56 823
    }
6c5f2c01 sago007 2017-03-15 17:56 824
6c5f2c01 sago007 2017-03-15 17:56 825
    //! free-standing swap function helper
6c5f2c01 sago007 2017-03-15 17:56 826
    /*!
6c5f2c01 sago007 2017-03-15 17:56 827
        Helper function to enable support for common swap implementation pattern based on \c std::swap:
6c5f2c01 sago007 2017-03-15 17:56 828
        \code
6c5f2c01 sago007 2017-03-15 17:56 829
        void swap(MyClass& a, MyClass& b) {
6c5f2c01 sago007 2017-03-15 17:56 830
            using std::swap;
6c5f2c01 sago007 2017-03-15 17:56 831
            swap(a.value, b.value);
6c5f2c01 sago007 2017-03-15 17:56 832
            // ...
6c5f2c01 sago007 2017-03-15 17:56 833
        }
6c5f2c01 sago007 2017-03-15 17:56 834
        \endcode
6c5f2c01 sago007 2017-03-15 17:56 835
        \see Swap()
6c5f2c01 sago007 2017-03-15 17:56 836
     */
6c5f2c01 sago007 2017-03-15 17:56 837
    friend inline void swap(GenericValue& a, GenericValue& b) CEREAL_RAPIDJSON_NOEXCEPT { a.Swap(b); }
6c5f2c01 sago007 2017-03-15 17:56 838
6c5f2c01 sago007 2017-03-15 17:56 839
    //! Prepare Value for move semantics
6c5f2c01 sago007 2017-03-15 17:56 840
    /*! \return *this */
6c5f2c01 sago007 2017-03-15 17:56 841
    GenericValue& Move() CEREAL_RAPIDJSON_NOEXCEPT { return *this; }
6c5f2c01 sago007 2017-03-15 17:56 842
    //@}
6c5f2c01 sago007 2017-03-15 17:56 843
6c5f2c01 sago007 2017-03-15 17:56 844
    //!@name Equal-to and not-equal-to operators
6c5f2c01 sago007 2017-03-15 17:56 845
    //@{
6c5f2c01 sago007 2017-03-15 17:56 846
    //! Equal-to operator
6c5f2c01 sago007 2017-03-15 17:56 847
    /*!
6c5f2c01 sago007 2017-03-15 17:56 848
        \note If an object contains duplicated named member, comparing equality with any object is always \c false.
6c5f2c01 sago007 2017-03-15 17:56 849
        \note Linear time complexity (number of all values in the subtree and total lengths of all strings).
6c5f2c01 sago007 2017-03-15 17:56 850
    */
6c5f2c01 sago007 2017-03-15 17:56 851
    template <typename SourceAllocator>
6c5f2c01 sago007 2017-03-15 17:56 852
    bool operator==(const GenericValue<Encoding, SourceAllocator>& rhs) const {
6c5f2c01 sago007 2017-03-15 17:56 853
        typedef GenericValue<Encoding, SourceAllocator> RhsType;
6c5f2c01 sago007 2017-03-15 17:56 854
        if (GetType() != rhs.GetType())
6c5f2c01 sago007 2017-03-15 17:56 855
            return false;
6c5f2c01 sago007 2017-03-15 17:56 856
6c5f2c01 sago007 2017-03-15 17:56 857
        switch (GetType()) {
6c5f2c01 sago007 2017-03-15 17:56 858
        case kObjectType: // Warning: O(n^2) inner-loop
6c5f2c01 sago007 2017-03-15 17:56 859
            if (data_.o.size != rhs.data_.o.size)
6c5f2c01 sago007 2017-03-15 17:56 860
                return false;           
6c5f2c01 sago007 2017-03-15 17:56 861
            for (ConstMemberIterator lhsMemberItr = MemberBegin(); lhsMemberItr != MemberEnd(); ++lhsMemberItr) {
6c5f2c01 sago007 2017-03-15 17:56 862
                typename RhsType::ConstMemberIterator rhsMemberItr = rhs.FindMember(lhsMemberItr->name);
6c5f2c01 sago007 2017-03-15 17:56 863
                if (rhsMemberItr == rhs.MemberEnd() || lhsMemberItr->value != rhsMemberItr->value)
6c5f2c01 sago007 2017-03-15 17:56 864
                    return false;
6c5f2c01 sago007 2017-03-15 17:56 865
            }
6c5f2c01 sago007 2017-03-15 17:56 866
            return true;
6c5f2c01 sago007 2017-03-15 17:56 867
            
6c5f2c01 sago007 2017-03-15 17:56 868
        case kArrayType:
6c5f2c01 sago007 2017-03-15 17:56 869
            if (data_.a.size != rhs.data_.a.size)
6c5f2c01 sago007 2017-03-15 17:56 870
                return false;
6c5f2c01 sago007 2017-03-15 17:56 871
            for (SizeType i = 0; i < data_.a.size; i++)
6c5f2c01 sago007 2017-03-15 17:56 872
                if ((*this)[i] != rhs[i])
6c5f2c01 sago007 2017-03-15 17:56 873
                    return false;
6c5f2c01 sago007 2017-03-15 17:56 874
            return true;
6c5f2c01 sago007 2017-03-15 17:56 875
6c5f2c01 sago007 2017-03-15 17:56 876
        case kStringType:
6c5f2c01 sago007 2017-03-15 17:56 877
            return StringEqual(rhs);
6c5f2c01 sago007 2017-03-15 17:56 878
6c5f2c01 sago007 2017-03-15 17:56 879
        case kNumberType:
6c5f2c01 sago007 2017-03-15 17:56 880
            if (IsDouble() || rhs.IsDouble()) {
6c5f2c01 sago007 2017-03-15 17:56 881
                double a = GetDouble();     // May convert from integer to double.
6c5f2c01 sago007 2017-03-15 17:56 882
                double b = rhs.GetDouble(); // Ditto
6c5f2c01 sago007 2017-03-15 17:56 883
                return a >= b && a <= b;    // Prevent -Wfloat-equal
6c5f2c01 sago007 2017-03-15 17:56 884
            }
6c5f2c01 sago007 2017-03-15 17:56 885
            else
6c5f2c01 sago007 2017-03-15 17:56 886
                return data_.n.u64 == rhs.data_.n.u64;
6c5f2c01 sago007 2017-03-15 17:56 887
6c5f2c01 sago007 2017-03-15 17:56 888
        default:
6c5f2c01 sago007 2017-03-15 17:56 889
            return true;
6c5f2c01 sago007 2017-03-15 17:56 890
        }
6c5f2c01 sago007 2017-03-15 17:56 891
    }
6c5f2c01 sago007 2017-03-15 17:56 892
6c5f2c01 sago007 2017-03-15 17:56 893
    //! Equal-to operator with const C-string pointer
6c5f2c01 sago007 2017-03-15 17:56 894
    bool operator==(const Ch* rhs) const { return *this == GenericValue(StringRef(rhs)); }
6c5f2c01 sago007 2017-03-15 17:56 895
6c5f2c01 sago007 2017-03-15 17:56 896
#if CEREAL_RAPIDJSON_HAS_STDSTRING
6c5f2c01 sago007 2017-03-15 17:56 897
    //! Equal-to operator with string object
6c5f2c01 sago007 2017-03-15 17:56 898
    /*! \note Requires the definition of the preprocessor symbol \ref CEREAL_RAPIDJSON_HAS_STDSTRING.
6c5f2c01 sago007 2017-03-15 17:56 899
     */
6c5f2c01 sago007 2017-03-15 17:56 900
    bool operator==(const std::basic_string<Ch>& rhs) const { return *this == GenericValue(StringRef(rhs)); }
6c5f2c01 sago007 2017-03-15 17:56 901
#endif
6c5f2c01 sago007 2017-03-15 17:56 902
6c5f2c01 sago007 2017-03-15 17:56 903
    //! Equal-to operator with primitive types
6c5f2c01 sago007 2017-03-15 17:56 904
    /*! \tparam T Either \ref Type, \c int, \c unsigned, \c int64_t, \c uint64_t, \c double, \c true, \c false
6c5f2c01 sago007 2017-03-15 17:56 905
    */
6c5f2c01 sago007 2017-03-15 17:56 906
    template <typename T> CEREAL_RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>,internal::IsGenericValue<T> >), (bool)) operator==(const T& rhs) const { return *this == GenericValue(rhs); }
6c5f2c01 sago007 2017-03-15 17:56 907
6c5f2c01 sago007 2017-03-15 17:56 908
    //! Not-equal-to operator
6c5f2c01 sago007 2017-03-15 17:56 909
    /*! \return !(*this == rhs)
6c5f2c01 sago007 2017-03-15 17:56 910
     */
6c5f2c01 sago007 2017-03-15 17:56 911
    template <typename SourceAllocator>
6c5f2c01 sago007 2017-03-15 17:56 912
    bool operator!=(const GenericValue<Encoding, SourceAllocator>& rhs) const { return !(*this == rhs); }
6c5f2c01 sago007 2017-03-15 17:56 913
6c5f2c01 sago007 2017-03-15 17:56 914
    //! Not-equal-to operator with const C-string pointer
6c5f2c01 sago007 2017-03-15 17:56 915
    bool operator!=(const Ch* rhs) const { return !(*this == rhs); }
6c5f2c01 sago007 2017-03-15 17:56 916
6c5f2c01 sago007 2017-03-15 17:56 917
    //! Not-equal-to operator with arbitrary types
6c5f2c01 sago007 2017-03-15 17:56 918
    /*! \return !(*this == rhs)
6c5f2c01 sago007 2017-03-15 17:56 919
     */
6c5f2c01 sago007 2017-03-15 17:56 920
    template <typename T> CEREAL_RAPIDJSON_DISABLEIF_RETURN((internal::IsGenericValue<T>), (bool)) operator!=(const T& rhs) const { return !(*this == rhs); }
6c5f2c01 sago007 2017-03-15 17:56 921
6c5f2c01 sago007 2017-03-15 17:56 922
    //! Equal-to operator with arbitrary types (symmetric version)
6c5f2c01 sago007 2017-03-15 17:56 923
    /*! \return (rhs == lhs)
6c5f2c01 sago007 2017-03-15 17:56 924
     */
6c5f2c01 sago007 2017-03-15 17:56 925
    template <typename T> friend CEREAL_RAPIDJSON_DISABLEIF_RETURN((internal::IsGenericValue<T>), (bool)) operator==(const T& lhs, const GenericValue& rhs) { return rhs == lhs; }
6c5f2c01 sago007 2017-03-15 17:56 926
6c5f2c01 sago007 2017-03-15 17:56 927
    //! Not-Equal-to operator with arbitrary types (symmetric version)
6c5f2c01 sago007 2017-03-15 17:56 928
    /*! \return !(rhs == lhs)
6c5f2c01 sago007 2017-03-15 17:56 929
     */
6c5f2c01 sago007 2017-03-15 17:56 930
    template <typename T> friend CEREAL_RAPIDJSON_DISABLEIF_RETURN((internal::IsGenericValue<T>), (bool)) operator!=(const T& lhs, const GenericValue& rhs) { return !(rhs == lhs); }
6c5f2c01 sago007 2017-03-15 17:56 931
    //@}
6c5f2c01 sago007 2017-03-15 17:56 932
6c5f2c01 sago007 2017-03-15 17:56 933
    //!@name Type
6c5f2c01 sago007 2017-03-15 17:56 934
    //@{
6c5f2c01 sago007 2017-03-15 17:56 935
6c5f2c01 sago007 2017-03-15 17:56 936
    Type GetType()  const { return static_cast<Type>(data_.f.flags & kTypeMask); }
6c5f2c01 sago007 2017-03-15 17:56 937
    bool IsNull()   const { return data_.f.flags == kNullFlag; }
6c5f2c01 sago007 2017-03-15 17:56 938
    bool IsFalse()  const { return data_.f.flags == kFalseFlag; }
6c5f2c01 sago007 2017-03-15 17:56 939
    bool IsTrue()   const { return data_.f.flags == kTrueFlag; }
6c5f2c01 sago007 2017-03-15 17:56 940
    bool IsBool()   const { return (data_.f.flags & kBoolFlag) != 0; }
6c5f2c01 sago007 2017-03-15 17:56 941
    bool IsObject() const { return data_.f.flags == kObjectFlag; }
6c5f2c01 sago007 2017-03-15 17:56 942
    bool IsArray()  const { return data_.f.flags == kArrayFlag; }
6c5f2c01 sago007 2017-03-15 17:56 943
    bool IsNumber() const { return (data_.f.flags & kNumberFlag) != 0; }
6c5f2c01 sago007 2017-03-15 17:56 944
    bool IsInt()    const { return (data_.f.flags & kIntFlag) != 0; }
6c5f2c01 sago007 2017-03-15 17:56 945
    bool IsUint()   const { return (data_.f.flags & kUintFlag) != 0; }
6c5f2c01 sago007 2017-03-15 17:56 946
    bool IsInt64()  const { return (data_.f.flags & kInt64Flag) != 0; }
6c5f2c01 sago007 2017-03-15 17:56 947
    bool IsUint64() const { return (data_.f.flags & kUint64Flag) != 0; }
6c5f2c01 sago007 2017-03-15 17:56 948
    bool IsDouble() const { return (data_.f.flags & kDoubleFlag) != 0; }
6c5f2c01 sago007 2017-03-15 17:56 949
    bool IsString() const { return (data_.f.flags & kStringFlag) != 0; }
6c5f2c01 sago007 2017-03-15 17:56 950
6c5f2c01 sago007 2017-03-15 17:56 951
    // Checks whether a number can be losslessly converted to a double.
6c5f2c01 sago007 2017-03-15 17:56 952
    bool IsLosslessDouble() const {
6c5f2c01 sago007 2017-03-15 17:56 953
        if (!IsNumber()) return false;
6c5f2c01 sago007 2017-03-15 17:56 954
        if (IsUint64()) {
6c5f2c01 sago007 2017-03-15 17:56 955
            uint64_t u = GetUint64();
6c5f2c01 sago007 2017-03-15 17:56 956
            volatile double d = static_cast<double>(u);
6c5f2c01 sago007 2017-03-15 17:56 957
            return (d >= 0.0)
6c5f2c01 sago007 2017-03-15 17:56 958
                && (d < static_cast<double>(std::numeric_limits<uint64_t>::max()))
6c5f2c01 sago007 2017-03-15 17:56 959
                && (u == static_cast<uint64_t>(d));
6c5f2c01 sago007 2017-03-15 17:56 960
        }
6c5f2c01 sago007 2017-03-15 17:56 961
        if (IsInt64()) {
6c5f2c01 sago007 2017-03-15 17:56 962
            int64_t i = GetInt64();
6c5f2c01 sago007 2017-03-15 17:56 963
            volatile double d = static_cast<double>(i);
6c5f2c01 sago007 2017-03-15 17:56 964
            return (d >= static_cast<double>(std::numeric_limits<int64_t>::min()))
6c5f2c01 sago007 2017-03-15 17:56 965
                && (d < static_cast<double>(std::numeric_limits<int64_t>::max()))
6c5f2c01 sago007 2017-03-15 17:56 966
                && (i == static_cast<int64_t>(d));
6c5f2c01 sago007 2017-03-15 17:56 967
        }
6c5f2c01 sago007 2017-03-15 17:56 968
        return true; // double, int, uint are always lossless
6c5f2c01 sago007 2017-03-15 17:56 969
    }
6c5f2c01 sago007 2017-03-15 17:56 970
6c5f2c01 sago007 2017-03-15 17:56 971
    // Checks whether a number is a float (possible lossy).
6c5f2c01 sago007 2017-03-15 17:56 972
    bool IsFloat() const  {
6c5f2c01 sago007 2017-03-15 17:56 973
        if ((data_.f.flags & kDoubleFlag) == 0)
6c5f2c01 sago007 2017-03-15 17:56 974
            return false;
6c5f2c01 sago007 2017-03-15 17:56 975
        double d = GetDouble();
6c5f2c01 sago007 2017-03-15 17:56 976
        return d >= -3.4028234e38 && d <= 3.4028234e38;
6c5f2c01 sago007 2017-03-15 17:56 977
    }
6c5f2c01 sago007 2017-03-15 17:56 978
    // Checks whether a number can be losslessly converted to a float.
6c5f2c01 sago007 2017-03-15 17:56 979
    bool IsLosslessFloat() const {
6c5f2c01 sago007 2017-03-15 17:56 980
        if (!IsNumber()) return false;
6c5f2c01 sago007 2017-03-15 17:56 981
        double a = GetDouble();
6c5f2c01 sago007 2017-03-15 17:56 982
        if (a < static_cast<double>(-std::numeric_limits<float>::max())
6c5f2c01 sago007 2017-03-15 17:56 983
                || a > static_cast<double>(std::numeric_limits<float>::max()))
6c5f2c01 sago007 2017-03-15 17:56 984
            return false;
6c5f2c01 sago007 2017-03-15 17:56 985
        double b = static_cast<double>(static_cast<float>(a));
6c5f2c01 sago007 2017-03-15 17:56 986
        return a >= b && a <= b;    // Prevent -Wfloat-equal
6c5f2c01 sago007 2017-03-15 17:56 987
    }
6c5f2c01 sago007 2017-03-15 17:56 988
6c5f2c01 sago007 2017-03-15 17:56 989
    //@}
6c5f2c01 sago007 2017-03-15 17:56 990
6c5f2c01 sago007 2017-03-15 17:56 991
    //!@name Null
6c5f2c01 sago007 2017-03-15 17:56 992
    //@{
6c5f2c01 sago007 2017-03-15 17:56 993
6c5f2c01 sago007 2017-03-15 17:56 994
    GenericValue& SetNull() { this->~GenericValue(); new (this) GenericValue(); return *this; }
6c5f2c01 sago007 2017-03-15 17:56 995
6c5f2c01 sago007 2017-03-15 17:56 996
    //@}
6c5f2c01 sago007 2017-03-15 17:56 997
6c5f2c01 sago007 2017-03-15 17:56 998
    //!@name Bool
6c5f2c01 sago007 2017-03-15 17:56 999
    //@{
6c5f2c01 sago007 2017-03-15 17:56 1000
6c5f2c01 sago007 2017-03-15 17:56 1001
    bool GetBool() const { CEREAL_RAPIDJSON_ASSERT(IsBool()); return data_.f.flags == kTrueFlag; }
6c5f2c01 sago007 2017-03-15 17:56 1002
    //!< Set boolean value
6c5f2c01 sago007 2017-03-15 17:56 1003
    /*! \post IsBool() == true */
6c5f2c01 sago007 2017-03-15 17:56 1004
    GenericValue& SetBool(bool b) { this->~GenericValue(); new (this) GenericValue(b); return *this; }
6c5f2c01 sago007 2017-03-15 17:56 1005
6c5f2c01 sago007 2017-03-15 17:56 1006
    //@}
6c5f2c01 sago007 2017-03-15 17:56 1007
6c5f2c01 sago007 2017-03-15 17:56 1008
    //!@name Object
6c5f2c01 sago007 2017-03-15 17:56 1009
    //@{
6c5f2c01 sago007 2017-03-15 17:56 1010
6c5f2c01 sago007 2017-03-15 17:56 1011
    //! Set this value as an empty object.
6c5f2c01 sago007 2017-03-15 17:56 1012
    /*! \post IsObject() == true */
6c5f2c01 sago007 2017-03-15 17:56 1013
    GenericValue& SetObject() { this->~GenericValue(); new (this) GenericValue(kObjectType); return *this; }
6c5f2c01 sago007 2017-03-15 17:56 1014
6c5f2c01 sago007 2017-03-15 17:56 1015
    //! Get the number of members in the object.
6c5f2c01 sago007 2017-03-15 17:56 1016
    SizeType MemberCount() const { CEREAL_RAPIDJSON_ASSERT(IsObject()); return data_.o.size; }
6c5f2c01 sago007 2017-03-15 17:56 1017
6c5f2c01 sago007 2017-03-15 17:56 1018
    //! Check whether the object is empty.
6c5f2c01 sago007 2017-03-15 17:56 1019
    bool ObjectEmpty() const { CEREAL_RAPIDJSON_ASSERT(IsObject()); return data_.o.size == 0; }
6c5f2c01 sago007 2017-03-15 17:56 1020
6c5f2c01 sago007 2017-03-15 17:56 1021
    //! Get a value from an object associated with the name.
6c5f2c01 sago007 2017-03-15 17:56 1022
    /*! \pre IsObject() == true
6c5f2c01 sago007 2017-03-15 17:56 1023
        \tparam T Either \c Ch or \c const \c Ch (template used for disambiguation with \ref operator[](SizeType))
6c5f2c01 sago007 2017-03-15 17:56 1024
        \note In version 0.1x, if the member is not found, this function returns a null value. This makes issue 7.
6c5f2c01 sago007 2017-03-15 17:56 1025
        Since 0.2, if the name is not correct, it will assert.
6c5f2c01 sago007 2017-03-15 17:56 1026
        If user is unsure whether a member exists, user should use HasMember() first.
6c5f2c01 sago007 2017-03-15 17:56 1027
        A better approach is to use FindMember().
6c5f2c01 sago007 2017-03-15 17:56 1028
        \note Linear time complexity.
6c5f2c01 sago007 2017-03-15 17:56 1029
    */
6c5f2c01 sago007 2017-03-15 17:56 1030
    template <typename T>
6c5f2c01 sago007 2017-03-15 17:56 1031
    CEREAL_RAPIDJSON_DISABLEIF_RETURN((internal::NotExpr<internal::IsSame<typename internal::RemoveConst<T>::Type, Ch> >),(GenericValue&)) operator[](T* name) {
6c5f2c01 sago007 2017-03-15 17:56 1032
        GenericValue n(StringRef(name));
6c5f2c01 sago007 2017-03-15 17:56 1033
        return (*this)[n];
6c5f2c01 sago007 2017-03-15 17:56 1034
    }
6c5f2c01 sago007 2017-03-15 17:56 1035
    template <typename T>
6c5f2c01 sago007 2017-03-15 17:56 1036
    CEREAL_RAPIDJSON_DISABLEIF_RETURN((internal::NotExpr<internal::IsSame<typename internal::RemoveConst<T>::Type, Ch> >),(const GenericValue&)) operator[](T* name) const { return const_cast<GenericValue&>(*this)[name]; }
6c5f2c01 sago007 2017-03-15 17:56 1037
6c5f2c01 sago007 2017-03-15 17:56 1038
    //! Get a value from an object associated with the name.
6c5f2c01 sago007 2017-03-15 17:56 1039
    /*! \pre IsObject() == true
6c5f2c01 sago007 2017-03-15 17:56 1040
        \tparam SourceAllocator Allocator of the \c name value
6c5f2c01 sago007 2017-03-15 17:56 1041
6c5f2c01 sago007 2017-03-15 17:56 1042
        \note Compared to \ref operator[](T*), this version is faster because it does not need a StrLen().
6c5f2c01 sago007 2017-03-15 17:56 1043
        And it can also handle strings with embedded null characters.
6c5f2c01 sago007 2017-03-15 17:56 1044
6c5f2c01 sago007 2017-03-15 17:56 1045
        \note Linear time complexity.
6c5f2c01 sago007 2017-03-15 17:56 1046
    */
6c5f2c01 sago007 2017-03-15 17:56 1047
    template <typename SourceAllocator>
6c5f2c01 sago007 2017-03-15 17:56 1048
    GenericValue& operator[](const GenericValue<Encoding, SourceAllocator>& name) {
6c5f2c01 sago007 2017-03-15 17:56 1049
        MemberIterator member = FindMember(name);
6c5f2c01 sago007 2017-03-15 17:56 1050
        if (member != MemberEnd())
6c5f2c01 sago007 2017-03-15 17:56 1051
            return member->value;
6c5f2c01 sago007 2017-03-15 17:56 1052
        else {
6c5f2c01 sago007 2017-03-15 17:56 1053
            CEREAL_RAPIDJSON_ASSERT(false);    // see above note
6c5f2c01 sago007 2017-03-15 17:56 1054
6c5f2c01 sago007 2017-03-15 17:56 1055
            // This will generate -Wexit-time-destructors in clang
6c5f2c01 sago007 2017-03-15 17:56 1056
            // static GenericValue NullValue;
6c5f2c01 sago007 2017-03-15 17:56 1057
            // return NullValue;
6c5f2c01 sago007 2017-03-15 17:56 1058
6c5f2c01 sago007 2017-03-15 17:56 1059
            // Use static buffer and placement-new to prevent destruction
6c5f2c01 sago007 2017-03-15 17:56 1060
            static char buffer[sizeof(GenericValue)];
6c5f2c01 sago007 2017-03-15 17:56 1061
            return *new (buffer) GenericValue();
6c5f2c01 sago007 2017-03-15 17:56 1062
        }
6c5f2c01 sago007 2017-03-15 17:56 1063
    }
6c5f2c01 sago007 2017-03-15 17:56 1064
    template <typename SourceAllocator>
6c5f2c01 sago007 2017-03-15 17:56 1065
    const GenericValue& operator[](const GenericValue<Encoding, SourceAllocator>& name) const { return const_cast<GenericValue&>(*this)[name]; }
6c5f2c01 sago007 2017-03-15 17:56 1066
6c5f2c01 sago007 2017-03-15 17:56 1067
#if CEREAL_RAPIDJSON_HAS_STDSTRING
6c5f2c01 sago007 2017-03-15 17:56 1068
    //! Get a value from an object associated with name (string object).
6c5f2c01 sago007 2017-03-15 17:56 1069
    GenericValue& operator[](const std::basic_string<Ch>& name) { return (*this)[GenericValue(StringRef(name))]; }
6c5f2c01 sago007 2017-03-15 17:56 1070
    const GenericValue& operator[](const std::basic_string<Ch>& name) const { return (*this)[GenericValue(StringRef(name))]; }
6c5f2c01 sago007 2017-03-15 17:56 1071
#endif
6c5f2c01 sago007 2017-03-15 17:56 1072
6c5f2c01 sago007 2017-03-15 17:56 1073
    //! Const member iterator
6c5f2c01 sago007 2017-03-15 17:56 1074
    /*! \pre IsObject() == true */
6c5f2c01 sago007 2017-03-15 17:56 1075
    ConstMemberIterator MemberBegin() const { CEREAL_RAPIDJSON_ASSERT(IsObject()); return ConstMemberIterator(GetMembersPointer()); }
6c5f2c01 sago007 2017-03-15 17:56 1076
    //! Const \em past-the-end member iterator
6c5f2c01 sago007 2017-03-15 17:56 1077
    /*! \pre IsObject() == true */
6c5f2c01 sago007 2017-03-15 17:56 1078
    ConstMemberIterator MemberEnd() const   { CEREAL_RAPIDJSON_ASSERT(IsObject()); return ConstMemberIterator(GetMembersPointer() + data_.o.size); }
6c5f2c01 sago007 2017-03-15 17:56 1079
    //! Member iterator
6c5f2c01 sago007 2017-03-15 17:56 1080
    /*! \pre IsObject() == true */
6c5f2c01 sago007 2017-03-15 17:56 1081
    MemberIterator MemberBegin()            { CEREAL_RAPIDJSON_ASSERT(IsObject()); return MemberIterator(GetMembersPointer()); }
6c5f2c01 sago007 2017-03-15 17:56 1082
    //! \em Past-the-end member iterator
6c5f2c01 sago007 2017-03-15 17:56 1083
    /*! \pre IsObject() == true */
6c5f2c01 sago007 2017-03-15 17:56 1084
    MemberIterator MemberEnd()              { CEREAL_RAPIDJSON_ASSERT(IsObject()); return MemberIterator(GetMembersPointer() + data_.o.size); }
6c5f2c01 sago007 2017-03-15 17:56 1085
6c5f2c01 sago007 2017-03-15 17:56 1086
    //! Check whether a member exists in the object.
6c5f2c01 sago007 2017-03-15 17:56 1087
    /*!
6c5f2c01 sago007 2017-03-15 17:56 1088
        \param name Member name to be searched.
6c5f2c01 sago007 2017-03-15 17:56 1089
        \pre IsObject() == true
6c5f2c01 sago007 2017-03-15 17:56 1090
        \return Whether a member with that name exists.
6c5f2c01 sago007 2017-03-15 17:56 1091
        \note It is better to use FindMember() directly if you need the obtain the value as well.
6c5f2c01 sago007 2017-03-15 17:56 1092
        \note Linear time complexity.
6c5f2c01 sago007 2017-03-15 17:56 1093
    */
6c5f2c01 sago007 2017-03-15 17:56 1094
    bool HasMember(const Ch* name) const { return FindMember(name) != MemberEnd(); }
6c5f2c01 sago007 2017-03-15 17:56 1095
6c5f2c01 sago007 2017-03-15 17:56 1096
#if CEREAL_RAPIDJSON_HAS_STDSTRING
6c5f2c01 sago007 2017-03-15 17:56 1097
    //! Check whether a member exists in the object with string object.
6c5f2c01 sago007 2017-03-15 17:56 1098
    /*!
6c5f2c01 sago007 2017-03-15 17:56 1099
        \param name Member name to be searched.
6c5f2c01 sago007 2017-03-15 17:56 1100
        \pre IsObject() == true
6c5f2c01 sago007 2017-03-15 17:56 1101
        \return Whether a member with that name exists.
6c5f2c01 sago007 2017-03-15 17:56 1102
        \note It is better to use FindMember() directly if you need the obtain the value as well.
6c5f2c01 sago007 2017-03-15 17:56 1103
        \note Linear time complexity.
6c5f2c01 sago007 2017-03-15 17:56 1104
    */
6c5f2c01 sago007 2017-03-15 17:56 1105
    bool HasMember(const std::basic_string<Ch>& name) const { return FindMember(name) != MemberEnd(); }
6c5f2c01 sago007 2017-03-15 17:56 1106
#endif
6c5f2c01 sago007 2017-03-15 17:56 1107
6c5f2c01 sago007 2017-03-15 17:56 1108
    //! Check whether a member exists in the object with GenericValue name.
6c5f2c01 sago007 2017-03-15 17:56 1109
    /*!
6c5f2c01 sago007 2017-03-15 17:56 1110
        This version is faster because it does not need a StrLen(). It can also handle string with null character.
6c5f2c01 sago007 2017-03-15 17:56 1111
        \param name Member name to be searched.
6c5f2c01 sago007 2017-03-15 17:56 1112
        \pre IsObject() == true
6c5f2c01 sago007 2017-03-15 17:56 1113
        \return Whether a member with that name exists.
6c5f2c01 sago007 2017-03-15 17:56 1114
        \note It is better to use FindMember() directly if you need the obtain the value as well.
6c5f2c01 sago007 2017-03-15 17:56 1115
        \note Linear time complexity.
6c5f2c01 sago007 2017-03-15 17:56 1116
    */
6c5f2c01 sago007 2017-03-15 17:56 1117
    template <typename SourceAllocator>
6c5f2c01 sago007 2017-03-15 17:56 1118
    bool HasMember(const GenericValue<Encoding, SourceAllocator>& name) const { return FindMember(name) != MemberEnd(); }
6c5f2c01 sago007 2017-03-15 17:56 1119
6c5f2c01 sago007 2017-03-15 17:56 1120
    //! Find member by name.
6c5f2c01 sago007 2017-03-15 17:56 1121
    /*!
6c5f2c01 sago007 2017-03-15 17:56 1122
        \param name Member name to be searched.
6c5f2c01 sago007 2017-03-15 17:56 1123
        \pre IsObject() == true
6c5f2c01 sago007 2017-03-15 17:56 1124
        \return Iterator to member, if it exists.
6c5f2c01 sago007 2017-03-15 17:56 1125
            Otherwise returns \ref MemberEnd().
6c5f2c01 sago007 2017-03-15 17:56 1126
6c5f2c01 sago007 2017-03-15 17:56 1127
        \note Earlier versions of Rapidjson returned a \c NULL pointer, in case
6c5f2c01 sago007 2017-03-15 17:56 1128
            the requested member doesn't exist. For consistency with e.g.
6c5f2c01 sago007 2017-03-15 17:56 1129
            \c std::map, this has been changed to MemberEnd() now.
6c5f2c01 sago007 2017-03-15 17:56 1130
        \note Linear time complexity.
6c5f2c01 sago007 2017-03-15 17:56 1131
    */
6c5f2c01 sago007 2017-03-15 17:56 1132
    MemberIterator FindMember(const Ch* name) {
6c5f2c01 sago007 2017-03-15 17:56 1133
        GenericValue n(StringRef(name));
6c5f2c01 sago007 2017-03-15 17:56 1134
        return FindMember(n);
6c5f2c01 sago007 2017-03-15 17:56 1135
    }
6c5f2c01 sago007 2017-03-15 17:56 1136
6c5f2c01 sago007 2017-03-15 17:56 1137
    ConstMemberIterator FindMember(const Ch* name) const { return const_cast<GenericValue&>(*this).FindMember(name); }
6c5f2c01 sago007 2017-03-15 17:56 1138
6c5f2c01 sago007 2017-03-15 17:56 1139
    //! Find member by name.
6c5f2c01 sago007 2017-03-15 17:56 1140
    /*!
6c5f2c01 sago007 2017-03-15 17:56 1141
        This version is faster because it does not need a StrLen(). It can also handle string with null character.
6c5f2c01 sago007 2017-03-15 17:56 1142
        \param name Member name to be searched.
6c5f2c01 sago007 2017-03-15 17:56 1143
        \pre IsObject() == true
6c5f2c01 sago007 2017-03-15 17:56 1144
        \return Iterator to member, if it exists.
6c5f2c01 sago007 2017-03-15 17:56 1145
            Otherwise returns \ref MemberEnd().
6c5f2c01 sago007 2017-03-15 17:56 1146
6c5f2c01 sago007 2017-03-15 17:56 1147
        \note Earlier versions of Rapidjson returned a \c NULL pointer, in case
6c5f2c01 sago007 2017-03-15 17:56 1148
            the requested member doesn't exist. For consistency with e.g.
6c5f2c01 sago007 2017-03-15 17:56 1149
            \c std::map, this has been changed to MemberEnd() now.
6c5f2c01 sago007 2017-03-15 17:56 1150
        \note Linear time complexity.
6c5f2c01 sago007 2017-03-15 17:56 1151
    */
6c5f2c01 sago007 2017-03-15 17:56 1152
    template <typename SourceAllocator>
6c5f2c01 sago007 2017-03-15 17:56 1153
    MemberIterator FindMember(const GenericValue<Encoding, SourceAllocator>& name) {
6c5f2c01 sago007 2017-03-15 17:56 1154
        CEREAL_RAPIDJSON_ASSERT(IsObject());
6c5f2c01 sago007 2017-03-15 17:56 1155
        CEREAL_RAPIDJSON_ASSERT(name.IsString());
6c5f2c01 sago007 2017-03-15 17:56 1156
        MemberIterator member = MemberBegin();
6c5f2c01 sago007 2017-03-15 17:56 1157
        for ( ; member != MemberEnd(); ++member)
6c5f2c01 sago007 2017-03-15 17:56 1158
            if (name.StringEqual(member->name))
6c5f2c01 sago007 2017-03-15 17:56 1159
                break;
6c5f2c01 sago007 2017-03-15 17:56 1160
        return member;
6c5f2c01 sago007 2017-03-15 17:56 1161
    }
6c5f2c01 sago007 2017-03-15 17:56 1162
    template <typename SourceAllocator> ConstMemberIterator FindMember(const GenericValue<Encoding, SourceAllocator>& name) const { return const_cast<GenericValue&>(*this).FindMember(name); }
6c5f2c01 sago007 2017-03-15 17:56 1163
6c5f2c01 sago007 2017-03-15 17:56 1164
#if CEREAL_RAPIDJSON_HAS_STDSTRING
6c5f2c01 sago007 2017-03-15 17:56 1165
    //! Find member by string object name.
6c5f2c01 sago007 2017-03-15 17:56 1166
    /*!
6c5f2c01 sago007 2017-03-15 17:56 1167
        \param name Member name to be searched.
6c5f2c01 sago007 2017-03-15 17:56 1168
        \pre IsObject() == true
6c5f2c01 sago007 2017-03-15 17:56 1169
        \return Iterator to member, if it exists.
6c5f2c01 sago007 2017-03-15 17:56 1170
            Otherwise returns \ref MemberEnd().
6c5f2c01 sago007 2017-03-15 17:56 1171
    */
6c5f2c01 sago007 2017-03-15 17:56 1172
    MemberIterator FindMember(const std::basic_string<Ch>& name) { return FindMember(GenericValue(StringRef(name))); }
6c5f2c01 sago007 2017-03-15 17:56 1173
    ConstMemberIterator FindMember(const std::basic_string<Ch>& name) const { return FindMember(GenericValue(StringRef(name))); }
6c5f2c01 sago007 2017-03-15 17:56 1174
#endif
6c5f2c01 sago007 2017-03-15 17:56 1175
6c5f2c01 sago007 2017-03-15 17:56 1176
    //! Add a member (name-value pair) to the object.
6c5f2c01 sago007 2017-03-15 17:56 1177
    /*! \param name A string value as name of member.
6c5f2c01 sago007 2017-03-15 17:56 1178
        \param value Value of any type.
6c5f2c01 sago007 2017-03-15 17:56 1179
        \param allocator    Allocator for reallocating memory. It must be the same one as used before. Commonly use GenericDocument::GetAllocator().
6c5f2c01 sago007 2017-03-15 17:56 1180
        \return The value itself for fluent API.
6c5f2c01 sago007 2017-03-15 17:56 1181
        \note The ownership of \c name and \c value will be transferred to this object on success.
6c5f2c01 sago007 2017-03-15 17:56 1182
        \pre  IsObject() && name.IsString()
6c5f2c01 sago007 2017-03-15 17:56 1183
        \post name.IsNull() && value.IsNull()
6c5f2c01 sago007 2017-03-15 17:56 1184
        \note Amortized Constant time complexity.
6c5f2c01 sago007 2017-03-15 17:56 1185
    */
6c5f2c01 sago007 2017-03-15 17:56 1186
    GenericValue& AddMember(GenericValue& name, GenericValue& value, Allocator& allocator) {
6c5f2c01 sago007 2017-03-15 17:56 1187
        CEREAL_RAPIDJSON_ASSERT(IsObject());
6c5f2c01 sago007 2017-03-15 17:56 1188
        CEREAL_RAPIDJSON_ASSERT(name.IsString());
6c5f2c01 sago007 2017-03-15 17:56 1189
6c5f2c01 sago007 2017-03-15 17:56 1190
        ObjectData& o = data_.o;
6c5f2c01 sago007 2017-03-15 17:56 1191
        if (o.size >= o.capacity) {
6c5f2c01 sago007 2017-03-15 17:56 1192
            if (o.capacity == 0) {
6c5f2c01 sago007 2017-03-15 17:56 1193
                o.capacity = kDefaultObjectCapacity;
6c5f2c01 sago007 2017-03-15 17:56 1194
                SetMembersPointer(reinterpret_cast<Member*>(allocator.Malloc(o.capacity * sizeof(Member))));
6c5f2c01 sago007 2017-03-15 17:56 1195
            }
6c5f2c01 sago007 2017-03-15 17:56 1196
            else {
6c5f2c01 sago007 2017-03-15 17:56 1197
                SizeType oldCapacity = o.capacity;
6c5f2c01 sago007 2017-03-15 17:56 1198
                o.capacity += (oldCapacity + 1) / 2; // grow by factor 1.5
6c5f2c01 sago007 2017-03-15 17:56 1199
                SetMembersPointer(reinterpret_cast<Member*>(allocator.Realloc(GetMembersPointer(), oldCapacity * sizeof(Member), o.capacity * sizeof(Member))));
6c5f2c01 sago007 2017-03-15 17:56 1200
            }
6c5f2c01 sago007 2017-03-15 17:56 1201
        }
6c5f2c01 sago007 2017-03-15 17:56 1202
        Member* members = GetMembersPointer();
6c5f2c01 sago007 2017-03-15 17:56 1203
        members[o.size].name.RawAssign(name);
6c5f2c01 sago007 2017-03-15 17:56 1204
        members[o.size].value.RawAssign(value);
6c5f2c01 sago007 2017-03-15 17:56 1205
        o.size++;
6c5f2c01 sago007 2017-03-15 17:56 1206
        return *this;
6c5f2c01 sago007 2017-03-15 17:56 1207
    }
6c5f2c01 sago007 2017-03-15 17:56 1208
6c5f2c01 sago007 2017-03-15 17:56 1209
    //! Add a constant string value as member (name-value pair) to the object.
6c5f2c01 sago007 2017-03-15 17:56 1210
    /*! \param name A string value as name of member.
6c5f2c01 sago007 2017-03-15 17:56 1211
        \param value constant string reference as value of member.
6c5f2c01 sago007 2017-03-15 17:56 1212
        \param allocator    Allocator for reallocating memory. It must be the same one as used before. Commonly use GenericDocument::GetAllocator().
6c5f2c01 sago007 2017-03-15 17:56 1213
        \return The value itself for fluent API.
6c5f2c01 sago007 2017-03-15 17:56 1214
        \pre  IsObject()
6c5f2c01 sago007 2017-03-15 17:56 1215
        \note This overload is needed to avoid clashes with the generic primitive type AddMember(GenericValue&,T,Allocator&) overload below.
6c5f2c01 sago007 2017-03-15 17:56 1216
        \note Amortized Constant time complexity.
6c5f2c01 sago007 2017-03-15 17:56 1217
    */
6c5f2c01 sago007 2017-03-15 17:56 1218
    GenericValue& AddMember(GenericValue& name, StringRefType value, Allocator& allocator) {
6c5f2c01 sago007 2017-03-15 17:56 1219
        GenericValue v(value);
6c5f2c01 sago007 2017-03-15 17:56 1220
        return AddMember(name, v, allocator);
6c5f2c01 sago007 2017-03-15 17:56 1221
    }
6c5f2c01 sago007 2017-03-15 17:56 1222
6c5f2c01 sago007 2017-03-15 17:56 1223
#if CEREAL_RAPIDJSON_HAS_STDSTRING
6c5f2c01 sago007 2017-03-15 17:56 1224
    //! Add a string object as member (name-value pair) to the object.
6c5f2c01 sago007 2017-03-15 17:56 1225
    /*! \param name A string value as name of member.
6c5f2c01 sago007 2017-03-15 17:56 1226
        \param value constant string reference as value of member.
6c5f2c01 sago007 2017-03-15 17:56 1227
        \param allocator    Allocator for reallocating memory. It must be the same one as used before. Commonly use GenericDocument::GetAllocator().
6c5f2c01 sago007 2017-03-15 17:56 1228
        \return The value itself for fluent API.
6c5f2c01 sago007 2017-03-15 17:56 1229
        \pre  IsObject()
6c5f2c01 sago007 2017-03-15 17:56 1230
        \note This overload is needed to avoid clashes with the generic primitive type AddMember(GenericValue&,T,Allocator&) overload below.
6c5f2c01 sago007 2017-03-15 17:56 1231
        \note Amortized Constant time complexity.
6c5f2c01 sago007 2017-03-15 17:56 1232
    */
6c5f2c01 sago007 2017-03-15 17:56 1233
    GenericValue& AddMember(GenericValue& name, std::basic_string<Ch>& value, Allocator& allocator) {
6c5f2c01 sago007 2017-03-15 17:56 1234
        GenericValue v(value, allocator);
6c5f2c01 sago007 2017-03-15 17:56 1235
        return AddMember(name, v, allocator);
6c5f2c01 sago007 2017-03-15 17:56 1236
    }
6c5f2c01 sago007 2017-03-15 17:56 1237
#endif
6c5f2c01 sago007 2017-03-15 17:56 1238
6c5f2c01 sago007 2017-03-15 17:56 1239
    //! Add any primitive value as member (name-value pair) to the object.
6c5f2c01 sago007 2017-03-15 17:56 1240
    /*! \tparam T Either \ref Type, \c int, \c unsigned, \c int64_t, \c uint64_t
6c5f2c01 sago007 2017-03-15 17:56 1241
        \param name A string value as name of member.
6c5f2c01 sago007 2017-03-15 17:56 1242
        \param value Value of primitive type \c T as value of member
6c5f2c01 sago007 2017-03-15 17:56 1243
        \param allocator Allocator for reallocating memory. Commonly use GenericDocument::GetAllocator().
6c5f2c01 sago007 2017-03-15 17:56 1244
        \return The value itself for fluent API.
6c5f2c01 sago007 2017-03-15 17:56 1245
        \pre  IsObject()
6c5f2c01 sago007 2017-03-15 17:56 1246
6c5f2c01 sago007 2017-03-15 17:56 1247
        \note The source type \c T explicitly disallows all pointer types,
6c5f2c01 sago007 2017-03-15 17:56 1248
            especially (\c const) \ref Ch*.  This helps avoiding implicitly
6c5f2c01 sago007 2017-03-15 17:56 1249
            referencing character strings with insufficient lifetime, use
6c5f2c01 sago007 2017-03-15 17:56 1250
            \ref AddMember(StringRefType, GenericValue&, Allocator&) or \ref
6c5f2c01 sago007 2017-03-15 17:56 1251
            AddMember(StringRefType, StringRefType, Allocator&).
6c5f2c01 sago007 2017-03-15 17:56 1252
            All other pointer types would implicitly convert to \c bool,
6c5f2c01 sago007 2017-03-15 17:56 1253
            use an explicit cast instead, if needed.
6c5f2c01 sago007 2017-03-15 17:56 1254
        \note Amortized Constant time complexity.
6c5f2c01 sago007 2017-03-15 17:56 1255
    */
6c5f2c01 sago007 2017-03-15 17:56 1256
    template <typename T>
6c5f2c01 sago007 2017-03-15 17:56 1257
    CEREAL_RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>, internal::IsGenericValue<T> >), (GenericValue&))
6c5f2c01 sago007 2017-03-15 17:56 1258
    AddMember(GenericValue& name, T value, Allocator& allocator) {
6c5f2c01 sago007 2017-03-15 17:56 1259
        GenericValue v(value);
6c5f2c01 sago007 2017-03-15 17:56 1260
        return AddMember(name, v, allocator);
6c5f2c01 sago007 2017-03-15 17:56 1261
    }
6c5f2c01 sago007 2017-03-15 17:56 1262
6c5f2c01 sago007 2017-03-15 17:56 1263
#if CEREAL_RAPIDJSON_HAS_CXX11_RVALUE_REFS
6c5f2c01 sago007 2017-03-15 17:56 1264
    GenericValue& AddMember(GenericValue&& name, GenericValue&& value, Allocator& allocator) {
6c5f2c01 sago007 2017-03-15 17:56 1265
        return AddMember(name, value, allocator);
6c5f2c01 sago007 2017-03-15 17:56 1266
    }
6c5f2c01 sago007 2017-03-15 17:56 1267
    GenericValue& AddMember(GenericValue&& name, GenericValue& value, Allocator& allocator) {
6c5f2c01 sago007 2017-03-15 17:56 1268
        return AddMember(name, value, allocator);
6c5f2c01 sago007 2017-03-15 17:56 1269
    }
6c5f2c01 sago007 2017-03-15 17:56 1270
    GenericValue& AddMember(GenericValue& name, GenericValue&& value, Allocator& allocator) {
6c5f2c01 sago007 2017-03-15 17:56 1271
        return AddMember(name, value, allocator);
6c5f2c01 sago007 2017-03-15 17:56 1272
    }
6c5f2c01 sago007 2017-03-15 17:56 1273
    GenericValue& AddMember(StringRefType name, GenericValue&& value, Allocator& allocator) {
6c5f2c01 sago007 2017-03-15 17:56 1274
        GenericValue n(name);
6c5f2c01 sago007 2017-03-15 17:56 1275
        return AddMember(n, value, allocator);
6c5f2c01 sago007 2017-03-15 17:56 1276
    }
6c5f2c01 sago007 2017-03-15 17:56 1277
#endif // CEREAL_RAPIDJSON_HAS_CXX11_RVALUE_REFS
6c5f2c01 sago007 2017-03-15 17:56 1278
6c5f2c01 sago007 2017-03-15 17:56 1279
6c5f2c01 sago007 2017-03-15 17:56 1280
    //! Add a member (name-value pair) to the object.
6c5f2c01 sago007 2017-03-15 17:56 1281
    /*! \param name A constant string reference as name of member.
6c5f2c01 sago007 2017-03-15 17:56 1282
        \param value Value of any type.
6c5f2c01 sago007 2017-03-15 17:56 1283
        \param allocator    Allocator for reallocating memory. It must be the same one as used before. Commonly use GenericDocument::GetAllocator().
6c5f2c01 sago007 2017-03-15 17:56 1284
        \return The value itself for fluent API.
6c5f2c01 sago007 2017-03-15 17:56 1285
        \note The ownership of \c value will be transferred to this object on success.
6c5f2c01 sago007 2017-03-15 17:56 1286
        \pre  IsObject()
6c5f2c01 sago007 2017-03-15 17:56 1287
        \post value.IsNull()
6c5f2c01 sago007 2017-03-15 17:56 1288
        \note Amortized Constant time complexity.
6c5f2c01 sago007 2017-03-15 17:56 1289
    */
6c5f2c01 sago007 2017-03-15 17:56 1290
    GenericValue& AddMember(StringRefType name, GenericValue& value, Allocator& allocator) {
6c5f2c01 sago007 2017-03-15 17:56 1291
        GenericValue n(name);
6c5f2c01 sago007 2017-03-15 17:56 1292
        return AddMember(n, value, allocator);
6c5f2c01 sago007 2017-03-15 17:56 1293
    }
6c5f2c01 sago007 2017-03-15 17:56 1294
6c5f2c01 sago007 2017-03-15 17:56 1295
    //! Add a constant string value as member (name-value pair) to the object.
6c5f2c01 sago007 2017-03-15 17:56 1296
    /*! \param name A constant string reference as name of member.
6c5f2c01 sago007 2017-03-15 17:56 1297
        \param value constant string reference as value of member.
6c5f2c01 sago007 2017-03-15 17:56 1298
        \param allocator    Allocator for reallocating memory. It must be the same one as used before. Commonly use GenericDocument::GetAllocator().
6c5f2c01 sago007 2017-03-15 17:56 1299
        \return The value itself for fluent API.
6c5f2c01 sago007 2017-03-15 17:56 1300
        \pre  IsObject()
6c5f2c01 sago007 2017-03-15 17:56 1301
        \note This overload is needed to avoid clashes with the generic primitive type AddMember(StringRefType,T,Allocator&) overload below.
6c5f2c01 sago007 2017-03-15 17:56 1302
        \note Amortized Constant time complexity.
6c5f2c01 sago007 2017-03-15 17:56 1303
    */
6c5f2c01 sago007 2017-03-15 17:56 1304
    GenericValue& AddMember(StringRefType name, StringRefType value, Allocator& allocator) {
6c5f2c01 sago007 2017-03-15 17:56 1305
        GenericValue v(value);
6c5f2c01 sago007 2017-03-15 17:56 1306
        return AddMember(name, v, allocator);
6c5f2c01 sago007 2017-03-15 17:56 1307
    }
6c5f2c01 sago007 2017-03-15 17:56 1308
6c5f2c01 sago007 2017-03-15 17:56 1309
    //! Add any primitive value as member (name-value pair) to the object.
6c5f2c01 sago007 2017-03-15 17:56 1310
    /*! \tparam T Either \ref Type, \c int, \c unsigned, \c int64_t, \c uint64_t
6c5f2c01 sago007 2017-03-15 17:56 1311
        \param name A constant string reference as name of member.
6c5f2c01 sago007 2017-03-15 17:56 1312
        \param value Value of primitive type \c T as value of member
6c5f2c01 sago007 2017-03-15 17:56 1313
        \param allocator Allocator for reallocating memory. Commonly use GenericDocument::GetAllocator().
6c5f2c01 sago007 2017-03-15 17:56 1314
        \return The value itself for fluent API.
6c5f2c01 sago007 2017-03-15 17:56 1315
        \pre  IsObject()
6c5f2c01 sago007 2017-03-15 17:56 1316
6c5f2c01 sago007 2017-03-15 17:56 1317
        \note The source type \c T explicitly disallows all pointer types,
6c5f2c01 sago007 2017-03-15 17:56 1318
            especially (\c const) \ref Ch*.  This helps avoiding implicitly
6c5f2c01 sago007 2017-03-15 17:56 1319
            referencing character strings with insufficient lifetime, use
6c5f2c01 sago007 2017-03-15 17:56 1320
            \ref AddMember(StringRefType, GenericValue&, Allocator&) or \ref
6c5f2c01 sago007 2017-03-15 17:56 1321
            AddMember(StringRefType, StringRefType, Allocator&).
6c5f2c01 sago007 2017-03-15 17:56 1322
            All other pointer types would implicitly convert to \c bool,
6c5f2c01 sago007 2017-03-15 17:56 1323
            use an explicit cast instead, if needed.
6c5f2c01 sago007 2017-03-15 17:56 1324
        \note Amortized Constant time complexity.
6c5f2c01 sago007 2017-03-15 17:56 1325
    */
6c5f2c01 sago007 2017-03-15 17:56 1326
    template <typename T>
6c5f2c01 sago007 2017-03-15 17:56 1327
    CEREAL_RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>, internal::IsGenericValue<T> >), (GenericValue&))
6c5f2c01 sago007 2017-03-15 17:56 1328
    AddMember(StringRefType name, T value, Allocator& allocator) {
6c5f2c01 sago007 2017-03-15 17:56 1329
        GenericValue n(name);
6c5f2c01 sago007 2017-03-15 17:56 1330
        return AddMember(n, value, allocator);
6c5f2c01 sago007 2017-03-15 17:56 1331
    }
6c5f2c01 sago007 2017-03-15 17:56 1332
6c5f2c01 sago007 2017-03-15 17:56 1333
    //! Remove all members in the object.
6c5f2c01 sago007 2017-03-15 17:56 1334
    /*! This function do not deallocate memory in the object, i.e. the capacity is unchanged.
6c5f2c01 sago007 2017-03-15 17:56 1335
        \note Linear time complexity.
6c5f2c01 sago007 2017-03-15 17:56 1336
    */
6c5f2c01 sago007 2017-03-15 17:56 1337
    void RemoveAllMembers() {
6c5f2c01 sago007 2017-03-15 17:56 1338
        CEREAL_RAPIDJSON_ASSERT(IsObject()); 
6c5f2c01 sago007 2017-03-15 17:56 1339
        for (MemberIterator m = MemberBegin(); m != MemberEnd(); ++m)
6c5f2c01 sago007 2017-03-15 17:56 1340
            m->~Member();
6c5f2c01 sago007 2017-03-15 17:56 1341
        data_.o.size = 0;
6c5f2c01 sago007 2017-03-15 17:56 1342
    }
6c5f2c01 sago007 2017-03-15 17:56 1343
6c5f2c01 sago007 2017-03-15 17:56 1344
    //! Remove a member in object by its name.
6c5f2c01 sago007 2017-03-15 17:56 1345
    /*! \param name Name of member to be removed.
6c5f2c01 sago007 2017-03-15 17:56 1346
        \return Whether the member existed.
6c5f2c01 sago007 2017-03-15 17:56 1347
        \note This function may reorder the object members. Use \ref
6c5f2c01 sago007 2017-03-15 17:56 1348
            EraseMember(ConstMemberIterator) if you need to preserve the
6c5f2c01 sago007 2017-03-15 17:56 1349
            relative order of the remaining members.
6c5f2c01 sago007 2017-03-15 17:56 1350
        \note Linear time complexity.
6c5f2c01 sago007 2017-03-15 17:56 1351
    */
6c5f2c01 sago007 2017-03-15 17:56 1352
    bool RemoveMember(const Ch* name) {
6c5f2c01 sago007 2017-03-15 17:56 1353
        GenericValue n(StringRef(name));
6c5f2c01 sago007 2017-03-15 17:56 1354
        return RemoveMember(n);
6c5f2c01 sago007 2017-03-15 17:56 1355
    }
6c5f2c01 sago007 2017-03-15 17:56 1356
6c5f2c01 sago007 2017-03-15 17:56 1357
#if CEREAL_RAPIDJSON_HAS_STDSTRING
6c5f2c01 sago007 2017-03-15 17:56 1358
    bool RemoveMember(const std::basic_string<Ch>& name) { return RemoveMember(GenericValue(StringRef(name))); }
6c5f2c01 sago007 2017-03-15 17:56 1359
#endif
6c5f2c01 sago007 2017-03-15 17:56 1360
6c5f2c01 sago007 2017-03-15 17:56 1361
    template <typename SourceAllocator>
6c5f2c01 sago007 2017-03-15 17:56 1362
    bool RemoveMember(const GenericValue<Encoding, SourceAllocator>& name) {
6c5f2c01 sago007 2017-03-15 17:56 1363
        MemberIterator m = FindMember(name);
6c5f2c01 sago007 2017-03-15 17:56 1364
        if (m != MemberEnd()) {
6c5f2c01 sago007 2017-03-15 17:56 1365
            RemoveMember(m);
6c5f2c01 sago007 2017-03-15 17:56 1366
            return true;
6c5f2c01 sago007 2017-03-15 17:56 1367
        }
6c5f2c01 sago007 2017-03-15 17:56 1368
        else
6c5f2c01 sago007 2017-03-15 17:56 1369
            return false;
6c5f2c01 sago007 2017-03-15 17:56 1370
    }
6c5f2c01 sago007 2017-03-15 17:56 1371
6c5f2c01 sago007 2017-03-15 17:56 1372
    //! Remove a member in object by iterator.
6c5f2c01 sago007 2017-03-15 17:56 1373
    /*! \param m member iterator (obtained by FindMember() or MemberBegin()).
6c5f2c01 sago007 2017-03-15 17:56 1374
        \return the new iterator after removal.
6c5f2c01 sago007 2017-03-15 17:56 1375
        \note This function may reorder the object members. Use \ref
6c5f2c01 sago007 2017-03-15 17:56 1376
            EraseMember(ConstMemberIterator) if you need to preserve the
6c5f2c01 sago007 2017-03-15 17:56 1377
            relative order of the remaining members.
6c5f2c01 sago007 2017-03-15 17:56 1378
        \note Constant time complexity.
6c5f2c01 sago007 2017-03-15 17:56 1379
    */
6c5f2c01 sago007 2017-03-15 17:56 1380
    MemberIterator RemoveMember(MemberIterator m) {
6c5f2c01 sago007 2017-03-15 17:56 1381
        CEREAL_RAPIDJSON_ASSERT(IsObject());
6c5f2c01 sago007 2017-03-15 17:56 1382
        CEREAL_RAPIDJSON_ASSERT(data_.o.size > 0);
6c5f2c01 sago007 2017-03-15 17:56 1383
        CEREAL_RAPIDJSON_ASSERT(GetMembersPointer() != 0);
6c5f2c01 sago007 2017-03-15 17:56 1384
        CEREAL_RAPIDJSON_ASSERT(m >= MemberBegin() && m < MemberEnd());
6c5f2c01 sago007 2017-03-15 17:56 1385
6c5f2c01 sago007 2017-03-15 17:56 1386
        MemberIterator last(GetMembersPointer() + (data_.o.size - 1));
6c5f2c01 sago007 2017-03-15 17:56 1387
        if (data_.o.size > 1 && m != last)
6c5f2c01 sago007 2017-03-15 17:56 1388
            *m = *last; // Move the last one to this place
6c5f2c01 sago007 2017-03-15 17:56 1389
        else
6c5f2c01 sago007 2017-03-15 17:56 1390
            m->~Member(); // Only one left, just destroy
6c5f2c01 sago007 2017-03-15 17:56 1391
        --data_.o.size;
6c5f2c01 sago007 2017-03-15 17:56 1392
        return m;
6c5f2c01 sago007 2017-03-15 17:56 1393
    }
6c5f2c01 sago007 2017-03-15 17:56 1394
6c5f2c01 sago007 2017-03-15 17:56 1395
    //! Remove a member from an object by iterator.
6c5f2c01 sago007 2017-03-15 17:56 1396
    /*! \param pos iterator to the member to remove
6c5f2c01 sago007 2017-03-15 17:56 1397
        \pre IsObject() == true && \ref MemberBegin() <= \c pos < \ref MemberEnd()
6c5f2c01 sago007 2017-03-15 17:56 1398
        \return Iterator following the removed element.
6c5f2c01 sago007 2017-03-15 17:56 1399
            If the iterator \c pos refers to the last element, the \ref MemberEnd() iterator is returned.
6c5f2c01 sago007 2017-03-15 17:56 1400
        \note This function preserves the relative order of the remaining object
6c5f2c01 sago007 2017-03-15 17:56 1401
            members. If you do not need this, use the more efficient \ref RemoveMember(MemberIterator).
6c5f2c01 sago007 2017-03-15 17:56 1402
        \note Linear time complexity.
6c5f2c01 sago007 2017-03-15 17:56 1403
    */
6c5f2c01 sago007 2017-03-15 17:56 1404
    MemberIterator EraseMember(ConstMemberIterator pos) {
6c5f2c01 sago007 2017-03-15 17:56 1405
        return EraseMember(pos, pos +1);
6c5f2c01 sago007 2017-03-15 17:56 1406
    }
6c5f2c01 sago007 2017-03-15 17:56 1407
6c5f2c01 sago007 2017-03-15 17:56 1408
    //! Remove members in the range [first, last) from an object.
6c5f2c01 sago007 2017-03-15 17:56 1409
    /*! \param first iterator to the first member to remove
6c5f2c01 sago007 2017-03-15 17:56 1410
        \param last  iterator following the last member to remove
6c5f2c01 sago007 2017-03-15 17:56 1411
        \pre IsObject() == true && \ref MemberBegin() <= \c first <= \c last <= \ref MemberEnd()
6c5f2c01 sago007 2017-03-15 17:56 1412
        \return Iterator following the last removed element.
6c5f2c01 sago007 2017-03-15 17:56 1413
        \note This function preserves the relative order of the remaining object
6c5f2c01 sago007 2017-03-15 17:56 1414
            members.
6c5f2c01 sago007 2017-03-15 17:56 1415
        \note Linear time complexity.
6c5f2c01 sago007 2017-03-15 17:56 1416
    */
6c5f2c01 sago007 2017-03-15 17:56 1417
    MemberIterator EraseMember(ConstMemberIterator first, ConstMemberIterator last) {
6c5f2c01 sago007 2017-03-15 17:56 1418
        CEREAL_RAPIDJSON_ASSERT(IsObject());
6c5f2c01 sago007 2017-03-15 17:56 1419
        CEREAL_RAPIDJSON_ASSERT(data_.o.size > 0);
6c5f2c01 sago007 2017-03-15 17:56 1420
        CEREAL_RAPIDJSON_ASSERT(GetMembersPointer() != 0);
6c5f2c01 sago007 2017-03-15 17:56 1421
        CEREAL_RAPIDJSON_ASSERT(first >= MemberBegin());
6c5f2c01 sago007 2017-03-15 17:56 1422
        CEREAL_RAPIDJSON_ASSERT(first <= last);
6c5f2c01 sago007 2017-03-15 17:56 1423
        CEREAL_RAPIDJSON_ASSERT(last <= MemberEnd());
6c5f2c01 sago007 2017-03-15 17:56 1424
6c5f2c01 sago007 2017-03-15 17:56 1425
        MemberIterator pos = MemberBegin() + (first - MemberBegin());
6c5f2c01 sago007 2017-03-15 17:56 1426
        for (MemberIterator itr = pos; itr != last; ++itr)
6c5f2c01 sago007 2017-03-15 17:56 1427
            itr->~Member();
6c5f2c01 sago007 2017-03-15 17:56 1428
        std::memmove(&*pos, &*last, static_cast<size_t>(MemberEnd() - last) * sizeof(Member));
6c5f2c01 sago007 2017-03-15 17:56 1429
        data_.o.size -= static_cast<SizeType>(last - first);
6c5f2c01 sago007 2017-03-15 17:56 1430
        return pos;
6c5f2c01 sago007 2017-03-15 17:56 1431
    }
6c5f2c01 sago007 2017-03-15 17:56 1432
6c5f2c01 sago007 2017-03-15 17:56 1433
    //! Erase a member in object by its name.
6c5f2c01 sago007 2017-03-15 17:56 1434
    /*! \param name Name of member to be removed.
6c5f2c01 sago007 2017-03-15 17:56 1435
        \return Whether the member existed.
6c5f2c01 sago007 2017-03-15 17:56 1436
        \note Linear time complexity.
6c5f2c01 sago007 2017-03-15 17:56 1437
    */
6c5f2c01 sago007 2017-03-15 17:56 1438
    bool EraseMember(const Ch* name) {
6c5f2c01 sago007 2017-03-15 17:56 1439
        GenericValue n(StringRef(name));
6c5f2c01 sago007 2017-03-15 17:56 1440
        return EraseMember(n);
6c5f2c01 sago007 2017-03-15 17:56 1441
    }
6c5f2c01 sago007 2017-03-15 17:56 1442
6c5f2c01 sago007 2017-03-15 17:56 1443
#if CEREAL_RAPIDJSON_HAS_STDSTRING
6c5f2c01 sago007 2017-03-15 17:56 1444
    bool EraseMember(const std::basic_string<Ch>& name) { return EraseMember(GenericValue(StringRef(name))); }
6c5f2c01 sago007 2017-03-15 17:56 1445
#endif
6c5f2c01 sago007 2017-03-15 17:56 1446
6c5f2c01 sago007 2017-03-15 17:56 1447
    template <typename SourceAllocator>
6c5f2c01 sago007 2017-03-15 17:56 1448
    bool EraseMember(const GenericValue<Encoding, SourceAllocator>& name) {
6c5f2c01 sago007 2017-03-15 17:56 1449
        MemberIterator m = FindMember(name);
6c5f2c01 sago007 2017-03-15 17:56 1450
        if (m != MemberEnd()) {
6c5f2c01 sago007 2017-03-15 17:56 1451
            EraseMember(m);
6c5f2c01 sago007 2017-03-15 17:56 1452
            return true;
6c5f2c01 sago007 2017-03-15 17:56 1453
        }
6c5f2c01 sago007 2017-03-15 17:56 1454
        else
6c5f2c01 sago007 2017-03-15 17:56 1455
            return false;
6c5f2c01 sago007 2017-03-15 17:56 1456
    }
6c5f2c01 sago007 2017-03-15 17:56 1457
6c5f2c01 sago007 2017-03-15 17:56 1458
    Object GetObject() { CEREAL_RAPIDJSON_ASSERT(IsObject()); return Object(*this); }
6c5f2c01 sago007 2017-03-15 17:56 1459
    ConstObject GetObject() const { CEREAL_RAPIDJSON_ASSERT(IsObject()); return ConstObject(*this); }
6c5f2c01 sago007 2017-03-15 17:56 1460
6c5f2c01 sago007 2017-03-15 17:56 1461
    //@}
6c5f2c01 sago007 2017-03-15 17:56 1462
6c5f2c01 sago007 2017-03-15 17:56 1463
    //!@name Array
6c5f2c01 sago007 2017-03-15 17:56 1464
    //@{
6c5f2c01 sago007 2017-03-15 17:56 1465
6c5f2c01 sago007 2017-03-15 17:56 1466
    //! Set this value as an empty array.
6c5f2c01 sago007 2017-03-15 17:56 1467
    /*! \post IsArray == true */
6c5f2c01 sago007 2017-03-15 17:56 1468
    GenericValue& SetArray() { this->~GenericValue(); new (this) GenericValue(kArrayType); return *this; }
6c5f2c01 sago007 2017-03-15 17:56 1469
6c5f2c01 sago007 2017-03-15 17:56 1470
    //! Get the number of elements in array.
6c5f2c01 sago007 2017-03-15 17:56 1471
    SizeType Size() const { CEREAL_RAPIDJSON_ASSERT(IsArray()); return data_.a.size; }
6c5f2c01 sago007 2017-03-15 17:56 1472
6c5f2c01 sago007 2017-03-15 17:56 1473
    //! Get the capacity of array.
6c5f2c01 sago007 2017-03-15 17:56 1474
    SizeType Capacity() const { CEREAL_RAPIDJSON_ASSERT(IsArray()); return data_.a.capacity; }
6c5f2c01 sago007 2017-03-15 17:56 1475
6c5f2c01 sago007 2017-03-15 17:56 1476
    //! Check whether the array is empty.
6c5f2c01 sago007 2017-03-15 17:56 1477
    bool Empty() const { CEREAL_RAPIDJSON_ASSERT(IsArray()); return data_.a.size == 0; }
6c5f2c01 sago007 2017-03-15 17:56 1478
6c5f2c01 sago007 2017-03-15 17:56 1479
    //! Remove all elements in the array.
6c5f2c01 sago007 2017-03-15 17:56 1480
    /*! This function do not deallocate memory in the array, i.e. the capacity is unchanged.
6c5f2c01 sago007 2017-03-15 17:56 1481
        \note Linear time complexity.
6c5f2c01 sago007 2017-03-15 17:56 1482
    */
6c5f2c01 sago007 2017-03-15 17:56 1483
    void Clear() {
6c5f2c01 sago007 2017-03-15 17:56 1484
        CEREAL_RAPIDJSON_ASSERT(IsArray()); 
6c5f2c01 sago007 2017-03-15 17:56 1485
        GenericValue* e = GetElementsPointer();
6c5f2c01 sago007 2017-03-15 17:56 1486
        for (GenericValue* v = e; v != e + data_.a.size; ++v)
6c5f2c01 sago007 2017-03-15 17:56 1487
            v->~GenericValue();
6c5f2c01 sago007 2017-03-15 17:56 1488
        data_.a.size = 0;
6c5f2c01 sago007 2017-03-15 17:56 1489
    }
6c5f2c01 sago007 2017-03-15 17:56 1490
6c5f2c01 sago007 2017-03-15 17:56 1491
    //! Get an element from array by index.
6c5f2c01 sago007 2017-03-15 17:56 1492
    /*! \pre IsArray() == true
6c5f2c01 sago007 2017-03-15 17:56 1493
        \param index Zero-based index of element.
6c5f2c01 sago007 2017-03-15 17:56 1494
        \see operator[](T*)
6c5f2c01 sago007 2017-03-15 17:56 1495
    */
6c5f2c01 sago007 2017-03-15 17:56 1496
    GenericValue& operator[](SizeType index) {
6c5f2c01 sago007 2017-03-15 17:56 1497
        CEREAL_RAPIDJSON_ASSERT(IsArray());
6c5f2c01 sago007 2017-03-15 17:56 1498
        CEREAL_RAPIDJSON_ASSERT(index < data_.a.size);
6c5f2c01 sago007 2017-03-15 17:56 1499
        return GetElementsPointer()[index];
6c5f2c01 sago007 2017-03-15 17:56 1500
    }
6c5f2c01 sago007 2017-03-15 17:56 1501
    const GenericValue& operator[](SizeType index) const { return const_cast<GenericValue&>(*this)[index]; }
6c5f2c01 sago007 2017-03-15 17:56 1502
6c5f2c01 sago007 2017-03-15 17:56 1503
    //! Element iterator
6c5f2c01 sago007 2017-03-15 17:56 1504
    /*! \pre IsArray() == true */
6c5f2c01 sago007 2017-03-15 17:56 1505
    ValueIterator Begin() { CEREAL_RAPIDJSON_ASSERT(IsArray()); return GetElementsPointer(); }
6c5f2c01 sago007 2017-03-15 17:56 1506
    //! \em Past-the-end element iterator
6c5f2c01 sago007 2017-03-15 17:56 1507
    /*! \pre IsArray() == true */
6c5f2c01 sago007 2017-03-15 17:56 1508
    ValueIterator End() { CEREAL_RAPIDJSON_ASSERT(IsArray()); return GetElementsPointer() + data_.a.size; }
6c5f2c01 sago007 2017-03-15 17:56 1509
    //! Constant element iterator
6c5f2c01 sago007 2017-03-15 17:56 1510
    /*! \pre IsArray() == true */
6c5f2c01 sago007 2017-03-15 17:56 1511
    ConstValueIterator Begin() const { return const_cast<GenericValue&>(*this).Begin(); }
6c5f2c01 sago007 2017-03-15 17:56 1512
    //! Constant \em past-the-end element iterator
6c5f2c01 sago007 2017-03-15 17:56 1513
    /*! \pre IsArray() == true */
6c5f2c01 sago007 2017-03-15 17:56 1514
    ConstValueIterator End() const { return const_cast<GenericValue&>(*this).End(); }
6c5f2c01 sago007 2017-03-15 17:56 1515
6c5f2c01 sago007 2017-03-15 17:56 1516
    //! Request the array to have enough capacity to store elements.
6c5f2c01 sago007 2017-03-15 17:56 1517
    /*! \param newCapacity  The capacity that the array at least need to have.
6c5f2c01 sago007 2017-03-15 17:56 1518
        \param allocator    Allocator for reallocating memory. It must be the same one as used before. Commonly use GenericDocument::GetAllocator().
6c5f2c01 sago007 2017-03-15 17:56 1519
        \return The value itself for fluent API.
6c5f2c01 sago007 2017-03-15 17:56 1520
        \note Linear time complexity.
6c5f2c01 sago007 2017-03-15 17:56 1521
    */
6c5f2c01 sago007 2017-03-15 17:56 1522
    GenericValue& Reserve(SizeType newCapacity, Allocator &allocator) {
6c5f2c01 sago007 2017-03-15 17:56 1523
        CEREAL_RAPIDJSON_ASSERT(IsArray());
6c5f2c01 sago007 2017-03-15 17:56 1524
        if (newCapacity > data_.a.capacity) {
6c5f2c01 sago007 2017-03-15 17:56 1525
            SetElementsPointer(reinterpret_cast<GenericValue*>(allocator.Realloc(GetElementsPointer(), data_.a.capacity * sizeof(GenericValue), newCapacity * sizeof(GenericValue))));
6c5f2c01 sago007 2017-03-15 17:56 1526
            data_.a.capacity = newCapacity;
6c5f2c01 sago007 2017-03-15 17:56 1527
        }
6c5f2c01 sago007 2017-03-15 17:56 1528
        return *this;
6c5f2c01 sago007 2017-03-15 17:56 1529
    }
6c5f2c01 sago007 2017-03-15 17:56 1530
6c5f2c01 sago007 2017-03-15 17:56 1531
    //! Append a GenericValue at the end of the array.
6c5f2c01 sago007 2017-03-15 17:56 1532
    /*! \param value        Value to be appended.
6c5f2c01 sago007 2017-03-15 17:56 1533
        \param allocator    Allocator for reallocating memory. It must be the same one as used before. Commonly use GenericDocument::GetAllocator().
6c5f2c01 sago007 2017-03-15 17:56 1534
        \pre IsArray() == true
6c5f2c01 sago007 2017-03-15 17:56 1535
        \post value.IsNull() == true
6c5f2c01 sago007 2017-03-15 17:56 1536
        \return The value itself for fluent API.
6c5f2c01 sago007 2017-03-15 17:56 1537
        \note The ownership of \c value will be transferred to this array on success.
6c5f2c01 sago007 2017-03-15 17:56 1538
        \note If the number of elements to be appended is known, calls Reserve() once first may be more efficient.
6c5f2c01 sago007 2017-03-15 17:56 1539
        \note Amortized constant time complexity.
6c5f2c01 sago007 2017-03-15 17:56 1540
    */
6c5f2c01 sago007 2017-03-15 17:56 1541
    GenericValue& PushBack(GenericValue& value, Allocator& allocator) {
6c5f2c01 sago007 2017-03-15 17:56 1542
        CEREAL_RAPIDJSON_ASSERT(IsArray());
6c5f2c01 sago007 2017-03-15 17:56 1543
        if (data_.a.size >= data_.a.capacity)
6c5f2c01 sago007 2017-03-15 17:56 1544
            Reserve(data_.a.capacity == 0 ? kDefaultArrayCapacity : (data_.a.capacity + (data_.a.capacity + 1) / 2), allocator);
6c5f2c01 sago007 2017-03-15 17:56 1545
        GetElementsPointer()[data_.a.size++].RawAssign(value);
6c5f2c01 sago007 2017-03-15 17:56 1546
        return *this;
6c5f2c01 sago007 2017-03-15 17:56 1547
    }
6c5f2c01 sago007 2017-03-15 17:56 1548
6c5f2c01 sago007 2017-03-15 17:56 1549
#if CEREAL_RAPIDJSON_HAS_CXX11_RVALUE_REFS
6c5f2c01 sago007 2017-03-15 17:56 1550
    GenericValue& PushBack(GenericValue&& value, Allocator& allocator) {
6c5f2c01 sago007 2017-03-15 17:56 1551
        return PushBack(value, allocator);
6c5f2c01 sago007 2017-03-15 17:56 1552
    }
6c5f2c01 sago007 2017-03-15 17:56 1553
#endif // CEREAL_RAPIDJSON_HAS_CXX11_RVALUE_REFS
6c5f2c01 sago007 2017-03-15 17:56 1554
6c5f2c01 sago007 2017-03-15 17:56 1555
    //! Append a constant string reference at the end of the array.
6c5f2c01 sago007 2017-03-15 17:56 1556
    /*! \param value        Constant string reference to be appended.
6c5f2c01 sago007 2017-03-15 17:56 1557
        \param allocator    Allocator for reallocating memory. It must be the same one used previously. Commonly use GenericDocument::GetAllocator().
6c5f2c01 sago007 2017-03-15 17:56 1558
        \pre IsArray() == true
6c5f2c01 sago007 2017-03-15 17:56 1559
        \return The value itself for fluent API.
6c5f2c01 sago007 2017-03-15 17:56 1560
        \note If the number of elements to be appended is known, calls Reserve() once first may be more efficient.
6c5f2c01 sago007 2017-03-15 17:56 1561
        \note Amortized constant time complexity.
6c5f2c01 sago007 2017-03-15 17:56 1562
        \see GenericStringRef
6c5f2c01 sago007 2017-03-15 17:56 1563
    */
6c5f2c01 sago007 2017-03-15 17:56 1564
    GenericValue& PushBack(StringRefType value, Allocator& allocator) {
6c5f2c01 sago007 2017-03-15 17:56 1565
        return (*this).template PushBack<StringRefType>(value, allocator);
6c5f2c01 sago007 2017-03-15 17:56 1566
    }
6c5f2c01 sago007 2017-03-15 17:56 1567
6c5f2c01 sago007 2017-03-15 17:56 1568
    //! Append a primitive value at the end of the array.
6c5f2c01 sago007 2017-03-15 17:56 1569
    /*! \tparam T Either \ref Type, \c int, \c unsigned, \c int64_t, \c uint64_t
6c5f2c01 sago007 2017-03-15 17:56 1570
        \param value Value of primitive type T to be appended.
6c5f2c01 sago007 2017-03-15 17:56 1571
        \param allocator    Allocator for reallocating memory. It must be the same one as used before. Commonly use GenericDocument::GetAllocator().
6c5f2c01 sago007 2017-03-15 17:56 1572
        \pre IsArray() == true
6c5f2c01 sago007 2017-03-15 17:56 1573
        \return The value itself for fluent API.
6c5f2c01 sago007 2017-03-15 17:56 1574
        \note If the number of elements to be appended is known, calls Reserve() once first may be more efficient.
6c5f2c01 sago007 2017-03-15 17:56 1575
6c5f2c01 sago007 2017-03-15 17:56 1576
        \note The source type \c T explicitly disallows all pointer types,
6c5f2c01 sago007 2017-03-15 17:56 1577
            especially (\c const) \ref Ch*.  This helps avoiding implicitly
6c5f2c01 sago007 2017-03-15 17:56 1578
            referencing character strings with insufficient lifetime, use
6c5f2c01 sago007 2017-03-15 17:56 1579
            \ref PushBack(GenericValue&, Allocator&) or \ref
6c5f2c01 sago007 2017-03-15 17:56 1580
            PushBack(StringRefType, Allocator&).
6c5f2c01 sago007 2017-03-15 17:56 1581
            All other pointer types would implicitly convert to \c bool,
6c5f2c01 sago007 2017-03-15 17:56 1582
            use an explicit cast instead, if needed.
6c5f2c01 sago007 2017-03-15 17:56 1583
        \note Amortized constant time complexity.
6c5f2c01 sago007 2017-03-15 17:56 1584
    */
6c5f2c01 sago007 2017-03-15 17:56 1585
    template <typename T>
6c5f2c01 sago007 2017-03-15 17:56 1586
    CEREAL_RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>, internal::IsGenericValue<T> >), (GenericValue&))
6c5f2c01 sago007 2017-03-15 17:56 1587
    PushBack(T value, Allocator& allocator) {
6c5f2c01 sago007 2017-03-15 17:56 1588
        GenericValue v(value);
6c5f2c01 sago007 2017-03-15 17:56 1589
        return PushBack(v, allocator);
6c5f2c01 sago007 2017-03-15 17:56 1590
    }
6c5f2c01 sago007 2017-03-15 17:56 1591
6c5f2c01 sago007 2017-03-15 17:56 1592
    //! Remove the last element in the array.
6c5f2c01 sago007 2017-03-15 17:56 1593
    /*!
6c5f2c01 sago007 2017-03-15 17:56 1594
        \note Constant time complexity.
6c5f2c01 sago007 2017-03-15 17:56 1595
    */
6c5f2c01 sago007 2017-03-15 17:56 1596
    GenericValue& PopBack() {
6c5f2c01 sago007 2017-03-15 17:56 1597
        CEREAL_RAPIDJSON_ASSERT(IsArray());
6c5f2c01 sago007 2017-03-15 17:56 1598
        CEREAL_RAPIDJSON_ASSERT(!Empty());
6c5f2c01 sago007 2017-03-15 17:56 1599
        GetElementsPointer()[--data_.a.size].~GenericValue();
6c5f2c01 sago007 2017-03-15 17:56 1600
        return *this;
6c5f2c01 sago007 2017-03-15 17:56 1601
    }
6c5f2c01 sago007 2017-03-15 17:56 1602
6c5f2c01 sago007 2017-03-15 17:56 1603
    //! Remove an element of array by iterator.
6c5f2c01 sago007 2017-03-15 17:56 1604
    /*!
6c5f2c01 sago007 2017-03-15 17:56 1605
        \param pos iterator to the element to remove
6c5f2c01 sago007 2017-03-15 17:56 1606
        \pre IsArray() == true && \ref Begin() <= \c pos < \ref End()
6c5f2c01 sago007 2017-03-15 17:56 1607
        \return Iterator following the removed element. If the iterator pos refers to the last element, the End() iterator is returned.
6c5f2c01 sago007 2017-03-15 17:56 1608
        \note Linear time complexity.
6c5f2c01 sago007 2017-03-15 17:56 1609
    */
6c5f2c01 sago007 2017-03-15 17:56 1610
    ValueIterator Erase(ConstValueIterator pos) {
6c5f2c01 sago007 2017-03-15 17:56 1611
        return Erase(pos, pos + 1);
6c5f2c01 sago007 2017-03-15 17:56 1612
    }
6c5f2c01 sago007 2017-03-15 17:56 1613
6c5f2c01 sago007 2017-03-15 17:56 1614
    //! Remove elements in the range [first, last) of the array.
6c5f2c01 sago007 2017-03-15 17:56 1615
    /*!
6c5f2c01 sago007 2017-03-15 17:56 1616
        \param first iterator to the first element to remove
6c5f2c01 sago007 2017-03-15 17:56 1617
        \param last  iterator following the last element to remove
6c5f2c01 sago007 2017-03-15 17:56 1618
        \pre IsArray() == true && \ref Begin() <= \c first <= \c last <= \ref End()
6c5f2c01 sago007 2017-03-15 17:56 1619
        \return Iterator following the last removed element.
6c5f2c01 sago007 2017-03-15 17:56 1620
        \note Linear time complexity.
6c5f2c01 sago007 2017-03-15 17:56 1621
    */
6c5f2c01 sago007 2017-03-15 17:56 1622
    ValueIterator Erase(ConstValueIterator first, ConstValueIterator last) {
6c5f2c01 sago007 2017-03-15 17:56 1623
        CEREAL_RAPIDJSON_ASSERT(IsArray());
6c5f2c01 sago007 2017-03-15 17:56 1624
        CEREAL_RAPIDJSON_ASSERT(data_.a.size > 0);
6c5f2c01 sago007 2017-03-15 17:56 1625
        CEREAL_RAPIDJSON_ASSERT(GetElementsPointer() != 0);
6c5f2c01 sago007 2017-03-15 17:56 1626
        CEREAL_RAPIDJSON_ASSERT(first >= Begin());
6c5f2c01 sago007 2017-03-15 17:56 1627
        CEREAL_RAPIDJSON_ASSERT(first <= last);
6c5f2c01 sago007 2017-03-15 17:56 1628
        CEREAL_RAPIDJSON_ASSERT(last <= End());
6c5f2c01 sago007 2017-03-15 17:56 1629
        ValueIterator pos = Begin() + (first - Begin());
6c5f2c01 sago007 2017-03-15 17:56 1630
        for (ValueIterator itr = pos; itr != last; ++itr)
6c5f2c01 sago007 2017-03-15 17:56 1631
            itr->~GenericValue();       
6c5f2c01 sago007 2017-03-15 17:56 1632
        std::memmove(pos, last, static_cast<size_t>(End() - last) * sizeof(GenericValue));
6c5f2c01 sago007 2017-03-15 17:56 1633
        data_.a.size -= static_cast<SizeType>(last - first);
6c5f2c01 sago007 2017-03-15 17:56 1634
        return pos;
6c5f2c01 sago007 2017-03-15 17:56 1635
    }
6c5f2c01 sago007 2017-03-15 17:56 1636
6c5f2c01 sago007 2017-03-15 17:56 1637
    Array GetArray() { CEREAL_RAPIDJSON_ASSERT(IsArray()); return Array(*this); }
6c5f2c01 sago007 2017-03-15 17:56 1638
    ConstArray GetArray() const { CEREAL_RAPIDJSON_ASSERT(IsArray()); return ConstArray(*this); }
6c5f2c01 sago007 2017-03-15 17:56 1639
6c5f2c01 sago007 2017-03-15 17:56 1640
    //@}
6c5f2c01 sago007 2017-03-15 17:56 1641
6c5f2c01 sago007 2017-03-15 17:56 1642
    //!@name Number
6c5f2c01 sago007 2017-03-15 17:56 1643
    //@{
6c5f2c01 sago007 2017-03-15 17:56 1644
6c5f2c01 sago007 2017-03-15 17:56 1645
    int GetInt() const          { CEREAL_RAPIDJSON_ASSERT(data_.f.flags & kIntFlag);   return data_.n.i.i;   }
6c5f2c01 sago007 2017-03-15 17:56 1646
    unsigned GetUint() const    { CEREAL_RAPIDJSON_ASSERT(data_.f.flags & kUintFlag);  return data_.n.u.u;   }
6c5f2c01 sago007 2017-03-15 17:56 1647
    int64_t GetInt64() const    { CEREAL_RAPIDJSON_ASSERT(data_.f.flags & kInt64Flag); return data_.n.i64; }
6c5f2c01 sago007 2017-03-15 17:56 1648
    uint64_t GetUint64() const  { CEREAL_RAPIDJSON_ASSERT(data_.f.flags & kUint64Flag); return data_.n.u64; }
6c5f2c01 sago007 2017-03-15 17:56 1649
6c5f2c01 sago007 2017-03-15 17:56 1650
    //! Get the value as double type.
6c5f2c01 sago007 2017-03-15 17:56 1651
    /*! \note If the value is 64-bit integer type, it may lose precision. Use \c IsLosslessDouble() to check whether the converison is lossless.
6c5f2c01 sago007 2017-03-15 17:56 1652
    */
6c5f2c01 sago007 2017-03-15 17:56 1653
    double GetDouble() const {
6c5f2c01 sago007 2017-03-15 17:56 1654
        CEREAL_RAPIDJSON_ASSERT(IsNumber());
6c5f2c01 sago007 2017-03-15 17:56 1655
        if ((data_.f.flags & kDoubleFlag) != 0)                return data_.n.d;   // exact type, no conversion.
6c5f2c01 sago007 2017-03-15 17:56 1656
        if ((data_.f.flags & kIntFlag) != 0)                   return data_.n.i.i; // int -> double
6c5f2c01 sago007 2017-03-15 17:56 1657
        if ((data_.f.flags & kUintFlag) != 0)                  return data_.n.u.u; // unsigned -> double
6c5f2c01 sago007 2017-03-15 17:56 1658
        if ((data_.f.flags & kInt64Flag) != 0)                 return static_cast<double>(data_.n.i64); // int64_t -> double (may lose precision)
6c5f2c01 sago007 2017-03-15 17:56 1659
        CEREAL_RAPIDJSON_ASSERT((data_.f.flags & kUint64Flag) != 0);  return static_cast<double>(data_.n.u64); // uint64_t -> double (may lose precision)
6c5f2c01 sago007 2017-03-15 17:56 1660
    }
6c5f2c01 sago007 2017-03-15 17:56 1661
6c5f2c01 sago007 2017-03-15 17:56 1662
    //! Get the value as float type.
6c5f2c01 sago007 2017-03-15 17:56 1663
    /*! \note If the value is 64-bit integer type, it may lose precision. Use \c IsLosslessFloat() to check whether the converison is lossless.
6c5f2c01 sago007 2017-03-15 17:56 1664
    */
6c5f2c01 sago007 2017-03-15 17:56 1665
    float GetFloat() const {
6c5f2c01 sago007 2017-03-15 17:56 1666
        return static_cast<float>(GetDouble());
6c5f2c01 sago007 2017-03-15 17:56 1667
    }
6c5f2c01 sago007 2017-03-15 17:56 1668
6c5f2c01 sago007 2017-03-15 17:56 1669
    GenericValue& SetInt(int i)             { this->~GenericValue(); new (this) GenericValue(i);    return *this; }
6c5f2c01 sago007 2017-03-15 17:56 1670
    GenericValue& SetUint(unsigned u)       { this->~GenericValue(); new (this) GenericValue(u);    return *this; }
6c5f2c01 sago007 2017-03-15 17:56 1671
    GenericValue& SetInt64(int64_t i64)     { this->~GenericValue(); new (this) GenericValue(i64);  return *this; }
6c5f2c01 sago007 2017-03-15 17:56 1672
    GenericValue& SetUint64(uint64_t u64)   { this->~GenericValue(); new (this) GenericValue(u64);  return *this; }
6c5f2c01 sago007 2017-03-15 17:56 1673
    GenericValue& SetDouble(double d)       { this->~GenericValue(); new (this) GenericValue(d);    return *this; }
6c5f2c01 sago007 2017-03-15 17:56 1674
    GenericValue& SetFloat(float f)         { this->~GenericValue(); new (this) GenericValue(f);    return *this; }
6c5f2c01 sago007 2017-03-15 17:56 1675
6c5f2c01 sago007 2017-03-15 17:56 1676
    //@}
6c5f2c01 sago007 2017-03-15 17:56 1677
6c5f2c01 sago007 2017-03-15 17:56 1678
    //!@name String
6c5f2c01 sago007 2017-03-15 17:56 1679
    //@{
6c5f2c01 sago007 2017-03-15 17:56 1680
6c5f2c01 sago007 2017-03-15 17:56 1681
    const Ch* GetString() const { CEREAL_RAPIDJSON_ASSERT(IsString()); return (data_.f.flags & kInlineStrFlag) ? data_.ss.str : GetStringPointer(); }
6c5f2c01 sago007 2017-03-15 17:56 1682
6c5f2c01 sago007 2017-03-15 17:56 1683
    //! Get the length of string.
6c5f2c01 sago007 2017-03-15 17:56 1684
    /*! Since rapidjson permits "\\u0000" in the json string, strlen(v.GetString()) may not equal to v.GetStringLength().
6c5f2c01 sago007 2017-03-15 17:56 1685
    */
6c5f2c01 sago007 2017-03-15 17:56 1686
    SizeType GetStringLength() const { CEREAL_RAPIDJSON_ASSERT(IsString()); return ((data_.f.flags & kInlineStrFlag) ? (data_.ss.GetLength()) : data_.s.length); }
6c5f2c01 sago007 2017-03-15 17:56 1687
6c5f2c01 sago007 2017-03-15 17:56 1688
    //! Set this value as a string without copying source string.
6c5f2c01 sago007 2017-03-15 17:56 1689
    /*! This version has better performance with supplied length, and also support string containing null character.
6c5f2c01 sago007 2017-03-15 17:56 1690
        \param s source string pointer. 
6c5f2c01 sago007 2017-03-15 17:56 1691
        \param length The length of source string, excluding the trailing null terminator.
6c5f2c01 sago007 2017-03-15 17:56 1692
        \return The value itself for fluent API.
6c5f2c01 sago007 2017-03-15 17:56 1693
        \post IsString() == true && GetString() == s && GetStringLength() == length
6c5f2c01 sago007 2017-03-15 17:56 1694
        \see SetString(StringRefType)
6c5f2c01 sago007 2017-03-15 17:56 1695
    */
6c5f2c01 sago007 2017-03-15 17:56 1696
    GenericValue& SetString(const Ch* s, SizeType length) { return SetString(StringRef(s, length)); }
6c5f2c01 sago007 2017-03-15 17:56 1697
6c5f2c01 sago007 2017-03-15 17:56 1698
    //! Set this value as a string without copying source string.
6c5f2c01 sago007 2017-03-15 17:56 1699
    /*! \param s source string reference
6c5f2c01 sago007 2017-03-15 17:56 1700
        \return The value itself for fluent API.
6c5f2c01 sago007 2017-03-15 17:56 1701
        \post IsString() == true && GetString() == s && GetStringLength() == s.length
6c5f2c01 sago007 2017-03-15 17:56 1702
    */
6c5f2c01 sago007 2017-03-15 17:56 1703
    GenericValue& SetString(StringRefType s) { this->~GenericValue(); SetStringRaw(s); return *this; }
6c5f2c01 sago007 2017-03-15 17:56 1704
6c5f2c01 sago007 2017-03-15 17:56 1705
    //! Set this value as a string by copying from source string.
6c5f2c01 sago007 2017-03-15 17:56 1706
    /*! This version has better performance with supplied length, and also support string containing null character.
6c5f2c01 sago007 2017-03-15 17:56 1707
        \param s source string. 
6c5f2c01 sago007 2017-03-15 17:56 1708
        \param length The length of source string, excluding the trailing null terminator.
6c5f2c01 sago007 2017-03-15 17:56 1709
        \param allocator Allocator for allocating copied buffer. Commonly use GenericDocument::GetAllocator().
6c5f2c01 sago007 2017-03-15 17:56 1710
        \return The value itself for fluent API.
6c5f2c01 sago007 2017-03-15 17:56 1711
        \post IsString() == true && GetString() != s && strcmp(GetString(),s) == 0 && GetStringLength() == length
6c5f2c01 sago007 2017-03-15 17:56 1712
    */
6c5f2c01 sago007 2017-03-15 17:56 1713
    GenericValue& SetString(const Ch* s, SizeType length, Allocator& allocator) { this->~GenericValue(); SetStringRaw(StringRef(s, length), allocator); return *this; }
6c5f2c01 sago007 2017-03-15 17:56 1714
6c5f2c01 sago007 2017-03-15 17:56 1715
    //! Set this value as a string by copying from source string.
6c5f2c01 sago007 2017-03-15 17:56 1716
    /*! \param s source string. 
6c5f2c01 sago007 2017-03-15 17:56 1717
        \param allocator Allocator for allocating copied buffer. Commonly use GenericDocument::GetAllocator().
6c5f2c01 sago007 2017-03-15 17:56 1718
        \return The value itself for fluent API.
6c5f2c01 sago007 2017-03-15 17:56 1719
        \post IsString() == true && GetString() != s && strcmp(GetString(),s) == 0 && GetStringLength() == length
6c5f2c01 sago007 2017-03-15 17:56 1720
    */
6c5f2c01 sago007 2017-03-15 17:56 1721
    GenericValue& SetString(const Ch* s, Allocator& allocator) { return SetString(s, internal::StrLen(s), allocator); }
6c5f2c01 sago007 2017-03-15 17:56 1722
6c5f2c01 sago007 2017-03-15 17:56 1723
#if CEREAL_RAPIDJSON_HAS_STDSTRING
6c5f2c01 sago007 2017-03-15 17:56 1724
    //! Set this value as a string by copying from source string.
6c5f2c01 sago007 2017-03-15 17:56 1725
    /*! \param s source string.
6c5f2c01 sago007 2017-03-15 17:56 1726
        \param allocator Allocator for allocating copied buffer. Commonly use GenericDocument::GetAllocator().
6c5f2c01 sago007 2017-03-15 17:56 1727
        \return The value itself for fluent API.
6c5f2c01 sago007 2017-03-15 17:56 1728
        \post IsString() == true && GetString() != s.data() && strcmp(GetString(),s.data() == 0 && GetStringLength() == s.size()
6c5f2c01 sago007 2017-03-15 17:56 1729
        \note Requires the definition of the preprocessor symbol \ref CEREAL_RAPIDJSON_HAS_STDSTRING.
6c5f2c01 sago007 2017-03-15 17:56 1730
    */
6c5f2c01 sago007 2017-03-15 17:56 1731
    GenericValue& SetString(const std::basic_string<Ch>& s, Allocator& allocator) { return SetString(s.data(), SizeType(s.size()), allocator); }
6c5f2c01 sago007 2017-03-15 17:56 1732
#endif
6c5f2c01 sago007 2017-03-15 17:56 1733
6c5f2c01 sago007 2017-03-15 17:56 1734
    //@}
6c5f2c01 sago007 2017-03-15 17:56 1735
6c5f2c01 sago007 2017-03-15 17:56 1736
    //!@name Array
6c5f2c01 sago007 2017-03-15 17:56 1737
    //@{
6c5f2c01 sago007 2017-03-15 17:56 1738
6c5f2c01 sago007 2017-03-15 17:56 1739
    //! Templated version for checking whether this value is type T.
6c5f2c01 sago007 2017-03-15 17:56 1740
    /*!
6c5f2c01 sago007 2017-03-15 17:56 1741
        \tparam T Either \c bool, \c int, \c unsigned, \c int64_t, \c uint64_t, \c double, \c float, \c const \c char*, \c std::basic_string<Ch>
6c5f2c01 sago007 2017-03-15 17:56 1742
    */
6c5f2c01 sago007 2017-03-15 17:56 1743
    template <typename T>
6c5f2c01 sago007 2017-03-15 17:56 1744
    bool Is() const { return internal::TypeHelper<ValueType, T>::Is(*this); }
6c5f2c01 sago007 2017-03-15 17:56 1745
6c5f2c01 sago007 2017-03-15 17:56 1746
    template <typename T>
6c5f2c01 sago007 2017-03-15 17:56 1747
    T Get() const { return internal::TypeHelper<ValueType, T>::Get(*this); }
6c5f2c01 sago007 2017-03-15 17:56 1748
6c5f2c01 sago007 2017-03-15 17:56 1749
    template <typename T>
6c5f2c01 sago007 2017-03-15 17:56 1750
    T Get() { return internal::TypeHelper<ValueType, T>::Get(*this); }
6c5f2c01 sago007 2017-03-15 17:56 1751
6c5f2c01 sago007 2017-03-15 17:56 1752
    template<typename T>
6c5f2c01 sago007 2017-03-15 17:56 1753
    ValueType& Set(const T& data) { return internal::TypeHelper<ValueType, T>::Set(*this, data); }
6c5f2c01 sago007 2017-03-15 17:56 1754
6c5f2c01 sago007 2017-03-15 17:56 1755
    template<typename T>
6c5f2c01 sago007 2017-03-15 17:56 1756
    ValueType& Set(const T& data, AllocatorType& allocator) { return internal::TypeHelper<ValueType, T>::Set(*this, data, allocator); }
6c5f2c01 sago007 2017-03-15 17:56 1757
6c5f2c01 sago007 2017-03-15 17:56 1758
    //@}
6c5f2c01 sago007 2017-03-15 17:56 1759
6c5f2c01 sago007 2017-03-15 17:56 1760
    //! Generate events of this value to a Handler.
6c5f2c01 sago007 2017-03-15 17:56 1761
    /*! This function adopts the GoF visitor pattern.
6c5f2c01 sago007 2017-03-15 17:56 1762
        Typical usage is to output this JSON value as JSON text via Writer, which is a Handler.
6c5f2c01 sago007 2017-03-15 17:56 1763
        It can also be used to deep clone this value via GenericDocument, which is also a Handler.
6c5f2c01 sago007 2017-03-15 17:56 1764
        \tparam Handler type of handler.
6c5f2c01 sago007 2017-03-15 17:56 1765
        \param handler An object implementing concept Handler.
6c5f2c01 sago007 2017-03-15 17:56 1766
    */
6c5f2c01 sago007 2017-03-15 17:56 1767
    template <typename Handler>
6c5f2c01 sago007 2017-03-15 17:56 1768
    bool Accept(Handler& handler) const {
6c5f2c01 sago007 2017-03-15 17:56 1769
        switch(GetType()) {
6c5f2c01 sago007 2017-03-15 17:56 1770
        case kNullType:     return handler.Null();
6c5f2c01 sago007 2017-03-15 17:56 1771
        case kFalseType:    return handler.Bool(false);
6c5f2c01 sago007 2017-03-15 17:56 1772
        case kTrueType:     return handler.Bool(true);
6c5f2c01 sago007 2017-03-15 17:56 1773
6c5f2c01 sago007 2017-03-15 17:56 1774
        case kObjectType:
6c5f2c01 sago007 2017-03-15 17:56 1775
            if (CEREAL_RAPIDJSON_UNLIKELY(!handler.StartObject()))
6c5f2c01 sago007 2017-03-15 17:56 1776
                return false;
6c5f2c01 sago007 2017-03-15 17:56 1777
            for (ConstMemberIterator m = MemberBegin(); m != MemberEnd(); ++m) {
6c5f2c01 sago007 2017-03-15 17:56 1778
                CEREAL_RAPIDJSON_ASSERT(m->name.IsString()); // User may change the type of name by MemberIterator.
6c5f2c01 sago007 2017-03-15 17:56 1779
                if (CEREAL_RAPIDJSON_UNLIKELY(!handler.Key(m->name.GetString(), m->name.GetStringLength(), (m->name.data_.f.flags & kCopyFlag) != 0)))
6c5f2c01 sago007 2017-03-15 17:56 1780
                    return false;
6c5f2c01 sago007 2017-03-15 17:56 1781
                if (CEREAL_RAPIDJSON_UNLIKELY(!m->value.Accept(handler)))
6c5f2c01 sago007 2017-03-15 17:56 1782
                    return false;
6c5f2c01 sago007 2017-03-15 17:56 1783
            }
6c5f2c01 sago007 2017-03-15 17:56 1784
            return handler.EndObject(data_.o.size);
6c5f2c01 sago007 2017-03-15 17:56 1785
6c5f2c01 sago007 2017-03-15 17:56 1786
        case kArrayType:
6c5f2c01 sago007 2017-03-15 17:56 1787
            if (CEREAL_RAPIDJSON_UNLIKELY(!handler.StartArray()))
6c5f2c01 sago007 2017-03-15 17:56 1788
                return false;
6c5f2c01 sago007 2017-03-15 17:56 1789
            for (const GenericValue* v = Begin(); v != End(); ++v)
6c5f2c01 sago007 2017-03-15 17:56 1790
                if (CEREAL_RAPIDJSON_UNLIKELY(!v->Accept(handler)))
6c5f2c01 sago007 2017-03-15 17:56 1791
                    return false;
6c5f2c01 sago007 2017-03-15 17:56 1792
            return handler.EndArray(data_.a.size);
6c5f2c01 sago007 2017-03-15 17:56 1793
    
6c5f2c01 sago007 2017-03-15 17:56 1794
        case kStringType:
6c5f2c01 sago007 2017-03-15 17:56 1795
            return handler.String(GetString(), GetStringLength(), (data_.f.flags & kCopyFlag) != 0);
6c5f2c01 sago007 2017-03-15 17:56 1796
    
6c5f2c01 sago007 2017-03-15 17:56 1797
        default:
6c5f2c01 sago007 2017-03-15 17:56 1798
            CEREAL_RAPIDJSON_ASSERT(GetType() == kNumberType);
6c5f2c01 sago007 2017-03-15 17:56 1799
            if (IsDouble())         return handler.Double(data_.n.d);
6c5f2c01 sago007 2017-03-15 17:56 1800
            else if (IsInt())       return handler.Int(data_.n.i.i);
6c5f2c01 sago007 2017-03-15 17:56 1801
            else if (IsUint())      return handler.Uint(data_.n.u.u);
6c5f2c01 sago007 2017-03-15 17:56 1802
            else if (IsInt64())     return handler.Int64(data_.n.i64);
6c5f2c01 sago007 2017-03-15 17:56 1803
            else                    return handler.Uint64(data_.n.u64);
6c5f2c01 sago007 2017-03-15 17:56 1804
        }
6c5f2c01 sago007 2017-03-15 17:56 1805
    }
7a956470 sago007 2016-02-14 17:09 1806
7a956470 sago007 2016-02-14 17:09 1807
private:
6c5f2c01 sago007 2017-03-15 17:56 1808
    template <typename, typename> friend class GenericValue;
6c5f2c01 sago007 2017-03-15 17:56 1809
    template <typename, typename, typename> friend class GenericDocument;
6c5f2c01 sago007 2017-03-15 17:56 1810
6c5f2c01 sago007 2017-03-15 17:56 1811
    enum {
6c5f2c01 sago007 2017-03-15 17:56 1812
        kBoolFlag       = 0x0008,
6c5f2c01 sago007 2017-03-15 17:56 1813
        kNumberFlag     = 0x0010,
6c5f2c01 sago007 2017-03-15 17:56 1814
        kIntFlag        = 0x0020,
6c5f2c01 sago007 2017-03-15 17:56 1815
        kUintFlag       = 0x0040,
6c5f2c01 sago007 2017-03-15 17:56 1816
        kInt64Flag      = 0x0080,
6c5f2c01 sago007 2017-03-15 17:56 1817
        kUint64Flag     = 0x0100,
6c5f2c01 sago007 2017-03-15 17:56 1818
        kDoubleFlag     = 0x0200,
6c5f2c01 sago007 2017-03-15 17:56 1819
        kStringFlag     = 0x0400,
6c5f2c01 sago007 2017-03-15 17:56 1820
        kCopyFlag       = 0x0800,
6c5f2c01 sago007 2017-03-15 17:56 1821
        kInlineStrFlag  = 0x1000,
6c5f2c01 sago007 2017-03-15 17:56 1822
6c5f2c01 sago007 2017-03-15 17:56 1823
        // Initial flags of different types.
6c5f2c01 sago007 2017-03-15 17:56 1824
        kNullFlag = kNullType,
6c5f2c01 sago007 2017-03-15 17:56 1825
        kTrueFlag = kTrueType | kBoolFlag,
6c5f2c01 sago007 2017-03-15 17:56 1826
        kFalseFlag = kFalseType | kBoolFlag,
6c5f2c01 sago007 2017-03-15 17:56 1827
        kNumberIntFlag = kNumberType | kNumberFlag | kIntFlag | kInt64Flag,
6c5f2c01 sago007 2017-03-15 17:56 1828
        kNumberUintFlag = kNumberType | kNumberFlag | kUintFlag | kUint64Flag | kInt64Flag,
6c5f2c01 sago007 2017-03-15 17:56 1829
        kNumberInt64Flag = kNumberType | kNumberFlag | kInt64Flag,
6c5f2c01 sago007 2017-03-15 17:56 1830
        kNumberUint64Flag = kNumberType | kNumberFlag | kUint64Flag,
6c5f2c01 sago007 2017-03-15 17:56 1831
        kNumberDoubleFlag = kNumberType | kNumberFlag | kDoubleFlag,
6c5f2c01 sago007 2017-03-15 17:56 1832
        kNumberAnyFlag = kNumberType | kNumberFlag | kIntFlag | kInt64Flag | kUintFlag | kUint64Flag | kDoubleFlag,
6c5f2c01 sago007 2017-03-15 17:56 1833
        kConstStringFlag = kStringType | kStringFlag,
6c5f2c01 sago007 2017-03-15 17:56 1834
        kCopyStringFlag = kStringType | kStringFlag | kCopyFlag,
6c5f2c01 sago007 2017-03-15 17:56 1835
        kShortStringFlag = kStringType | kStringFlag | kCopyFlag | kInlineStrFlag,
6c5f2c01 sago007 2017-03-15 17:56 1836
        kObjectFlag = kObjectType,
6c5f2c01 sago007 2017-03-15 17:56 1837
        kArrayFlag = kArrayType,
6c5f2c01 sago007 2017-03-15 17:56 1838
6c5f2c01 sago007 2017-03-15 17:56 1839
        kTypeMask = 0x07
6c5f2c01 sago007 2017-03-15 17:56 1840
    };
6c5f2c01 sago007 2017-03-15 17:56 1841
6c5f2c01 sago007 2017-03-15 17:56 1842
    static const SizeType kDefaultArrayCapacity = 16;
6c5f2c01 sago007 2017-03-15 17:56 1843
    static const SizeType kDefaultObjectCapacity = 16;
6c5f2c01 sago007 2017-03-15 17:56 1844
6c5f2c01 sago007 2017-03-15 17:56 1845
    struct Flag {
6c5f2c01 sago007 2017-03-15 17:56 1846
#if CEREAL_RAPIDJSON_48BITPOINTER_OPTIMIZATION
6c5f2c01 sago007 2017-03-15 17:56 1847
        char payload[sizeof(SizeType) * 2 + 6];     // 2 x SizeType + lower 48-bit pointer
6c5f2c01 sago007 2017-03-15 17:56 1848
#elif CEREAL_RAPIDJSON_64BIT
6c5f2c01 sago007 2017-03-15 17:56 1849
        char payload[sizeof(SizeType) * 2 + sizeof(void*) + 6]; // 6 padding bytes
7a956470 sago007 2016-02-14 17:09 1850
#else
6c5f2c01 sago007 2017-03-15 17:56 1851
        char payload[sizeof(SizeType) * 2 + sizeof(void*) + 2]; // 2 padding bytes
6c5f2c01 sago007 2017-03-15 17:56 1852
#endif
6c5f2c01 sago007 2017-03-15 17:56 1853
        uint16_t flags;
6c5f2c01 sago007 2017-03-15 17:56 1854
    };
6c5f2c01 sago007 2017-03-15 17:56 1855
6c5f2c01 sago007 2017-03-15 17:56 1856
    struct String {
6c5f2c01 sago007 2017-03-15 17:56 1857
        SizeType length;
6c5f2c01 sago007 2017-03-15 17:56 1858
        SizeType hashcode;  //!< reserved
6c5f2c01 sago007 2017-03-15 17:56 1859
        const Ch* str;
6c5f2c01 sago007 2017-03-15 17:56 1860
    };  // 12 bytes in 32-bit mode, 16 bytes in 64-bit mode
6c5f2c01 sago007 2017-03-15 17:56 1861
6c5f2c01 sago007 2017-03-15 17:56 1862
    // implementation detail: ShortString can represent zero-terminated strings up to MaxSize chars
6c5f2c01 sago007 2017-03-15 17:56 1863
    // (excluding the terminating zero) and store a value to determine the length of the contained
6c5f2c01 sago007 2017-03-15 17:56 1864
    // string in the last character str[LenPos] by storing "MaxSize - length" there. If the string
6c5f2c01 sago007 2017-03-15 17:56 1865
    // to store has the maximal length of MaxSize then str[LenPos] will be 0 and therefore act as
6c5f2c01 sago007 2017-03-15 17:56 1866
    // the string terminator as well. For getting the string length back from that value just use
6c5f2c01 sago007 2017-03-15 17:56 1867
    // "MaxSize - str[LenPos]".
6c5f2c01 sago007 2017-03-15 17:56 1868
    // This allows to store 13-chars strings in 32-bit mode, 21-chars strings in 64-bit mode,
6c5f2c01 sago007 2017-03-15 17:56 1869
    // 13-chars strings for CEREAL_RAPIDJSON_48BITPOINTER_OPTIMIZATION=1 inline (for `UTF8`-encoded strings).
6c5f2c01 sago007 2017-03-15 17:56 1870
    struct ShortString {
6c5f2c01 sago007 2017-03-15 17:56 1871
        enum { MaxChars = sizeof(static_cast<Flag*>(0)->payload) / sizeof(Ch), MaxSize = MaxChars - 1, LenPos = MaxSize };
6c5f2c01 sago007 2017-03-15 17:56 1872
        Ch str[MaxChars];
6c5f2c01 sago007 2017-03-15 17:56 1873
6c5f2c01 sago007 2017-03-15 17:56 1874
        inline static bool Usable(SizeType len) { return                       (MaxSize >= len); }
6c5f2c01 sago007 2017-03-15 17:56 1875
        inline void     SetLength(SizeType len) { str[LenPos] = static_cast<Ch>(MaxSize -  len); }
6c5f2c01 sago007 2017-03-15 17:56 1876
        inline SizeType GetLength() const       { return  static_cast<SizeType>(MaxSize -  str[LenPos]); }
6c5f2c01 sago007 2017-03-15 17:56 1877
    };  // at most as many bytes as "String" above => 12 bytes in 32-bit mode, 16 bytes in 64-bit mode
6c5f2c01 sago007 2017-03-15 17:56 1878
6c5f2c01 sago007 2017-03-15 17:56 1879
    // By using proper binary layout, retrieval of different integer types do not need conversions.
6c5f2c01 sago007 2017-03-15 17:56 1880
    union Number {
6c5f2c01 sago007 2017-03-15 17:56 1881
#if CEREAL_RAPIDJSON_ENDIAN == CEREAL_RAPIDJSON_LITTLEENDIAN
6c5f2c01 sago007 2017-03-15 17:56 1882
        struct I {
6c5f2c01 sago007 2017-03-15 17:56 1883
            int i;
6c5f2c01 sago007 2017-03-15 17:56 1884
            char padding[4];
6c5f2c01 sago007 2017-03-15 17:56 1885
        }i;
6c5f2c01 sago007 2017-03-15 17:56 1886
        struct U {
6c5f2c01 sago007 2017-03-15 17:56 1887
            unsigned u;
6c5f2c01 sago007 2017-03-15 17:56 1888
            char padding2[4];
6c5f2c01 sago007 2017-03-15 17:56 1889
        }u;
6c5f2c01 sago007 2017-03-15 17:56 1890
#else
6c5f2c01 sago007 2017-03-15 17:56 1891
        struct I {
6c5f2c01 sago007 2017-03-15 17:56 1892
            char padding[4];
6c5f2c01 sago007 2017-03-15 17:56 1893
            int i;
6c5f2c01 sago007 2017-03-15 17:56 1894
        }i;
6c5f2c01 sago007 2017-03-15 17:56 1895
        struct U {
6c5f2c01 sago007 2017-03-15 17:56 1896
            char padding2[4];
6c5f2c01 sago007 2017-03-15 17:56 1897
            unsigned u;
6c5f2c01 sago007 2017-03-15 17:56 1898
        }u;
6c5f2c01 sago007 2017-03-15 17:56 1899
#endif
6c5f2c01 sago007 2017-03-15 17:56 1900
        int64_t i64;
6c5f2c01 sago007 2017-03-15 17:56 1901
        uint64_t u64;
6c5f2c01 sago007 2017-03-15 17:56 1902
        double d;
6c5f2c01 sago007 2017-03-15 17:56 1903
    };  // 8 bytes
6c5f2c01 sago007 2017-03-15 17:56 1904
6c5f2c01 sago007 2017-03-15 17:56 1905
    struct ObjectData {
6c5f2c01 sago007 2017-03-15 17:56 1906
        SizeType size;
6c5f2c01 sago007 2017-03-15 17:56 1907
        SizeType capacity;
6c5f2c01 sago007 2017-03-15 17:56 1908
        Member* members;
6c5f2c01 sago007 2017-03-15 17:56 1909
    };  // 12 bytes in 32-bit mode, 16 bytes in 64-bit mode
6c5f2c01 sago007 2017-03-15 17:56 1910
6c5f2c01 sago007 2017-03-15 17:56 1911
    struct ArrayData {
6c5f2c01 sago007 2017-03-15 17:56 1912
        SizeType size;
6c5f2c01 sago007 2017-03-15 17:56 1913
        SizeType capacity;
6c5f2c01 sago007 2017-03-15 17:56 1914
        GenericValue* elements;
6c5f2c01 sago007 2017-03-15 17:56 1915
    };  // 12 bytes in 32-bit mode, 16 bytes in 64-bit mode
6c5f2c01 sago007 2017-03-15 17:56 1916
6c5f2c01 sago007 2017-03-15 17:56 1917
    union Data {
6c5f2c01 sago007 2017-03-15 17:56 1918
        String s;
6c5f2c01 sago007 2017-03-15 17:56 1919
        ShortString ss;
6c5f2c01 sago007 2017-03-15 17:56 1920
        Number n;
6c5f2c01 sago007 2017-03-15 17:56 1921
        ObjectData o;
6c5f2c01 sago007 2017-03-15 17:56 1922
        ArrayData a;
6c5f2c01 sago007 2017-03-15 17:56 1923
        Flag f;
6c5f2c01 sago007 2017-03-15 17:56 1924
    };  // 16 bytes in 32-bit mode, 24 bytes in 64-bit mode, 16 bytes in 64-bit with CEREAL_RAPIDJSON_48BITPOINTER_OPTIMIZATION
6c5f2c01 sago007 2017-03-15 17:56 1925
6c5f2c01 sago007 2017-03-15 17:56 1926
    CEREAL_RAPIDJSON_FORCEINLINE const Ch* GetStringPointer() const { return CEREAL_RAPIDJSON_GETPOINTER(Ch, data_.s.str); }
6c5f2c01 sago007 2017-03-15 17:56 1927
    CEREAL_RAPIDJSON_FORCEINLINE const Ch* SetStringPointer(const Ch* str) { return CEREAL_RAPIDJSON_SETPOINTER(Ch, data_.s.str, str); }
6c5f2c01 sago007 2017-03-15 17:56 1928
    CEREAL_RAPIDJSON_FORCEINLINE GenericValue* GetElementsPointer() const { return CEREAL_RAPIDJSON_GETPOINTER(GenericValue, data_.a.elements); }
6c5f2c01 sago007 2017-03-15 17:56 1929
    CEREAL_RAPIDJSON_FORCEINLINE GenericValue* SetElementsPointer(GenericValue* elements) { return CEREAL_RAPIDJSON_SETPOINTER(GenericValue, data_.a.elements, elements); }
6c5f2c01 sago007 2017-03-15 17:56 1930
    CEREAL_RAPIDJSON_FORCEINLINE Member* GetMembersPointer() const { return CEREAL_RAPIDJSON_GETPOINTER(Member, data_.o.members); }
6c5f2c01 sago007 2017-03-15 17:56 1931
    CEREAL_RAPIDJSON_FORCEINLINE Member* SetMembersPointer(Member* members) { return CEREAL_RAPIDJSON_SETPOINTER(Member, data_.o.members, members); }
6c5f2c01 sago007 2017-03-15 17:56 1932
6c5f2c01 sago007 2017-03-15 17:56 1933
    // Initialize this value as array with initial data, without calling destructor.
6c5f2c01 sago007 2017-03-15 17:56 1934
    void SetArrayRaw(GenericValue* values, SizeType count, Allocator& allocator) {
6c5f2c01 sago007 2017-03-15 17:56 1935
        data_.f.flags = kArrayFlag;
6c5f2c01 sago007 2017-03-15 17:56 1936
        if (count) {
6c5f2c01 sago007 2017-03-15 17:56 1937
            GenericValue* e = static_cast<GenericValue*>(allocator.Malloc(count * sizeof(GenericValue)));
6c5f2c01 sago007 2017-03-15 17:56 1938
            SetElementsPointer(e);
6c5f2c01 sago007 2017-03-15 17:56 1939
            std::memcpy(e, values, count * sizeof(GenericValue));
6c5f2c01 sago007 2017-03-15 17:56 1940
        }
6c5f2c01 sago007 2017-03-15 17:56 1941
        else
6c5f2c01 sago007 2017-03-15 17:56 1942
            SetElementsPointer(0);
6c5f2c01 sago007 2017-03-15 17:56 1943
        data_.a.size = data_.a.capacity = count;
6c5f2c01 sago007 2017-03-15 17:56 1944
    }
6c5f2c01 sago007 2017-03-15 17:56 1945
6c5f2c01 sago007 2017-03-15 17:56 1946
    //! Initialize this value as object with initial data, without calling destructor.
6c5f2c01 sago007 2017-03-15 17:56 1947
    void SetObjectRaw(Member* members, SizeType count, Allocator& allocator) {
6c5f2c01 sago007 2017-03-15 17:56 1948
        data_.f.flags = kObjectFlag;
6c5f2c01 sago007 2017-03-15 17:56 1949
        if (count) {
6c5f2c01 sago007 2017-03-15 17:56 1950
            Member* m = static_cast<Member*>(allocator.Malloc(count * sizeof(Member)));
6c5f2c01 sago007 2017-03-15 17:56 1951
            SetMembersPointer(m);
6c5f2c01 sago007 2017-03-15 17:56 1952
            std::memcpy(m, members, count * sizeof(Member));
6c5f2c01 sago007 2017-03-15 17:56 1953
        }
6c5f2c01 sago007 2017-03-15 17:56 1954
        else
6c5f2c01 sago007 2017-03-15 17:56 1955
            SetMembersPointer(0);
6c5f2c01 sago007 2017-03-15 17:56 1956
        data_.o.size = data_.o.capacity = count;
6c5f2c01 sago007 2017-03-15 17:56 1957
    }
6c5f2c01 sago007 2017-03-15 17:56 1958
6c5f2c01 sago007 2017-03-15 17:56 1959
    //! Initialize this value as constant string, without calling destructor.
6c5f2c01 sago007 2017-03-15 17:56 1960
    void SetStringRaw(StringRefType s) CEREAL_RAPIDJSON_NOEXCEPT {
6c5f2c01 sago007 2017-03-15 17:56 1961
        data_.f.flags = kConstStringFlag;
6c5f2c01 sago007 2017-03-15 17:56 1962
        SetStringPointer(s);
6c5f2c01 sago007 2017-03-15 17:56 1963
        data_.s.length = s.length;
6c5f2c01 sago007 2017-03-15 17:56 1964
    }
6c5f2c01 sago007 2017-03-15 17:56 1965
6c5f2c01 sago007 2017-03-15 17:56 1966
    //! Initialize this value as copy string with initial data, without calling destructor.
6c5f2c01 sago007 2017-03-15 17:56 1967
    void SetStringRaw(StringRefType s, Allocator& allocator) {
6c5f2c01 sago007 2017-03-15 17:56 1968
        Ch* str = 0;
6c5f2c01 sago007 2017-03-15 17:56 1969
        if (ShortString::Usable(s.length)) {
6c5f2c01 sago007 2017-03-15 17:56 1970
            data_.f.flags = kShortStringFlag;
6c5f2c01 sago007 2017-03-15 17:56 1971
            data_.ss.SetLength(s.length);
6c5f2c01 sago007 2017-03-15 17:56 1972
            str = data_.ss.str;
6c5f2c01 sago007 2017-03-15 17:56 1973
        } else {
6c5f2c01 sago007 2017-03-15 17:56 1974
            data_.f.flags = kCopyStringFlag;
6c5f2c01 sago007 2017-03-15 17:56 1975
            data_.s.length = s.length;
6c5f2c01 sago007 2017-03-15 17:56 1976
            str = static_cast<Ch *>(allocator.Malloc((s.length + 1) * sizeof(Ch)));
6c5f2c01 sago007 2017-03-15 17:56 1977
            SetStringPointer(str);
6c5f2c01 sago007 2017-03-15 17:56 1978
        }
6c5f2c01 sago007 2017-03-15 17:56 1979
        std::memcpy(str, s, s.length * sizeof(Ch));
6c5f2c01 sago007 2017-03-15 17:56 1980
        str[s.length] = '\0';
6c5f2c01 sago007 2017-03-15 17:56 1981
    }
6c5f2c01 sago007 2017-03-15 17:56 1982
6c5f2c01 sago007 2017-03-15 17:56 1983
    //! Assignment without calling destructor
6c5f2c01 sago007 2017-03-15 17:56 1984
    void RawAssign(GenericValue& rhs) CEREAL_RAPIDJSON_NOEXCEPT {
6c5f2c01 sago007 2017-03-15 17:56 1985
        data_ = rhs.data_;
6c5f2c01 sago007 2017-03-15 17:56 1986
        // data_.f.flags = rhs.data_.f.flags;
6c5f2c01 sago007 2017-03-15 17:56 1987
        rhs.data_.f.flags = kNullFlag;
6c5f2c01 sago007 2017-03-15 17:56 1988
    }
6c5f2c01 sago007 2017-03-15 17:56 1989
6c5f2c01 sago007 2017-03-15 17:56 1990
    template <typename SourceAllocator>
6c5f2c01 sago007 2017-03-15 17:56 1991
    bool StringEqual(const GenericValue<Encoding, SourceAllocator>& rhs) const {
6c5f2c01 sago007 2017-03-15 17:56 1992
        CEREAL_RAPIDJSON_ASSERT(IsString());
6c5f2c01 sago007 2017-03-15 17:56 1993
        CEREAL_RAPIDJSON_ASSERT(rhs.IsString());
6c5f2c01 sago007 2017-03-15 17:56 1994
6c5f2c01 sago007 2017-03-15 17:56 1995
        const SizeType len1 = GetStringLength();
6c5f2c01 sago007 2017-03-15 17:56 1996
        const SizeType len2 = rhs.GetStringLength();
6c5f2c01 sago007 2017-03-15 17:56 1997
        if(len1 != len2) { return false; }
6c5f2c01 sago007 2017-03-15 17:56 1998
6c5f2c01 sago007 2017-03-15 17:56 1999
        const Ch* const str1 = GetString();
6c5f2c01 sago007 2017-03-15 17:56 2000
        const Ch* const str2 = rhs.GetString();
6c5f2c01 sago007 2017-03-15 17:56 2001
        if(str1 == str2) { return true; } // fast path for constant string
6c5f2c01 sago007 2017-03-15 17:56 2002
6c5f2c01 sago007 2017-03-15 17:56 2003
        return (std::memcmp(str1, str2, sizeof(Ch) * len1) == 0);
6c5f2c01 sago007 2017-03-15 17:56 2004
    }
6c5f2c01 sago007 2017-03-15 17:56 2005
6c5f2c01 sago007 2017-03-15 17:56 2006
    Data data_;
7a956470 sago007 2016-02-14 17:09 2007
};
7a956470 sago007 2016-02-14 17:09 2008
6c5f2c01 sago007 2017-03-15 17:56 2009
//! GenericValue with UTF8 encoding
7a956470 sago007 2016-02-14 17:09 2010
typedef GenericValue<UTF8<> > Value;
7a956470 sago007 2016-02-14 17:09 2011
7a956470 sago007 2016-02-14 17:09 2012
///////////////////////////////////////////////////////////////////////////////
6c5f2c01 sago007 2017-03-15 17:56 2013
// GenericDocument 
7a956470 sago007 2016-02-14 17:09 2014
7a956470 sago007 2016-02-14 17:09 2015
//! A document for parsing JSON text as DOM.
7a956470 sago007 2016-02-14 17:09 2016
/*!
6c5f2c01 sago007 2017-03-15 17:56 2017
    \note implements Handler concept
6c5f2c01 sago007 2017-03-15 17:56 2018
    \tparam Encoding Encoding for both parsing and string storage.
6c5f2c01 sago007 2017-03-15 17:56 2019
    \tparam Allocator Allocator for allocating memory for the DOM
6c5f2c01 sago007 2017-03-15 17:56 2020
    \tparam StackAllocator Allocator for allocating memory for stack during parsing.
6c5f2c01 sago007 2017-03-15 17:56 2021
    \warning Although GenericDocument inherits from GenericValue, the API does \b not provide any virtual functions, especially no virtual destructor.  To avoid memory leaks, do not \c delete a GenericDocument object via a pointer to a GenericValue.
7a956470 sago007 2016-02-14 17:09 2022
*/
6c5f2c01 sago007 2017-03-15 17:56 2023
template <typename Encoding, typename Allocator = MemoryPoolAllocator<>, typename StackAllocator = CrtAllocator>
7a956470 sago007 2016-02-14 17:09 2024
class GenericDocument : public GenericValue<Encoding, Allocator> {
7a956470 sago007 2016-02-14 17:09 2025
public:
6c5f2c01 sago007 2017-03-15 17:56 2026
    typedef typename Encoding::Ch Ch;                       //!< Character type derived from Encoding.
6c5f2c01 sago007 2017-03-15 17:56 2027
    typedef GenericValue<Encoding, Allocator> ValueType;    //!< Value type of the document.
6c5f2c01 sago007 2017-03-15 17:56 2028
    typedef Allocator AllocatorType;                        //!< Allocator type from template parameter.
6c5f2c01 sago007 2017-03-15 17:56 2029
6c5f2c01 sago007 2017-03-15 17:56 2030
    //! Constructor
6c5f2c01 sago007 2017-03-15 17:56 2031
    /*! Creates an empty document of specified type.
6c5f2c01 sago007 2017-03-15 17:56 2032
        \param type             Mandatory type of object to create.
6c5f2c01 sago007 2017-03-15 17:56 2033
        \param allocator        Optional allocator for allocating memory.
6c5f2c01 sago007 2017-03-15 17:56 2034
        \param stackCapacity    Optional initial capacity of stack in bytes.
6c5f2c01 sago007 2017-03-15 17:56 2035
        \param stackAllocator   Optional allocator for allocating memory for stack.
6c5f2c01 sago007 2017-03-15 17:56 2036
    */
6c5f2c01 sago007 2017-03-15 17:56 2037
    explicit GenericDocument(Type type, Allocator* allocator = 0, size_t stackCapacity = kDefaultStackCapacity, StackAllocator* stackAllocator = 0) :
6c5f2c01 sago007 2017-03-15 17:56 2038
        GenericValue<Encoding, Allocator>(type),  allocator_(allocator), ownAllocator_(0), stack_(stackAllocator, stackCapacity), parseResult_()
6c5f2c01 sago007 2017-03-15 17:56 2039
    {
6c5f2c01 sago007 2017-03-15 17:56 2040
        if (!allocator_)
6c5f2c01 sago007 2017-03-15 17:56 2041
            ownAllocator_ = allocator_ = CEREAL_RAPIDJSON_NEW(Allocator());
6c5f2c01 sago007 2017-03-15 17:56 2042
    }
6c5f2c01 sago007 2017-03-15 17:56 2043
6c5f2c01 sago007 2017-03-15 17:56 2044
    //! Constructor
6c5f2c01 sago007 2017-03-15 17:56 2045
    /*! Creates an empty document which type is Null. 
6c5f2c01 sago007 2017-03-15 17:56 2046
        \param allocator        Optional allocator for allocating memory.
6c5f2c01 sago007 2017-03-15 17:56 2047
        \param stackCapacity    Optional initial capacity of stack in bytes.
6c5f2c01 sago007 2017-03-15 17:56 2048
        \param stackAllocator   Optional allocator for allocating memory for stack.
6c5f2c01 sago007 2017-03-15 17:56 2049
    */
6c5f2c01 sago007 2017-03-15 17:56 2050
    GenericDocument(Allocator* allocator = 0, size_t stackCapacity = kDefaultStackCapacity, StackAllocator* stackAllocator = 0) : 
6c5f2c01 sago007 2017-03-15 17:56 2051
        allocator_(allocator), ownAllocator_(0), stack_(stackAllocator, stackCapacity), parseResult_()
6c5f2c01 sago007 2017-03-15 17:56 2052
    {
6c5f2c01 sago007 2017-03-15 17:56 2053
        if (!allocator_)
6c5f2c01 sago007 2017-03-15 17:56 2054
            ownAllocator_ = allocator_ = CEREAL_RAPIDJSON_NEW(Allocator());
6c5f2c01 sago007 2017-03-15 17:56 2055
    }
6c5f2c01 sago007 2017-03-15 17:56 2056
6c5f2c01 sago007 2017-03-15 17:56 2057
#if CEREAL_RAPIDJSON_HAS_CXX11_RVALUE_REFS
6c5f2c01 sago007 2017-03-15 17:56 2058
    //! Move constructor in C++11
6c5f2c01 sago007 2017-03-15 17:56 2059
    GenericDocument(GenericDocument&& rhs) CEREAL_RAPIDJSON_NOEXCEPT
6c5f2c01 sago007 2017-03-15 17:56 2060
        : ValueType(std::forward<ValueType>(rhs)), // explicit cast to avoid prohibited move from Document
6c5f2c01 sago007 2017-03-15 17:56 2061
          allocator_(rhs.allocator_),
6c5f2c01 sago007 2017-03-15 17:56 2062
          ownAllocator_(rhs.ownAllocator_),
6c5f2c01 sago007 2017-03-15 17:56 2063
          stack_(std::move(rhs.stack_)),
6c5f2c01 sago007 2017-03-15 17:56 2064
          parseResult_(rhs.parseResult_)
6c5f2c01 sago007 2017-03-15 17:56 2065
    {
6c5f2c01 sago007 2017-03-15 17:56 2066
        rhs.allocator_ = 0;
6c5f2c01 sago007 2017-03-15 17:56 2067
        rhs.ownAllocator_ = 0;
6c5f2c01 sago007 2017-03-15 17:56 2068
        rhs.parseResult_ = ParseResult();
6c5f2c01 sago007 2017-03-15 17:56 2069
    }
6c5f2c01 sago007 2017-03-15 17:56 2070
#endif
6c5f2c01 sago007 2017-03-15 17:56 2071
6c5f2c01 sago007 2017-03-15 17:56 2072
    ~GenericDocument() {
6c5f2c01 sago007 2017-03-15 17:56 2073
        Destroy();
6c5f2c01 sago007 2017-03-15 17:56 2074
    }
6c5f2c01 sago007 2017-03-15 17:56 2075
6c5f2c01 sago007 2017-03-15 17:56 2076
#if CEREAL_RAPIDJSON_HAS_CXX11_RVALUE_REFS
6c5f2c01 sago007 2017-03-15 17:56 2077
    //! Move assignment in C++11
6c5f2c01 sago007 2017-03-15 17:56 2078
    GenericDocument& operator=(GenericDocument&& rhs) CEREAL_RAPIDJSON_NOEXCEPT
6c5f2c01 sago007 2017-03-15 17:56 2079
    {
6c5f2c01 sago007 2017-03-15 17:56 2080
        // The cast to ValueType is necessary here, because otherwise it would
6c5f2c01 sago007 2017-03-15 17:56 2081
        // attempt to call GenericValue's templated assignment operator.
6c5f2c01 sago007 2017-03-15 17:56 2082
        ValueType::operator=(std::forward<ValueType>(rhs));
6c5f2c01 sago007 2017-03-15 17:56 2083
6c5f2c01 sago007 2017-03-15 17:56 2084
        // Calling the destructor here would prematurely call stack_'s destructor
6c5f2c01 sago007 2017-03-15 17:56 2085
        Destroy();
6c5f2c01 sago007 2017-03-15 17:56 2086
6c5f2c01 sago007 2017-03-15 17:56 2087
        allocator_ = rhs.allocator_;
6c5f2c01 sago007 2017-03-15 17:56 2088
        ownAllocator_ = rhs.ownAllocator_;
6c5f2c01 sago007 2017-03-15 17:56 2089
        stack_ = std::move(rhs.stack_);
6c5f2c01 sago007 2017-03-15 17:56 2090
        parseResult_ = rhs.parseResult_;
6c5f2c01 sago007 2017-03-15 17:56 2091
6c5f2c01 sago007 2017-03-15 17:56 2092
        rhs.allocator_ = 0;
6c5f2c01 sago007 2017-03-15 17:56 2093
        rhs.ownAllocator_ = 0;
6c5f2c01 sago007 2017-03-15 17:56 2094
        rhs.parseResult_ = ParseResult();
6c5f2c01 sago007 2017-03-15 17:56 2095
6c5f2c01 sago007 2017-03-15 17:56 2096
        return *this;
6c5f2c01 sago007 2017-03-15 17:56 2097
    }
6c5f2c01 sago007 2017-03-15 17:56 2098
#endif
6c5f2c01 sago007 2017-03-15 17:56 2099
6c5f2c01 sago007 2017-03-15 17:56 2100
    //! Exchange the contents of this document with those of another.
6c5f2c01 sago007 2017-03-15 17:56 2101
    /*!
6c5f2c01 sago007 2017-03-15 17:56 2102
        \param rhs Another document.
6c5f2c01 sago007 2017-03-15 17:56 2103
        \note Constant complexity.
6c5f2c01 sago007 2017-03-15 17:56 2104
        \see GenericValue::Swap
6c5f2c01 sago007 2017-03-15 17:56 2105
    */
6c5f2c01 sago007 2017-03-15 17:56 2106
    GenericDocument& Swap(GenericDocument& rhs) CEREAL_RAPIDJSON_NOEXCEPT {
6c5f2c01 sago007 2017-03-15 17:56 2107
        ValueType::Swap(rhs);
6c5f2c01 sago007 2017-03-15 17:56 2108
        stack_.Swap(rhs.stack_);
6c5f2c01 sago007 2017-03-15 17:56 2109
        internal::Swap(allocator_, rhs.allocator_);
6c5f2c01 sago007 2017-03-15 17:56 2110
        internal::Swap(ownAllocator_, rhs.ownAllocator_);
6c5f2c01 sago007 2017-03-15 17:56 2111
        internal::Swap(parseResult_, rhs.parseResult_);
6c5f2c01 sago007 2017-03-15 17:56 2112
        return *this;
6c5f2c01 sago007 2017-03-15 17:56 2113
    }
6c5f2c01 sago007 2017-03-15 17:56 2114
6c5f2c01 sago007 2017-03-15 17:56 2115
    //! free-standing swap function helper
6c5f2c01 sago007 2017-03-15 17:56 2116
    /*!
6c5f2c01 sago007 2017-03-15 17:56 2117
        Helper function to enable support for common swap implementation pattern based on \c std::swap:
6c5f2c01 sago007 2017-03-15 17:56 2118
        \code
6c5f2c01 sago007 2017-03-15 17:56 2119
        void swap(MyClass& a, MyClass& b) {
6c5f2c01 sago007 2017-03-15 17:56 2120
            using std::swap;
6c5f2c01 sago007 2017-03-15 17:56 2121
            swap(a.doc, b.doc);
6c5f2c01 sago007 2017-03-15 17:56 2122
            // ...
6c5f2c01 sago007 2017-03-15 17:56 2123
        }
6c5f2c01 sago007 2017-03-15 17:56 2124
        \endcode
6c5f2c01 sago007 2017-03-15 17:56 2125
        \see Swap()
6c5f2c01 sago007 2017-03-15 17:56 2126
     */
6c5f2c01 sago007 2017-03-15 17:56 2127
    friend inline void swap(GenericDocument& a, GenericDocument& b) CEREAL_RAPIDJSON_NOEXCEPT { a.Swap(b); }
6c5f2c01 sago007 2017-03-15 17:56 2128
6c5f2c01 sago007 2017-03-15 17:56 2129
    //! Populate this document by a generator which produces SAX events.
6c5f2c01 sago007 2017-03-15 17:56 2130
    /*! \tparam Generator A functor with <tt>bool f(Handler)</tt> prototype.
6c5f2c01 sago007 2017-03-15 17:56 2131
        \param g Generator functor which sends SAX events to the parameter.
6c5f2c01 sago007 2017-03-15 17:56 2132
        \return The document itself for fluent API.
6c5f2c01 sago007 2017-03-15 17:56 2133
    */
6c5f2c01 sago007 2017-03-15 17:56 2134
    template <typename Generator>
6c5f2c01 sago007 2017-03-15 17:56 2135
    GenericDocument& Populate(Generator& g) {
6c5f2c01 sago007 2017-03-15 17:56 2136
        ClearStackOnExit scope(*this);
6c5f2c01 sago007 2017-03-15 17:56 2137
        if (g(*this)) {
6c5f2c01 sago007 2017-03-15 17:56 2138
            CEREAL_RAPIDJSON_ASSERT(stack_.GetSize() == sizeof(ValueType)); // Got one and only one root object
6c5f2c01 sago007 2017-03-15 17:56 2139
            ValueType::operator=(*stack_.template Pop<ValueType>(1));// Move value from stack to document
6c5f2c01 sago007 2017-03-15 17:56 2140
        }
6c5f2c01 sago007 2017-03-15 17:56 2141
        return *this;
6c5f2c01 sago007 2017-03-15 17:56 2142
    }
6c5f2c01 sago007 2017-03-15 17:56 2143
6c5f2c01 sago007 2017-03-15 17:56 2144
    //!@name Parse from stream
6c5f2c01 sago007 2017-03-15 17:56 2145
    //!@{
6c5f2c01 sago007 2017-03-15 17:56 2146
6c5f2c01 sago007 2017-03-15 17:56 2147
    //! Parse JSON text from an input stream (with Encoding conversion)
6c5f2c01 sago007 2017-03-15 17:56 2148
    /*! \tparam parseFlags Combination of \ref ParseFlag.
6c5f2c01 sago007 2017-03-15 17:56 2149
        \tparam SourceEncoding Encoding of input stream
6c5f2c01 sago007 2017-03-15 17:56 2150
        \tparam InputStream Type of input stream, implementing Stream concept
6c5f2c01 sago007 2017-03-15 17:56 2151
        \param is Input stream to be parsed.
6c5f2c01 sago007 2017-03-15 17:56 2152
        \return The document itself for fluent API.
6c5f2c01 sago007 2017-03-15 17:56 2153
    */
6c5f2c01 sago007 2017-03-15 17:56 2154
    template <unsigned parseFlags, typename SourceEncoding, typename InputStream>
6c5f2c01 sago007 2017-03-15 17:56 2155
    GenericDocument& ParseStream(InputStream& is) {
6c5f2c01 sago007 2017-03-15 17:56 2156
        GenericReader<SourceEncoding, Encoding, StackAllocator> reader(
6c5f2c01 sago007 2017-03-15 17:56 2157
            stack_.HasAllocator() ? &stack_.GetAllocator() : 0);
6c5f2c01 sago007 2017-03-15 17:56 2158
        ClearStackOnExit scope(*this);
6c5f2c01 sago007 2017-03-15 17:56 2159
        parseResult_ = reader.template Parse<parseFlags>(is, *this);
6c5f2c01 sago007 2017-03-15 17:56 2160
        if (parseResult_) {
6c5f2c01 sago007 2017-03-15 17:56 2161
            CEREAL_RAPIDJSON_ASSERT(stack_.GetSize() == sizeof(ValueType)); // Got one and only one root object
6c5f2c01 sago007 2017-03-15 17:56 2162
            ValueType::operator=(*stack_.template Pop<ValueType>(1));// Move value from stack to document
6c5f2c01 sago007 2017-03-15 17:56 2163
        }
6c5f2c01 sago007 2017-03-15 17:56 2164
        return *this;
6c5f2c01 sago007 2017-03-15 17:56 2165
    }
6c5f2c01 sago007 2017-03-15 17:56 2166
6c5f2c01 sago007 2017-03-15 17:56 2167
    //! Parse JSON text from an input stream
6c5f2c01 sago007 2017-03-15 17:56 2168
    /*! \tparam parseFlags Combination of \ref ParseFlag.
6c5f2c01 sago007 2017-03-15 17:56 2169
        \tparam InputStream Type of input stream, implementing Stream concept
6c5f2c01 sago007 2017-03-15 17:56 2170
        \param is Input stream to be parsed.
6c5f2c01 sago007 2017-03-15 17:56 2171
        \return The document itself for fluent API.
6c5f2c01 sago007 2017-03-15 17:56 2172
    */
6c5f2c01 sago007 2017-03-15 17:56 2173
    template <unsigned parseFlags, typename InputStream>
6c5f2c01 sago007 2017-03-15 17:56 2174
    GenericDocument& ParseStream(InputStream& is) {
6c5f2c01 sago007 2017-03-15 17:56 2175
        return ParseStream<parseFlags, Encoding, InputStream>(is);
6c5f2c01 sago007 2017-03-15 17:56 2176
    }
6c5f2c01 sago007 2017-03-15 17:56 2177
6c5f2c01 sago007 2017-03-15 17:56 2178
    //! Parse JSON text from an input stream (with \ref kParseDefaultFlags)
6c5f2c01 sago007 2017-03-15 17:56 2179
    /*! \tparam InputStream Type of input stream, implementing Stream concept
6c5f2c01 sago007 2017-03-15 17:56 2180
        \param is Input stream to be parsed.
6c5f2c01 sago007 2017-03-15 17:56 2181
        \return The document itself for fluent API.
6c5f2c01 sago007 2017-03-15 17:56 2182
    */
6c5f2c01 sago007 2017-03-15 17:56 2183
    template <typename InputStream>
6c5f2c01 sago007 2017-03-15 17:56 2184
    GenericDocument& ParseStream(InputStream& is) {
6c5f2c01 sago007 2017-03-15 17:56 2185
        return ParseStream<kParseDefaultFlags, Encoding, InputStream>(is);
6c5f2c01 sago007 2017-03-15 17:56 2186
    }
6c5f2c01 sago007 2017-03-15 17:56 2187
    //!@}
6c5f2c01 sago007 2017-03-15 17:56 2188
6c5f2c01 sago007 2017-03-15 17:56 2189
    //!@name Parse in-place from mutable string
6c5f2c01 sago007 2017-03-15 17:56 2190
    //!@{
6c5f2c01 sago007 2017-03-15 17:56 2191
6c5f2c01 sago007 2017-03-15 17:56 2192
    //! Parse JSON text from a mutable string
6c5f2c01 sago007 2017-03-15 17:56 2193
    /*! \tparam parseFlags Combination of \ref ParseFlag.
6c5f2c01 sago007 2017-03-15 17:56 2194
        \param str Mutable zero-terminated string to be parsed.
6c5f2c01 sago007 2017-03-15 17:56 2195
        \return The document itself for fluent API.
6c5f2c01 sago007 2017-03-15 17:56 2196
    */
6c5f2c01 sago007 2017-03-15 17:56 2197
    template <unsigned parseFlags>
6c5f2c01 sago007 2017-03-15 17:56 2198
    GenericDocument& ParseInsitu(Ch* str) {
6c5f2c01 sago007 2017-03-15 17:56 2199
        GenericInsituStringStream<Encoding> s(str);
6c5f2c01 sago007 2017-03-15 17:56 2200
        return ParseStream<parseFlags | kParseInsituFlag>(s);
6c5f2c01 sago007 2017-03-15 17:56 2201
    }
6c5f2c01 sago007 2017-03-15 17:56 2202
6c5f2c01 sago007 2017-03-15 17:56 2203
    //! Parse JSON text from a mutable string (with \ref kParseDefaultFlags)
6c5f2c01 sago007 2017-03-15 17:56 2204
    /*! \param str Mutable zero-terminated string to be parsed.
6c5f2c01 sago007 2017-03-15 17:56 2205
        \return The document itself for fluent API.
6c5f2c01 sago007 2017-03-15 17:56 2206
    */
6c5f2c01 sago007 2017-03-15 17:56 2207
    GenericDocument& ParseInsitu(Ch* str) {
6c5f2c01 sago007 2017-03-15 17:56 2208
        return ParseInsitu<kParseDefaultFlags>(str);
6c5f2c01 sago007 2017-03-15 17:56 2209
    }
6c5f2c01 sago007 2017-03-15 17:56 2210
    //!@}
6c5f2c01 sago007 2017-03-15 17:56 2211
6c5f2c01 sago007 2017-03-15 17:56 2212
    //!@name Parse from read-only string
6c5f2c01 sago007 2017-03-15 17:56 2213
    //!@{
6c5f2c01 sago007 2017-03-15 17:56 2214
6c5f2c01 sago007 2017-03-15 17:56 2215
    //! Parse JSON text from a read-only string (with Encoding conversion)
6c5f2c01 sago007 2017-03-15 17:56 2216
    /*! \tparam parseFlags Combination of \ref ParseFlag (must not contain \ref kParseInsituFlag).
6c5f2c01 sago007 2017-03-15 17:56 2217
        \tparam SourceEncoding Transcoding from input Encoding
6c5f2c01 sago007 2017-03-15 17:56 2218
        \param str Read-only zero-terminated string to be parsed.
6c5f2c01 sago007 2017-03-15 17:56 2219
    */
6c5f2c01 sago007 2017-03-15 17:56 2220
    template <unsigned parseFlags, typename SourceEncoding>
6c5f2c01 sago007 2017-03-15 17:56 2221
    GenericDocument& Parse(const typename SourceEncoding::Ch* str) {
6c5f2c01 sago007 2017-03-15 17:56 2222
        CEREAL_RAPIDJSON_ASSERT(!(parseFlags & kParseInsituFlag));
6c5f2c01 sago007 2017-03-15 17:56 2223
        GenericStringStream<SourceEncoding> s(str);
6c5f2c01 sago007 2017-03-15 17:56 2224
        return ParseStream<parseFlags, SourceEncoding>(s);
6c5f2c01 sago007 2017-03-15 17:56 2225
    }
6c5f2c01 sago007 2017-03-15 17:56 2226
6c5f2c01 sago007 2017-03-15 17:56 2227
    //! Parse JSON text from a read-only string
6c5f2c01 sago007 2017-03-15 17:56 2228
    /*! \tparam parseFlags Combination of \ref ParseFlag (must not contain \ref kParseInsituFlag).
6c5f2c01 sago007 2017-03-15 17:56 2229
        \param str Read-only zero-terminated string to be parsed.
6c5f2c01 sago007 2017-03-15 17:56 2230
    */
6c5f2c01 sago007 2017-03-15 17:56 2231
    template <unsigned parseFlags>
6c5f2c01 sago007 2017-03-15 17:56 2232
    GenericDocument& Parse(const Ch* str) {
6c5f2c01 sago007 2017-03-15 17:56 2233
        return Parse<parseFlags, Encoding>(str);
6c5f2c01 sago007 2017-03-15 17:56 2234
    }
6c5f2c01 sago007 2017-03-15 17:56 2235
6c5f2c01 sago007 2017-03-15 17:56 2236
    //! Parse JSON text from a read-only string (with \ref kParseDefaultFlags)
6c5f2c01 sago007 2017-03-15 17:56 2237
    /*! \param str Read-only zero-terminated string to be parsed.
6c5f2c01 sago007 2017-03-15 17:56 2238
    */
6c5f2c01 sago007 2017-03-15 17:56 2239
    GenericDocument& Parse(const Ch* str) {
6c5f2c01 sago007 2017-03-15 17:56 2240
        return Parse<kParseDefaultFlags>(str);
6c5f2c01 sago007 2017-03-15 17:56 2241
    }
6c5f2c01 sago007 2017-03-15 17:56 2242
6c5f2c01 sago007 2017-03-15 17:56 2243
    template <unsigned parseFlags, typename SourceEncoding>
6c5f2c01 sago007 2017-03-15 17:56 2244
    GenericDocument& Parse(const typename SourceEncoding::Ch* str, size_t length) {
6c5f2c01 sago007 2017-03-15 17:56 2245
        CEREAL_RAPIDJSON_ASSERT(!(parseFlags & kParseInsituFlag));
6c5f2c01 sago007 2017-03-15 17:56 2246
        MemoryStream ms(static_cast<const char*>(str), length * sizeof(typename SourceEncoding::Ch));
6c5f2c01 sago007 2017-03-15 17:56 2247
        EncodedInputStream<SourceEncoding, MemoryStream> is(ms);
6c5f2c01 sago007 2017-03-15 17:56 2248
        ParseStream<parseFlags, SourceEncoding>(is);
6c5f2c01 sago007 2017-03-15 17:56 2249
        return *this;
6c5f2c01 sago007 2017-03-15 17:56 2250
    }
6c5f2c01 sago007 2017-03-15 17:56 2251
6c5f2c01 sago007 2017-03-15 17:56 2252
    template <unsigned parseFlags>
6c5f2c01 sago007 2017-03-15 17:56 2253
    GenericDocument& Parse(const Ch* str, size_t length) {
6c5f2c01 sago007 2017-03-15 17:56 2254
        return Parse<parseFlags, Encoding>(str, length);
6c5f2c01 sago007 2017-03-15 17:56 2255
    }
6c5f2c01 sago007 2017-03-15 17:56 2256
    
6c5f2c01 sago007 2017-03-15 17:56 2257
    GenericDocument& Parse(const Ch* str, size_t length) {
6c5f2c01 sago007 2017-03-15 17:56 2258
        return Parse<kParseDefaultFlags>(str, length);
6c5f2c01 sago007 2017-03-15 17:56 2259
    }
6c5f2c01 sago007 2017-03-15 17:56 2260
6c5f2c01 sago007 2017-03-15 17:56 2261
#if CEREAL_RAPIDJSON_HAS_STDSTRING
6c5f2c01 sago007 2017-03-15 17:56 2262
    template <unsigned parseFlags, typename SourceEncoding>
6c5f2c01 sago007 2017-03-15 17:56 2263
    GenericDocument& Parse(const std::basic_string<typename SourceEncoding::Ch>& str) {
6c5f2c01 sago007 2017-03-15 17:56 2264
        // c_str() is constant complexity according to standard. Should be faster than Parse(const char*, size_t)
6c5f2c01 sago007 2017-03-15 17:56 2265
        return Parse<parseFlags, SourceEncoding>(str.c_str());
6c5f2c01 sago007 2017-03-15 17:56 2266
    }
6c5f2c01 sago007 2017-03-15 17:56 2267
6c5f2c01 sago007 2017-03-15 17:56 2268
    template <unsigned parseFlags>
6c5f2c01 sago007 2017-03-15 17:56 2269
    GenericDocument& Parse(const std::basic_string<Ch>& str) {
6c5f2c01 sago007 2017-03-15 17:56 2270
        return Parse<parseFlags, Encoding>(str.c_str());
6c5f2c01 sago007 2017-03-15 17:56 2271
    }
6c5f2c01 sago007 2017-03-15 17:56 2272
6c5f2c01 sago007 2017-03-15 17:56 2273
    GenericDocument& Parse(const std::basic_string<Ch>& str) {
6c5f2c01 sago007 2017-03-15 17:56 2274
        return Parse<kParseDefaultFlags>(str);
6c5f2c01 sago007 2017-03-15 17:56 2275
    }
6c5f2c01 sago007 2017-03-15 17:56 2276
#endif // CEREAL_RAPIDJSON_HAS_STDSTRING    
6c5f2c01 sago007 2017-03-15 17:56 2277
6c5f2c01 sago007 2017-03-15 17:56 2278
    //!@}
6c5f2c01 sago007 2017-03-15 17:56 2279
6c5f2c01 sago007 2017-03-15 17:56 2280
    //!@name Handling parse errors
6c5f2c01 sago007 2017-03-15 17:56 2281
    //!@{
6c5f2c01 sago007 2017-03-15 17:56 2282
6c5f2c01 sago007 2017-03-15 17:56 2283
    //! Whether a parse error has occured in the last parsing.
6c5f2c01 sago007 2017-03-15 17:56 2284
    bool HasParseError() const { return parseResult_.IsError(); }
6c5f2c01 sago007 2017-03-15 17:56 2285
6c5f2c01 sago007 2017-03-15 17:56 2286
    //! Get the \ref ParseErrorCode of last parsing.
6c5f2c01 sago007 2017-03-15 17:56 2287
    ParseErrorCode GetParseError() const { return parseResult_.Code(); }
6c5f2c01 sago007 2017-03-15 17:56 2288
6c5f2c01 sago007 2017-03-15 17:56 2289
    //! Get the position of last parsing error in input, 0 otherwise.
6c5f2c01 sago007 2017-03-15 17:56 2290
    size_t GetErrorOffset() const { return parseResult_.Offset(); }
6c5f2c01 sago007 2017-03-15 17:56 2291
6c5f2c01 sago007 2017-03-15 17:56 2292
    //! Implicit conversion to get the last parse result
6c5f2c01 sago007 2017-03-15 17:56 2293
#ifndef __clang // -Wdocumentation
6c5f2c01 sago007 2017-03-15 17:56 2294
    /*! \return \ref ParseResult of the last parse operation
6c5f2c01 sago007 2017-03-15 17:56 2295
6c5f2c01 sago007 2017-03-15 17:56 2296
        \code
6c5f2c01 sago007 2017-03-15 17:56 2297
          Document doc;
6c5f2c01 sago007 2017-03-15 17:56 2298
          ParseResult ok = doc.Parse(json);
6c5f2c01 sago007 2017-03-15 17:56 2299
          if (!ok)
6c5f2c01 sago007 2017-03-15 17:56 2300
            printf( "JSON parse error: %s (%u)\n", GetParseError_En(ok.Code()), ok.Offset());
6c5f2c01 sago007 2017-03-15 17:56 2301
        \endcode
6c5f2c01 sago007 2017-03-15 17:56 2302
     */
6c5f2c01 sago007 2017-03-15 17:56 2303
#endif
6c5f2c01 sago007 2017-03-15 17:56 2304
    operator ParseResult() const { return parseResult_; }
6c5f2c01 sago007 2017-03-15 17:56 2305
    //!@}
6c5f2c01 sago007 2017-03-15 17:56 2306
6c5f2c01 sago007 2017-03-15 17:56 2307
    //! Get the allocator of this document.
6c5f2c01 sago007 2017-03-15 17:56 2308
    Allocator& GetAllocator() {
6c5f2c01 sago007 2017-03-15 17:56 2309
        CEREAL_RAPIDJSON_ASSERT(allocator_);
6c5f2c01 sago007 2017-03-15 17:56 2310
        return *allocator_;
6c5f2c01 sago007 2017-03-15 17:56 2311
    }
6c5f2c01 sago007 2017-03-15 17:56 2312
6c5f2c01 sago007 2017-03-15 17:56 2313
    //! Get the capacity of stack in bytes.
6c5f2c01 sago007 2017-03-15 17:56 2314
    size_t GetStackCapacity() const { return stack_.GetCapacity(); }
6c5f2c01 sago007 2017-03-15 17:56 2315
6c5f2c01 sago007 2017-03-15 17:56 2316
private:
6c5f2c01 sago007 2017-03-15 17:56 2317
    // clear stack on any exit from ParseStream, e.g. due to exception
6c5f2c01 sago007 2017-03-15 17:56 2318
    struct ClearStackOnExit {
6c5f2c01 sago007 2017-03-15 17:56 2319
        explicit ClearStackOnExit(GenericDocument& d) : d_(d) {}
6c5f2c01 sago007 2017-03-15 17:56 2320
        ~ClearStackOnExit() { d_.ClearStack(); }
6c5f2c01 sago007 2017-03-15 17:56 2321
    private:
6c5f2c01 sago007 2017-03-15 17:56 2322
        ClearStackOnExit(const ClearStackOnExit&);
6c5f2c01 sago007 2017-03-15 17:56 2323
        ClearStackOnExit& operator=(const ClearStackOnExit&);
6c5f2c01 sago007 2017-03-15 17:56 2324
        GenericDocument& d_;
6c5f2c01 sago007 2017-03-15 17:56 2325
    };
6c5f2c01 sago007 2017-03-15 17:56 2326
6c5f2c01 sago007 2017-03-15 17:56 2327
    // callers of the following private Handler functions
6c5f2c01 sago007 2017-03-15 17:56 2328
    // template <typename,typename,typename> friend class GenericReader; // for parsing
6c5f2c01 sago007 2017-03-15 17:56 2329
    template <typename, typename> friend class GenericValue; // for deep copying
6c5f2c01 sago007 2017-03-15 17:56 2330
6c5f2c01 sago007 2017-03-15 17:56 2331
public:
6c5f2c01 sago007 2017-03-15 17:56 2332
    // Implementation of Handler
6c5f2c01 sago007 2017-03-15 17:56 2333
    bool Null() { new (stack_.template Push<ValueType>()) ValueType(); return true; }
6c5f2c01 sago007 2017-03-15 17:56 2334
    bool Bool(bool b) { new (stack_.template Push<ValueType>()) ValueType(b); return true; }
6c5f2c01 sago007 2017-03-15 17:56 2335
    bool Int(int i) { new (stack_.template Push<ValueType>()) ValueType(i); return true; }
6c5f2c01 sago007 2017-03-15 17:56 2336
    bool Uint(unsigned i) { new (stack_.template Push<ValueType>()) ValueType(i); return true; }
6c5f2c01 sago007 2017-03-15 17:56 2337
    bool Int64(int64_t i) { new (stack_.template Push<ValueType>()) ValueType(i); return true; }
6c5f2c01 sago007 2017-03-15 17:56 2338
    bool Uint64(uint64_t i) { new (stack_.template Push<ValueType>()) ValueType(i); return true; }
6c5f2c01 sago007 2017-03-15 17:56 2339
    bool Double(double d) { new (stack_.template Push<ValueType>()) ValueType(d); return true; }
6c5f2c01 sago007 2017-03-15 17:56 2340
6c5f2c01 sago007 2017-03-15 17:56 2341
    bool RawNumber(const Ch* str, SizeType length, bool copy) { 
6c5f2c01 sago007 2017-03-15 17:56 2342
        if (copy) 
6c5f2c01 sago007 2017-03-15 17:56 2343
            new (stack_.template Push<ValueType>()) ValueType(str, length, GetAllocator());
6c5f2c01 sago007 2017-03-15 17:56 2344
        else
6c5f2c01 sago007 2017-03-15 17:56 2345
            new (stack_.template Push<ValueType>()) ValueType(str, length);
6c5f2c01 sago007 2017-03-15 17:56 2346
        return true;
6c5f2c01 sago007 2017-03-15 17:56 2347
    }
6c5f2c01 sago007 2017-03-15 17:56 2348
6c5f2c01 sago007 2017-03-15 17:56 2349
    bool String(const Ch* str, SizeType length, bool copy) { 
6c5f2c01 sago007 2017-03-15 17:56 2350
        if (copy) 
6c5f2c01 sago007 2017-03-15 17:56 2351
            new (stack_.template Push<ValueType>()) ValueType(str, length, GetAllocator());
6c5f2c01 sago007 2017-03-15 17:56 2352
        else
6c5f2c01 sago007 2017-03-15 17:56 2353
            new (stack_.template Push<ValueType>()) ValueType(str, length);
6c5f2c01 sago007 2017-03-15 17:56 2354
        return true;
6c5f2c01 sago007 2017-03-15 17:56 2355
    }
6c5f2c01 sago007 2017-03-15 17:56 2356
6c5f2c01 sago007 2017-03-15 17:56 2357
    bool StartObject() { new (stack_.template Push<ValueType>()) ValueType(kObjectType); return true; }
6c5f2c01 sago007 2017-03-15 17:56 2358
    
6c5f2c01 sago007 2017-03-15 17:56 2359
    bool Key(const Ch* str, SizeType length, bool copy) { return String(str, length, copy); }
6c5f2c01 sago007 2017-03-15 17:56 2360
6c5f2c01 sago007 2017-03-15 17:56 2361
    bool EndObject(SizeType memberCount) {
6c5f2c01 sago007 2017-03-15 17:56 2362
        typename ValueType::Member* members = stack_.template Pop<typename ValueType::Member>(memberCount);
6c5f2c01 sago007 2017-03-15 17:56 2363
        stack_.template Top<ValueType>()->SetObjectRaw(members, memberCount, GetAllocator());
6c5f2c01 sago007 2017-03-15 17:56 2364
        return true;
6c5f2c01 sago007 2017-03-15 17:56 2365
    }
6c5f2c01 sago007 2017-03-15 17:56 2366
6c5f2c01 sago007 2017-03-15 17:56 2367
    bool StartArray() { new (stack_.template Push<ValueType>()) ValueType(kArrayType); return true; }
6c5f2c01 sago007 2017-03-15 17:56 2368
    
6c5f2c01 sago007 2017-03-15 17:56 2369
    bool EndArray(SizeType elementCount) {
6c5f2c01 sago007 2017-03-15 17:56 2370
        ValueType* elements = stack_.template Pop<ValueType>(elementCount);
6c5f2c01 sago007 2017-03-15 17:56 2371
        stack_.template Top<ValueType>()->SetArrayRaw(elements, elementCount, GetAllocator());
6c5f2c01 sago007 2017-03-15 17:56 2372
        return true;
6c5f2c01 sago007 2017-03-15 17:56 2373
    }
7a956470 sago007 2016-02-14 17:09 2374
7a956470 sago007 2016-02-14 17:09 2375
private:
6c5f2c01 sago007 2017-03-15 17:56 2376
    //! Prohibit copying
6c5f2c01 sago007 2017-03-15 17:56 2377
    GenericDocument(const GenericDocument&);
6c5f2c01 sago007 2017-03-15 17:56 2378
    //! Prohibit assignment
6c5f2c01 sago007 2017-03-15 17:56 2379
    GenericDocument& operator=(const GenericDocument&);
6c5f2c01 sago007 2017-03-15 17:56 2380
6c5f2c01 sago007 2017-03-15 17:56 2381
    void ClearStack() {
6c5f2c01 sago007 2017-03-15 17:56 2382
        if (Allocator::kNeedFree)
6c5f2c01 sago007 2017-03-15 17:56 2383
            while (stack_.GetSize() > 0)    // Here assumes all elements in stack array are GenericValue (Member is actually 2 GenericValue objects)
6c5f2c01 sago007 2017-03-15 17:56 2384
                (stack_.template Pop<ValueType>(1))->~ValueType();
6c5f2c01 sago007 2017-03-15 17:56 2385
        else
6c5f2c01 sago007 2017-03-15 17:56 2386
            stack_.Clear();
6c5f2c01 sago007 2017-03-15 17:56 2387
        stack_.ShrinkToFit();
6c5f2c01 sago007 2017-03-15 17:56 2388
    }
6c5f2c01 sago007 2017-03-15 17:56 2389
6c5f2c01 sago007 2017-03-15 17:56 2390
    void Destroy() {
6c5f2c01 sago007 2017-03-15 17:56 2391
        CEREAL_RAPIDJSON_DELETE(ownAllocator_);
6c5f2c01 sago007 2017-03-15 17:56 2392
    }
6c5f2c01 sago007 2017-03-15 17:56 2393
6c5f2c01 sago007 2017-03-15 17:56 2394
    static const size_t kDefaultStackCapacity = 1024;
6c5f2c01 sago007 2017-03-15 17:56 2395
    Allocator* allocator_;
6c5f2c01 sago007 2017-03-15 17:56 2396
    Allocator* ownAllocator_;
6c5f2c01 sago007 2017-03-15 17:56 2397
    internal::Stack<StackAllocator> stack_;
6c5f2c01 sago007 2017-03-15 17:56 2398
    ParseResult parseResult_;
7a956470 sago007 2016-02-14 17:09 2399
};
7a956470 sago007 2016-02-14 17:09 2400
6c5f2c01 sago007 2017-03-15 17:56 2401
//! GenericDocument with UTF8 encoding
7a956470 sago007 2016-02-14 17:09 2402
typedef GenericDocument<UTF8<> > Document;
7a956470 sago007 2016-02-14 17:09 2403
6c5f2c01 sago007 2017-03-15 17:56 2404
// defined here due to the dependency on GenericDocument
6c5f2c01 sago007 2017-03-15 17:56 2405
template <typename Encoding, typename Allocator>
6c5f2c01 sago007 2017-03-15 17:56 2406
template <typename SourceAllocator>
6c5f2c01 sago007 2017-03-15 17:56 2407
inline
6c5f2c01 sago007 2017-03-15 17:56 2408
GenericValue<Encoding,Allocator>::GenericValue(const GenericValue<Encoding,SourceAllocator>& rhs, Allocator& allocator)
6c5f2c01 sago007 2017-03-15 17:56 2409
{
6c5f2c01 sago007 2017-03-15 17:56 2410
    switch (rhs.GetType()) {
6c5f2c01 sago007 2017-03-15 17:56 2411
    case kObjectType:
6c5f2c01 sago007 2017-03-15 17:56 2412
    case kArrayType: { // perform deep copy via SAX Handler
6c5f2c01 sago007 2017-03-15 17:56 2413
            GenericDocument<Encoding,Allocator> d(&allocator);
6c5f2c01 sago007 2017-03-15 17:56 2414
            rhs.Accept(d);
6c5f2c01 sago007 2017-03-15 17:56 2415
            RawAssign(*d.stack_.template Pop<GenericValue>(1));
6c5f2c01 sago007 2017-03-15 17:56 2416
        }
6c5f2c01 sago007 2017-03-15 17:56 2417
        break;
6c5f2c01 sago007 2017-03-15 17:56 2418
    case kStringType:
6c5f2c01 sago007 2017-03-15 17:56 2419
        if (rhs.data_.f.flags == kConstStringFlag) {
6c5f2c01 sago007 2017-03-15 17:56 2420
            data_.f.flags = rhs.data_.f.flags;
6c5f2c01 sago007 2017-03-15 17:56 2421
            data_  = *reinterpret_cast<const Data*>(&rhs.data_);
6c5f2c01 sago007 2017-03-15 17:56 2422
        } else {
6c5f2c01 sago007 2017-03-15 17:56 2423
            SetStringRaw(StringRef(rhs.GetString(), rhs.GetStringLength()), allocator);
6c5f2c01 sago007 2017-03-15 17:56 2424
        }
6c5f2c01 sago007 2017-03-15 17:56 2425
        break;
6c5f2c01 sago007 2017-03-15 17:56 2426
    default:
6c5f2c01 sago007 2017-03-15 17:56 2427
        data_.f.flags = rhs.data_.f.flags;
6c5f2c01 sago007 2017-03-15 17:56 2428
        data_  = *reinterpret_cast<const Data*>(&rhs.data_);
6c5f2c01 sago007 2017-03-15 17:56 2429
        break;
6c5f2c01 sago007 2017-03-15 17:56 2430
    }
6c5f2c01 sago007 2017-03-15 17:56 2431
}
6c5f2c01 sago007 2017-03-15 17:56 2432
6c5f2c01 sago007 2017-03-15 17:56 2433
//! Helper class for accessing Value of array type.
6c5f2c01 sago007 2017-03-15 17:56 2434
/*!
6c5f2c01 sago007 2017-03-15 17:56 2435
    Instance of this helper class is obtained by \c GenericValue::GetArray().
6c5f2c01 sago007 2017-03-15 17:56 2436
    In addition to all APIs for array type, it provides range-based for loop if \c CEREAL_RAPIDJSON_HAS_CXX11_RANGE_FOR=1.
6c5f2c01 sago007 2017-03-15 17:56 2437
*/
6c5f2c01 sago007 2017-03-15 17:56 2438
template <bool Const, typename ValueT>
6c5f2c01 sago007 2017-03-15 17:56 2439
class GenericArray {
6c5f2c01 sago007 2017-03-15 17:56 2440
public:
6c5f2c01 sago007 2017-03-15 17:56 2441
    typedef GenericArray<true, ValueT> ConstArray;
6c5f2c01 sago007 2017-03-15 17:56 2442
    typedef GenericArray<false, ValueT> Array;
6c5f2c01 sago007 2017-03-15 17:56 2443
    typedef ValueT PlainType;
6c5f2c01 sago007 2017-03-15 17:56 2444
    typedef typename internal::MaybeAddConst<Const,PlainType>::Type ValueType;
6c5f2c01 sago007 2017-03-15 17:56 2445
    typedef ValueType* ValueIterator;  // This may be const or non-const iterator
6c5f2c01 sago007 2017-03-15 17:56 2446
    typedef const ValueT* ConstValueIterator;
6c5f2c01 sago007 2017-03-15 17:56 2447
    typedef typename ValueType::AllocatorType AllocatorType;
6c5f2c01 sago007 2017-03-15 17:56 2448
    typedef typename ValueType::StringRefType StringRefType;
6c5f2c01 sago007 2017-03-15 17:56 2449
6c5f2c01 sago007 2017-03-15 17:56 2450
    template <typename, typename>
6c5f2c01 sago007 2017-03-15 17:56 2451
    friend class GenericValue;
6c5f2c01 sago007 2017-03-15 17:56 2452
6c5f2c01 sago007 2017-03-15 17:56 2453
    GenericArray(const GenericArray& rhs) : value_(rhs.value_) {}
6c5f2c01 sago007 2017-03-15 17:56 2454
    GenericArray& operator=(const GenericArray& rhs) { value_ = rhs.value_; return *this; }
6c5f2c01 sago007 2017-03-15 17:56 2455
    ~GenericArray() {}
6c5f2c01 sago007 2017-03-15 17:56 2456
6c5f2c01 sago007 2017-03-15 17:56 2457
    SizeType Size() const { return value_.Size(); }
6c5f2c01 sago007 2017-03-15 17:56 2458
    SizeType Capacity() const { return value_.Capacity(); }
6c5f2c01 sago007 2017-03-15 17:56 2459
    bool Empty() const { return value_.Empty(); }
6c5f2c01 sago007 2017-03-15 17:56 2460
    void Clear() const { value_.Clear(); }
6c5f2c01 sago007 2017-03-15 17:56 2461
    ValueType& operator[](SizeType index) const {  return value_[index]; }
6c5f2c01 sago007 2017-03-15 17:56 2462
    ValueIterator Begin() const { return value_.Begin(); }
6c5f2c01 sago007 2017-03-15 17:56 2463
    ValueIterator End() const { return value_.End(); }
6c5f2c01 sago007 2017-03-15 17:56 2464
    GenericArray Reserve(SizeType newCapacity, AllocatorType &allocator) const { value_.Reserve(newCapacity, allocator); return *this; }
6c5f2c01 sago007 2017-03-15 17:56 2465
    GenericArray PushBack(ValueType& value, AllocatorType& allocator) const { value_.PushBack(value, allocator); return *this; }
6c5f2c01 sago007 2017-03-15 17:56 2466
#if CEREAL_RAPIDJSON_HAS_CXX11_RVALUE_REFS
6c5f2c01 sago007 2017-03-15 17:56 2467
    GenericArray PushBack(ValueType&& value, AllocatorType& allocator) const { value_.PushBack(value, allocator); return *this; }
6c5f2c01 sago007 2017-03-15 17:56 2468
#endif // CEREAL_RAPIDJSON_HAS_CXX11_RVALUE_REFS
6c5f2c01 sago007 2017-03-15 17:56 2469
    GenericArray PushBack(StringRefType value, AllocatorType& allocator) const { value_.PushBack(value, allocator); return *this; }
6c5f2c01 sago007 2017-03-15 17:56 2470
    template <typename T> CEREAL_RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>, internal::IsGenericValue<T> >), (const GenericArray&)) PushBack(T value, AllocatorType& allocator) const { value_.PushBack(value, allocator); return *this; }
6c5f2c01 sago007 2017-03-15 17:56 2471
    GenericArray PopBack() const { value_.PopBack(); return *this; }
6c5f2c01 sago007 2017-03-15 17:56 2472
    ValueIterator Erase(ConstValueIterator pos) const { return value_.Erase(pos); }
6c5f2c01 sago007 2017-03-15 17:56 2473
    ValueIterator Erase(ConstValueIterator first, ConstValueIterator last) const { return value_.Erase(first, last); }
6c5f2c01 sago007 2017-03-15 17:56 2474
6c5f2c01 sago007 2017-03-15 17:56 2475
#if CEREAL_RAPIDJSON_HAS_CXX11_RANGE_FOR
6c5f2c01 sago007 2017-03-15 17:56 2476
    ValueIterator begin() const { return value_.Begin(); }
6c5f2c01 sago007 2017-03-15 17:56 2477
    ValueIterator end() const { return value_.End(); }
6c5f2c01 sago007 2017-03-15 17:56 2478
#endif
7a956470 sago007 2016-02-14 17:09 2479
6c5f2c01 sago007 2017-03-15 17:56 2480
private:
6c5f2c01 sago007 2017-03-15 17:56 2481
    GenericArray();
6c5f2c01 sago007 2017-03-15 17:56 2482
    GenericArray(ValueType& value) : value_(value) {}
6c5f2c01 sago007 2017-03-15 17:56 2483
    ValueType& value_;
6c5f2c01 sago007 2017-03-15 17:56 2484
};
6c5f2c01 sago007 2017-03-15 17:56 2485
6c5f2c01 sago007 2017-03-15 17:56 2486
//! Helper class for accessing Value of object type.
6c5f2c01 sago007 2017-03-15 17:56 2487
/*!
6c5f2c01 sago007 2017-03-15 17:56 2488
    Instance of this helper class is obtained by \c GenericValue::GetObject().
6c5f2c01 sago007 2017-03-15 17:56 2489
    In addition to all APIs for array type, it provides range-based for loop if \c CEREAL_RAPIDJSON_HAS_CXX11_RANGE_FOR=1.
6c5f2c01 sago007 2017-03-15 17:56 2490
*/
6c5f2c01 sago007 2017-03-15 17:56 2491
template <bool Const, typename ValueT>
6c5f2c01 sago007 2017-03-15 17:56 2492
class GenericObject {
6c5f2c01 sago007 2017-03-15 17:56 2493
public:
6c5f2c01 sago007 2017-03-15 17:56 2494
    typedef GenericObject<true, ValueT> ConstObject;
6c5f2c01 sago007 2017-03-15 17:56 2495
    typedef GenericObject<false, ValueT> Object;
6c5f2c01 sago007 2017-03-15 17:56 2496
    typedef ValueT PlainType;
6c5f2c01 sago007 2017-03-15 17:56 2497
    typedef typename internal::MaybeAddConst<Const,PlainType>::Type ValueType;
6c5f2c01 sago007 2017-03-15 17:56 2498
    typedef GenericMemberIterator<Const, typename ValueT::EncodingType, typename ValueT::AllocatorType> MemberIterator;  // This may be const or non-const iterator
6c5f2c01 sago007 2017-03-15 17:56 2499
    typedef GenericMemberIterator<true, typename ValueT::EncodingType, typename ValueT::AllocatorType> ConstMemberIterator;
6c5f2c01 sago007 2017-03-15 17:56 2500
    typedef typename ValueType::AllocatorType AllocatorType;
6c5f2c01 sago007 2017-03-15 17:56 2501
    typedef typename ValueType::StringRefType StringRefType;
6c5f2c01 sago007 2017-03-15 17:56 2502
    typedef typename ValueType::EncodingType EncodingType;
6c5f2c01 sago007 2017-03-15 17:56 2503
    typedef typename ValueType::Ch Ch;
6c5f2c01 sago007 2017-03-15 17:56 2504
6c5f2c01 sago007 2017-03-15 17:56 2505
    template <typename, typename>
6c5f2c01 sago007 2017-03-15 17:56 2506
    friend class GenericValue;
6c5f2c01 sago007 2017-03-15 17:56 2507
6c5f2c01 sago007 2017-03-15 17:56 2508
    GenericObject(const GenericObject& rhs) : value_(rhs.value_) {}
6c5f2c01 sago007 2017-03-15 17:56 2509
    GenericObject& operator=(const GenericObject& rhs) { value_ = rhs.value_; return *this; }
6c5f2c01 sago007 2017-03-15 17:56 2510
    ~GenericObject() {}
6c5f2c01 sago007 2017-03-15 17:56 2511
6c5f2c01 sago007 2017-03-15 17:56 2512
    SizeType MemberCount() const { return value_.MemberCount(); }
6c5f2c01 sago007 2017-03-15 17:56 2513
    bool ObjectEmpty() const { return value_.ObjectEmpty(); }
6c5f2c01 sago007 2017-03-15 17:56 2514
    template <typename T> ValueType& operator[](T* name) const { return value_[name]; }
6c5f2c01 sago007 2017-03-15 17:56 2515
    template <typename SourceAllocator> ValueType& operator[](const GenericValue<EncodingType, SourceAllocator>& name) const { return value_[name]; }
6c5f2c01 sago007 2017-03-15 17:56 2516
#if CEREAL_RAPIDJSON_HAS_STDSTRING
6c5f2c01 sago007 2017-03-15 17:56 2517
    ValueType& operator[](const std::basic_string<Ch>& name) const { return value_[name]; }
6c5f2c01 sago007 2017-03-15 17:56 2518
#endif
6c5f2c01 sago007 2017-03-15 17:56 2519
    MemberIterator MemberBegin() const { return value_.MemberBegin(); }
6c5f2c01 sago007 2017-03-15 17:56 2520
    MemberIterator MemberEnd() const { return value_.MemberEnd(); }
6c5f2c01 sago007 2017-03-15 17:56 2521
    bool HasMember(const Ch* name) const { return value_.HasMember(name); }
6c5f2c01 sago007 2017-03-15 17:56 2522
#if CEREAL_RAPIDJSON_HAS_STDSTRING
6c5f2c01 sago007 2017-03-15 17:56 2523
    bool HasMember(const std::basic_string<Ch>& name) const { return value_.HasMember(name); }
7a956470 sago007 2016-02-14 17:09 2524
#endif
6c5f2c01 sago007 2017-03-15 17:56 2525
    template <typename SourceAllocator> bool HasMember(const GenericValue<EncodingType, SourceAllocator>& name) const { return value_.HasMember(name); }
6c5f2c01 sago007 2017-03-15 17:56 2526
    MemberIterator FindMember(const Ch* name) const { return value_.FindMember(name); }
6c5f2c01 sago007 2017-03-15 17:56 2527
    template <typename SourceAllocator> MemberIterator FindMember(const GenericValue<EncodingType, SourceAllocator>& name) const { return value_.FindMember(name); }
6c5f2c01 sago007 2017-03-15 17:56 2528
#if CEREAL_RAPIDJSON_HAS_STDSTRING
6c5f2c01 sago007 2017-03-15 17:56 2529
    MemberIterator FindMember(const std::basic_string<Ch>& name) const { return value_.FindMember(name); }
6c5f2c01 sago007 2017-03-15 17:56 2530
#endif
6c5f2c01 sago007 2017-03-15 17:56 2531
    GenericObject AddMember(ValueType& name, ValueType& value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; }
6c5f2c01 sago007 2017-03-15 17:56 2532
    GenericObject AddMember(ValueType& name, StringRefType value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; }
6c5f2c01 sago007 2017-03-15 17:56 2533
#if CEREAL_RAPIDJSON_HAS_STDSTRING
6c5f2c01 sago007 2017-03-15 17:56 2534
    GenericObject AddMember(ValueType& name, std::basic_string<Ch>& value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; }
6c5f2c01 sago007 2017-03-15 17:56 2535
#endif
6c5f2c01 sago007 2017-03-15 17:56 2536
    template <typename T> CEREAL_RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>, internal::IsGenericValue<T> >), (ValueType&)) AddMember(ValueType& name, T value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; }
6c5f2c01 sago007 2017-03-15 17:56 2537
#if CEREAL_RAPIDJSON_HAS_CXX11_RVALUE_REFS
6c5f2c01 sago007 2017-03-15 17:56 2538
    GenericObject AddMember(ValueType&& name, ValueType&& value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; }
6c5f2c01 sago007 2017-03-15 17:56 2539
    GenericObject AddMember(ValueType&& name, ValueType& value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; }
6c5f2c01 sago007 2017-03-15 17:56 2540
    GenericObject AddMember(ValueType& name, ValueType&& value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; }
6c5f2c01 sago007 2017-03-15 17:56 2541
    GenericObject AddMember(StringRefType name, ValueType&& value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; }
6c5f2c01 sago007 2017-03-15 17:56 2542
#endif // CEREAL_RAPIDJSON_HAS_CXX11_RVALUE_REFS
6c5f2c01 sago007 2017-03-15 17:56 2543
    GenericObject AddMember(StringRefType name, ValueType& value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; }
6c5f2c01 sago007 2017-03-15 17:56 2544
    GenericObject AddMember(StringRefType name, StringRefType value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; }
6c5f2c01 sago007 2017-03-15 17:56 2545
    template <typename T> CEREAL_RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>, internal::IsGenericValue<T> >), (GenericObject)) AddMember(StringRefType name, T value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; }
6c5f2c01 sago007 2017-03-15 17:56 2546
    void RemoveAllMembers() { return value_.RemoveAllMembers(); }
6c5f2c01 sago007 2017-03-15 17:56 2547
    bool RemoveMember(const Ch* name) const { return value_.RemoveMember(name); }
6c5f2c01 sago007 2017-03-15 17:56 2548
#if CEREAL_RAPIDJSON_HAS_STDSTRING
6c5f2c01 sago007 2017-03-15 17:56 2549
    bool RemoveMember(const std::basic_string<Ch>& name) const { return value_.RemoveMember(name); }
6c5f2c01 sago007 2017-03-15 17:56 2550
#endif
6c5f2c01 sago007 2017-03-15 17:56 2551
    template <typename SourceAllocator> bool RemoveMember(const GenericValue<EncodingType, SourceAllocator>& name) const { return value_.RemoveMember(name); }
6c5f2c01 sago007 2017-03-15 17:56 2552
    MemberIterator RemoveMember(MemberIterator m) const { return value_.RemoveMember(m); }
6c5f2c01 sago007 2017-03-15 17:56 2553
    MemberIterator EraseMember(ConstMemberIterator pos) const { return value_.EraseMember(pos); }
6c5f2c01 sago007 2017-03-15 17:56 2554
    MemberIterator EraseMember(ConstMemberIterator first, ConstMemberIterator last) const { return value_.EraseMember(first, last); }
6c5f2c01 sago007 2017-03-15 17:56 2555
    bool EraseMember(const Ch* name) const { return value_.EraseMember(name); }
6c5f2c01 sago007 2017-03-15 17:56 2556
#if CEREAL_RAPIDJSON_HAS_STDSTRING
6c5f2c01 sago007 2017-03-15 17:56 2557
    bool EraseMember(const std::basic_string<Ch>& name) const { return EraseMember(ValueType(StringRef(name))); }
6c5f2c01 sago007 2017-03-15 17:56 2558
#endif
6c5f2c01 sago007 2017-03-15 17:56 2559
    template <typename SourceAllocator> bool EraseMember(const GenericValue<EncodingType, SourceAllocator>& name) const { return value_.EraseMember(name); }
6c5f2c01 sago007 2017-03-15 17:56 2560
6c5f2c01 sago007 2017-03-15 17:56 2561
#if CEREAL_RAPIDJSON_HAS_CXX11_RANGE_FOR
6c5f2c01 sago007 2017-03-15 17:56 2562
    MemberIterator begin() const { return value_.MemberBegin(); }
6c5f2c01 sago007 2017-03-15 17:56 2563
    MemberIterator end() const { return value_.MemberEnd(); }
6c5f2c01 sago007 2017-03-15 17:56 2564
#endif
6c5f2c01 sago007 2017-03-15 17:56 2565
6c5f2c01 sago007 2017-03-15 17:56 2566
private:
6c5f2c01 sago007 2017-03-15 17:56 2567
    GenericObject();
6c5f2c01 sago007 2017-03-15 17:56 2568
    GenericObject(ValueType& value) : value_(value) {}
6c5f2c01 sago007 2017-03-15 17:56 2569
    ValueType& value_;
6c5f2c01 sago007 2017-03-15 17:56 2570
};
6c5f2c01 sago007 2017-03-15 17:56 2571
6c5f2c01 sago007 2017-03-15 17:56 2572
CEREAL_RAPIDJSON_NAMESPACE_END
6c5f2c01 sago007 2017-03-15 17:56 2573
CEREAL_RAPIDJSON_DIAG_POP
7a956470 sago007 2016-02-14 17:09 2574
6c5f2c01 sago007 2017-03-15 17:56 2575
#endif // CEREAL_RAPIDJSON_DOCUMENT_H_
1970-01-01 00:00 2576