vector.h 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  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. void extend(const pod_vector& other){
  62. for(int i=0; i<other.size(); i++) push_back(other[i]);
  63. }
  64. T& operator[](int index) { return _data[index]; }
  65. const T& operator[](int index) const { return _data[index]; }
  66. T* begin() { return _data; }
  67. T* end() { return _data + _size; }
  68. const T* begin() const { return _data; }
  69. const T* end() const { return _data + _size; }
  70. T& back() { return _data[_size - 1]; }
  71. const T& back() const { return _data[_size - 1]; }
  72. bool empty() const { return _size == 0; }
  73. int size() const { return _size; }
  74. T* data() { return _data; }
  75. const T* data() const { return _data; }
  76. void pop_back_n(int n) { _size -= n; }
  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. ~pod_vector() {
  90. if(_data!=nullptr) pool128.dealloc(_data);
  91. }
  92. };
  93. template <typename T, typename Container=std::vector<T>>
  94. class stack{
  95. Container vec;
  96. public:
  97. void push(const T& t){ vec.push_back(t); }
  98. void push(T&& t){ vec.push_back(std::move(t)); }
  99. template<typename... Args>
  100. void emplace(Args&&... args){
  101. vec.emplace_back(std::forward<Args>(args)...);
  102. }
  103. void pop(){ vec.pop_back(); }
  104. void clear(){ vec.clear(); }
  105. bool empty() const { return vec.empty(); }
  106. size_t size() const { return vec.size(); }
  107. T& top(){ return vec.back(); }
  108. const T& top() const { return vec.back(); }
  109. T popx(){ T t = std::move(vec.back()); vec.pop_back(); return t; }
  110. Container& data() { return vec; }
  111. };
  112. template <typename T>
  113. using pod_stack = stack<T, pod_vector<T>>;
  114. } // namespace pkpy