vector.hpp (2266B)
1 #pragma once 2 #include "linux.hpp" 3 4 inline void* operator new(size_t, void* p) noexcept 5 { 6 return p; 7 } 8 9 struct false_type { static constexpr bool value = false; }; 10 struct true_type { static constexpr bool value = true; }; 11 12 template<typename T, typename U> struct is_same : false_type {}; 13 template<typename T> struct is_same<T, T> : true_type {}; 14 template<typename T, typename U> constexpr bool is_same_v = is_same<T, U>::value; 15 16 template <typename T> 17 consteval unsigned bits() 18 { 19 if constexpr (is_same_v<T, uint64_t>) 20 return 64; 21 if constexpr (is_same_v<T, int64_t>) 22 return 64; 23 if constexpr (is_same_v<T, uint32_t>) 24 return 32; 25 if constexpr (is_same_v<T, int32_t>) 26 return 32; 27 } 28 29 static_assert(bits<int64_t>() == 64); 30 static_assert(bits<uint64_t>() == 64); 31 static_assert(bits<int32_t>() == 32); 32 static_assert(bits<uint32_t>() == 32); 33 34 constexpr size_t next_power_of_two(size_t n) 35 { 36 if (not n) 37 return n; 38 --n; 39 for (unsigned i = 1; i <= bits<size_t>(); i <<= 1) 40 n |= n >> i; 41 return ++n; 42 } 43 44 template <typename T> 45 struct vector 46 { 47 vector() = default; 48 ~vector() 49 { 50 for (auto p = buf + used; p != buf; --p) 51 p->~T(); 52 if (buf) 53 *munmap(buf, capacity); 54 } 55 vector(vector const& old) 56 { 57 reserve(old.size()); 58 push_back(old); 59 } 60 vector& operator =(vector const&) = delete; // todo: clear, assign 61 62 void reserve(size_t min) 63 { 64 min *= sizeof(T); 65 if (min <= capacity) 66 return; 67 min = min <= 4096u ? 4096u : next_power_of_two(min); 68 auto new_buf = reinterpret_cast<T*>(*mmap(nullptr, min, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, {}, 0)); 69 for (size_t i = 0; i < used; ++i) 70 { 71 new (new_buf + i) T{buf[i]}; 72 buf[i].~T(); 73 } 74 if (buf) 75 *munmap(buf, capacity); 76 buf = new_buf; 77 capacity = min; 78 } 79 void push_back(T c) 80 { 81 reserve(used + 1); 82 new (buf + used++) T{c}; 83 } 84 void push_back(span<T const> data) 85 { 86 reserve(size() + data.size()); 87 T* p = buf + used; 88 for (auto const& x : data) 89 new (p++) T{x}; 90 used += data.size(); 91 } 92 93 T const* data() const { return buf; } 94 T* data() { return buf; } 95 size_t size() const { return used; } 96 97 operator span<T>() const { return {buf, used}; } 98 T* begin() { return buf; } 99 T* end() { return buf + used; } 100 101 private: 102 T* buf = nullptr; 103 size_t capacity = 0, used = 0; 104 };