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>
@@ -570,7 +573,7 @@ class _LIBCPP_TEMPLATE_VIS vector {
570573
571574 if (__n > 0 ) {
572575 __vallocate (__n);
573- __construct_at_end (__first, __last, __n);
576+ __construct_at_end (std::move ( __first), std::move ( __last) , __n);
574577 }
575578
576579 __guard.__complete ();
@@ -590,9 +593,12 @@ class _LIBCPP_TEMPLATE_VIS vector {
590593 template <class _Iterator , class _Sentinel >
591594 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __assign_with_sentinel (_Iterator __first, _Sentinel __last);
592595
593- template <class _ForwardIterator , class _Sentinel >
596+ // The `_Iterator` in `*_with_size` functions can be input-only only if called from `*_range` (since C++23).
597+ // Otherwise, `_Iterator` is a forward iterator.
598+
599+ template <class _Iterator , class _Sentinel >
594600 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void
595- __assign_with_size (_ForwardIterator __first, _Sentinel __last, difference_type __n);
601+ __assign_with_size (_Iterator __first, _Sentinel __last, difference_type __n);
596602
597603 template <class _InputIterator , class _Sentinel >
598604 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI iterator
@@ -906,7 +912,7 @@ template <class _InputIterator, class _Sentinel>
906912_LIBCPP_CONSTEXPR_SINCE_CXX20 void
907913vector<_Tp, _Allocator>::__construct_at_end(_InputIterator __first, _Sentinel __last, size_type __n) {
908914 _ConstructTransaction __tx (*this , __n);
909- __tx.__pos_ = std::__uninitialized_allocator_copy (this ->__alloc_ , __first, __last, __tx.__pos_ );
915+ __tx.__pos_ = std::__uninitialized_allocator_copy (this ->__alloc_ , std::move ( __first), std::move ( __last) , __tx.__pos_ );
910916}
911917
912918// Default constructs __n objects starting at __end_
@@ -1011,23 +1017,31 @@ vector<_Tp, _Allocator>::__assign_with_sentinel(_Iterator __first, _Sentinel __l
10111017}
10121018
10131019template <class _Tp , class _Allocator >
1014- template <class _ForwardIterator , class _Sentinel >
1020+ template <class _Iterator , class _Sentinel >
10151021_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void
1016- vector<_Tp, _Allocator>::__assign_with_size(_ForwardIterator __first, _Sentinel __last, difference_type __n) {
1022+ vector<_Tp, _Allocator>::__assign_with_size(_Iterator __first, _Sentinel __last, difference_type __n) {
10171023 size_type __new_size = static_cast <size_type>(__n);
10181024 if (__new_size <= capacity ()) {
10191025 if (__new_size > size ()) {
1020- _ForwardIterator __mid = std::next (__first, size ());
1021- std::copy (__first, __mid, this ->__begin_ );
1022- __construct_at_end (__mid, __last, __new_size - size ());
1026+ #if _LIBCPP_STD_VER >= 23
1027+ if constexpr (!forward_iterator<_Iterator>) {
1028+ auto __mid = ranges::copy_n (std::move (__first), size (), this ->__begin_ ).in ;
1029+ __construct_at_end (std::move (__mid), std::move (__last), __new_size - size ());
1030+ } else
1031+ #endif
1032+ {
1033+ _Iterator __mid = std::next (__first, size ());
1034+ std::copy (__first, __mid, this ->__begin_ );
1035+ __construct_at_end (__mid, __last, __new_size - size ());
1036+ }
10231037 } else {
1024- pointer __m = std::__copy (__first, __last, this ->__begin_ ).second ;
1038+ pointer __m = std::__copy (std::move ( __first) , __last, this ->__begin_ ).second ;
10251039 this ->__destruct_at_end (__m);
10261040 }
10271041 } else {
10281042 __vdeallocate ();
10291043 __vallocate (__recommend (__new_size));
1030- __construct_at_end (__first, __last, __new_size);
1044+ __construct_at_end (std::move ( __first), std::move ( __last) , __new_size);
10311045 }
10321046}
10331047
@@ -1277,28 +1291,40 @@ template <class _Iterator, class _Sentinel>
12771291_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI typename vector<_Tp, _Allocator>::iterator
12781292vector<_Tp, _Allocator>::__insert_with_size (
12791293 const_iterator __position, _Iterator __first, _Sentinel __last, difference_type __n) {
1280- auto __insertion_size = __n;
1281- pointer __p = this ->__begin_ + (__position - begin ());
1294+ pointer __p = this ->__begin_ + (__position - begin ());
12821295 if (__n > 0 ) {
12831296 if (__n <= this ->__cap_ - this ->__end_ ) {
1284- size_type __old_n = __n;
12851297 pointer __old_last = this ->__end_ ;
1286- _Iterator __m = std::next (__first, __n);
12871298 difference_type __dx = this ->__end_ - __p;
12881299 if (__n > __dx) {
1289- __m = __first;
1290- difference_type __diff = this ->__end_ - __p;
1291- std::advance (__m, __diff);
1292- __construct_at_end (__m, __last, __n - __diff);
1293- __n = __dx;
1294- }
1295- if (__n > 0 ) {
1296- __move_range (__p, __old_last, __p + __old_n);
1297- std::copy (__first, __m, __p);
1300+ #if _LIBCPP_STD_VER >= 23
1301+ if constexpr (!forward_iterator<_Iterator>) {
1302+ __construct_at_end (std::move (__first), std::move (__last), __n);
1303+ std::rotate (__p, __old_last, this ->__end_ );
1304+ } else
1305+ #endif
1306+ {
1307+ _Iterator __m = std::next (__first, __dx);
1308+ __construct_at_end (__m, __last, __n - __dx);
1309+ if (__dx > 0 ) {
1310+ __move_range (__p, __old_last, __p + __n);
1311+ std::copy (__first, __m, __p);
1312+ }
1313+ }
1314+ } else {
1315+ __move_range (__p, __old_last, __p + __n);
1316+ #if _LIBCPP_STD_VER >= 23
1317+ if constexpr (!forward_iterator<_Iterator>) {
1318+ ranges::copy_n (std::move (__first), __n, __p);
1319+ } else
1320+ #endif
1321+ {
1322+ std::copy_n (__first, __n, __p);
1323+ }
12981324 }
12991325 } else {
13001326 __split_buffer<value_type, allocator_type&> __v (__recommend (size () + __n), __p - this ->__begin_ , this ->__alloc_ );
1301- __v.__construct_at_end_with_size (__first, __insertion_size );
1327+ __v.__construct_at_end_with_size (std::move ( __first), __n );
13021328 __p = __swap_out_circular_buffer (__v, __p);
13031329 }
13041330 }
0 commit comments