[ 2021-06-23; Reflector poll ]
Set priority to 3 after reflector poll.
Previous resolution [SUPERSEDED]:
Wording relative to the post 2021-06 virtual plenary working draft. This PR is currently being implemented in MSVC.
Modify [range.join.iterator] as indicated:
[…]namespace std::ranges { template<input_range V> requires view<V> && input_range<range_reference_t<V>> && (is_reference_v<range_reference_t<V>> || view<range_value_t<V>>) template<bool Const> struct join_view<V>::iterator { […] optional<InnerIter> inner_= InnerIter(); […] constexpr decltype(auto) operator*() const { return **inner_; } […] friend constexpr decltype(auto) iter_move(const iterator& i) noexcept(noexcept(ranges::iter_move(*i.inner_))) { return ranges::iter_move(*i.inner_); } friend constexpr void iter_swap(const iterator& x, const iterator& y) noexcept(noexcept(ranges::iter_swap(*x.inner_, *y.inner_))) requires indirectly_swappable<InnerIter>; }; }constexpr void satisfy(); // exposition only[…]-5- Effects: Equivalent to:
auto update_inner = [this](const iterator_t<Base>& x) -> auto&& { […] }; for (; outer_ != ranges::end(parent_->base_); ++outer_) { auto&& inner = update_inner(*outer_); inner_ = ranges::begin(inner); if (*inner_ != ranges::end(inner)) return; } if constexpr (ref-is-glvalue) inner_.reset()= InnerIter();constexpr InnerIter operator->() const requires has-arrow<InnerIter> && copyable<InnerIter>;-8- Effects: Equivalent to: return *inner_;
constexpr iterator& operator++();[…]-9- Let inner-range be:
[…]
-10- Effects: Equivalent to:
auto&& inner_rng = inner-range; if (++*inner_ == ranges::end(inner_rng)) { ++outer_; satisfy(); } return *this;constexpr iterator& operator--() requires ref-is-glvalue && bidirectional_range<Base> && bidirectional_range<range_reference_t<Base>> && common_range<range_reference_t<Base>>;[…]-13- Effects: Equivalent to:
if (outer_ == ranges::end(parent_->base_)) inner_ = ranges::end(*--outer_); while (*inner_ == ranges::begin(*outer_)) *inner_ = ranges::end(*--outer_); --*inner_; return *this;friend constexpr void iter_swap(const iterator& x, const iterator& y) noexcept(noexcept(ranges::iter_swap(*x.inner_, *y.inner_))) requires indirectly_swappable<InnerIter>;-16- Effects: Equivalent to: return ranges::iter_swap(*x.inner_, *y.inner_);