mirror of
https://github.com/pocketpy/pocketpy
synced 2025-10-24 05:20:17 +00:00
up
This commit is contained in:
parent
6a27bc8bda
commit
7efb440388
@ -55,6 +55,7 @@ class Compiler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void init_pratt_rules(){
|
static void init_pratt_rules(){
|
||||||
|
if(rules[TK(".")].precedence != PREC_NONE) return;
|
||||||
// http://journal.stuffwithstuff.com/2011/03/19/pratt-parsers-expression-parsing-made-easy/
|
// http://journal.stuffwithstuff.com/2011/03/19/pratt-parsers-expression-parsing-made-easy/
|
||||||
#define METHOD(name) &Compiler::name
|
#define METHOD(name) &Compiler::name
|
||||||
#define NO_INFIX nullptr, PREC_NONE
|
#define NO_INFIX nullptr, PREC_NONE
|
||||||
|
|||||||
@ -7,7 +7,7 @@ namespace pkpy{
|
|||||||
|
|
||||||
static THREAD_LOCAL uint64_t kFrameGlobalId = 0;
|
static THREAD_LOCAL uint64_t kFrameGlobalId = 0;
|
||||||
|
|
||||||
using ValueStack = small_vector<PyObject*, 6>;
|
using ValueStack = pod_vector<PyObject*>;
|
||||||
|
|
||||||
struct Frame {
|
struct Frame {
|
||||||
ValueStack _data;
|
ValueStack _data;
|
||||||
|
|||||||
@ -100,7 +100,7 @@ struct Lexer {
|
|||||||
const char* curr_char;
|
const char* curr_char;
|
||||||
int current_line = 1;
|
int current_line = 1;
|
||||||
std::vector<Token> nexts;
|
std::vector<Token> nexts;
|
||||||
small_stack<int, 4> indents;
|
stack<int> indents;
|
||||||
int brackets_level = 0;
|
int brackets_level = 0;
|
||||||
bool used = false;
|
bool used = false;
|
||||||
|
|
||||||
|
|||||||
46
src/memory.h
46
src/memory.h
@ -1,7 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
#include "vector.h"
|
|
||||||
|
|
||||||
namespace pkpy{
|
namespace pkpy{
|
||||||
|
|
||||||
@ -69,48 +68,12 @@ shared_ptr<T> make_sp(Args&&... args) {
|
|||||||
return shared_ptr<T>(p);
|
return shared_ptr<T>(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T, int __Bucket, bool __ZeroInit>
|
|
||||||
struct FreeListA {
|
|
||||||
std::vector<T*> buckets[__Bucket+1];
|
|
||||||
|
|
||||||
T* alloc(int n){
|
|
||||||
static_assert(std::is_standard_layout_v<T>);
|
|
||||||
T* p;
|
|
||||||
if(n > __Bucket || buckets[n].empty()){
|
|
||||||
p = (T*)malloc(sizeof(T) * n);
|
|
||||||
}else{
|
|
||||||
p = buckets[n].back();
|
|
||||||
buckets[n].pop_back();
|
|
||||||
}
|
|
||||||
if constexpr(__ZeroInit){
|
|
||||||
// the constructor of T should be equivalent to zero initialization
|
|
||||||
memset((void*)p, 0, sizeof(T) * n);
|
|
||||||
}
|
|
||||||
return p;
|
|
||||||
}
|
|
||||||
|
|
||||||
void dealloc(T* p, int n){
|
|
||||||
if(p == nullptr) return;
|
|
||||||
if(n > __Bucket || buckets[n].size() >= 80){
|
|
||||||
free(p);
|
|
||||||
}else{
|
|
||||||
buckets[n].push_back(p);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
~FreeListA(){
|
|
||||||
for(int i=0; i<=__Bucket; i++){
|
|
||||||
for(T* p : buckets[i]) free(p);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
struct LinkedListNode{
|
struct LinkedListNode{
|
||||||
LinkedListNode* prev;
|
LinkedListNode* prev;
|
||||||
LinkedListNode* next;
|
LinkedListNode* next;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
struct DoubleLinkedList{
|
struct DoubleLinkedList{
|
||||||
static_assert(std::is_base_of_v<LinkedListNode, T>);
|
static_assert(std::is_base_of_v<LinkedListNode, T>);
|
||||||
@ -295,6 +258,9 @@ struct MemoryPool{
|
|||||||
}
|
}
|
||||||
|
|
||||||
void dealloc(void* p){
|
void dealloc(void* p){
|
||||||
|
#if DEBUG_MEMORY_POOL
|
||||||
|
if(p == nullptr) throw std::runtime_error("MemoryPool::dealloc() called on nullptr");
|
||||||
|
#endif
|
||||||
Block* block = (Block*)((char*)p - sizeof(void*));
|
Block* block = (Block*)((char*)p - sizeof(void*));
|
||||||
if(block->arena == nullptr){
|
if(block->arena == nullptr){
|
||||||
free(block);
|
free(block);
|
||||||
@ -328,4 +294,8 @@ struct MemoryPool{
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
inline MemoryPool<64> pool64;
|
||||||
|
inline MemoryPool<128> pool128;
|
||||||
|
inline MemoryPool<256> pool256;
|
||||||
|
|
||||||
}; // namespace pkpy
|
}; // namespace pkpy
|
||||||
|
|||||||
@ -34,8 +34,6 @@ inline static uint16_t find_perfect_hash_seed(uint16_t capacity, const std::vect
|
|||||||
|
|
||||||
struct NameDict {
|
struct NameDict {
|
||||||
using Item = std::pair<StrName, PyObject*>;
|
using Item = std::pair<StrName, PyObject*>;
|
||||||
inline static THREAD_LOCAL FreeListA<Item, 32, true> _pool;
|
|
||||||
|
|
||||||
uint16_t _capacity;
|
uint16_t _capacity;
|
||||||
uint16_t _size;
|
uint16_t _size;
|
||||||
float _load_factor;
|
float _load_factor;
|
||||||
@ -43,31 +41,36 @@ struct NameDict {
|
|||||||
uint16_t _mask;
|
uint16_t _mask;
|
||||||
Item* _items;
|
Item* _items;
|
||||||
|
|
||||||
|
void _alloc(int cap){
|
||||||
|
_items = (Item*)pool128.alloc(cap * sizeof(Item));
|
||||||
|
memset(_items, 0, cap * sizeof(Item));
|
||||||
|
}
|
||||||
|
|
||||||
NameDict(uint16_t capacity=2, float load_factor=0.67, uint16_t hash_seed=kHashSeeds[0]):
|
NameDict(uint16_t capacity=2, float load_factor=0.67, uint16_t hash_seed=kHashSeeds[0]):
|
||||||
_capacity(capacity), _size(0), _load_factor(load_factor),
|
_capacity(capacity), _size(0), _load_factor(load_factor),
|
||||||
_hash_seed(hash_seed), _mask(capacity-1) {
|
_hash_seed(hash_seed), _mask(capacity-1) {
|
||||||
_items = _pool.alloc(_capacity);
|
_alloc(capacity);
|
||||||
}
|
}
|
||||||
|
|
||||||
NameDict(const NameDict& other) {
|
NameDict(const NameDict& other) {
|
||||||
memcpy(this, &other, sizeof(NameDict));
|
memcpy(this, &other, sizeof(NameDict));
|
||||||
_items = _pool.alloc(_capacity);
|
_alloc(_capacity);
|
||||||
for(int i=0; i<_capacity; i++){
|
for(int i=0; i<_capacity; i++){
|
||||||
_items[i] = other._items[i];
|
_items[i] = other._items[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
NameDict& operator=(const NameDict& other) {
|
NameDict& operator=(const NameDict& other) {
|
||||||
_pool.dealloc(_items, _capacity);
|
pool128.dealloc(_items);
|
||||||
memcpy(this, &other, sizeof(NameDict));
|
memcpy(this, &other, sizeof(NameDict));
|
||||||
_items = _pool.alloc(_capacity);
|
_alloc(_capacity);
|
||||||
for(int i=0; i<_capacity; i++){
|
for(int i=0; i<_capacity; i++){
|
||||||
_items[i] = other._items[i];
|
_items[i] = other._items[i];
|
||||||
}
|
}
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
~NameDict(){ _pool.dealloc(_items, _capacity); }
|
~NameDict(){ pool128.dealloc(_items); }
|
||||||
|
|
||||||
NameDict(NameDict&&) = delete;
|
NameDict(NameDict&&) = delete;
|
||||||
NameDict& operator=(NameDict&&) = delete;
|
NameDict& operator=(NameDict&&) = delete;
|
||||||
@ -109,7 +112,7 @@ while(!_items[i].first.empty()) { \
|
|||||||
_capacity = find_next_capacity(_capacity * 2);
|
_capacity = find_next_capacity(_capacity * 2);
|
||||||
_mask = _capacity - 1;
|
_mask = _capacity - 1;
|
||||||
}
|
}
|
||||||
_items = _pool.alloc(_capacity);
|
_alloc(_capacity);
|
||||||
for(uint16_t i=0; i<old_capacity; i++){
|
for(uint16_t i=0; i<old_capacity; i++){
|
||||||
if(old_items[i].first.empty()) continue;
|
if(old_items[i].first.empty()) continue;
|
||||||
bool ok; uint16_t j;
|
bool ok; uint16_t j;
|
||||||
@ -117,7 +120,7 @@ while(!_items[i].first.empty()) { \
|
|||||||
if(ok) UNREACHABLE();
|
if(ok) UNREACHABLE();
|
||||||
_items[j] = old_items[i];
|
_items[j] = old_items[i];
|
||||||
}
|
}
|
||||||
_pool.dealloc(old_items, old_capacity);
|
pool128.dealloc(old_items);
|
||||||
}
|
}
|
||||||
|
|
||||||
void _try_perfect_rehash(){
|
void _try_perfect_rehash(){
|
||||||
|
|||||||
143
src/new_str.h
Normal file
143
src/new_str.h
Normal file
@ -0,0 +1,143 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "common.h"
|
||||||
|
#include "memory.h"
|
||||||
|
#include <string_view>
|
||||||
|
|
||||||
|
namespace pkpy{
|
||||||
|
|
||||||
|
struct String{
|
||||||
|
char* data;
|
||||||
|
int size;
|
||||||
|
|
||||||
|
String(): data((char*)pool64.alloc(0)), size(0) {}
|
||||||
|
String(int size): data((char*)pool64.alloc(size)), size(size) {}
|
||||||
|
String(const char* str) {
|
||||||
|
size = strlen(str);
|
||||||
|
data = (char*)pool64.alloc(size);
|
||||||
|
memcpy(data, str, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
String(const String& other): data((char*)pool64.alloc(other.size)), size(other.size) {
|
||||||
|
memcpy(data, other.data, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
String(String&& other): data(other.data), size(other.size) {
|
||||||
|
other.data = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
String& operator=(const String& other){
|
||||||
|
if(data!=nullptr) pool64.dealloc(data);
|
||||||
|
size = other.size;
|
||||||
|
data = (char*)pool64.alloc(size);
|
||||||
|
memcpy(data, other.data, size);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
String& operator=(String&& other){
|
||||||
|
if(data!=nullptr) pool64.dealloc(data);
|
||||||
|
size = other.size;
|
||||||
|
data = other.data;
|
||||||
|
other.data = nullptr;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
~String(){
|
||||||
|
if(data!=nullptr) pool64.dealloc(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
char operator[](int idx) const {
|
||||||
|
return data[idx];
|
||||||
|
}
|
||||||
|
|
||||||
|
int length() const {
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
|
String operator+(const String& other) const {
|
||||||
|
String ret(size + other.size);
|
||||||
|
memcpy(ret.data, data, size);
|
||||||
|
memcpy(ret.data + size, other.data, other.size);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
friend std::ostream& operator<<(std::ostream& os, const String& str){
|
||||||
|
os.write(str.data, str.size);
|
||||||
|
return os;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator==(const String& other) const {
|
||||||
|
if(size != other.size) return false;
|
||||||
|
return memcmp(data, other.data, size) == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator!=(const String& other) const {
|
||||||
|
if(size != other.size) return true;
|
||||||
|
return memcmp(data, other.data, size) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator<(const String& other) const {
|
||||||
|
int ret = strncmp(data, other.data, std::min(size, other.size));
|
||||||
|
if(ret != 0) return ret < 0;
|
||||||
|
return size < other.size;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator>(const String& other) const {
|
||||||
|
int ret = strncmp(data, other.data, std::min(size, other.size));
|
||||||
|
if(ret != 0) return ret > 0;
|
||||||
|
return size > other.size;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator<=(const String& other) const {
|
||||||
|
int ret = strncmp(data, other.data, std::min(size, other.size));
|
||||||
|
if(ret != 0) return ret < 0;
|
||||||
|
return size <= other.size;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator>=(const String& other) const {
|
||||||
|
int ret = strncmp(data, other.data, std::min(size, other.size));
|
||||||
|
if(ret != 0) return ret > 0;
|
||||||
|
return size >= other.size;
|
||||||
|
}
|
||||||
|
|
||||||
|
String substr(int start, int len) const {
|
||||||
|
String ret(len);
|
||||||
|
memcpy(ret.data, data + start, len);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
String substr(int start) const {
|
||||||
|
return substr(start, size - start);
|
||||||
|
}
|
||||||
|
|
||||||
|
char* dup_c_str() const {
|
||||||
|
char* p = (char*)malloc(size + 1);
|
||||||
|
memcpy(p, data, size);
|
||||||
|
p[size] = 0;
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string_view view() const {
|
||||||
|
return std::string_view(data, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string str() const {
|
||||||
|
return std::string(data, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
String lstrip() const {
|
||||||
|
std::string copy = str();
|
||||||
|
copy.erase(copy.begin(), std::find_if(copy.begin(), copy.end(), [](char c) {
|
||||||
|
// std::isspace(c) does not working on windows (Debug)
|
||||||
|
return c != ' ' && c != '\t' && c != '\r' && c != '\n';
|
||||||
|
}));
|
||||||
|
return String(copy.c_str());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct UnicodeString: String{
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
} // namespace pkpy
|
||||||
@ -3,19 +3,18 @@
|
|||||||
#include "common.h"
|
#include "common.h"
|
||||||
#include "memory.h"
|
#include "memory.h"
|
||||||
#include "str.h"
|
#include "str.h"
|
||||||
|
#include "vector.h"
|
||||||
|
|
||||||
namespace pkpy {
|
namespace pkpy {
|
||||||
|
|
||||||
using List = small_vector<PyObject*, 4>;
|
using List = pod_vector<PyObject*>;
|
||||||
|
|
||||||
class Args {
|
class Args {
|
||||||
inline static THREAD_LOCAL FreeListA<PyObject*, 10, false> _pool;
|
|
||||||
|
|
||||||
PyObject** _args;
|
PyObject** _args;
|
||||||
int _size;
|
int _size;
|
||||||
|
|
||||||
void _alloc(int n){
|
void _alloc(int n){
|
||||||
this->_args = (n==0) ? nullptr : _pool.alloc(n);
|
this->_args = (n==0) ? nullptr : (PyObject**)pool64.alloc(n * sizeof(void*));
|
||||||
this->_size = n;
|
this->_size = n;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -48,7 +47,7 @@ public:
|
|||||||
PyObject* operator[](int i) const { return _args[i]; }
|
PyObject* operator[](int i) const { return _args[i]; }
|
||||||
|
|
||||||
Args& operator=(Args&& other) noexcept {
|
Args& operator=(Args&& other) noexcept {
|
||||||
_pool.dealloc(_args, _size);
|
if(_args!=nullptr) pool64.dealloc(_args);
|
||||||
this->_args = other._args;
|
this->_args = other._args;
|
||||||
this->_size = other._size;
|
this->_size = other._size;
|
||||||
other._args = nullptr;
|
other._args = nullptr;
|
||||||
@ -71,10 +70,10 @@ public:
|
|||||||
_alloc(old_size+1);
|
_alloc(old_size+1);
|
||||||
_args[0] = self;
|
_args[0] = self;
|
||||||
for(int i=0; i<old_size; i++) _args[i+1] = old_args[i];
|
for(int i=0; i<old_size; i++) _args[i+1] = old_args[i];
|
||||||
_pool.dealloc(old_args, old_size);
|
if(old_args!=nullptr) pool64.dealloc(old_args);
|
||||||
}
|
}
|
||||||
|
|
||||||
~Args(){ _pool.dealloc(_args, _size); }
|
~Args(){ if(_args!=nullptr) pool64.dealloc(_args); }
|
||||||
};
|
};
|
||||||
|
|
||||||
inline const Args& no_arg() {
|
inline const Args& no_arg() {
|
||||||
|
|||||||
71
src/vector.h
71
src/vector.h
@ -1,65 +1,51 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
|
#include "memory.h"
|
||||||
|
|
||||||
namespace pkpy{
|
namespace pkpy{
|
||||||
|
|
||||||
template<typename T, int N>
|
template<typename T>
|
||||||
struct small_vector{
|
struct pod_vector{
|
||||||
|
static_assert(128 % sizeof(T) == 0);
|
||||||
|
static_assert(std::is_pod_v<T>);
|
||||||
|
static constexpr int N = 128 / sizeof(T);
|
||||||
|
static_assert(N > 4);
|
||||||
int _size;
|
int _size;
|
||||||
int _capacity;
|
int _capacity;
|
||||||
T* _data;
|
T* _data;
|
||||||
T _buffer[N];
|
|
||||||
|
|
||||||
small_vector(): _size(0), _capacity(N) {
|
pod_vector(): _size(0), _capacity(N) {
|
||||||
static_assert(std::is_pod_v<T>);
|
_data = (T*)pool128.alloc(_capacity * sizeof(T));
|
||||||
_data = _buffer;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
small_vector(int size): _size(0), _capacity(N){
|
pod_vector(int size): _size(size), _capacity(std::max(N, size)) {
|
||||||
_data = _buffer;
|
_data = (T*)pool128.alloc(_capacity * sizeof(T));
|
||||||
reserve(size);
|
|
||||||
_size = size;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
small_vector(const small_vector& other): _size(other._size), _capacity(other._capacity) {
|
pod_vector(const pod_vector& other): _size(other._size), _capacity(other._capacity) {
|
||||||
if(other.is_small()){
|
_data = (T*)pool128.alloc(_capacity * sizeof(T));
|
||||||
_data = _buffer;
|
|
||||||
memcpy(_buffer, other._buffer, sizeof(T) * _size);
|
|
||||||
} else {
|
|
||||||
_data = (T*)malloc(sizeof(T) * _capacity);
|
|
||||||
memcpy(_data, other._data, sizeof(T) * _size);
|
memcpy(_data, other._data, sizeof(T) * _size);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
small_vector(small_vector&& other) noexcept {
|
pod_vector(pod_vector&& other) noexcept {
|
||||||
_size = other._size;
|
_size = other._size;
|
||||||
_capacity = other._capacity;
|
_capacity = other._capacity;
|
||||||
if(other.is_small()){
|
|
||||||
_data = _buffer;
|
|
||||||
memcpy(_buffer, other._buffer, sizeof(T) * _size);
|
|
||||||
} else {
|
|
||||||
_data = other._data;
|
_data = other._data;
|
||||||
other._data = other._buffer;
|
other._data = nullptr;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
small_vector& operator=(small_vector&& other) noexcept {
|
pod_vector& operator=(pod_vector&& other) noexcept {
|
||||||
if (!is_small()) free(_data);
|
if(_data!=nullptr) pool128.dealloc(_data);
|
||||||
_size = other._size;
|
_size = other._size;
|
||||||
_capacity = other._capacity;
|
_capacity = other._capacity;
|
||||||
if(other.is_small()){
|
|
||||||
_data = _buffer;
|
|
||||||
memcpy(_buffer, other._buffer, sizeof(T) * _size);
|
|
||||||
} else {
|
|
||||||
_data = other._data;
|
_data = other._data;
|
||||||
other._data = other._buffer;
|
other._data = nullptr;
|
||||||
}
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
// remove copy assignment
|
// remove copy assignment
|
||||||
small_vector& operator=(const small_vector& other) = delete;
|
pod_vector& operator=(const pod_vector& other) = delete;
|
||||||
|
|
||||||
template<typename __ValueT>
|
template<typename __ValueT>
|
||||||
void push_back(__ValueT&& t) {
|
void push_back(__ValueT&& t) {
|
||||||
@ -70,16 +56,12 @@ struct small_vector{
|
|||||||
void reserve(int cap){
|
void reserve(int cap){
|
||||||
if(cap < _capacity) return;
|
if(cap < _capacity) return;
|
||||||
_capacity = cap;
|
_capacity = cap;
|
||||||
if (is_small()) {
|
if(_data!=nullptr) pool128.dealloc(_data);
|
||||||
_data = (T*)malloc(sizeof(T) * _capacity);
|
_data = (T*)pool128.alloc(_capacity * sizeof(T));
|
||||||
memcpy(_data, _buffer, sizeof(T) * _size);
|
|
||||||
} else {
|
|
||||||
_data = (T*)realloc(_data, sizeof(T) * _capacity);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void pop_back() { _size--; }
|
void pop_back() { _size--; }
|
||||||
void extend(const small_vector& other){
|
void extend(const pod_vector& other){
|
||||||
for(int i=0; i<other.size(); i++) push_back(other[i]);
|
for(int i=0; i<other.size(); i++) push_back(other[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -97,7 +79,6 @@ struct small_vector{
|
|||||||
int size() const { return _size; }
|
int size() const { return _size; }
|
||||||
T* data() { return _data; }
|
T* data() { return _data; }
|
||||||
const T* data() const { return _data; }
|
const T* data() const { return _data; }
|
||||||
bool is_small() const { return _data == _buffer; }
|
|
||||||
void pop_back_n(int n) { _size -= n; }
|
void pop_back_n(int n) { _size -= n; }
|
||||||
void clear() { _size=0; }
|
void clear() { _size=0; }
|
||||||
|
|
||||||
@ -114,8 +95,8 @@ struct small_vector{
|
|||||||
_size--;
|
_size--;
|
||||||
}
|
}
|
||||||
|
|
||||||
~small_vector() {
|
~pod_vector() {
|
||||||
if (!is_small()) free(_data);
|
if(_data!=nullptr) pool128.dealloc(_data);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -136,6 +117,6 @@ public:
|
|||||||
const Container& data() const { return vec; }
|
const Container& data() const { return vec; }
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename T, int N>
|
template <typename T>
|
||||||
using small_stack = stack<T, small_vector<T, N>>;
|
using pod_stack = stack<T, pod_vector<T>>;
|
||||||
} // namespace pkpy
|
} // namespace pkpy
|
||||||
Loading…
x
Reference in New Issue
Block a user