vector.h 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  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(64 % sizeof(T) == 0);
  8. static_assert(std::is_pod_v<T>);
  9. static constexpr int N = 64 / 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*)pool64.alloc(_capacity * sizeof(T));
  16. }
  17. pod_vector(int size): _size(size), _capacity(std::max(N, size)) {
  18. _data = (T*)pool64.alloc(_capacity * sizeof(T));
  19. }
  20. pod_vector(const pod_vector& other): _size(other._size), _capacity(other._capacity) {
  21. _data = (T*)pool64.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) pool64.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*)pool64.alloc(_capacity * sizeof(T));
  55. if(old_data!=nullptr){
  56. memcpy(_data, old_data, sizeof(T) * _size);
  57. pool64.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 reverse(){
  90. std::reverse(_data, _data+_size);
  91. }
  92. void resize(int size){
  93. if(size > _capacity) reserve(size);
  94. _size = size;
  95. }
  96. ~pod_vector() {
  97. if(_data!=nullptr) pool64.dealloc(_data);
  98. }
  99. };
  100. template <typename T, typename Container=std::vector<T>>
  101. class stack{
  102. Container vec;
  103. public:
  104. void push(const T& t){ vec.push_back(t); }
  105. void push(T&& t){ vec.push_back(std::move(t)); }
  106. template<typename... Args>
  107. void emplace(Args&&... args){
  108. vec.emplace_back(std::forward<Args>(args)...);
  109. }
  110. void pop(){ vec.pop_back(); }
  111. void clear(){ vec.clear(); }
  112. bool empty() const { return vec.empty(); }
  113. size_t size() const { return vec.size(); }
  114. T& top(){ return vec.back(); }
  115. const T& top() const { return vec.back(); }
  116. T popx(){ T t = std::move(vec.back()); vec.pop_back(); return t; }
  117. void reserve(int n){ vec.reserve(n); }
  118. Container& data() { return vec; }
  119. };
  120. template <typename T, typename Container=std::vector<T>>
  121. class stack_no_copy: public stack<T, Container>{
  122. public:
  123. stack_no_copy() = default;
  124. stack_no_copy(const stack_no_copy& other) = delete;
  125. stack_no_copy& operator=(const stack_no_copy& other) = delete;
  126. stack_no_copy(stack_no_copy&& other) noexcept = default;
  127. stack_no_copy& operator=(stack_no_copy&& other) noexcept = default;
  128. };
  129. } // namespace pkpy