#include <iostream>
#include <iterator>
#include <algorithm>
#include <vector>
#include <queue>
#include <cassert>
template<typename Iterator, typename Operation>
void iterate_ranges (Iterator from, Iterator to, Operation op) {
using R = typename std::iterator_traits<Iterator>::value_type;
using N = typename std::decay<decltype(std::declval<R>().first)>::type;
using P = std::pair<N, R>;
auto compare = [](P const & left, P const & right) {
return left.first > right.first;};
std::priority_queue<P, std::vector<P>, decltype(compare)> queue(compare);
auto push = [& queue] (P p) {
if (p.first < p.second.last) queue.push(p); };
auto next = [](P const & p) -> P {
assert(p.second.step > 0);
return {p.first + p.second.step, p.second}; };
auto init = [&push] (R const & r) {
push({r.first, r}); };
std::for_each(from, to, init);
if (queue.empty()) return;
N last = queue.top().first;
push(next(queue.top()));
queue.pop();
op(last);
while (! queue.empty()) {
P current = queue.top();
queue.pop();
if (current.first != last) {
op(current.first);
last = current.first;
}
push(next(current));
}
}
struct Range {
int first;
int last;
int step;
};
int main() {
Range ranges [] = {
{1, 10, 2},
{2, 50, 5}};
auto print = [](auto n) { std::cout << n << std::endl; };
iterate_ranges(std::begin(ranges), std::end(ranges), print);
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8aXRlcmF0b3I+CiNpbmNsdWRlIDxhbGdvcml0aG0+CiNpbmNsdWRlIDx2ZWN0b3I+CiNpbmNsdWRlIDxxdWV1ZT4KI2luY2x1ZGUgPGNhc3NlcnQ+CgoKdGVtcGxhdGU8dHlwZW5hbWUgSXRlcmF0b3IsIHR5cGVuYW1lIE9wZXJhdGlvbj4Kdm9pZCBpdGVyYXRlX3JhbmdlcyAoSXRlcmF0b3IgZnJvbSwgSXRlcmF0b3IgdG8sIE9wZXJhdGlvbiBvcCkgewogIHVzaW5nIFIgPSB0eXBlbmFtZSBzdGQ6Oml0ZXJhdG9yX3RyYWl0czxJdGVyYXRvcj46OnZhbHVlX3R5cGU7CiAgdXNpbmcgTiA9IHR5cGVuYW1lIHN0ZDo6ZGVjYXk8ZGVjbHR5cGUoc3RkOjpkZWNsdmFsPFI+KCkuZmlyc3QpPjo6dHlwZTsKICB1c2luZyBQID0gc3RkOjpwYWlyPE4sIFI+OwogIGF1dG8gY29tcGFyZSA9IFtdKFAgY29uc3QgJiBsZWZ0LCBQIGNvbnN0ICYgcmlnaHQpIHsKICAgIHJldHVybiBsZWZ0LmZpcnN0ID4gcmlnaHQuZmlyc3Q7fTsKCiAgc3RkOjpwcmlvcml0eV9xdWV1ZTxQLCBzdGQ6OnZlY3RvcjxQPiwgZGVjbHR5cGUoY29tcGFyZSk+IHF1ZXVlKGNvbXBhcmUpOwoKICBhdXRvIHB1c2ggPSBbJiBxdWV1ZV0gKFAgcCkgewogICAgaWYgKHAuZmlyc3QgPCBwLnNlY29uZC5sYXN0KSBxdWV1ZS5wdXNoKHApOyB9OwogIGF1dG8gbmV4dCA9IFtdKFAgY29uc3QgJiBwKSAtPiBQIHsKICAgIGFzc2VydChwLnNlY29uZC5zdGVwID4gMCk7CiAgICByZXR1cm4ge3AuZmlyc3QgKyBwLnNlY29uZC5zdGVwLCBwLnNlY29uZH07IH07CiAgYXV0byBpbml0ID0gWyZwdXNoXSAoUiBjb25zdCAmIHIpIHsKICAgIHB1c2goe3IuZmlyc3QsIHJ9KTsgfTsKCiAgc3RkOjpmb3JfZWFjaChmcm9tLCB0bywgaW5pdCk7CgogIGlmIChxdWV1ZS5lbXB0eSgpKSByZXR1cm47CiAgCiAgTiBsYXN0ID0gcXVldWUudG9wKCkuZmlyc3Q7CiAgcHVzaChuZXh0KHF1ZXVlLnRvcCgpKSk7CiAgcXVldWUucG9wKCk7CiAgb3AobGFzdCk7CgogIHdoaWxlICghIHF1ZXVlLmVtcHR5KCkpIHsKICAgIFAgY3VycmVudCA9IHF1ZXVlLnRvcCgpOwogICAgcXVldWUucG9wKCk7CiAgICBpZiAoY3VycmVudC5maXJzdCAhPSBsYXN0KSB7CiAgICAgIG9wKGN1cnJlbnQuZmlyc3QpOwogICAgICBsYXN0ID0gY3VycmVudC5maXJzdDsKICAgIH0KICAgIHB1c2gobmV4dChjdXJyZW50KSk7CiAgfQp9CgpzdHJ1Y3QgUmFuZ2UgewogIGludCBmaXJzdDsKICBpbnQgbGFzdDsKICBpbnQgc3RlcDsKfTsKCgppbnQgbWFpbigpIHsKICBSYW5nZSByYW5nZXMgW10gPSB7CiAgICB7MSwgMTAsIDJ9LAogICAgezIsIDUwLCA1fX07CgogIGF1dG8gcHJpbnQgPSBbXShhdXRvIG4pIHsgc3RkOjpjb3V0IDw8IG4gPDwgc3RkOjplbmRsOyB9OwoKICBpdGVyYXRlX3JhbmdlcyhzdGQ6OmJlZ2luKHJhbmdlcyksIHN0ZDo6ZW5kKHJhbmdlcyksIHByaW50KTsKfQ==