#pragma once
#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 bgn, It end, const size_t p_sz) {
const size_t sz = std::distance(bgn, end);
for (size_t i = sz; i > 0;) {
size_t temp = min(p_sz, i);
auto last = std::next(bgn, temp);
pages_.push_back(IteratorRange<It>(bgn, last));
i -= temp;
bgn = last;
}
}
auto begin() const { 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 sz) {
return Slicer(c.begin(), c.end(), sz);
}