git repos / blockattack-game

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

normal view · raw

6c5f2c01 sago007 2017-03-15 17:56 1
// Tencent is pleased to support the open source community by making RapidJSON available.
6c5f2c01 sago007 2017-03-15 17:56 2
// 
6c5f2c01 sago007 2017-03-15 17:56 3
// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
6c5f2c01 sago007 2017-03-15 17:56 4
//
6c5f2c01 sago007 2017-03-15 17:56 5
// Licensed under the MIT License (the "License"); you may not use this file except
6c5f2c01 sago007 2017-03-15 17:56 6
// in compliance with the License. You may obtain a copy of the License at
6c5f2c01 sago007 2017-03-15 17:56 7
//
6c5f2c01 sago007 2017-03-15 17:56 8
// http://opensource.org/licenses/MIT
6c5f2c01 sago007 2017-03-15 17:56 9
//
6c5f2c01 sago007 2017-03-15 17:56 10
// Unless required by applicable law or agreed to in writing, software distributed 
6c5f2c01 sago007 2017-03-15 17:56 11
// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 
6c5f2c01 sago007 2017-03-15 17:56 12
// CONDITIONS OF ANY KIND, either express or implied. See the License for the 
6c5f2c01 sago007 2017-03-15 17:56 13
// specific language governing permissions and limitations under the License.
6c5f2c01 sago007 2017-03-15 17:56 14
6c5f2c01 sago007 2017-03-15 17:56 15
#ifndef CEREAL_RAPIDJSON_INTERNAL_STACK_H_
6c5f2c01 sago007 2017-03-15 17:56 16
#define CEREAL_RAPIDJSON_INTERNAL_STACK_H_
6c5f2c01 sago007 2017-03-15 17:56 17
6c5f2c01 sago007 2017-03-15 17:56 18
#include "../allocators.h"
6c5f2c01 sago007 2017-03-15 17:56 19
#include "swap.h"
8f94a7f5 sago007 2020-05-10 10:26 20
#include <cstddef>
6c5f2c01 sago007 2017-03-15 17:56 21
6c5f2c01 sago007 2017-03-15 17:56 22
#if defined(__clang__)
6c5f2c01 sago007 2017-03-15 17:56 23
CEREAL_RAPIDJSON_DIAG_PUSH
6c5f2c01 sago007 2017-03-15 17:56 24
CEREAL_RAPIDJSON_DIAG_OFF(c++98-compat)
6c5f2c01 sago007 2017-03-15 17:56 25
#endif
6c5f2c01 sago007 2017-03-15 17:56 26
6c5f2c01 sago007 2017-03-15 17:56 27
CEREAL_RAPIDJSON_NAMESPACE_BEGIN
6c5f2c01 sago007 2017-03-15 17:56 28
namespace internal {
6c5f2c01 sago007 2017-03-15 17:56 29
6c5f2c01 sago007 2017-03-15 17:56 30
///////////////////////////////////////////////////////////////////////////////
6c5f2c01 sago007 2017-03-15 17:56 31
// Stack
6c5f2c01 sago007 2017-03-15 17:56 32
6c5f2c01 sago007 2017-03-15 17:56 33
//! A type-unsafe stack for storing different types of data.
6c5f2c01 sago007 2017-03-15 17:56 34
/*! \tparam Allocator Allocator for allocating stack memory.
6c5f2c01 sago007 2017-03-15 17:56 35
*/
6c5f2c01 sago007 2017-03-15 17:56 36
template <typename Allocator>
6c5f2c01 sago007 2017-03-15 17:56 37
class Stack {
6c5f2c01 sago007 2017-03-15 17:56 38
public:
6c5f2c01 sago007 2017-03-15 17:56 39
    // Optimization note: Do not allocate memory for stack_ in constructor.
6c5f2c01 sago007 2017-03-15 17:56 40
    // Do it lazily when first Push() -> Expand() -> Resize().
6c5f2c01 sago007 2017-03-15 17:56 41
    Stack(Allocator* allocator, size_t stackCapacity) : allocator_(allocator), ownAllocator_(0), stack_(0), stackTop_(0), stackEnd_(0), initialCapacity_(stackCapacity) {
6c5f2c01 sago007 2017-03-15 17:56 42
    }
6c5f2c01 sago007 2017-03-15 17:56 43
6c5f2c01 sago007 2017-03-15 17:56 44
#if CEREAL_RAPIDJSON_HAS_CXX11_RVALUE_REFS
6c5f2c01 sago007 2017-03-15 17:56 45
    Stack(Stack&& rhs)
6c5f2c01 sago007 2017-03-15 17:56 46
        : allocator_(rhs.allocator_),
6c5f2c01 sago007 2017-03-15 17:56 47
          ownAllocator_(rhs.ownAllocator_),
6c5f2c01 sago007 2017-03-15 17:56 48
          stack_(rhs.stack_),
6c5f2c01 sago007 2017-03-15 17:56 49
          stackTop_(rhs.stackTop_),
6c5f2c01 sago007 2017-03-15 17:56 50
          stackEnd_(rhs.stackEnd_),
6c5f2c01 sago007 2017-03-15 17:56 51
          initialCapacity_(rhs.initialCapacity_)
6c5f2c01 sago007 2017-03-15 17:56 52
    {
6c5f2c01 sago007 2017-03-15 17:56 53
        rhs.allocator_ = 0;
6c5f2c01 sago007 2017-03-15 17:56 54
        rhs.ownAllocator_ = 0;
6c5f2c01 sago007 2017-03-15 17:56 55
        rhs.stack_ = 0;
6c5f2c01 sago007 2017-03-15 17:56 56
        rhs.stackTop_ = 0;
6c5f2c01 sago007 2017-03-15 17:56 57
        rhs.stackEnd_ = 0;
6c5f2c01 sago007 2017-03-15 17:56 58
        rhs.initialCapacity_ = 0;
6c5f2c01 sago007 2017-03-15 17:56 59
    }
6c5f2c01 sago007 2017-03-15 17:56 60
#endif
6c5f2c01 sago007 2017-03-15 17:56 61
6c5f2c01 sago007 2017-03-15 17:56 62
    ~Stack() {
6c5f2c01 sago007 2017-03-15 17:56 63
        Destroy();
6c5f2c01 sago007 2017-03-15 17:56 64
    }
6c5f2c01 sago007 2017-03-15 17:56 65
6c5f2c01 sago007 2017-03-15 17:56 66
#if CEREAL_RAPIDJSON_HAS_CXX11_RVALUE_REFS
6c5f2c01 sago007 2017-03-15 17:56 67
    Stack& operator=(Stack&& rhs) {
6c5f2c01 sago007 2017-03-15 17:56 68
        if (&rhs != this)
6c5f2c01 sago007 2017-03-15 17:56 69
        {
6c5f2c01 sago007 2017-03-15 17:56 70
            Destroy();
6c5f2c01 sago007 2017-03-15 17:56 71
6c5f2c01 sago007 2017-03-15 17:56 72
            allocator_ = rhs.allocator_;
6c5f2c01 sago007 2017-03-15 17:56 73
            ownAllocator_ = rhs.ownAllocator_;
6c5f2c01 sago007 2017-03-15 17:56 74
            stack_ = rhs.stack_;
6c5f2c01 sago007 2017-03-15 17:56 75
            stackTop_ = rhs.stackTop_;
6c5f2c01 sago007 2017-03-15 17:56 76
            stackEnd_ = rhs.stackEnd_;
6c5f2c01 sago007 2017-03-15 17:56 77
            initialCapacity_ = rhs.initialCapacity_;
6c5f2c01 sago007 2017-03-15 17:56 78
6c5f2c01 sago007 2017-03-15 17:56 79
            rhs.allocator_ = 0;
6c5f2c01 sago007 2017-03-15 17:56 80
            rhs.ownAllocator_ = 0;
6c5f2c01 sago007 2017-03-15 17:56 81
            rhs.stack_ = 0;
6c5f2c01 sago007 2017-03-15 17:56 82
            rhs.stackTop_ = 0;
6c5f2c01 sago007 2017-03-15 17:56 83
            rhs.stackEnd_ = 0;
6c5f2c01 sago007 2017-03-15 17:56 84
            rhs.initialCapacity_ = 0;
6c5f2c01 sago007 2017-03-15 17:56 85
        }
6c5f2c01 sago007 2017-03-15 17:56 86
        return *this;
6c5f2c01 sago007 2017-03-15 17:56 87
    }
6c5f2c01 sago007 2017-03-15 17:56 88
#endif
6c5f2c01 sago007 2017-03-15 17:56 89
6c5f2c01 sago007 2017-03-15 17:56 90
    void Swap(Stack& rhs) CEREAL_RAPIDJSON_NOEXCEPT {
6c5f2c01 sago007 2017-03-15 17:56 91
        internal::Swap(allocator_, rhs.allocator_);
6c5f2c01 sago007 2017-03-15 17:56 92
        internal::Swap(ownAllocator_, rhs.ownAllocator_);
6c5f2c01 sago007 2017-03-15 17:56 93
        internal::Swap(stack_, rhs.stack_);
6c5f2c01 sago007 2017-03-15 17:56 94
        internal::Swap(stackTop_, rhs.stackTop_);
6c5f2c01 sago007 2017-03-15 17:56 95
        internal::Swap(stackEnd_, rhs.stackEnd_);
6c5f2c01 sago007 2017-03-15 17:56 96
        internal::Swap(initialCapacity_, rhs.initialCapacity_);
6c5f2c01 sago007 2017-03-15 17:56 97
    }
6c5f2c01 sago007 2017-03-15 17:56 98
6c5f2c01 sago007 2017-03-15 17:56 99
    void Clear() { stackTop_ = stack_; }
6c5f2c01 sago007 2017-03-15 17:56 100
6c5f2c01 sago007 2017-03-15 17:56 101
    void ShrinkToFit() { 
6c5f2c01 sago007 2017-03-15 17:56 102
        if (Empty()) {
6c5f2c01 sago007 2017-03-15 17:56 103
            // If the stack is empty, completely deallocate the memory.
8f94a7f5 sago007 2020-05-10 10:26 104
            Allocator::Free(stack_); // NOLINT (+clang-analyzer-unix.Malloc)
6c5f2c01 sago007 2017-03-15 17:56 105
            stack_ = 0;
6c5f2c01 sago007 2017-03-15 17:56 106
            stackTop_ = 0;
6c5f2c01 sago007 2017-03-15 17:56 107
            stackEnd_ = 0;
6c5f2c01 sago007 2017-03-15 17:56 108
        }
6c5f2c01 sago007 2017-03-15 17:56 109
        else
6c5f2c01 sago007 2017-03-15 17:56 110
            Resize(GetSize());
6c5f2c01 sago007 2017-03-15 17:56 111
    }
6c5f2c01 sago007 2017-03-15 17:56 112
6c5f2c01 sago007 2017-03-15 17:56 113
    // Optimization note: try to minimize the size of this function for force inline.
6c5f2c01 sago007 2017-03-15 17:56 114
    // Expansion is run very infrequently, so it is moved to another (probably non-inline) function.
6c5f2c01 sago007 2017-03-15 17:56 115
    template<typename T>
6c5f2c01 sago007 2017-03-15 17:56 116
    CEREAL_RAPIDJSON_FORCEINLINE void Reserve(size_t count = 1) {
6c5f2c01 sago007 2017-03-15 17:56 117
         // Expand the stack if needed
8f94a7f5 sago007 2020-05-10 10:26 118
        if (CEREAL_RAPIDJSON_UNLIKELY(static_cast<std::ptrdiff_t>(sizeof(T) * count) > (stackEnd_ - stackTop_)))
6c5f2c01 sago007 2017-03-15 17:56 119
            Expand<T>(count);
6c5f2c01 sago007 2017-03-15 17:56 120
    }
6c5f2c01 sago007 2017-03-15 17:56 121
6c5f2c01 sago007 2017-03-15 17:56 122
    template<typename T>
6c5f2c01 sago007 2017-03-15 17:56 123
    CEREAL_RAPIDJSON_FORCEINLINE T* Push(size_t count = 1) {
6c5f2c01 sago007 2017-03-15 17:56 124
        Reserve<T>(count);
6c5f2c01 sago007 2017-03-15 17:56 125
        return PushUnsafe<T>(count);
6c5f2c01 sago007 2017-03-15 17:56 126
    }
6c5f2c01 sago007 2017-03-15 17:56 127
6c5f2c01 sago007 2017-03-15 17:56 128
    template<typename T>
6c5f2c01 sago007 2017-03-15 17:56 129
    CEREAL_RAPIDJSON_FORCEINLINE T* PushUnsafe(size_t count = 1) {
8f94a7f5 sago007 2020-05-10 10:26 130
        CEREAL_RAPIDJSON_ASSERT(stackTop_);
8f94a7f5 sago007 2020-05-10 10:26 131
        CEREAL_RAPIDJSON_ASSERT(static_cast<std::ptrdiff_t>(sizeof(T) * count) <= (stackEnd_ - stackTop_));
6c5f2c01 sago007 2017-03-15 17:56 132
        T* ret = reinterpret_cast<T*>(stackTop_);
6c5f2c01 sago007 2017-03-15 17:56 133
        stackTop_ += sizeof(T) * count;
6c5f2c01 sago007 2017-03-15 17:56 134
        return ret;
6c5f2c01 sago007 2017-03-15 17:56 135
    }
6c5f2c01 sago007 2017-03-15 17:56 136
6c5f2c01 sago007 2017-03-15 17:56 137
    template<typename T>
6c5f2c01 sago007 2017-03-15 17:56 138
    T* Pop(size_t count) {
6c5f2c01 sago007 2017-03-15 17:56 139
        CEREAL_RAPIDJSON_ASSERT(GetSize() >= count * sizeof(T));
6c5f2c01 sago007 2017-03-15 17:56 140
        stackTop_ -= count * sizeof(T);
6c5f2c01 sago007 2017-03-15 17:56 141
        return reinterpret_cast<T*>(stackTop_);
6c5f2c01 sago007 2017-03-15 17:56 142
    }
6c5f2c01 sago007 2017-03-15 17:56 143
6c5f2c01 sago007 2017-03-15 17:56 144
    template<typename T>
6c5f2c01 sago007 2017-03-15 17:56 145
    T* Top() { 
6c5f2c01 sago007 2017-03-15 17:56 146
        CEREAL_RAPIDJSON_ASSERT(GetSize() >= sizeof(T));
6c5f2c01 sago007 2017-03-15 17:56 147
        return reinterpret_cast<T*>(stackTop_ - sizeof(T));
6c5f2c01 sago007 2017-03-15 17:56 148
    }
6c5f2c01 sago007 2017-03-15 17:56 149
6c5f2c01 sago007 2017-03-15 17:56 150
    template<typename T>
6c5f2c01 sago007 2017-03-15 17:56 151
    const T* Top() const {
6c5f2c01 sago007 2017-03-15 17:56 152
        CEREAL_RAPIDJSON_ASSERT(GetSize() >= sizeof(T));
6c5f2c01 sago007 2017-03-15 17:56 153
        return reinterpret_cast<T*>(stackTop_ - sizeof(T));
6c5f2c01 sago007 2017-03-15 17:56 154
    }
6c5f2c01 sago007 2017-03-15 17:56 155
6c5f2c01 sago007 2017-03-15 17:56 156
    template<typename T>
6c5f2c01 sago007 2017-03-15 17:56 157
    T* End() { return reinterpret_cast<T*>(stackTop_); }
6c5f2c01 sago007 2017-03-15 17:56 158
6c5f2c01 sago007 2017-03-15 17:56 159
    template<typename T>
6c5f2c01 sago007 2017-03-15 17:56 160
    const T* End() const { return reinterpret_cast<T*>(stackTop_); }
6c5f2c01 sago007 2017-03-15 17:56 161
6c5f2c01 sago007 2017-03-15 17:56 162
    template<typename T>
6c5f2c01 sago007 2017-03-15 17:56 163
    T* Bottom() { return reinterpret_cast<T*>(stack_); }
6c5f2c01 sago007 2017-03-15 17:56 164
6c5f2c01 sago007 2017-03-15 17:56 165
    template<typename T>
6c5f2c01 sago007 2017-03-15 17:56 166
    const T* Bottom() const { return reinterpret_cast<T*>(stack_); }
6c5f2c01 sago007 2017-03-15 17:56 167
6c5f2c01 sago007 2017-03-15 17:56 168
    bool HasAllocator() const {
6c5f2c01 sago007 2017-03-15 17:56 169
        return allocator_ != 0;
6c5f2c01 sago007 2017-03-15 17:56 170
    }
6c5f2c01 sago007 2017-03-15 17:56 171
6c5f2c01 sago007 2017-03-15 17:56 172
    Allocator& GetAllocator() {
6c5f2c01 sago007 2017-03-15 17:56 173
        CEREAL_RAPIDJSON_ASSERT(allocator_);
6c5f2c01 sago007 2017-03-15 17:56 174
        return *allocator_;
6c5f2c01 sago007 2017-03-15 17:56 175
    }
6c5f2c01 sago007 2017-03-15 17:56 176
6c5f2c01 sago007 2017-03-15 17:56 177
    bool Empty() const { return stackTop_ == stack_; }
6c5f2c01 sago007 2017-03-15 17:56 178
    size_t GetSize() const { return static_cast<size_t>(stackTop_ - stack_); }
6c5f2c01 sago007 2017-03-15 17:56 179
    size_t GetCapacity() const { return static_cast<size_t>(stackEnd_ - stack_); }
6c5f2c01 sago007 2017-03-15 17:56 180
6c5f2c01 sago007 2017-03-15 17:56 181
private:
6c5f2c01 sago007 2017-03-15 17:56 182
    template<typename T>
6c5f2c01 sago007 2017-03-15 17:56 183
    void Expand(size_t count) {
6c5f2c01 sago007 2017-03-15 17:56 184
        // Only expand the capacity if the current stack exists. Otherwise just create a stack with initial capacity.
6c5f2c01 sago007 2017-03-15 17:56 185
        size_t newCapacity;
6c5f2c01 sago007 2017-03-15 17:56 186
        if (stack_ == 0) {
6c5f2c01 sago007 2017-03-15 17:56 187
            if (!allocator_)
8f94a7f5 sago007 2020-05-10 10:26 188
                ownAllocator_ = allocator_ = CEREAL_RAPIDJSON_NEW(Allocator)();
6c5f2c01 sago007 2017-03-15 17:56 189
            newCapacity = initialCapacity_;
6c5f2c01 sago007 2017-03-15 17:56 190
        } else {
6c5f2c01 sago007 2017-03-15 17:56 191
            newCapacity = GetCapacity();
6c5f2c01 sago007 2017-03-15 17:56 192
            newCapacity += (newCapacity + 1) / 2;
6c5f2c01 sago007 2017-03-15 17:56 193
        }
6c5f2c01 sago007 2017-03-15 17:56 194
        size_t newSize = GetSize() + sizeof(T) * count;
6c5f2c01 sago007 2017-03-15 17:56 195
        if (newCapacity < newSize)
6c5f2c01 sago007 2017-03-15 17:56 196
            newCapacity = newSize;
6c5f2c01 sago007 2017-03-15 17:56 197
6c5f2c01 sago007 2017-03-15 17:56 198
        Resize(newCapacity);
6c5f2c01 sago007 2017-03-15 17:56 199
    }
6c5f2c01 sago007 2017-03-15 17:56 200
6c5f2c01 sago007 2017-03-15 17:56 201
    void Resize(size_t newCapacity) {
6c5f2c01 sago007 2017-03-15 17:56 202
        const size_t size = GetSize();  // Backup the current size
6c5f2c01 sago007 2017-03-15 17:56 203
        stack_ = static_cast<char*>(allocator_->Realloc(stack_, GetCapacity(), newCapacity));
6c5f2c01 sago007 2017-03-15 17:56 204
        stackTop_ = stack_ + size;
6c5f2c01 sago007 2017-03-15 17:56 205
        stackEnd_ = stack_ + newCapacity;
6c5f2c01 sago007 2017-03-15 17:56 206
    }
6c5f2c01 sago007 2017-03-15 17:56 207
6c5f2c01 sago007 2017-03-15 17:56 208
    void Destroy() {
6c5f2c01 sago007 2017-03-15 17:56 209
        Allocator::Free(stack_);
6c5f2c01 sago007 2017-03-15 17:56 210
        CEREAL_RAPIDJSON_DELETE(ownAllocator_); // Only delete if it is owned by the stack
6c5f2c01 sago007 2017-03-15 17:56 211
    }
6c5f2c01 sago007 2017-03-15 17:56 212
6c5f2c01 sago007 2017-03-15 17:56 213
    // Prohibit copy constructor & assignment operator.
6c5f2c01 sago007 2017-03-15 17:56 214
    Stack(const Stack&);
6c5f2c01 sago007 2017-03-15 17:56 215
    Stack& operator=(const Stack&);
6c5f2c01 sago007 2017-03-15 17:56 216
6c5f2c01 sago007 2017-03-15 17:56 217
    Allocator* allocator_;
6c5f2c01 sago007 2017-03-15 17:56 218
    Allocator* ownAllocator_;
6c5f2c01 sago007 2017-03-15 17:56 219
    char *stack_;
6c5f2c01 sago007 2017-03-15 17:56 220
    char *stackTop_;
6c5f2c01 sago007 2017-03-15 17:56 221
    char *stackEnd_;
6c5f2c01 sago007 2017-03-15 17:56 222
    size_t initialCapacity_;
6c5f2c01 sago007 2017-03-15 17:56 223
};
6c5f2c01 sago007 2017-03-15 17:56 224
6c5f2c01 sago007 2017-03-15 17:56 225
} // namespace internal
6c5f2c01 sago007 2017-03-15 17:56 226
CEREAL_RAPIDJSON_NAMESPACE_END
6c5f2c01 sago007 2017-03-15 17:56 227
6c5f2c01 sago007 2017-03-15 17:56 228
#if defined(__clang__)
6c5f2c01 sago007 2017-03-15 17:56 229
CEREAL_RAPIDJSON_DIAG_POP
6c5f2c01 sago007 2017-03-15 17:56 230
#endif
6c5f2c01 sago007 2017-03-15 17:56 231
6c5f2c01 sago007 2017-03-15 17:56 232
#endif // CEREAL_RAPIDJSON_STACK_H_
1970-01-01 00:00 233