Skip to content

Commit 4c862ee

Browse files
authored
<algorithm>: fix GH-1932 (#1933)
* <algorithm>: fix GH-1932 ... by extracting the constant expression we'd like to short-circuit into a concept. Fixes #1932.
1 parent 20288f9 commit 4c862ee

File tree

2 files changed

+18
-2
lines changed

2 files changed

+18
-2
lines changed

stl/inc/algorithm

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4072,9 +4072,12 @@ namespace ranges {
40724072

40734073
// VARIABLE ranges::unique_copy
40744074
// clang-format off
4075+
template <class _It, class _Ty>
4076+
concept _Is_input_with_value_type = input_iterator<_It> && same_as<iter_value_t<_It>, _Ty>;
4077+
40754078
template <class _It, class _Out>
40764079
concept _Can_reread_or_store = forward_iterator<_It>
4077-
|| (input_iterator<_Out> && same_as<iter_value_t<_It>, iter_value_t<_Out>>)
4080+
|| _Is_input_with_value_type<_Out, iter_value_t<_It>>
40784081
|| indirectly_copyable_storable<_It, _Out>;
40794082
// clang-format on
40804083
class _Unique_copy_fn : private _Not_quite_object {
@@ -4127,7 +4130,7 @@ namespace ranges {
41274130
return {_STD move(_First), _STD move(_Result)};
41284131
}
41294132

4130-
if constexpr (input_iterator<_Out> && same_as<iter_value_t<_It>, iter_value_t<_Out>>) {
4133+
if constexpr (_Is_input_with_value_type<_Out, iter_value_t<_It>>) {
41314134
// Can reread _Result
41324135
*_Result = *_First;
41334136

tests/std/tests/P0896R4_ranges_alg_unique_copy/test.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
#include <cassert>
66
#include <concepts>
77
#include <ranges>
8+
#include <sstream>
89
#include <utility>
910

1011
#include <range_algorithm_support.hpp>
@@ -142,8 +143,20 @@ constexpr bool run_tests() {
142143
return true;
143144
}
144145

146+
void test_gh1932() {
147+
// Defend against regression of GH-1932, in which ranges::unique_copy instantiated
148+
// iter_value_t<I> for a non-input iterator I.
149+
150+
istringstream str("42 42 42");
151+
ostringstream result;
152+
ranges::unique_copy(istream_iterator<int>{str}, istream_iterator<int>{}, ostream_iterator<int>{result, " "});
153+
assert(result.str() == "42 ");
154+
}
155+
145156
int main() {
146157
STATIC_ASSERT(run_tests());
147158
run_tests();
159+
160+
test_gh1932();
148161
}
149162
#endif // TEST_EVERYTHING

0 commit comments

Comments
 (0)