aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJonathan Wakely <jwakely@redhat.com>2024-10-13 22:48:43 +0100
committerJonathan Wakely <redi@gcc.gnu.org>2024-10-14 10:55:50 +0100
commit03623fa91ff36ecb9faa3b55f7842a39b759594e (patch)
tree061355f4468d8f7ed2337a42c4f81ae87e12a7f6
parentd8ef4471cb9c9f86784b62424a215ea42173bfe1 (diff)
downloadgcc-03623fa91ff36ecb9faa3b55f7842a39b759594e.zip
gcc-03623fa91ff36ecb9faa3b55f7842a39b759594e.tar.gz
gcc-03623fa91ff36ecb9faa3b55f7842a39b759594e.tar.bz2
libstdc++: Use std::move for iterator in ranges::fill [PR117094]
Input iterators aren't required to be copyable. libstdc++-v3/ChangeLog: PR libstdc++/117094 * include/bits/ranges_algobase.h (__fill_fn): Use std::move for iterator that might not be copyable. * testsuite/25_algorithms/fill/constrained.cc: Check non-copyable iterator with sized sentinel.
-rw-r--r--libstdc++-v3/include/bits/ranges_algobase.h2
-rw-r--r--libstdc++-v3/testsuite/25_algorithms/fill/constrained.cc34
2 files changed, 35 insertions, 1 deletions
diff --git a/libstdc++-v3/include/bits/ranges_algobase.h b/libstdc++-v3/include/bits/ranges_algobase.h
index 3c8d461..0345ea8 100644
--- a/libstdc++-v3/include/bits/ranges_algobase.h
+++ b/libstdc++-v3/include/bits/ranges_algobase.h
@@ -592,7 +592,7 @@ namespace ranges
if constexpr (sized_sentinel_for<_Sent, _Out>)
{
const auto __len = __last - __first;
- return ranges::fill_n(__first, __len, __value);
+ return ranges::fill_n(std::move(__first), __len, __value);
}
else if constexpr (is_scalar_v<_Tp>)
{
diff --git a/libstdc++-v3/testsuite/25_algorithms/fill/constrained.cc b/libstdc++-v3/testsuite/25_algorithms/fill/constrained.cc
index 126515e..7cae99f 100644
--- a/libstdc++-v3/testsuite/25_algorithms/fill/constrained.cc
+++ b/libstdc++-v3/testsuite/25_algorithms/fill/constrained.cc
@@ -83,9 +83,43 @@ test02()
return ok;
}
+void
+test03()
+{
+ // Bug libstdc++/117094 - ranges::fill misses std::move for output_iterator
+
+ // Move-only output iterator
+ struct Iterator
+ {
+ using difference_type = long;
+ Iterator(int* p) : p(p) { }
+ Iterator(Iterator&&) = default;
+ Iterator& operator=(Iterator&&) = default;
+ int& operator*() const { return *p; }
+ Iterator& operator++() { ++p; return *this; }
+ Iterator operator++(int) { return Iterator(p++ ); }
+ int* p;
+
+ struct Sentinel
+ {
+ const int* p;
+ bool operator==(const Iterator& i) const { return p == i.p; }
+ long operator-(const Iterator& i) const { return p - i.p; }
+ };
+
+ long operator-(Sentinel s) const { return p - s.p; }
+ };
+ static_assert(std::sized_sentinel_for<Iterator::Sentinel, Iterator>);
+ int a[2];
+ std::ranges::fill(Iterator(a), Iterator::Sentinel{a+2}, 999);
+ VERIFY( a[0] == 999 );
+ VERIFY( a[1] == 999 );
+}
+
int
main()
{
test01();
static_assert(test02());
+ test03();
}