|
4 | 4 | #include "noinclude.h" |
5 | 5 |
|
6 | 6 | // miscellaneous templates |
7 | | -#include <algorithm> |
8 | | -#include <memory> |
| 7 | + |
9 | 8 | #include <cstdlib> |
10 | 9 | #include <string> |
11 | 10 | #include <string_view> |
12 | 11 | #include <unordered_map> |
13 | 12 | #include <cassert> |
14 | | -#include <vector> |
15 | 13 |
|
16 | 14 | // zero-initialized dynamic array, similar to std::vector but way faster when you don't need constructors |
17 | 15 | // obviously don't use it on complex types :) |
@@ -105,153 +103,6 @@ struct zarray { |
105 | 103 | T *memory = NULL; |
106 | 104 | }; |
107 | 105 |
|
108 | | -// "fixed-size std::vector", but 2*sizeof(size_t) bytes instead of 3*sizeof(size_t) |
109 | | -template <typename T> |
110 | | -struct FixedSizeArray { |
111 | | - struct zero_init_t {}; |
112 | | - static inline constexpr zero_init_t zero_init{}; |
113 | | - |
114 | | - FixedSizeArray() = default; |
115 | | - ~FixedSizeArray() = default; |
116 | | - |
117 | | - explicit FixedSizeArray(size_t size) : data_(std::make_unique_for_overwrite<T[]>(size)), size_(size) {} |
118 | | - FixedSizeArray(size_t size, zero_init_t /**/) : data_(std::make_unique<T[]>(size)), size_(size) {} |
119 | | - |
120 | | - FixedSizeArray(const FixedSizeArray &other) |
121 | | - : data_(other.size_ ? std::make_unique_for_overwrite<T[]>(other.size_) : nullptr), size_(other.size_) { |
122 | | - if constexpr(std::is_trivially_copyable_v<T>) { |
123 | | - if(size_) memcpy(data_.get(), other.data_.get(), size_ * sizeof(T)); |
124 | | - } else { |
125 | | - std::copy_n(other.data_.get(), size_, data_.get()); |
126 | | - } |
127 | | - } |
128 | | - |
129 | | - FixedSizeArray &operator=(const FixedSizeArray &other) { |
130 | | - if(this != &other) { |
131 | | - size_ = other.size_; |
132 | | - data_ = other.size_ ? std::make_unique_for_overwrite<T[]>(other.size_) : nullptr; |
133 | | - if constexpr(std::is_trivially_copyable_v<T>) { |
134 | | - if(size_) memcpy(data_.get(), other.data_.get(), size_ * sizeof(T)); |
135 | | - } else { |
136 | | - std::copy_n(other.data_.get(), size_, data_.get()); |
137 | | - } |
138 | | - } |
139 | | - return *this; |
140 | | - } |
141 | | - |
142 | | - FixedSizeArray(FixedSizeArray &&other) noexcept : data_(std::move(other.data_)), size_(other.size_) { |
143 | | - other.size_ = 0; |
144 | | - } |
145 | | - |
146 | | - FixedSizeArray &operator=(FixedSizeArray &&other) noexcept { |
147 | | - if(this != &other) { |
148 | | - data_ = std::move(other.data_); |
149 | | - size_ = other.size_; |
150 | | - other.size_ = 0; |
151 | | - } |
152 | | - return *this; |
153 | | - } |
154 | | - |
155 | | - // constructors/assignment operators from a std::vector |
156 | | - // NOLINTNEXTLINE(cppcoreguidelines-rvalue-reference-param-not-moved) |
157 | | - explicit FixedSizeArray(std::vector<T> &&vec) noexcept |
158 | | - : data_(vec.size() ? std::make_unique_for_overwrite<T[]>(vec.size()) : nullptr), size_(vec.size()) { |
159 | | - if constexpr(std::is_trivially_copyable_v<T>) { |
160 | | - if(size_) memcpy(data_.get(), vec.data(), size_ * sizeof(T)); |
161 | | - } else { |
162 | | - std::ranges::move(vec, data_.get()); |
163 | | - } |
164 | | - } |
165 | | - |
166 | | - explicit FixedSizeArray(const std::vector<T> &vec) noexcept |
167 | | - : data_(vec.size() ? std::make_unique_for_overwrite<T[]>(vec.size()) : nullptr), size_(vec.size()) { |
168 | | - if constexpr(std::is_trivially_copyable_v<T>) { |
169 | | - if(size_) memcpy(data_.get(), vec.data(), size_ * sizeof(T)); |
170 | | - } else { |
171 | | - std::ranges::copy(vec, data_.get()); |
172 | | - } |
173 | | - } |
174 | | - |
175 | | - // NOLINTNEXTLINE(cppcoreguidelines-rvalue-reference-param-not-moved) |
176 | | - FixedSizeArray &operator=(std::vector<T> &&vec) noexcept { |
177 | | - size_ = vec.size(); |
178 | | - data_ = size_ ? std::make_unique_for_overwrite<T[]>(size_) : nullptr; |
179 | | - if constexpr(std::is_trivially_copyable_v<T>) { |
180 | | - if(size_) memcpy(data_.get(), vec.data(), size_ * sizeof(T)); |
181 | | - } else { |
182 | | - std::ranges::move(vec, data_.get()); |
183 | | - } |
184 | | - return *this; |
185 | | - } |
186 | | - |
187 | | - FixedSizeArray &operator=(const std::vector<T> &vec) noexcept { |
188 | | - size_ = vec.size(); |
189 | | - data_ = size_ ? std::make_unique_for_overwrite<T[]>(size_) : nullptr; |
190 | | - if constexpr(std::is_trivially_copyable_v<T>) { |
191 | | - if(size_) memcpy(data_.get(), vec.data(), size_ * sizeof(T)); |
192 | | - } else { |
193 | | - std::ranges::copy(vec, data_.get()); |
194 | | - } |
195 | | - return *this; |
196 | | - } |
197 | | - |
198 | | - [[nodiscard]] constexpr inline T *data() noexcept { return data_.get(); } |
199 | | - [[nodiscard]] constexpr inline const T *data() const noexcept { return data_.get(); } |
200 | | - |
201 | | - [[nodiscard]] constexpr inline T &operator[](size_t i) noexcept { |
202 | | - assert(!!data_ && "T &operator[](size_t i): !data_"); |
203 | | - assert(i >= 0 && "T &operator[](size_t i): i < 0"); |
204 | | - assert(i < size_ && "T &operator[](size_t i): i >= size_"); |
205 | | - return data_[i]; |
206 | | - } |
207 | | - [[nodiscard]] constexpr inline const T &operator[](size_t i) const noexcept { |
208 | | - assert(!!data_ && "const T &operator[](size_t i) const: !data_"); |
209 | | - assert(i >= 0 && "const T &operator[](size_t i) const: i < 0"); |
210 | | - assert(i < size_ && "const T &operator[](size_t i) const: i >= size_"); |
211 | | - return data_[i]; |
212 | | - } |
213 | | - |
214 | | - [[nodiscard]] constexpr inline T &front() noexcept { |
215 | | - assert(!empty()); |
216 | | - return operator[](0); |
217 | | - } |
218 | | - |
219 | | - [[nodiscard]] constexpr inline T &back() noexcept { |
220 | | - assert(!empty()); |
221 | | - return operator[](size_ - 1); |
222 | | - } |
223 | | - |
224 | | - [[nodiscard]] inline constexpr const T &front() const noexcept { |
225 | | - assert(!empty()); |
226 | | - return operator[](0); |
227 | | - } |
228 | | - |
229 | | - [[nodiscard]] inline constexpr const T &back() const noexcept { |
230 | | - assert(!empty()); |
231 | | - return operator[](size_ - 1); |
232 | | - } |
233 | | - |
234 | | - [[nodiscard]] constexpr inline size_t size() const noexcept { return size_; } |
235 | | - [[nodiscard]] constexpr inline bool empty() const noexcept { return size_ == 0; } |
236 | | - |
237 | | - [[nodiscard]] constexpr inline T *begin() noexcept { return data_.get(); } |
238 | | - [[nodiscard]] constexpr inline T *end() noexcept { return data_.get() + size_; } |
239 | | - [[nodiscard]] constexpr inline const T *begin() const noexcept { return data_.get(); } |
240 | | - [[nodiscard]] constexpr inline const T *end() const noexcept { return data_.get() + size_; } |
241 | | - |
242 | | - [[nodiscard]] constexpr inline const T *cbegin() const noexcept { return data_.get(); } |
243 | | - [[nodiscard]] constexpr inline const T *cend() const noexcept { return data_.get() + size_; } |
244 | | - |
245 | | - void clear() noexcept { |
246 | | - size_ = 0; |
247 | | - data_.reset(); |
248 | | - } |
249 | | - |
250 | | - private: |
251 | | - std::unique_ptr<T[]> data_{nullptr}; |
252 | | - size_t size_{0}; |
253 | | -}; |
254 | | - |
255 | 106 | // transparent hash and equality for heterogeneous lookup |
256 | 107 | struct StringHash { |
257 | 108 | using is_transparent = void; |
|
0 commit comments