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"
6c5f2c01 sago007 2017-03-15 17:56 20
6c5f2c01 sago007 2017-03-15 17:56 21
#if defined(__clang__)
6c5f2c01 sago007 2017-03-15 17:56 22
CEREAL_RAPIDJSON_DIAG_PUSH
6c5f2c01 sago007 2017-03-15 17:56 23
CEREAL_RAPIDJSON_DIAG_OFF(c++98-compat)
6c5f2c01 sago007 2017-03-15 17:56 24
#endif
6c5f2c01 sago007 2017-03-15 17:56 25
6c5f2c01 sago007 2017-03-15 17:56 26
CEREAL_RAPIDJSON_NAMESPACE_BEGIN
6c5f2c01 sago007 2017-03-15 17:56 27
namespace internal {
6c5f2c01 sago007 2017-03-15 17:56 28
6c5f2c01 sago007 2017-03-15 17:56 29
///////////////////////////////////////////////////////////////////////////////
6c5f2c01 sago007 2017-03-15 17:56 30
// Stack
6c5f2c01 sago007 2017-03-15 17:56 31
6c5f2c01 sago007 2017-03-15 17:56 32
//! A type-unsafe stack for storing different types of data.
6c5f2c01 sago007 2017-03-15 17:56 33
/*! \tparam Allocator Allocator for allocating stack memory.
6c5f2c01 sago007 2017-03-15 17:56 34
*/
6c5f2c01 sago007 2017-03-15 17:56 35
template <typename Allocator>
6c5f2c01 sago007 2017-03-15 17:56 36
class Stack {
6c5f2c01 sago007 2017-03-15 17:56 37
public:
6c5f2c01 sago007 2017-03-15 17:56 38
    // Optimization note: Do not allocate memory for stack_ in constructor.
6c5f2c01 sago007 2017-03-15 17:56 39
    // Do it lazily when first Push() -> Expand() -> Resize().
6c5f2c01 sago007 2017-03-15 17:56 40
    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 41
    }
6c5f2c01 sago007 2017-03-15 17:56 42
6c5f2c01 sago007 2017-03-15 17:56 43
#if CEREAL_RAPIDJSON_HAS_CXX11_RVALUE_REFS
6c5f2c01 sago007 2017-03-15 17:56 44
    Stack(Stack&& rhs)
6c5f2c01 sago007 2017-03-15 17:56 45
        : allocator_(rhs.allocator_),
6c5f2c01 sago007 2017-03-15 17:56 46
          ownAllocator_(rhs.ownAllocator_),
6c5f2c01 sago007 2017-03-15 17:56 47
          stack_(rhs.stack_),
6c5f2c01 sago007 2017-03-15 17:56 48
          stackTop_(rhs.stackTop_),
6c5f2c01 sago007 2017-03-15 17:56 49
          stackEnd_(rhs.stackEnd_),
6c5f2c01 sago007 2017-03-15 17:56 50
          initialCapacity_(rhs.initialCapacity_)
6c5f2c01 sago007 2017-03-15 17:56 51
    {
6c5f2c01 sago007 2017-03-15 17:56 52
        rhs.allocator_ = 0;
6c5f2c01 sago007 2017-03-15 17:56 53
        rhs.ownAllocator_ = 0;
6c5f2c01 sago007 2017-03-15 17:56 54
        rhs.stack_ = 0;
6c5f2c01 sago007 2017-03-15 17:56 55
        rhs.stackTop_ = 0;
6c5f2c01 sago007 2017-03-15 17:56 56
        rhs.stackEnd_ = 0;
6c5f2c01 sago007 2017-03-15 17:56 57
        rhs.initialCapacity_ = 0;
6c5f2c01 sago007 2017-03-15 17:56 58
    }
6c5f2c01 sago007 2017-03-15 17:56 59
#endif
6c5f2c01 sago007 2017-03-15 17:56 60
6c5f2c01 sago007 2017-03-15 17:56 61
    ~Stack() {
6c5f2c01 sago007 2017-03-15 17:56 62
        Destroy();
6c5f2c01 sago007 2017-03-15 17:56 63
    }
6c5f2c01 sago007 2017-03-15 17:56 64
6c5f2c01 sago007 2017-03-15 17:56 65
#if CEREAL_RAPIDJSON_HAS_CXX11_RVALUE_REFS
6c5f2c01 sago007 2017-03-15 17:56 66
    Stack& operator=(Stack&& rhs) {
6c5f2c01 sago007 2017-03-15 17:56 67
        if (&rhs != this)
6c5f2c01 sago007 2017-03-15 17:56 68
        {
6c5f2c01 sago007 2017-03-15 17:56 69
            Destroy();
6c5f2c01 sago007 2017-03-15 17:56 70
6c5f2c01 sago007 2017-03-15 17:56 71
            allocator_ = rhs.allocator_;
6c5f2c01 sago007 2017-03-15 17:56 72
            ownAllocator_ = rhs.ownAllocator_;
6c5f2c01 sago007 2017-03-15 17:56 73
            stack_ = rhs.stack_;
6c5f2c01 sago007 2017-03-15 17:56 74
            stackTop_ = rhs.stackTop_;
6c5f2c01 sago007 2017-03-15 17:56 75
            stackEnd_ = rhs.stackEnd_;
6c5f2c01 sago007 2017-03-15 17:56 76
            initialCapacity_ = rhs.initialCapacity_;
6c5f2c01 sago007 2017-03-15 17:56 77
6c5f2c01 sago007 2017-03-15 17:56 78
            rhs.allocator_ = 0;
6c5f2c01 sago007 2017-03-15 17:56 79
            rhs.ownAllocator_ = 0;
6c5f2c01 sago007 2017-03-15 17:56 80
            rhs.stack_ = 0;
6c5f2c01 sago007 2017-03-15 17:56 81
            rhs.stackTop_ = 0;
6c5f2c01 sago007 2017-03-15 17:56 82
            rhs.stackEnd_ = 0;
6c5f2c01 sago007 2017-03-15 17:56 83
            rhs.initialCapacity_ = 0;
6c5f2c01 sago007 2017-03-15 17:56 84
        }
6c5f2c01 sago007 2017-03-15 17:56 85
        return *this;
6c5f2c01 sago007 2017-03-15 17:56 86
    }
6c5f2c01 sago007 2017-03-15 17:56 87
#endif
6c5f2c01 sago007 2017-03-15 17:56 88
6c5f2c01 sago007 2017-03-15 17:56 89
    void Swap(Stack& rhs) CEREAL_RAPIDJSON_NOEXCEPT {
6c5f2c01 sago007 2017-03-15 17:56 90
        internal::Swap(allocator_, rhs.allocator_);
6c5f2c01 sago007 2017-03-15 17:56 91
        internal::Swap(ownAllocator_, rhs.ownAllocator_);
6c5f2c01 sago007 2017-03-15 17:56 92
        internal::Swap(stack_, rhs.stack_);
6c5f2c01 sago007 2017-03-15 17:56 93
        internal::Swap(stackTop_, rhs.stackTop_);
6c5f2c01 sago007 2017-03-15 17:56 94
        internal::Swap(stackEnd_, rhs.stackEnd_);
6c5f2c01 sago007 2017-03-15 17:56 95
        internal::Swap(initialCapacity_, rhs.initialCapacity_);
6c5f2c01 sago007 2017-03-15 17:56 96
    }
6c5f2c01 sago007 2017-03-15 17:56 97
6c5f2c01 sago007 2017-03-15 17:56 98
    void Clear() { stackTop_ = stack_; }
6c5f2c01 sago007 2017-03-15 17:56 99
6c5f2c01 sago007 2017-03-15 17:56 100
    void ShrinkToFit() { 
6c5f2c01 sago007 2017-03-15 17:56 101
        if (Empty()) {
6c5f2c01 sago007 2017-03-15 17:56 102
            // If the stack is empty, completely deallocate the memory.
6c5f2c01 sago007 2017-03-15 17:56 103
            Allocator::Free(stack_);
6c5f2c01 sago007 2017-03-15 17:56 104
            stack_ = 0;
6c5f2c01 sago007 2017-03-15 17:56 105
            stackTop_ = 0;
6c5f2c01 sago007 2017-03-15 17:56 106
            stackEnd_ = 0;
6c5f2c01 sago007 2017-03-15 17:56 107
        }
6c5f2c01 sago007 2017-03-15 17:56 108
        else
6c5f2c01 sago007 2017-03-15 17:56 109
            Resize(GetSize());
6c5f2c01 sago007 2017-03-15 17:56 110
    }
6c5f2c01 sago007 2017-03-15 17:56 111
6c5f2c01 sago007 2017-03-15 17:56 112
    // Optimization note: try to minimize the size of this function for force inline.
6c5f2c01 sago007 2017-03-15 17:56 113
    // Expansion is run very infrequently, so it is moved to another (probably non-inline) function.
6c5f2c01 sago007 2017-03-15 17:56 114
    template<typename T>
6c5f2c01 sago007 2017-03-15 17:56 115
    CEREAL_RAPIDJSON_FORCEINLINE void Reserve(size_t count = 1) {
6c5f2c01 sago007 2017-03-15 17:56 116
         // Expand the stack if needed
6c5f2c01 sago007 2017-03-15 17:56 117
        if (CEREAL_RAPIDJSON_UNLIKELY(stackTop_ + sizeof(T) * count > stackEnd_))
6c5f2c01 sago007 2017-03-15 17:56 118
            Expand<T>(count);
6c5f2c01 sago007 2017-03-15 17:56 119
    }
6c5f2c01 sago007 2017-03-15 17:56 120
6c5f2c01 sago007 2017-03-15 17:56 121
    template<typename T>
6c5f2c01 sago007 2017-03-15 17:56 122
    CEREAL_RAPIDJSON_FORCEINLINE T* Push(size_t count = 1) {
6c5f2c01 sago007 2017-03-15 17:56 123
        Reserve<T>(count);
6c5f2c01 sago007 2017-03-15 17:56 124
        return PushUnsafe<T>(count);
6c5f2c01 sago007 2017-03-15 17:56 125
    }
6c5f2c01 sago007 2017-03-15 17:56 126
6c5f2c01 sago007 2017-03-15 17:56 127
    template<typename T>
6c5f2c01 sago007 2017-03-15 17:56 128
    CEREAL_RAPIDJSON_FORCEINLINE T* PushUnsafe(size_t count = 1) {
6c5f2c01 sago007 2017-03-15 17:56 129
        CEREAL_RAPIDJSON_ASSERT(stackTop_ + sizeof(T) * count <= stackEnd_);
6c5f2c01 sago007 2017-03-15 17:56 130
        T* ret = reinterpret_cast<T*>(stackTop_);
6c5f2c01 sago007 2017-03-15 17:56 131
        stackTop_ += sizeof(T) * count;
6c5f2c01 sago007 2017-03-15 17:56 132
        return ret;
6c5f2c01 sago007 2017-03-15 17:56 133
    }
6c5f2c01 sago007 2017-03-15 17:56 134
6c5f2c01 sago007 2017-03-15 17:56 135
    template<typename T>
6c5f2c01 sago007 2017-03-15 17:56 136
    T* Pop(size_t count) {
6c5f2c01 sago007 2017-03-15 17:56 137
        CEREAL_RAPIDJSON_ASSERT(GetSize() >= count * sizeof(T));
6c5f2c01 sago007 2017-03-15 17:56 138
        stackTop_ -= count * sizeof(T);
6c5f2c01 sago007 2017-03-15 17:56 139
        return reinterpret_cast<T*>(stackTop_);
6c5f2c01 sago007 2017-03-15 17:56 140
    }
6c5f2c01 sago007 2017-03-15 17:56 141
6c5f2c01 sago007 2017-03-15 17:56 142
    template<typename T>
6c5f2c01 sago007 2017-03-15 17:56 143
    T* Top() { 
6c5f2c01 sago007 2017-03-15 17:56 144
        CEREAL_RAPIDJSON_ASSERT(GetSize() >= sizeof(T));
6c5f2c01 sago007 2017-03-15 17:56 145
        return reinterpret_cast<T*>(stackTop_ - sizeof(T));
6c5f2c01 sago007 2017-03-15 17:56 146
    }
6c5f2c01 sago007 2017-03-15 17:56 147
6c5f2c01 sago007 2017-03-15 17:56 148
    template<typename T>
6c5f2c01 sago007 2017-03-15 17:56 149
    const T* Top() const {
6c5f2c01 sago007 2017-03-15 17:56 150
        CEREAL_RAPIDJSON_ASSERT(GetSize() >= sizeof(T));
6c5f2c01 sago007 2017-03-15 17:56 151
        return reinterpret_cast<T*>(stackTop_ - sizeof(T));
6c5f2c01 sago007 2017-03-15 17:56 152
    }
6c5f2c01 sago007 2017-03-15 17:56 153
6c5f2c01 sago007 2017-03-15 17:56 154
    template<typename T>
6c5f2c01 sago007 2017-03-15 17:56 155
    T* End() { return reinterpret_cast<T*>(stackTop_); }
6c5f2c01 sago007 2017-03-15 17:56 156
6c5f2c01 sago007 2017-03-15 17:56 157
    template<typename T>
6c5f2c01 sago007 2017-03-15 17:56 158
    const T* End() const { return reinterpret_cast<T*>(stackTop_); }
6c5f2c01 sago007 2017-03-15 17:56 159
6c5f2c01 sago007 2017-03-15 17:56 160
    template<typename T>
6c5f2c01 sago007 2017-03-15 17:56 161
    T* Bottom() { return reinterpret_cast<T*>(stack_); }
6c5f2c01 sago007 2017-03-15 17:56 162
6c5f2c01 sago007 2017-03-15 17:56 163
    template<typename T>
6c5f2c01 sago007 2017-03-15 17:56 164
    const T* Bottom() const { return reinterpret_cast<T*>(stack_); }
6c5f2c01 sago007 2017-03-15 17:56 165
6c5f2c01 sago007 2017-03-15 17:56 166
    bool HasAllocator() const {
6c5f2c01 sago007 2017-03-15 17:56 167
        return allocator_ != 0;
6c5f2c01 sago007 2017-03-15 17:56 168
    }
6c5f2c01 sago007 2017-03-15 17:56 169
6c5f2c01 sago007 2017-03-15 17:56 170
    Allocator& GetAllocator() {
6c5f2c01 sago007 2017-03-15 17:56 171
        CEREAL_RAPIDJSON_ASSERT(allocator_);
6c5f2c01 sago007 2017-03-15 17:56 172
        return *allocator_;
6c5f2c01 sago007 2017-03-15 17:56 173
    }
6c5f2c01 sago007 2017-03-15 17:56 174
6c5f2c01 sago007 2017-03-15 17:56 175
    bool Empty() const { return stackTop_ == stack_; }
6c5f2c01 sago007 2017-03-15 17:56 176
    size_t GetSize() const { return static_cast<size_t>(stackTop_ - stack_); }
6c5f2c01 sago007 2017-03-15 17:56 177
    size_t GetCapacity() const { return static_cast<size_t>(stackEnd_ - stack_); }
6c5f2c01 sago007 2017-03-15 17:56 178
6c5f2c01 sago007 2017-03-15 17:56 179
private:
6c5f2c01 sago007 2017-03-15 17:56 180
    template<typename T>
6c5f2c01 sago007 2017-03-15 17:56 181
    void Expand(size_t count) {
6c5f2c01 sago007 2017-03-15 17:56 182
        // Only expand the capacity if the current stack exists. Otherwise just create a stack with initial capacity.
6c5f2c01 sago007 2017-03-15 17:56 183
        size_t newCapacity;
6c5f2c01 sago007 2017-03-15 17:56 184
        if (stack_ == 0) {
6c5f2c01 sago007 2017-03-15 17:56 185
            if (!allocator_)
6c5f2c01 sago007 2017-03-15 17:56 186
                ownAllocator_ = allocator_ = CEREAL_RAPIDJSON_NEW(Allocator());
6c5f2c01 sago007 2017-03-15 17:56 187
            newCapacity = initialCapacity_;
6c5f2c01 sago007 2017-03-15 17:56 188
        } else {
6c5f2c01 sago007 2017-03-15 17:56 189
            newCapacity = GetCapacity();
6c5f2c01 sago007 2017-03-15 17:56 190
            newCapacity += (newCapacity + 1) / 2;
6c5f2c01 sago007 2017-03-15 17:56 191
        }
6c5f2c01 sago007 2017-03-15 17:56 192
        size_t newSize = GetSize() + sizeof(T) * count;
6c5f2c01 sago007 2017-03-15 17:56 193
        if (newCapacity < newSize)
6c5f2c01 sago007 2017-03-15 17:56 194
            newCapacity = newSize;
6c5f2c01 sago007 2017-03-15 17:56 195
6c5f2c01 sago007 2017-03-15 17:56 196
        Resize(newCapacity);
6c5f2c01 sago007 2017-03-15 17:56 197
    }
6c5f2c01 sago007 2017-03-15 17:56 198
6c5f2c01 sago007 2017-03-15 17:56 199
    void Resize(size_t newCapacity) {
6c5f2c01 sago007 2017-03-15 17:56 200
        const size_t size = GetSize();  // Backup the current size
6c5f2c01 sago007 2017-03-15 17:56 201
        stack_ = static_cast<char*>(allocator_->Realloc(stack_, GetCapacity(), newCapacity));
6c5f2c01 sago007 2017-03-15 17:56 202
        stackTop_ = stack_ + size;
6c5f2c01 sago007 2017-03-15 17:56 203
        stackEnd_ = stack_ + newCapacity;
6c5f2c01 sago007 2017-03-15 17:56 204
    }
6c5f2c01 sago007 2017-03-15 17:56 205
6c5f2c01 sago007 2017-03-15 17:56 206
    void Destroy() {
6c5f2c01 sago007 2017-03-15 17:56 207
        Allocator::Free(stack_);
6c5f2c01 sago007 2017-03-15 17:56 208
        CEREAL_RAPIDJSON_DELETE(ownAllocator_); // Only delete if it is owned by the stack
6c5f2c01 sago007 2017-03-15 17:56 209
    }
6c5f2c01 sago007 2017-03-15 17:56 210
6c5f2c01 sago007 2017-03-15 17:56 211
    // Prohibit copy constructor & assignment operator.
6c5f2c01 sago007 2017-03-15 17:56 212
    Stack(const Stack&);
6c5f2c01 sago007 2017-03-15 17:56 213
    Stack& operator=(const Stack&);
6c5f2c01 sago007 2017-03-15 17:56 214
6c5f2c01 sago007 2017-03-15 17:56 215
    Allocator* allocator_;
6c5f2c01 sago007 2017-03-15 17:56 216
    Allocator* ownAllocator_;
6c5f2c01 sago007 2017-03-15 17:56 217
    char *stack_;
6c5f2c01 sago007 2017-03-15 17:56 218
    char *stackTop_;
6c5f2c01 sago007 2017-03-15 17:56 219
    char *stackEnd_;
6c5f2c01 sago007 2017-03-15 17:56 220
    size_t initialCapacity_;
6c5f2c01 sago007 2017-03-15 17:56 221
};
6c5f2c01 sago007 2017-03-15 17:56 222
6c5f2c01 sago007 2017-03-15 17:56 223
} // namespace internal
6c5f2c01 sago007 2017-03-15 17:56 224
CEREAL_RAPIDJSON_NAMESPACE_END
6c5f2c01 sago007 2017-03-15 17:56 225
6c5f2c01 sago007 2017-03-15 17:56 226
#if defined(__clang__)
6c5f2c01 sago007 2017-03-15 17:56 227
CEREAL_RAPIDJSON_DIAG_POP
6c5f2c01 sago007 2017-03-15 17:56 228
#endif
6c5f2c01 sago007 2017-03-15 17:56 229
6c5f2c01 sago007 2017-03-15 17:56 230
#endif // CEREAL_RAPIDJSON_STACK_H_
1970-01-01 00:00 231