diff --git a/stl/inc/algorithm b/stl/inc/algorithm index 29d6bcbefe4..e93ad656a40 100644 --- a/stl/inc/algorithm +++ b/stl/inc/algorithm @@ -4460,6 +4460,7 @@ namespace ranges { for (;; ++_Current) { if (++_First == _Last) { + ++_Current; return {_STD move(_Current), _STD move(_First)}; } diff --git a/tests/std/tests/P0896R4_ranges_alg_unique/test.cpp b/tests/std/tests/P0896R4_ranges_alg_unique/test.cpp index 8e1ab7324c0..b214962d7b6 100644 --- a/tests/std/tests/P0896R4_ranges_alg_unique/test.cpp +++ b/tests/std/tests/P0896R4_ranges_alg_unique/test.cpp @@ -45,6 +45,15 @@ struct instantiator { assert(comparisonCounter == size(input) - 1); } + { // Validate already unique range returns empty subrange + P input[4] = {{0, 99}, {1, 47}, {3, 99}, {4, 47}}; + ReadWrite wrapped_input{input}; + + auto result = unique(wrapped_input.begin(), wrapped_input.end(), countedEq, get_second); + STATIC_ASSERT(same_as>>); + assert(result.empty()); + } + comparisonCounter = 0; { // Validate range overload @@ -58,6 +67,15 @@ struct instantiator { assert(equal(expected, span{input}.first<4>())); assert(comparisonCounter == size(input) - 1); } + + { // Validate already unique range returns empty subrange + P input[4] = {{0, 99}, {1, 47}, {3, 99}, {4, 47}}; + ReadWrite wrapped_input{input}; + + auto result = unique(wrapped_input, countedEq, get_second); + STATIC_ASSERT(same_as>>); + assert(result.empty()); + } } }; 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 71e6a268aee..71407f89798 100644 --- a/tests/std/tests/P0896R4_ranges_alg_unique_copy/test.cpp +++ b/tests/std/tests/P0896R4_ranges_alg_unique_copy/test.cpp @@ -34,21 +34,34 @@ struct test_iterator_overload { static constexpr void call() { using ranges::unique_copy, ranges::unique_copy_result, ranges::equal, ranges::equal_to, ranges::iterator_t, ranges::size; - // Validate iterator + sentinel overload - P input[6] = {{0, 99}, {0, 47}, {0, 47}, {0, 99}, {0, 47}, {0, 47}}; - P output[4] = {{-1, -1}, {-1, -1}, {-1, -1}, {-1, -1}}; - Read wrapped_input{input}; - - const same_as, Write>> auto result = - unique_copy(wrapped_input.begin(), wrapped_input.end(), Write{output}, equal_to{}, countedProjection); - assert(result.in == wrapped_input.end()); - assert(result.out.peek() == end(output)); - if constexpr (input_iterator || !ranges::forward_range) { - assert(equal(output, expectedOutputRead)); - assert(equal(input, expectedInputRead)); - } else { - assert(equal(output, expectedOutput)); - assert(equal(input, expectedInput)); + { // Validate iterator + sentinel overload + P input[6] = {{0, 99}, {0, 47}, {0, 47}, {0, 99}, {0, 47}, {0, 47}}; + P output[4] = {{-1, -1}, {-1, -1}, {-1, -1}, {-1, -1}}; + Read wrapped_input{input}; + + const same_as, Write>> auto result = + unique_copy(wrapped_input.begin(), wrapped_input.end(), Write{output}, equal_to{}, countedProjection); + assert(result.in == wrapped_input.end()); + assert(result.out.peek() == end(output)); + if constexpr (input_iterator || !ranges::forward_range) { + assert(equal(output, expectedOutputRead)); + assert(equal(input, expectedInputRead)); + } else { + assert(equal(output, expectedOutput)); + assert(equal(input, expectedInput)); + } + } + + { // Validate already unique range + P input[4] = {{0, 99}, {0, 47}, {0, 99}, {0, 47}}; + P output[4] = {{-1, -1}, {-1, -1}, {-1, -1}, {-1, -1}}; + Read wrapped_input{input}; + + const same_as, Write>> auto result = + unique_copy(wrapped_input.begin(), wrapped_input.end(), Write{output}, equal_to{}); + assert(result.in == wrapped_input.end()); + assert(result.out.peek() == end(output)); + assert(equal(output, input)); } } }; @@ -58,21 +71,34 @@ struct test_range_overload { static constexpr void call() { using ranges::unique_copy, ranges::unique_copy_result, ranges::equal, ranges::equal_to, ranges::iterator_t, ranges::size; - // Validate range overload - P input[6] = {{0, 99}, {0, 47}, {0, 47}, {0, 99}, {0, 47}, {0, 47}}; - P output[4] = {{-1, -1}, {-1, -1}, {-1, -1}, {-1, -1}}; - Read wrapped_input{input}; - - const same_as, Write>> auto result = - unique_copy(wrapped_input, Write{output}, equal_to{}, countedProjection); - assert(result.in == wrapped_input.end()); - assert(result.out.peek() == end(output)); - if constexpr (input_iterator || !ranges::forward_range) { - assert(equal(output, expectedOutputRead)); - assert(equal(input, expectedInputRead)); - } else { - assert(equal(output, expectedOutput)); - assert(equal(input, expectedInput)); + { // Validate range overload + P input[6] = {{0, 99}, {0, 47}, {0, 47}, {0, 99}, {0, 47}, {0, 47}}; + P output[4] = {{-1, -1}, {-1, -1}, {-1, -1}, {-1, -1}}; + Read wrapped_input{input}; + + const same_as, Write>> auto result = + unique_copy(wrapped_input, Write{output}, equal_to{}, countedProjection); + assert(result.in == wrapped_input.end()); + assert(result.out.peek() == end(output)); + if constexpr (input_iterator || !ranges::forward_range) { + assert(equal(output, expectedOutputRead)); + assert(equal(input, expectedInputRead)); + } else { + assert(equal(output, expectedOutput)); + assert(equal(input, expectedInput)); + } + } + + { // Validate already unique range + P input[4] = {{0, 99}, {0, 47}, {0, 99}, {0, 47}}; + P output[4] = {{-1, -1}, {-1, -1}, {-1, -1}, {-1, -1}}; + Read wrapped_input{input}; + + const same_as, Write>> auto result = + unique_copy(wrapped_input, Write{output}, equal_to{}); + assert(result.in == wrapped_input.end()); + assert(result.out.peek() == end(output)); + assert(equal(output, input)); } } };