#include <vector>
template <typename It>
class IteratorRange {
public:
IteratorRange<It>(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 <typename It>
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<It>(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<IteratorRange<It>> pages_;
};
template <typename C>
auto Slice(C& c, size_t page_size) {
return Slicer(c.begin(), c.end(), page_size);
}