1010#define _LIBCPP___VECTOR_VECTOR_H
1111
1212#include < __algorithm/copy.h>
13+ #include < __algorithm/copy_n.h>
1314#include < __algorithm/fill_n.h>
1415#include < __algorithm/max.h>
1516#include < __algorithm/min.h>
1617#include < __algorithm/move.h>
1718#include < __algorithm/move_backward.h>
19+ #include < __algorithm/ranges_copy_n.h>
1820#include < __algorithm/rotate.h>
1921#include < __assert>
2022#include < __config>
2325#include < __fwd/vector.h>
2426#include < __iterator/advance.h>
2527#include < __iterator/bounded_iter.h>
28+ #include < __iterator/concepts.h>
2629#include < __iterator/distance.h>
2730#include < __iterator/iterator_traits.h>
2831#include < __iterator/move_iterator.h>
@@ -575,7 +578,7 @@ class _LIBCPP_TEMPLATE_VIS vector {
575578
576579 if (__n > 0 ) {
577580 __vallocate (__n);
578- __construct_at_end (__first, __last, __n);
581+ __construct_at_end (std::move ( __first), std::move ( __last) , __n);
579582 }
580583
581584 __guard.__complete ();
@@ -595,9 +598,12 @@ class _LIBCPP_TEMPLATE_VIS vector {
595598 template <class _Iterator , class _Sentinel >
596599 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __assign_with_sentinel (_Iterator __first, _Sentinel __last);
597600
598- template <class _ForwardIterator , class _Sentinel >
601+ // The `_Iterator` in `*_with_size` functions can be input-only only if called from `*_range` (since C++23).
602+ // Otherwise, `_Iterator` is a forward iterator.
603+
604+ template <class _Iterator , class _Sentinel >
599605 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void
600- __assign_with_size (_ForwardIterator __first, _Sentinel __last, difference_type __n);
606+ __assign_with_size (_Iterator __first, _Sentinel __last, difference_type __n);
601607
602608 template <class _InputIterator , class _Sentinel >
603609 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI iterator
@@ -918,7 +924,7 @@ template <class _InputIterator, class _Sentinel>
918924_LIBCPP_CONSTEXPR_SINCE_CXX20 void
919925vector<_Tp, _Allocator>::__construct_at_end(_InputIterator __first, _Sentinel __last, size_type __n) {
920926 _ConstructTransaction __tx (*this , __n);
921- __tx.__pos_ = std::__uninitialized_allocator_copy (this ->__alloc_ , __first, __last, __tx.__pos_ );
927+ __tx.__pos_ = std::__uninitialized_allocator_copy (this ->__alloc_ , std::move ( __first), std::move ( __last) , __tx.__pos_ );
922928}
923929
924930// Default constructs __n objects starting at __end_
@@ -1027,23 +1033,28 @@ vector<_Tp, _Allocator>::__assign_with_sentinel(_Iterator __first, _Sentinel __l
10271033}
10281034
10291035template <class _Tp , class _Allocator >
1030- template <class _ForwardIterator , class _Sentinel >
1036+ template <class _Iterator , class _Sentinel >
10311037_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void
1032- vector<_Tp, _Allocator>::__assign_with_size(_ForwardIterator __first, _Sentinel __last, difference_type __n) {
1038+ vector<_Tp, _Allocator>::__assign_with_size(_Iterator __first, _Sentinel __last, difference_type __n) {
10331039 size_type __new_size = static_cast <size_type>(__n);
10341040 if (__new_size <= capacity ()) {
10351041 if (__new_size > size ()) {
1036- _ForwardIterator __mid = std::next (__first, size ());
1042+ #if _LIBCPP_STD_VER >= 23
1043+ auto __mid = ranges::copy_n (std::move (__first), size (), this ->__begin_ ).in ;
1044+ __construct_at_end (std::move (__mid), std::move (__last), __new_size - size ());
1045+ #else
1046+ _Iterator __mid = std::next (__first, size ());
10371047 std::copy (__first, __mid, this ->__begin_ );
10381048 __construct_at_end (__mid, __last, __new_size - size ());
1049+ #endif
10391050 } else {
1040- pointer __m = std::__copy (__first, __last, this ->__begin_ ).second ;
1051+ pointer __m = std::__copy (std::move ( __first) , __last, this ->__begin_ ).second ;
10411052 this ->__destruct_at_end (__m);
10421053 }
10431054 } else {
10441055 __vdeallocate ();
10451056 __vallocate (__recommend (__new_size));
1046- __construct_at_end (__first, __last, __new_size);
1057+ __construct_at_end (std::move ( __first), std::move ( __last) , __new_size);
10471058 }
10481059}
10491060
@@ -1293,28 +1304,40 @@ template <class _Iterator, class _Sentinel>
12931304_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI typename vector<_Tp, _Allocator>::iterator
12941305vector<_Tp, _Allocator>::__insert_with_size (
12951306 const_iterator __position, _Iterator __first, _Sentinel __last, difference_type __n) {
1296- auto __insertion_size = __n;
1297- pointer __p = this ->__begin_ + (__position - begin ());
1307+ pointer __p = this ->__begin_ + (__position - begin ());
12981308 if (__n > 0 ) {
12991309 if (__n <= this ->__cap_ - this ->__end_ ) {
1300- size_type __old_n = __n;
13011310 pointer __old_last = this ->__end_ ;
1302- _Iterator __m = std::next (__first, __n);
13031311 difference_type __dx = this ->__end_ - __p;
13041312 if (__n > __dx) {
1305- __m = __first;
1306- difference_type __diff = this ->__end_ - __p;
1307- std::advance (__m, __diff);
1308- __construct_at_end (__m, __last, __n - __diff);
1309- __n = __dx;
1310- }
1311- if (__n > 0 ) {
1312- __move_range (__p, __old_last, __p + __old_n);
1313- std::copy (__first, __m, __p);
1313+ #if _LIBCPP_STD_VER >= 23
1314+ if constexpr (!forward_iterator<_Iterator>) {
1315+ __construct_at_end (std::move (__first), std::move (__last), __n);
1316+ std::rotate (__p, __old_last, this ->__end_ );
1317+ } else
1318+ #endif
1319+ {
1320+ _Iterator __m = std::next (__first, __dx);
1321+ __construct_at_end (__m, __last, __n - __dx);
1322+ if (__dx > 0 ) {
1323+ __move_range (__p, __old_last, __p + __n);
1324+ std::copy (__first, __m, __p);
1325+ }
1326+ }
1327+ } else {
1328+ __move_range (__p, __old_last, __p + __n);
1329+ #if _LIBCPP_STD_VER >= 23
1330+ if constexpr (!forward_iterator<_Iterator>) {
1331+ ranges::copy_n (std::move (__first), __n, __p);
1332+ } else
1333+ #endif
1334+ {
1335+ std::copy_n (__first, __n, __p);
1336+ }
13141337 }
13151338 } else {
13161339 __split_buffer<value_type, allocator_type&> __v (__recommend (size () + __n), __p - this ->__begin_ , this ->__alloc_ );
1317- __v.__construct_at_end_with_size (__first, __insertion_size );
1340+ __v.__construct_at_end_with_size (std::move ( __first), __n );
13181341 __p = __swap_out_circular_buffer (__v, __p);
13191342 }
13201343 }
0 commit comments