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