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