Created on 2023-11-05.00:00:00 last changed 3 weeks ago
Proposed resolution:
This wording is relative to N4964.
Modify [range.chunk.outer.value] as indicated:
[…]namespace std::ranges { template<view V> requires input_range<V> struct chunk_view<V>::outer-iterator::value_type : view_interface<value_type> { private: chunk_view* parent_; // exposition only constexpr explicit value_type(chunk_view& parent); // exposition only public: constexpr inner-iterator begin() const noexcept; constexpr default_sentinel_t end() const noexcept; constexpr bool empty() const noexcept; constexpr auto size() const requires sized_sentinel_for<sentinel_t<V>, iterator_t<V>>; }; }constexpr default_sentinel_t end() const noexcept;-3- Returns: default_sentinel.
constexpr bool empty() const noexcept;-?- Effects: Equivalent to: return parent_->remainder_ == 0;
chunk_view::outer-iterator::value_type can determine whether it is empty by simply checking whether the chunk_view's remainder_ is 0, which makes it valuable to explicitly provide a noexcept empty member.
Otherwise, the view_interface::empty is synthesized only through the size member when the original sentinel and iterator type model sized_sentinel_for, which seems overkill:#include <cassert> #include <iostream> #include <sstream> #include <ranges> int main() { auto ints = std::istringstream{"1 2 3 4 5 6 7 8 9 10"}; for (auto chunk : std::views::istream<int>(ints) | std::views::chunk(3)) { for (auto elem : chunk) { assert(!chunk.empty()); // no matching function for call to 'empty()' std::cout << elem << " "; } assert(chunk.empty()); // ditto std::cout << "\n"; } }
History | |||
---|---|---|---|
Date | User | Action | Args |
2023-11-05 10:47:39 | admin | set | messages: + msg13819 |
2023-11-05 00:00:00 | admin | create |