vector.hpp 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459
  1. #pragma once
  2. #include <cassert>
  3. #include <cstdlib>
  4. #include <cstring>
  5. #include <memory>
  6. #include <algorithm>
  7. #include "pocketpy/common/traits.hpp"
  8. #include "pocketpy/common/types.hpp"
  9. #include "pocketpy/common/algorithm.h"
  10. namespace pkpy {
  11. template <typename T>
  12. struct array {
  13. static_assert(is_pod_v<T>);
  14. T* _data;
  15. int _size;
  16. using size_type = int;
  17. array() : _data(nullptr), _size(0) {}
  18. array(int size) : _data((T*)std::malloc(sizeof(T) * size)), _size(size) {}
  19. array(array&& other) noexcept : _data(other._data), _size(other._size) {
  20. other._data = nullptr;
  21. other._size = 0;
  22. }
  23. array(const array& other) = delete;
  24. array(explicit_copy_t, const array& other) {
  25. _data = (T*)std::malloc(sizeof(T) * other._size);
  26. _size = other._size;
  27. for(int i = 0; i < _size; i++)
  28. _data[i] = other._data[i];
  29. }
  30. array(T* data, int size) : _data(data), _size(size) {}
  31. array& operator= (array&& other) noexcept {
  32. if(_data) std::free(_data);
  33. _data = other._data;
  34. _size = other._size;
  35. other._data = nullptr;
  36. other._size = 0;
  37. return *this;
  38. }
  39. array& operator= (const array& other) = delete;
  40. T& operator[] (int i) {
  41. assert(i >= 0 && i < _size);
  42. return _data[i];
  43. }
  44. const T& operator[] (int i) const {
  45. assert(i >= 0 && i < _size);
  46. return _data[i];
  47. }
  48. int size() const { return _size; }
  49. T* begin() const { return _data; }
  50. T* end() const { return _data + _size; }
  51. T* data() const { return _data; }
  52. pair<T*, int> detach() noexcept {
  53. pair<T*, int> retval(_data, _size);
  54. _data = nullptr;
  55. _size = 0;
  56. return retval;
  57. }
  58. ~array() {
  59. if(_data) std::free(_data);
  60. }
  61. };
  62. template <bool may_alias = false, typename T>
  63. void uninitialized_copy_n(const T* src, int n, T* dest) {
  64. if(n == 0) return;
  65. if constexpr(std::is_trivially_copyable_v<T>) {
  66. if constexpr(may_alias) {
  67. std::memmove(dest, src, sizeof(T) * n);
  68. } else {
  69. std::memcpy(dest, src, sizeof(T) * n);
  70. }
  71. } else {
  72. for(int i = 0; i < n; i++) {
  73. new (dest + i) T(*(src + i));
  74. }
  75. }
  76. }
  77. template <bool may_alias = false, bool backward = false, typename T>
  78. void uninitialized_relocate_n(T* src, int n, T* dest) {
  79. if(n == 0) return;
  80. if constexpr(is_trivially_relocatable_v<T>) {
  81. if constexpr(may_alias) {
  82. std::memmove(dest, src, sizeof(T) * n);
  83. } else {
  84. std::memcpy(dest, src, sizeof(T) * n);
  85. }
  86. } else {
  87. if constexpr(backward) {
  88. for(int i = n - 1; i >= 0; i--) {
  89. new (dest + i) T(std::move(*(src + i)));
  90. (src + i)->~T();
  91. }
  92. } else {
  93. for(int i = 0; i < n; i++) {
  94. new (dest + i) T(std::move(*(src + i)));
  95. (src + i)->~T();
  96. }
  97. }
  98. }
  99. }
  100. template <typename T>
  101. struct vector {
  102. T* _data;
  103. int _capacity;
  104. int _size;
  105. using size_type = int;
  106. vector() : _data(nullptr), _capacity(0), _size(0) {}
  107. vector(int size) : _data((T*)std::malloc(sizeof(T) * size)), _capacity(size), _size(size) {}
  108. vector(vector&& other) noexcept : _data(other._data), _capacity(other._capacity), _size(other._size) {
  109. other._data = nullptr;
  110. other._capacity = 0;
  111. other._size = 0;
  112. }
  113. vector(const vector& other) = delete;
  114. vector(explicit_copy_t, const vector& other) : _capacity(other._size), _size(other._size) {
  115. _data = (T*)std::malloc(sizeof(T) * _capacity);
  116. uninitialized_copy_n(other._data, _size, _data);
  117. }
  118. // allow move
  119. vector& operator= (vector&& other) noexcept {
  120. if(_data) {
  121. std::destroy(begin(), end());
  122. std::free(_data);
  123. }
  124. new (this) vector(std::move(other));
  125. return *this;
  126. }
  127. // disallow copy
  128. vector& operator= (const vector& other) = delete;
  129. bool empty() const { return _size == 0; }
  130. int size() const { return _size; }
  131. int capacity() const { return _capacity; }
  132. T& back() {
  133. assert(_size > 0);
  134. return _data[_size - 1];
  135. }
  136. T* begin() const { return _data; }
  137. T* end() const { return _data + _size; }
  138. T* data() const { return _data; }
  139. T& operator[] (int i) {
  140. assert(i >= 0 && i < _size);
  141. return _data[i];
  142. }
  143. const T& operator[] (int i) const {
  144. assert(i >= 0 && i < _size);
  145. return _data[i];
  146. }
  147. void clear() {
  148. std::destroy(begin(), end());
  149. _size = 0;
  150. }
  151. void reserve(int cap) {
  152. if(cap < 4) cap = 4; // minimum capacity
  153. if(cap <= capacity()) return;
  154. T* new_data = (T*)std::malloc(sizeof(T) * cap);
  155. uninitialized_relocate_n(_data, _size, new_data);
  156. if(_data) std::free(_data);
  157. _data = new_data;
  158. _capacity = cap;
  159. }
  160. template <typename... Args>
  161. void emplace_back(Args&&... args) {
  162. if(_size == _capacity) reserve(_capacity * 2);
  163. new (_data + _size) T(std::forward<Args>(args)...);
  164. _size++;
  165. }
  166. void push_back(const T& t) { emplace_back(t); }
  167. void push_back(T&& t) { emplace_back(std::move(t)); }
  168. bool contains(const T& t) const {
  169. for(int i = 0; i < _size; i++) {
  170. if(_data[i] == t) return true;
  171. }
  172. return false;
  173. }
  174. void extend(const T* begin, const T* end) {
  175. int n = end - begin;
  176. reserve(_size + n);
  177. uninitialized_copy_n(begin, n, _data + _size);
  178. _size += n;
  179. }
  180. void insert(const T* it, const T& t) {
  181. assert(it >= begin() && it <= end());
  182. int pos = it - begin();
  183. if(_size == _capacity) {
  184. int new_capacity = (_capacity == 0) ? 4 : _capacity * 2;
  185. T* new_data = (T*)std::malloc(sizeof(T) * new_capacity);
  186. uninitialized_relocate_n(_data, pos, new_data);
  187. new (new_data + pos) T(t);
  188. uninitialized_relocate_n(_data + pos, _size - pos, new_data + pos + 1);
  189. if(_data) std::free(_data);
  190. _data = new_data;
  191. _capacity = new_capacity;
  192. } else {
  193. uninitialized_relocate_n<true, true>(_data + pos, _size - pos, _data + pos + 1);
  194. new (_data + pos) T(t);
  195. }
  196. _size++;
  197. }
  198. void erase(T* it) {
  199. assert(it >= begin() && it < end());
  200. int pos = it - begin();
  201. _data[pos].~T();
  202. uninitialized_relocate_n<true>(_data + pos + 1, _size - pos, _data + pos);
  203. _size--;
  204. }
  205. void pop_back() {
  206. assert(_size > 0);
  207. _size--;
  208. _data[_size].~T();
  209. }
  210. [[nodiscard]] T popx_back() {
  211. T retval = std::move(back());
  212. pop_back();
  213. return retval;
  214. }
  215. pair<T*, int> detach() noexcept {
  216. pair<T*, int> retval(_data, _size);
  217. _data = nullptr;
  218. _capacity = 0;
  219. _size = 0;
  220. return retval;
  221. }
  222. void swap(vector& other) {
  223. std::swap(_data, other._data);
  224. std::swap(_capacity, other._capacity);
  225. std::swap(_size, other._size);
  226. }
  227. ~vector() {
  228. if(_data) {
  229. std::destroy(begin(), end());
  230. std::free(_data);
  231. }
  232. }
  233. };
  234. template <typename T, std::size_t N>
  235. struct small_vector {
  236. static_assert(is_pod_v<T>);
  237. alignas(T) char _buffer[sizeof(T) * N];
  238. T* _begin;
  239. T* _end;
  240. T* _capacity;
  241. [[nodiscard]] bool is_small() const { return _begin == reinterpret_cast<const T*>(_buffer); }
  242. [[nodiscard]] int size() const { return _end - _begin; }
  243. [[nodiscard]] int capacity() const { return _capacity - _begin; }
  244. [[nodiscard]] bool empty() const { return _begin == _end; }
  245. [[nodiscard]] T* data() const { return _begin; }
  246. [[nodiscard]] T* begin() const { return _begin; }
  247. [[nodiscard]] T* end() const { return _end; }
  248. [[nodiscard]] T& back() const { return *(end() - 1); }
  249. [[nodiscard]] T& operator[] (int index) { return _begin[index]; }
  250. [[nodiscard]] const T& operator[] (int index) const { return _begin[index]; }
  251. small_vector() : _begin(reinterpret_cast<T*>(_buffer)), _end(_begin), _capacity(_begin + N) {}
  252. small_vector(const small_vector& other) noexcept {
  253. const auto size = other.size();
  254. const auto capacity = other.capacity();
  255. _begin = reinterpret_cast<T*>(other.is_small() ? _buffer : std::malloc(sizeof(T) * capacity));
  256. uninitialized_copy_n(other._begin, size, this->_begin);
  257. _end = _begin + size;
  258. _capacity = _begin + capacity;
  259. }
  260. small_vector(small_vector&& other) noexcept {
  261. if(other.is_small()) {
  262. _begin = reinterpret_cast<T*>(_buffer);
  263. uninitialized_relocate_n((T*)other._buffer, other.size(), (T*)_buffer);
  264. _end = _begin + other.size();
  265. _capacity = _begin + N;
  266. } else {
  267. _begin = other._begin;
  268. _end = other._end;
  269. _capacity = other._capacity;
  270. }
  271. other._begin = reinterpret_cast<T*>(other._buffer);
  272. other._end = other._begin;
  273. other._capacity = other._begin + N;
  274. }
  275. small_vector& operator= (const small_vector& other) = delete;
  276. small_vector& operator= (small_vector&& other) noexcept {
  277. if(this != &other) {
  278. ~small_vector();
  279. ::new (this) small_vector(std::move(other));
  280. }
  281. return *this;
  282. }
  283. ~small_vector() {
  284. std::destroy(_begin, _end);
  285. if(!is_small()) std::free(_begin);
  286. }
  287. template <typename... Args>
  288. void emplace_back(Args&&... args) noexcept {
  289. if(_end == _capacity) {
  290. const auto new_capacity = capacity() * 2;
  291. const auto size = this->size();
  292. auto new_data = (T*)std::malloc(sizeof(T) * new_capacity);
  293. uninitialized_relocate_n(_begin, size, new_data);
  294. if(!is_small()) std::free(_begin);
  295. _begin = new_data;
  296. _end = _begin + size;
  297. _capacity = _begin + new_capacity;
  298. }
  299. ::new (_end) T(std::forward<Args>(args)...);
  300. _end++;
  301. }
  302. void push_back(const T& value) { emplace_back(value); }
  303. void push_back(T&& value) { emplace_back(std::move(value)); }
  304. void pop_back() {
  305. _end--;
  306. _end->~T();
  307. }
  308. void clear() {
  309. std::destroy(_begin, _end);
  310. _end = _begin;
  311. }
  312. };
  313. template <typename T, std::size_t N>
  314. class small_vector_2 : public small_vector<T, N> {
  315. public:
  316. small_vector_2() = default;
  317. small_vector_2(const small_vector_2& other) = delete;
  318. small_vector_2& operator= (const small_vector_2& other) = delete;
  319. small_vector_2(small_vector_2&& other) = delete;
  320. small_vector_2& operator= (small_vector_2&& other) = delete;
  321. };
  322. template <typename K, typename V>
  323. struct small_map {
  324. struct Item {
  325. K first;
  326. V second;
  327. bool operator< (const K& other) const { return first < other; }
  328. bool operator< (const Item& other) const { return first < other.first; }
  329. };
  330. vector<Item> _data;
  331. small_map() = default;
  332. using size_type = int;
  333. int size() const { return _data.size(); }
  334. bool empty() const { return _data.empty(); }
  335. Item* begin() const { return _data.begin(); }
  336. Item* end() const { return _data.end(); }
  337. Item* data() const { return _data.data(); }
  338. void insert(const K& key, const V& value) {
  339. Item* it = lower_bound(_data.begin(), _data.end(), key);
  340. assert(it == _data.end() || it->first != key);
  341. _data.insert(it, {key, value});
  342. }
  343. V* try_get(const K& key) const {
  344. auto it = lower_bound(_data.begin(), _data.end(), key);
  345. if(it == _data.end() || it->first != key) return nullptr;
  346. return &it->second;
  347. }
  348. V get(const K& key, V default_value) const {
  349. static_assert(is_pod_v<V>);
  350. auto it = try_get(key);
  351. return it ? *it : default_value;
  352. }
  353. bool contains(const K& key) const { return try_get(key) != nullptr; }
  354. void clear() { _data.clear(); }
  355. const V& operator[] (const K& key) const {
  356. auto it = try_get(key);
  357. assert(it != nullptr);
  358. return *it;
  359. }
  360. };
  361. } // namespace pkpy