|
10 | 10 | #define _LIBCPP___VECTOR_VECTOR_H |
11 | 11 |
|
12 | 12 | #include <__algorithm/copy.h> |
| 13 | +#include <__algorithm/copy_n.h> |
13 | 14 | #include <__algorithm/fill_n.h> |
14 | 15 | #include <__algorithm/max.h> |
15 | 16 | #include <__algorithm/min.h> |
16 | 17 | #include <__algorithm/move.h> |
17 | 18 | #include <__algorithm/move_backward.h> |
| 19 | +#include <__algorithm/ranges_copy_n.h> |
18 | 20 | #include <__algorithm/rotate.h> |
19 | 21 | #include <__assert> |
20 | 22 | #include <__config> |
|
23 | 25 | #include <__fwd/vector.h> |
24 | 26 | #include <__iterator/advance.h> |
25 | 27 | #include <__iterator/bounded_iter.h> |
| 28 | +#include <__iterator/concepts.h> |
26 | 29 | #include <__iterator/distance.h> |
27 | 30 | #include <__iterator/iterator_traits.h> |
28 | 31 | #include <__iterator/move_iterator.h> |
|
54 | 57 | #include <__type_traits/is_same.h> |
55 | 58 | #include <__type_traits/is_trivially_relocatable.h> |
56 | 59 | #include <__type_traits/type_identity.h> |
| 60 | +#include <__utility/declval.h> |
57 | 61 | #include <__utility/exception_guard.h> |
58 | 62 | #include <__utility/forward.h> |
59 | 63 | #include <__utility/is_pointer_in_range.h> |
@@ -594,6 +598,30 @@ class _LIBCPP_TEMPLATE_VIS vector { |
594 | 598 | _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void |
595 | 599 | __assign_with_size(_ForwardIterator __first, _Sentinel __last, difference_type __n); |
596 | 600 |
|
| 601 | + template <class _Iterator, |
| 602 | + __enable_if_t<!is_same<decltype(*std::declval<_Iterator&>())&&, value_type&&>::value, int> = 0> |
| 603 | + _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void |
| 604 | + __insert_assign_n_unchecked(_Iterator __first, difference_type __n, pointer __position) { |
| 605 | + for (pointer __end_position = __position + __n; __position != __end_position; (void)++__position, ++__first) { |
| 606 | + __temp_value<value_type, _Allocator> __tmp(this->__alloc(), *__first); |
| 607 | + *__position = std::move(__tmp.get()); |
| 608 | + } |
| 609 | + } |
| 610 | + |
| 611 | + template <class _Iterator, |
| 612 | + __enable_if_t<is_same<decltype(*std::declval<_Iterator&>())&&, value_type&&>::value, int> = 0> |
| 613 | + _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void |
| 614 | + __insert_assign_n_unchecked(_Iterator __first, difference_type __n, pointer __position) { |
| 615 | +#if _LIBCPP_STD_VER >= 23 |
| 616 | + if constexpr (!forward_iterator<_Iterator>) { |
| 617 | + ranges::copy_n(std::move(__first), __n, __position); |
| 618 | + } else |
| 619 | +#endif |
| 620 | + { |
| 621 | + std::copy_n(__first, __n, __position); |
| 622 | + } |
| 623 | + } |
| 624 | + |
597 | 625 | template <class _InputIterator, class _Sentinel> |
598 | 626 | _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI iterator |
599 | 627 | __insert_with_sentinel(const_iterator __position, _InputIterator __first, _Sentinel __last); |
@@ -1297,29 +1325,34 @@ template <class _Iterator, class _Sentinel> |
1297 | 1325 | _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI typename vector<_Tp, _Allocator>::iterator |
1298 | 1326 | vector<_Tp, _Allocator>::__insert_with_size( |
1299 | 1327 | const_iterator __position, _Iterator __first, _Sentinel __last, difference_type __n) { |
1300 | | - auto __insertion_size = __n; |
1301 | | - pointer __p = this->__begin_ + (__position - begin()); |
| 1328 | + pointer __p = this->__begin_ + (__position - begin()); |
1302 | 1329 | if (__n > 0) { |
1303 | 1330 | if (__n <= this->__end_cap() - this->__end_) { |
1304 | | - size_type __old_n = __n; |
1305 | 1331 | pointer __old_last = this->__end_; |
1306 | | - _Iterator __m = std::next(__first, __n); |
1307 | 1332 | difference_type __dx = this->__end_ - __p; |
1308 | 1333 | if (__n > __dx) { |
1309 | | - __m = __first; |
1310 | | - difference_type __diff = this->__end_ - __p; |
1311 | | - std::advance(__m, __diff); |
1312 | | - __construct_at_end(__m, __last, __n - __diff); |
1313 | | - __n = __dx; |
1314 | | - } |
1315 | | - if (__n > 0) { |
1316 | | - __move_range(__p, __old_last, __p + __old_n); |
1317 | | - std::copy(__first, __m, __p); |
| 1334 | +#if _LIBCPP_STD_VER >= 23 |
| 1335 | + if constexpr (!forward_iterator<_Iterator>) { |
| 1336 | + __construct_at_end(std::move(__first), std::move(__last), __n); |
| 1337 | + std::rotate(__p, __old_last, this->__end_); |
| 1338 | + } else |
| 1339 | +#endif |
| 1340 | + { |
| 1341 | + _Iterator __m = std::next(__first, __dx); |
| 1342 | + __construct_at_end(__m, __last, __n - __dx); |
| 1343 | + if (__dx > 0) { |
| 1344 | + __move_range(__p, __old_last, __p + __n); |
| 1345 | + __insert_assign_n_unchecked(__first, __dx, __p); |
| 1346 | + } |
| 1347 | + } |
| 1348 | + } else { |
| 1349 | + __move_range(__p, __old_last, __p + __n); |
| 1350 | + __insert_assign_n_unchecked(std::move(__first), __n, __p); |
1318 | 1351 | } |
1319 | 1352 | } else { |
1320 | 1353 | allocator_type& __a = this->__alloc(); |
1321 | 1354 | __split_buffer<value_type, allocator_type&> __v(__recommend(size() + __n), __p - this->__begin_, __a); |
1322 | | - __v.__construct_at_end_with_size(__first, __insertion_size); |
| 1355 | + __v.__construct_at_end_with_size(__first, __n); |
1323 | 1356 | __p = __swap_out_circular_buffer(__v, __p); |
1324 | 1357 | } |
1325 | 1358 | } |
|
0 commit comments