#include template class IteratorRange { public: IteratorRange(It b, It e) : begin_(b), end_(e), size_(std::distance(b, e)) {} It begin() const { return begin_; } It end() const { return end_; } size_t size() const { return size_; } private: It begin_, end_; size_t size_; }; template class Slicer { public: Slicer(It first_, It last_, const size_t size_of_page) { const size_t size = std::distance(first_, last_); for (size_t sz = size; sz > 0;) { size_t cur_page_size = std::min(size_of_page, sz); auto cur_page_end = std::next(first_, cur_page_size); pages_.push_back(IteratorRange(first_, cur_page_end)); sz -= cur_page_size; first_ = cur_page_end; } } auto begin() const { return pages_.begin(); } auto end() const { return pages_.end(); } size_t size() const { return pages_.size(); } private: std::vector> pages_; }; template auto Slice(C& c, size_t page_size) { return Slicer(c.begin(), c.end(), page_size); }