|
10 | 10 | #include <stdint.h> |
11 | 11 | #include <string.h> |
12 | 12 |
|
| 13 | +#include <cstddef> |
13 | 14 | #include <iterator> |
14 | 15 | #include <type_traits> |
15 | 16 |
|
| 17 | +#include <compat.h> |
| 18 | + |
16 | 19 | #pragma pack(push, 1) |
17 | 20 | /** Implements a drop-in replacement for std::vector<T> which stores up to N |
18 | 21 | * elements directly (without heap allocation). The types Size and Diff are |
@@ -194,8 +197,21 @@ class prevector { |
194 | 197 | T* item_ptr(difference_type pos) { return is_direct() ? direct_ptr(pos) : indirect_ptr(pos); } |
195 | 198 | const T* item_ptr(difference_type pos) const { return is_direct() ? direct_ptr(pos) : indirect_ptr(pos); } |
196 | 199 |
|
197 | | - void fill(T* dst, size_type count, const T& value) { |
198 | | - for (size_type i = 0; i < count; ++i) { |
| 200 | + void fill(T* dst, ptrdiff_t count) { |
| 201 | + if (IS_TRIVIALLY_CONSTRUCTIBLE<T>::value) { |
| 202 | + // The most common use of prevector is where T=unsigned char. For |
| 203 | + // trivially constructible types, we can use memset() to avoid |
| 204 | + // looping. |
| 205 | + ::memset(dst, 0, count * sizeof(T)); |
| 206 | + } else { |
| 207 | + for (auto i = 0; i < count; ++i) { |
| 208 | + new(static_cast<void*>(dst + i)) T(); |
| 209 | + } |
| 210 | + } |
| 211 | + } |
| 212 | + |
| 213 | + void fill(T* dst, ptrdiff_t count, const T& value) { |
| 214 | + for (auto i = 0; i < count; ++i) { |
199 | 215 | new(static_cast<void*>(dst + i)) T(value); |
200 | 216 | } |
201 | 217 | } |
@@ -310,16 +326,19 @@ class prevector { |
310 | 326 |
|
311 | 327 | void resize(size_type new_size) { |
312 | 328 | size_type cur_size = size(); |
| 329 | + if (cur_size == new_size) { |
| 330 | + return; |
| 331 | + } |
313 | 332 | if (cur_size > new_size) { |
314 | 333 | erase(item_ptr(new_size), end()); |
| 334 | + return; |
315 | 335 | } |
316 | 336 | if (new_size > capacity()) { |
317 | 337 | change_capacity(new_size); |
318 | 338 | } |
319 | | - for (T* p = item_ptr(0); cur_size < new_size; cur_size++) { |
320 | | - _size++; |
321 | | - new(static_cast<void*>(p + cur_size)) T(); |
322 | | - } |
| 339 | + ptrdiff_t increase = new_size - cur_size; |
| 340 | + fill(item_ptr(cur_size), increase); |
| 341 | + _size += increase; |
323 | 342 | } |
324 | 343 |
|
325 | 344 | void reserve(size_type new_capacity) { |
|
0 commit comments