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
@@ -916,7 +922,7 @@ template <class _InputIterator, class _Sentinel>
916922_LIBCPP_CONSTEXPR_SINCE_CXX20 void
917923vector<_Tp, _Allocator>::__construct_at_end(_InputIterator __first, _Sentinel __last, size_type __n) {
918924 _ConstructTransaction __tx (*this , __n);
919- __tx.__pos_ = std::__uninitialized_allocator_copy (__alloc (), __first, __last, __tx.__pos_ );
925+ __tx.__pos_ = std::__uninitialized_allocator_copy (__alloc (), std::move ( __first), std::move ( __last) , __tx.__pos_ );
920926}
921927
922928// Default constructs __n objects starting at __end_
@@ -1023,23 +1029,31 @@ vector<_Tp, _Allocator>::__assign_with_sentinel(_Iterator __first, _Sentinel __l
10231029}
10241030
10251031template <class _Tp , class _Allocator >
1026- template <class _ForwardIterator , class _Sentinel >
1032+ template <class _Iterator , class _Sentinel >
10271033_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void
1028- vector<_Tp, _Allocator>::__assign_with_size(_ForwardIterator __first, _Sentinel __last, difference_type __n) {
1034+ vector<_Tp, _Allocator>::__assign_with_size(_Iterator __first, _Sentinel __last, difference_type __n) {
10291035 size_type __new_size = static_cast <size_type>(__n);
10301036 if (__new_size <= capacity ()) {
10311037 if (__new_size > size ()) {
1032- _ForwardIterator __mid = std::next (__first, size ());
1033- std::copy (__first, __mid, this ->__begin_ );
1034- __construct_at_end (__mid, __last, __new_size - size ());
1038+ #if _LIBCPP_STD_VER >= 23
1039+ if constexpr (!forward_iterator<_Iterator>) {
1040+ auto __mid = ranges::copy_n (std::move (__first), size (), this ->__begin_ ).in ;
1041+ __construct_at_end (std::move (__mid), std::move (__last), __new_size - size ());
1042+ } else
1043+ #endif
1044+ {
1045+ _Iterator __mid = std::next (__first, size ());
1046+ std::copy (__first, __mid, this ->__begin_ );
1047+ __construct_at_end (__mid, __last, __new_size - size ());
1048+ }
10351049 } else {
1036- pointer __m = std::__copy (__first, __last, this ->__begin_ ).second ;
1050+ pointer __m = std::__copy (std::move ( __first) , __last, this ->__begin_ ).second ;
10371051 this ->__destruct_at_end (__m);
10381052 }
10391053 } else {
10401054 __vdeallocate ();
10411055 __vallocate (__recommend (__new_size));
1042- __construct_at_end (__first, __last, __new_size);
1056+ __construct_at_end (std::move ( __first), std::move ( __last) , __new_size);
10431057 }
10441058}
10451059
@@ -1297,29 +1311,41 @@ template <class _Iterator, class _Sentinel>
12971311_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI typename vector<_Tp, _Allocator>::iterator
12981312vector<_Tp, _Allocator>::__insert_with_size (
12991313 const_iterator __position, _Iterator __first, _Sentinel __last, difference_type __n) {
1300- auto __insertion_size = __n;
1301- pointer __p = this ->__begin_ + (__position - begin ());
1314+ pointer __p = this ->__begin_ + (__position - begin ());
13021315 if (__n > 0 ) {
13031316 if (__n <= this ->__end_cap () - this ->__end_ ) {
1304- size_type __old_n = __n;
13051317 pointer __old_last = this ->__end_ ;
1306- _Iterator __m = std::next (__first, __n);
13071318 difference_type __dx = this ->__end_ - __p;
13081319 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);
1320+ #if _LIBCPP_STD_VER >= 23
1321+ if constexpr (!forward_iterator<_Iterator>) {
1322+ __construct_at_end (std::move (__first), std::move (__last), __n);
1323+ std::rotate (__p, __old_last, this ->__end_ );
1324+ } else
1325+ #endif
1326+ {
1327+ _Iterator __m = std::next (__first, __dx);
1328+ __construct_at_end (__m, __last, __n - __dx);
1329+ if (__dx > 0 ) {
1330+ __move_range (__p, __old_last, __p + __n);
1331+ std::copy (__first, __m, __p);
1332+ }
1333+ }
1334+ } else {
1335+ __move_range (__p, __old_last, __p + __n);
1336+ #if _LIBCPP_STD_VER >= 23
1337+ if constexpr (!forward_iterator<_Iterator>) {
1338+ ranges::copy_n (std::move (__first), __n, __p);
1339+ } else
1340+ #endif
1341+ {
1342+ std::copy_n (__first, __n, __p);
1343+ }
13181344 }
13191345 } else {
13201346 allocator_type& __a = this ->__alloc ();
13211347 __split_buffer<value_type, allocator_type&> __v (__recommend (size () + __n), __p - this ->__begin_ , __a);
1322- __v.__construct_at_end_with_size (__first, __insertion_size );
1348+ __v.__construct_at_end_with_size (std::move ( __first), __n );
13231349 __p = __swap_out_circular_buffer (__v, __p);
13241350 }
13251351 }
0 commit comments