[libcxx-commits] [libcxx] [libc++] Fix input-only range handling for `vector` (PR #116157)
Louis Dionne via libcxx-commits
libcxx-commits at lists.llvm.org
Thu Nov 28 13:16:56 PST 2024
================
@@ -1011,23 +1017,31 @@ vector<_Tp, _Allocator>::__assign_with_sentinel(_Iterator __first, _Sentinel __l
}
template <class _Tp, class _Allocator>
-template <class _ForwardIterator, class _Sentinel>
+template <class _Iterator, class _Sentinel>
_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void
-vector<_Tp, _Allocator>::__assign_with_size(_ForwardIterator __first, _Sentinel __last, difference_type __n) {
+vector<_Tp, _Allocator>::__assign_with_size(_Iterator __first, _Sentinel __last, difference_type __n) {
size_type __new_size = static_cast<size_type>(__n);
if (__new_size <= capacity()) {
if (__new_size > size()) {
- _ForwardIterator __mid = std::next(__first, size());
- std::copy(__first, __mid, this->__begin_);
- __construct_at_end(__mid, __last, __new_size - size());
+#if _LIBCPP_STD_VER >= 23
+ if constexpr (!forward_iterator<_Iterator>) {
+ auto __mid = ranges::copy_n(std::move(__first), size(), this->__begin_).in;
+ __construct_at_end(std::move(__mid), std::move(__last), __new_size - size());
+ } else
----------------
ldionne wrote:
This trailing `else` is really confusing IMO! I think you can do this instead:
```c++
#if _LIBCPP_STD_VER >= 23
if constexpr (!forward_iterator<_Iterator>) {
auto __mid = ranges::copy_n(std::move(__first), size(), this->__begin_).in;
__construct_at_end(std::move(__mid), std::move(__last), __new_size - size());
return;
}
#endif
// not under any else
_Iterator __mid = std::next(__first, size());
std::copy(__first, __mid, this->__begin_);
__construct_at_end(__mid, __last, __new_size - size());
```
Actually, is there a reason why we don't do this instead?
```c++
#if _LIBCPP_STD_VER >= 23
auto __mid = ranges::copy_n(std::move(__first), size(), this->__begin_).in;
__construct_at_end(std::move(__mid), std::move(__last), __new_size - size());
#else
_Iterator __mid = std::next(__first, size());
std::copy(__first, __mid, this->__begin_);
__construct_at_end(__mid, __last, __new_size - size());
#endif
```
IOW, I don't see why we can't use `ranges::copy_n` regardless of the iterator category in C++23.
https://github.com/llvm/llvm-project/pull/116157
More information about the libcxx-commits
mailing list