Limits of std::views::take/drop for paginating non‑random‑access ranges
0 reputation · 22 Sept 2024, 04:00 UTC
Goal
In a C++20 application, we wish to expose a paginated view of a large collection by applying std::views::drop(offset) | std::views::take(page_size) to the underlying range.
Constraints
The underlying range may be a std::vector (random‑access, sized) or a std::forward_list or an istream_view (forward‑only). In the latter case, each drop must walk the range from its beginning, making pagination potentially quadratic in the number of pages. Additionally, an offset near SIZE_MAX combined with a non‑zero page_size can overflow size_t, producing an empty or incorrect page. Finally, once a view has been consumed, its iterators cannot be reused because views are lazy and non‑owning.
Unresolved Questions
- For non‑random‑access, sized ranges, is there a documented way to avoid re‑traversing the source on each
dropwithout materializing the entire collection? - Does the standard guarantee that
offset + page_sizewill be checked for overflow when constructing astd::ranges::subrangeor when applyingtake? - When a page view is exhausted, can it be safely re‑iterated by reapplying the same
drop/takepipeline, or must a fresh source range be created?