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>
@@ -570,7 +573,7 @@ class _LIBCPP_TEMPLATE_VIS vector {
570
573
571
574
if (__n > 0 ) {
572
575
__vallocate (__n);
573
- __construct_at_end (__first, __last, __n);
576
+ __construct_at_end (std::move ( __first), std::move ( __last) , __n);
574
577
}
575
578
576
579
__guard.__complete ();
@@ -590,9 +593,31 @@ class _LIBCPP_TEMPLATE_VIS vector {
590
593
template <class _Iterator , class _Sentinel >
591
594
_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __assign_with_sentinel (_Iterator __first, _Sentinel __last);
592
595
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 >
600
+ _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void
601
+ __assign_with_size (_Iterator __first, _Sentinel __last, difference_type __n);
602
+
603
+ template <class _Iterator ,
604
+ __enable_if_t <!is_same<decltype (*std::declval<_Iterator&>())&&, value_type&&>::value, int > = 0 >
605
+ _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void
606
+ __insert_assign_n_unchecked (_Iterator __first, difference_type __n, pointer __position) {
607
+ for (pointer __end_position = __position + __n; __position != __end_position; (void )++__position, ++__first) {
608
+ __temp_value<value_type, _Allocator> __tmp (this ->__alloc (), *__first);
609
+ *__position = std::move (__tmp.get ());
610
+ }
611
+ }
612
+
613
+ template <class _Iterator ,
614
+ __enable_if_t <is_same<decltype (*std::declval<_Iterator&>())&&, value_type&&>::value, int > = 0 >
594
615
_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void
595
- __assign_with_size (_ForwardIterator __first, _Sentinel __last, difference_type __n);
616
+ __insert_assign_n_unchecked (_Iterator __first, difference_type __n, pointer __position) {
617
+ for (pointer __end_position = __position + __n; __position != __end_position; (void )++__position, ++__first) {
618
+ *__position = *__first;
619
+ }
620
+ }
596
621
597
622
template <class _InputIterator , class _Sentinel >
598
623
_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI iterator
@@ -916,7 +941,7 @@ template <class _InputIterator, class _Sentinel>
916
941
_LIBCPP_CONSTEXPR_SINCE_CXX20 void
917
942
vector<_Tp, _Allocator>::__construct_at_end(_InputIterator __first, _Sentinel __last, size_type __n) {
918
943
_ConstructTransaction __tx (*this , __n);
919
- __tx.__pos_ = std::__uninitialized_allocator_copy (__alloc (), __first, __last, __tx.__pos_ );
944
+ __tx.__pos_ = std::__uninitialized_allocator_copy (__alloc (), std::move ( __first), std::move ( __last) , __tx.__pos_ );
920
945
}
921
946
922
947
// Default constructs __n objects starting at __end_
@@ -1023,23 +1048,31 @@ vector<_Tp, _Allocator>::__assign_with_sentinel(_Iterator __first, _Sentinel __l
1023
1048
}
1024
1049
1025
1050
template <class _Tp , class _Allocator >
1026
- template <class _ForwardIterator , class _Sentinel >
1051
+ template <class _Iterator , class _Sentinel >
1027
1052
_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void
1028
- vector<_Tp, _Allocator>::__assign_with_size(_ForwardIterator __first, _Sentinel __last, difference_type __n) {
1053
+ vector<_Tp, _Allocator>::__assign_with_size(_Iterator __first, _Sentinel __last, difference_type __n) {
1029
1054
size_type __new_size = static_cast <size_type>(__n);
1030
1055
if (__new_size <= capacity ()) {
1031
1056
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 ());
1057
+ #if _LIBCPP_STD_VER >= 23
1058
+ if constexpr (!forward_iterator<_Iterator>) {
1059
+ auto __mid = ranges::copy_n (std::move (__first), size (), this ->__begin_ ).in ;
1060
+ __construct_at_end (std::move (__mid), std::move (__last), __new_size - size ());
1061
+ } else
1062
+ #endif
1063
+ {
1064
+ _Iterator __mid = std::next (__first, size ());
1065
+ std::copy (__first, __mid, this ->__begin_ );
1066
+ __construct_at_end (__mid, __last, __new_size - size ());
1067
+ }
1035
1068
} else {
1036
- pointer __m = std::__copy (__first, __last, this ->__begin_ ).second ;
1069
+ pointer __m = std::__copy (std::move ( __first) , __last, this ->__begin_ ).second ;
1037
1070
this ->__destruct_at_end (__m);
1038
1071
}
1039
1072
} else {
1040
1073
__vdeallocate ();
1041
1074
__vallocate (__recommend (__new_size));
1042
- __construct_at_end (__first, __last, __new_size);
1075
+ __construct_at_end (std::move ( __first), std::move ( __last) , __new_size);
1043
1076
}
1044
1077
}
1045
1078
@@ -1297,29 +1330,34 @@ template <class _Iterator, class _Sentinel>
1297
1330
_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI typename vector<_Tp, _Allocator>::iterator
1298
1331
vector<_Tp, _Allocator>::__insert_with_size (
1299
1332
const_iterator __position, _Iterator __first, _Sentinel __last, difference_type __n) {
1300
- auto __insertion_size = __n;
1301
- pointer __p = this ->__begin_ + (__position - begin ());
1333
+ pointer __p = this ->__begin_ + (__position - begin ());
1302
1334
if (__n > 0 ) {
1303
1335
if (__n <= this ->__end_cap () - this ->__end_ ) {
1304
- size_type __old_n = __n;
1305
1336
pointer __old_last = this ->__end_ ;
1306
- _Iterator __m = std::next (__first, __n);
1307
1337
difference_type __dx = this ->__end_ - __p;
1308
1338
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);
1339
+ #if _LIBCPP_STD_VER >= 23
1340
+ if constexpr (!forward_iterator<_Iterator>) {
1341
+ __construct_at_end (std::move (__first), std::move (__last), __n);
1342
+ std::rotate (__p, __old_last, this ->__end_ );
1343
+ } else
1344
+ #endif
1345
+ {
1346
+ _Iterator __m = std::next (__first, __dx);
1347
+ __construct_at_end (__m, __last, __n - __dx);
1348
+ if (__dx > 0 ) {
1349
+ __move_range (__p, __old_last, __p + __n);
1350
+ __insert_assign_n_unchecked (__first, __dx, __p);
1351
+ }
1352
+ }
1353
+ } else {
1354
+ __move_range (__p, __old_last, __p + __n);
1355
+ __insert_assign_n_unchecked (std::move (__first), __n, __p);
1318
1356
}
1319
1357
} else {
1320
1358
allocator_type& __a = this ->__alloc ();
1321
1359
__split_buffer<value_type, allocator_type&> __v (__recommend (size () + __n), __p - this ->__begin_ , __a);
1322
- __v.__construct_at_end_with_size (__first, __insertion_size );
1360
+ __v.__construct_at_end_with_size (std::move ( __first), __n );
1323
1361
__p = __swap_out_circular_buffer (__v, __p);
1324
1362
}
1325
1363
}
0 commit comments