#pragma once #include "common.h" #include "memory.h" namespace pkpy{ template struct pod_vector{ static_assert(64 % sizeof(T) == 0); static_assert(std::is_pod_v); static constexpr int N = 64 / sizeof(T); static_assert(N >= 4); int _size; int _capacity; T* _data; pod_vector(): _size(0), _capacity(N) { _data = (T*)pool64.alloc(_capacity * sizeof(T)); } pod_vector(int size): _size(size), _capacity(std::max(N, size)) { _data = (T*)pool64.alloc(_capacity * sizeof(T)); } pod_vector(const pod_vector& other): _size(other._size), _capacity(other._capacity) { _data = (T*)pool64.alloc(_capacity * sizeof(T)); memcpy(_data, other._data, sizeof(T) * _size); } pod_vector(pod_vector&& other) noexcept { _size = other._size; _capacity = other._capacity; _data = other._data; other._data = nullptr; } pod_vector& operator=(pod_vector&& other) noexcept { if(_data!=nullptr) pool64.dealloc(_data); _size = other._size; _capacity = other._capacity; _data = other._data; other._data = nullptr; return *this; } // remove copy assignment pod_vector& operator=(const pod_vector& other) = delete; template void push_back(__ValueT&& t) { if (_size == _capacity) reserve(_capacity*2); _data[_size++] = std::forward<__ValueT>(t); } template void emplace_back(Args&&... args) { if (_size == _capacity) reserve(_capacity*2); new (&_data[_size++]) T(std::forward(args)...); } void reserve(int cap){ if(cap <= _capacity) return; _capacity = cap; T* old_data = _data; _data = (T*)pool64.alloc(_capacity * sizeof(T)); if(old_data!=nullptr){ memcpy(_data, old_data, sizeof(T) * _size); pool64.dealloc(old_data); } } void pop_back() { _size--; } T popx_back() { T t = std::move(_data[_size-1]); _size--; return t; } void extend(const pod_vector& other){ for(int i=0; i void insert(int i, __ValueT&& val){ if (_size == _capacity) reserve(_capacity*2); for(int j=_size; j>i; j--) _data[j] = _data[j-1]; _data[i] = std::forward<__ValueT>(val); _size++; } void erase(int i){ for(int j=i; j<_size-1; j++) _data[j] = _data[j+1]; _size--; } void reverse(){ std::reverse(_data, _data+_size); } void resize(int size){ if(size > _capacity) reserve(size); _size = size; } ~pod_vector() { if(_data!=nullptr) pool64.dealloc(_data); } }; template > class stack{ Container vec; public: void push(const T& t){ vec.push_back(t); } void push(T&& t){ vec.push_back(std::move(t)); } template void emplace(Args&&... args){ vec.emplace_back(std::forward(args)...); } void pop(){ vec.pop_back(); } void clear(){ vec.clear(); } bool empty() const { return vec.empty(); } size_t size() const { return vec.size(); } T& top(){ return vec.back(); } const T& top() const { return vec.back(); } T popx(){ T t = std::move(vec.back()); vec.pop_back(); return t; } void reserve(int n){ vec.reserve(n); } Container& data() { return vec; } }; template > class stack_no_copy: public stack{ public: stack_no_copy() = default; stack_no_copy(const stack_no_copy& other) = delete; stack_no_copy& operator=(const stack_no_copy& other) = delete; stack_no_copy(stack_no_copy&& other) noexcept = default; stack_no_copy& operator=(stack_no_copy&& other) noexcept = default; }; } // namespace pkpy