From 4c862ee11ce956556b810a813e77b0f8f97fb642 Mon Sep 17 00:00:00 2001 From: Casey Carter Date: Fri, 4 Jun 2021 09:56:26 -0700 Subject: [PATCH] : fix GH-1932 (#1933) * : fix GH-1932 ... by extracting the constant expression we'd like to short-circuit into a concept. Fixes #1932. --- stl/inc/algorithm | 7 +++++-- .../tests/P0896R4_ranges_alg_unique_copy/test.cpp | 13 +++++++++++++ 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/stl/inc/algorithm b/stl/inc/algorithm index 75a4b7df91..9fcee8193a 100644 --- a/stl/inc/algorithm +++ b/stl/inc/algorithm @@ -4072,9 +4072,12 @@ namespace ranges { // VARIABLE ranges::unique_copy // clang-format off + template + concept _Is_input_with_value_type = input_iterator<_It> && same_as, _Ty>; + template concept _Can_reread_or_store = forward_iterator<_It> - || (input_iterator<_Out> && same_as, iter_value_t<_Out>>) + || _Is_input_with_value_type<_Out, iter_value_t<_It>> || indirectly_copyable_storable<_It, _Out>; // clang-format on class _Unique_copy_fn : private _Not_quite_object { @@ -4127,7 +4130,7 @@ namespace ranges { return {_STD move(_First), _STD move(_Result)}; } - if constexpr (input_iterator<_Out> && same_as, iter_value_t<_Out>>) { + if constexpr (_Is_input_with_value_type<_Out, iter_value_t<_It>>) { // Can reread _Result *_Result = *_First; diff --git a/tests/std/tests/P0896R4_ranges_alg_unique_copy/test.cpp b/tests/std/tests/P0896R4_ranges_alg_unique_copy/test.cpp index 71407f8979..239a1ab353 100644 --- a/tests/std/tests/P0896R4_ranges_alg_unique_copy/test.cpp +++ b/tests/std/tests/P0896R4_ranges_alg_unique_copy/test.cpp @@ -5,6 +5,7 @@ #include #include #include +#include #include #include @@ -142,8 +143,20 @@ constexpr bool run_tests() { return true; } +void test_gh1932() { + // Defend against regression of GH-1932, in which ranges::unique_copy instantiated + // iter_value_t for a non-input iterator I. + + istringstream str("42 42 42"); + ostringstream result; + ranges::unique_copy(istream_iterator{str}, istream_iterator{}, ostream_iterator{result, " "}); + assert(result.str() == "42 "); +} + int main() { STATIC_ASSERT(run_tests()); run_tests(); + + test_gh1932(); } #endif // TEST_EVERYTHING