vector.h 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  1. #pragma once
  2. #include "common.h"
  3. #include "memory.h"
  4. namespace pkpy{
  5. template<typename T>
  6. struct pod_vector{
  7. static_assert(128 % sizeof(T) == 0);
  8. static_assert(std::is_pod_v<T>);
  9. static constexpr int N = 128 / sizeof(T);
  10. static_assert(N > 4);
  11. int _size;
  12. int _capacity;
  13. T* _data;
  14. pod_vector(): _size(0), _capacity(N) {
  15. _data = (T*)pool128.alloc(_capacity * sizeof(T));
  16. }
  17. pod_vector(int size): _size(size), _capacity(std::max(N, size)) {
  18. _data = (T*)pool128.alloc(_capacity * sizeof(T));
  19. }
  20. pod_vector(const pod_vector& other): _size(other._size), _capacity(other._capacity) {
  21. _data = (T*)pool128.alloc(_capacity * sizeof(T));
  22. memcpy(_data, other._data, sizeof(T) * _size);
  23. }
  24. pod_vector(pod_vector&& other) noexcept {
  25. _size = other._size;
  26. _capacity = other._capacity;
  27. _data = other._data;
  28. other._data = nullptr;
  29. }
  30. pod_vector& operator=(pod_vector&& other) noexcept {
  31. if(_data!=nullptr) pool128.dealloc(_data);
  32. _size = other._size;
  33. _capacity = other._capacity;
  34. _data = other._data;
  35. other._data = nullptr;
  36. return *this;
  37. }
  38. // remove copy assignment
  39. pod_vector& operator=(const pod_vector& other) = delete;
  40. template<typename __ValueT>
  41. void push_back(__ValueT&& t) {
  42. if (_size == _capacity) reserve(_capacity*2);
  43. _data[_size++] = std::forward<__ValueT>(t);
  44. }
  45. template<typename... Args>
  46. void emplace_back(Args&&... args) {
  47. if (_size == _capacity) reserve(_capacity*2);
  48. new (&_data[_size++]) T(std::forward<Args>(args)...);
  49. }
  50. void reserve(int cap){
  51. if(cap <= _capacity) return;
  52. _capacity = cap;
  53. T* old_data = _data;
  54. _data = (T*)pool128.alloc(_capacity * sizeof(T));
  55. if(old_data!=nullptr){
  56. memcpy(_data, old_data, sizeof(T) * _size);
  57. pool128.dealloc(old_data);
  58. }
  59. }
  60. void pop_back() { _size--; }
  61. T popx_back() { T t = std::move(_data[_size-1]); _size--; return t; }
  62. void extend(const pod_vector& other){
  63. for(int i=0; i<other.size(); i++) push_back(other[i]);
  64. }
  65. T& operator[](int index) { return _data[index]; }
  66. const T& operator[](int index) const { return _data[index]; }
  67. T* begin() { return _data; }
  68. T* end() { return _data + _size; }
  69. const T* begin() const { return _data; }
  70. const T* end() const { return _data + _size; }
  71. T& back() { return _data[_size - 1]; }
  72. const T& back() const { return _data[_size - 1]; }
  73. bool empty() const { return _size == 0; }
  74. int size() const { return _size; }
  75. T* data() { return _data; }
  76. const T* data() const { return _data; }
  77. void clear() { _size=0; }
  78. template<typename __ValueT>
  79. void insert(int i, __ValueT&& val){
  80. if (_size == _capacity) reserve(_capacity*2);
  81. for(int j=_size; j>i; j--) _data[j] = _data[j-1];
  82. _data[i] = std::forward<__ValueT>(val);
  83. _size++;
  84. }
  85. void erase(int i){
  86. for(int j=i; j<_size-1; j++) _data[j] = _data[j+1];
  87. _size--;
  88. }
  89. void resize(int size){
  90. if(size > _capacity) reserve(size);
  91. _size = size;
  92. }
  93. ~pod_vector() {
  94. if(_data!=nullptr) pool128.dealloc(_data);
  95. }
  96. };
  97. template <typename T, typename Container=std::vector<T>>
  98. class stack{
  99. Container vec;
  100. public:
  101. void push(const T& t){ vec.push_back(t); }
  102. void push(T&& t){ vec.push_back(std::move(t)); }
  103. template<typename... Args>
  104. void emplace(Args&&... args){
  105. vec.emplace_back(std::forward<Args>(args)...);
  106. }
  107. void pop(){ vec.pop_back(); }
  108. void clear(){ vec.clear(); }
  109. bool empty() const { return vec.empty(); }
  110. size_t size() const { return vec.size(); }
  111. T& top(){ return vec.back(); }
  112. const T& top() const { return vec.back(); }
  113. T popx(){ T t = std::move(vec.back()); vec.pop_back(); return t; }
  114. void reserve(int n){ vec.reserve(n); }
  115. Container& data() { return vec; }
  116. };
  117. template <typename T>
  118. using pod_stack = stack<T, pod_vector<T>>;
  119. } // namespace pkpy