template class SlicerRange { private: Iterator begin_, end_; public: SlicerRange(Iterator b, Iterator e) : begin_(b), end_(e) {} Iterator begin() const { return begin_; } Iterator end() const { return end_; } size_t size() const { return distance(begin_, end_); } }; template class Slicer { private: size_t size_; vector> pages_; public: Slicer(Iterator b, Iterator e, size_t page_size) { auto d = distance(b, e); size_ = d / page_size + (d % page_size != 0 ? 1 : 0); for (int i = 0; i < size_; ++i) { auto b_it = next(b, page_size * i); auto e_it = (i == size_ - 1 ? e : next(b_it, page_size)); pages_.push_back({b_it, e_it}); } } size_t size() const { return size_; } auto begin() { return pages_.begin(); } auto end() { return pages_.end(); } }; template auto Slice(C& c, size_t page_size) { return Slicer(begin(c), end(c), page_size); }