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>::sentinel {
private:
using Parent =
conditional_t<Const, const join_view, join_view>;
using Base = conditional_t<Const, const V, V>;
sentinel_t<Base> end_ = sentinel_t<Base>();
public:
sentinel() = default;
constexpr explicit sentinel(Parent& parent);
constexpr sentinel(sentinel<!Const> s)
requires Const && convertible_to<sentinel_t<V>, sentinel_t<Base>>;
friend constexpr bool operator==(const iterator<Const>& x, const sentinel& y);
};
}
constexpr explicit sentinel(Parent& parent);
Effects: Initializes
end_ with
ranges::end(parent.base_). constexpr sentinel(sentinel<!Const> s)
requires Const && convertible_to<sentinel_t<V>, sentinel_t<Base>>;
Effects: Initializes
end_ with
std::move(s.end_). friend constexpr bool operator==(const iterator<Const>& x, const sentinel& y);
Effects: Equivalent to: return x.outer_ == y.end_;