@@ -200,9 +200,10 @@ class bpt_vector {
200
200
auto index = to_index (iter);
201
201
202
202
pointer dst_ptr = {const_cast <pointer>(&*iter)};
203
- std::memmove (dst_ptr + length, dst_ptr, sizeof (V) * ( size_ - index ) );
203
+ move_to_back (dst_ptr + length, dst_ptr, size_ - index );
204
204
205
205
// TODO Use memmove if the source is also a bpt_vector....
206
+ // if constexpr (src_begin.base() is b_vector_iterator) ... move_to_back else loop
206
207
auto src = src_begin;
207
208
while (src != src_end) {
208
209
place (dst_ptr, std::move (*src));
@@ -219,7 +220,7 @@ class bpt_vector {
219
220
assert (size_ < SIZE);
220
221
auto index = to_index (iter);
221
222
pointer dst_ptr{const_cast <pointer>(&*iter)};
222
- memmove (dst_ptr + 1 , dst_ptr, sizeof (V) * ( size_ - index ) );
223
+ move_to_back (dst_ptr + 1 , dst_ptr, size_ - index );
223
224
place (dst_ptr, std::forward<Args>(args)...);
224
225
++size_;
225
226
return iterator{dst_ptr};
@@ -234,7 +235,7 @@ class bpt_vector {
234
235
iterator erase (const_iterator iter) noexcept {
235
236
iter->~V ();
236
237
pointer dst{const_cast <pointer>(&*iter)};
237
- memmove (dst, dst + 1 , sizeof (V) * ( size_ - to_index (iter) - 1 ) );
238
+ move_to_front (dst, dst + 1 , size_ - to_index (iter) - 1 );
238
239
--size_;
239
240
return iterator{dst};
240
241
}
@@ -246,7 +247,7 @@ class bpt_vector {
246
247
}
247
248
auto length = last - first;
248
249
pointer dst{const_cast <pointer>(&*first)};
249
- memmove (dst, dst + length, sizeof (V) * ( end_ptr () - &*last) );
250
+ move_to_front (dst, dst + length, end_ptr () - &*last);
250
251
size_ -= length;
251
252
return iterator{dst};
252
253
}
@@ -262,6 +263,32 @@ class bpt_vector {
262
263
void reserve (size_t ) noexcept {}
263
264
264
265
private:
266
+ template <class V2 = V, typename std::enable_if_t <std::is_trivially_copyable_v<V2>, int > = 0 >
267
+ void move_to_back (pointer dst, pointer src, size_t count) noexcept {
268
+ memmove (dst, src, count * sizeof (V));
269
+ }
270
+
271
+ template <class V2 = V, typename std::enable_if_t <!std::is_trivially_copyable_v<V2>, int > = 0 >
272
+ void move_to_back (pointer dst, pointer src, size_t count) noexcept {
273
+ dst += count - 1 ;
274
+ src += count - 1 ;
275
+ for (size_t i = 0 ; i < count; ++i, --dst, --src) {
276
+ data (dst) = std::move (data (src));
277
+ }
278
+ }
279
+
280
+ template <class V2 = V, typename std::enable_if_t <std::is_trivially_copyable_v<V2>, int > = 0 >
281
+ void move_to_front (pointer dst, pointer src, size_t count) noexcept {
282
+ memmove (dst, src, count * sizeof (V));
283
+ }
284
+
285
+ template <class V2 = V, typename std::enable_if_t <!std::is_trivially_copyable_v<V2>, int > = 0 >
286
+ void move_to_front (pointer dst, pointer src, size_t count) noexcept {
287
+ for (size_t i = 0 ; i < count; ++i, ++dst, ++src) {
288
+ *dst = std::move (*src);
289
+ }
290
+ }
291
+
265
292
template <typename ... Args>
266
293
pointer place (size_t index, Args&&... args) noexcept {
267
294
return new (reinterpret_cast <void *>(&data_[index * sizeof (V)]))
@@ -285,6 +312,10 @@ class bpt_vector {
285
312
return iterator{&data (index )};
286
313
}
287
314
315
+ reference data (pointer ptr) noexcept {
316
+ return *std::launder (ptr);
317
+ }
318
+
288
319
reference data (size_t index) noexcept {
289
320
return *std::launder (reinterpret_cast <V*>(&data_[index * sizeof (V)]));
290
321
}
0 commit comments