#pragma once
#include <vector>
template<class It>
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 It>
class Slicer {
public:
Slicer(It begin_, It end_, size_t page_size) {
for (auto it = begin_; it != end_; it = std::next(it, min_check(it, end_, page_size))) {
pages_.push_back(IteratorRange<It>(it, std::next(it, min_check(it, end_, page_size))));
}
}
Slicer() = default;
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_;
auto min_check(It iter, It end_, size_t page_size){
return std::min<size_t>(std::distance(iter, end_), page_size);
}
};
template <typename C>
auto Slice(C & c, size_t page_size) {
return Slicer(c.begin(), c.end(), page_size);
}