Skip to content

Commit

Permalink
LWG-3851: chunk_view::inner-iterator missing custom iter_move and…
Browse files Browse the repository at this point in the history
… `iter_swap` (#3517)

Co-authored-by: Stephan T. Lavavej <[email protected]>
  • Loading branch information
JMazurkiewicz and StephanTLavavej authored Mar 4, 2023
1 parent 649128c commit 994f941
Show file tree
Hide file tree
Showing 4 changed files with 70 additions and 4 deletions.
16 changes: 16 additions & 0 deletions stl/inc/ranges
Original file line number Diff line number Diff line change
Expand Up @@ -6377,6 +6377,10 @@ namespace ranges {
return (_STD min)(_Parent->_Remainder, _RANGES end(_Parent->_Range) - *_Parent->_Current);
}

_NODISCARD constexpr const iterator_t<_Vw>& _Get_current() const noexcept {
return *_Parent->_Current;
}

public:
using iterator_concept = input_iterator_tag;
using difference_type = range_difference_t<_Vw>;
Expand Down Expand Up @@ -6443,6 +6447,18 @@ namespace ranges {
{
return -_Left._Get_size();
}

_NODISCARD_FRIEND constexpr range_rvalue_reference_t<_Vw> iter_move(const _Inner_iterator& _It) noexcept(
noexcept(_RANGES iter_move(_It._Get_current()))) {
return _RANGES iter_move(_It._Get_current());
}

friend constexpr void iter_swap(const _Inner_iterator& _Left, const _Inner_iterator& _Right) noexcept(
noexcept(_RANGES iter_swap(_Left._Get_current(), _Right._Get_current())))
requires indirectly_swappable<iterator_t<_Vw>>
{
_RANGES iter_swap(_Left._Get_current(), _Right._Get_current());
}
};

class _Outer_iterator {
Expand Down
2 changes: 1 addition & 1 deletion tests/std/tests/P2442R1_views_chunk/env.lst
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Copyright (c) Microsoft Corporation.
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception

RUNALL_INCLUDE ..\concepts_latest_matrix.lst
RUNALL_INCLUDE ..\strict_concepts_latest_matrix.lst
54 changes: 52 additions & 2 deletions tests/std/tests/P2442R1_views_chunk/test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
#include <forward_list>
#include <ranges>
#include <span>
#include <sstream>
#include <string>
#include <type_traits>
#include <utility>
#include <vector>
Expand Down Expand Up @@ -464,8 +466,9 @@ template <ranges::input_range Rng, class Expected>
constexpr bool test_input(Rng&& rng, Expected&& expected) {
using ranges::chunk_view, ranges::equal, ranges::iterator_t, ranges::sentinel_t;

using V = views::all_t<Rng>;
using R = chunk_view<V>;
using V = views::all_t<Rng>;
using BI = iterator_t<V>;
using R = chunk_view<V>;

same_as<R> auto r = chunk_view{forward<Rng>(rng), 2};
auto outer_iter = r.begin();
Expand All @@ -478,6 +481,19 @@ constexpr bool test_input(Rng&& rng, Expected&& expected) {

auto inner_iter = val_ty.begin();
same_as<default_sentinel_t> auto inner_sen = val_ty.end();

{ // Check iter_move (other tests are defined in 'test_lwg3851' function)
same_as<ranges::range_rvalue_reference_t<Rng>> decltype(auto) rval = iter_move(as_const(inner_iter));
assert(rval == expected[0][0]);
STATIC_ASSERT(noexcept(iter_move(inner_iter)) == noexcept(ranges::iter_move(declval<const BI&>())));
}

if constexpr (indirectly_swappable<BI>) { // Check iter_swap (other tests are defined in 'test_lwg3851' function)
STATIC_ASSERT(is_void_v<decltype(iter_swap(as_const(inner_iter), as_const(inner_iter)))>);
STATIC_ASSERT(noexcept(iter_swap(inner_iter, inner_iter))
== noexcept(ranges::iter_swap(declval<const BI&>(), declval<const BI&>())));
}

assert(inner_iter != inner_sen);
if constexpr (sized_sentinel_for<sentinel_t<Rng>, iterator_t<Rng>>) {
assert(inner_sen - inner_iter == 2);
Expand Down Expand Up @@ -579,6 +595,38 @@ using move_only_view = test::range<Category, const int, test::Sized{is_random},
IsCommon, test::CanCompare{derived_from<Category, forward_iterator_tag>},
test::ProxyRef{!derived_from<Category, contiguous_iterator_tag>}, test::CanView::yes, test::Copyability::move_only>;

// Check LWG-3851: 'chunk_view::inner-iterator missing custom iter_move and iter_swap'
void test_lwg3851() {
{ // Check 'iter_move'
istringstream ints{"0 1 2 3 4"};
auto v = views::istream<int>(ints) | views::chunk(2);
auto o = v.begin();
auto c = *o;
auto i = c.begin();

same_as<int&&> decltype(auto) rval = iter_move(i);
assert(rval == 0);
}

{ // Check 'iter_swap'
istringstream ints1{"0 1 2 3 4"};
auto v1 = views::istream<int>(ints1) | views::chunk(2);
auto o1 = v1.begin();
auto c1 = *o1;
auto i1 = c1.begin();

istringstream ints2{"5 6 7 8 9"};
auto v2 = views::istream<int>(ints2) | views::chunk(2);
auto o2 = v2.begin();
auto c2 = *o2;
auto i2 = c2.begin();

iter_swap(as_const(i1), as_const(i2));
assert(*i1 == 5);
assert(*i2 == 0);
}
}

int main() {
{ // Validate views
// ... copyable
Expand Down Expand Up @@ -617,4 +665,6 @@ int main() {

STATIC_ASSERT((instantiation_test(), true));
instantiation_test();

test_lwg3851();
}
2 changes: 1 addition & 1 deletion tests/std/tests/P2442R1_views_chunk_death/env.lst
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Copyright (c) Microsoft Corporation.
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception

RUNALL_INCLUDE ..\concepts_latest_matrix.lst
RUNALL_INCLUDE ..\strict_concepts_latest_matrix.lst

0 comments on commit 994f941

Please sign in to comment.