#include <iostream>
namespace
{
enum Block_Edges
{
FROM = 0,
TO = 4,
};
Block_Edges& operator++(Block_Edges& e)
{
return e = static_cast<Block_Edges>(e + 1);
}
}
template<typename T, bool enable = std::is_integral<T>::value || std::is_enum<T>::value>
struct range_impl
{
struct iterator
{
T operator * ()const noexcept
{
return value;
}
iterator& operator ++() noexcept
{
++value;
return *this;
}
friend bool operator != (const iterator& lhs, const iterator& rhs) noexcept
{
return lhs.value != rhs.value;
}
T value;
};
std::size_t size() const
{
return last - first;
}
const iterator begin()const noexcept
{
return{ first };
}
const iterator end()const noexcept
{
return{ last };
}
T first;
T last;
};
template<typename T>
struct range_impl<T, false>
{
range_impl(T first, T last)
: first(first)
, last(last)
{}
std::size_t size() const
{
return std::distance(first, last);
}
const T begin()const noexcept
{
return{ first };
}
const T end()const noexcept
{
return{ last };
}
T first;
T last;
};
template<typename T>
range_impl<T> range(T first, T last) noexcept
{
return{ first, last };
}
int main()
{
for (const auto& i : range(Block_Edges::FROM, Block_Edges::TO))
{
std::cout << '\n' << i << ':';
for (const auto& j : range(Block_Edges::FROM, Block_Edges::TO))
{
std::cout << j << ' ';
}
}
}
I2luY2x1ZGUgPGlvc3RyZWFtPgoKbmFtZXNwYWNlCnsKICAgIGVudW0gQmxvY2tfRWRnZXMKICAgIHsKICAgICAgICBGUk9NID0gMCwKICAgICAgICBUTyA9IDQsCiAgICB9OwoKICAgIEJsb2NrX0VkZ2VzJiBvcGVyYXRvcisrKEJsb2NrX0VkZ2VzJiBlKQogICAgewogICAgICAgIHJldHVybiBlID0gc3RhdGljX2Nhc3Q8QmxvY2tfRWRnZXM+KGUgKyAxKTsKICAgIH0KCn0KCnRlbXBsYXRlPHR5cGVuYW1lIFQsIGJvb2wgZW5hYmxlID0gc3RkOjppc19pbnRlZ3JhbDxUPjo6dmFsdWUgfHwgc3RkOjppc19lbnVtPFQ+Ojp2YWx1ZT4Kc3RydWN0IHJhbmdlX2ltcGwKewogICAgc3RydWN0IGl0ZXJhdG9yCiAgICB7CiAgICAgICAgVCBvcGVyYXRvciAqICgpY29uc3Qgbm9leGNlcHQKICAgICAgICB7CiAgICAgICAgICAgIHJldHVybiB2YWx1ZTsKICAgICAgICB9CgogICAgICAgIGl0ZXJhdG9yJiBvcGVyYXRvciArKygpIG5vZXhjZXB0CiAgICAgICAgewogICAgICAgICAgICArK3ZhbHVlOwogICAgICAgICAgICByZXR1cm4gKnRoaXM7CiAgICAgICAgfQoKICAgICAgICBmcmllbmQgYm9vbCBvcGVyYXRvciAhPSAoY29uc3QgaXRlcmF0b3ImIGxocywgY29uc3QgaXRlcmF0b3ImIHJocykgbm9leGNlcHQKICAgICAgICB7CiAgICAgICAgICAgIHJldHVybiBsaHMudmFsdWUgIT0gcmhzLnZhbHVlOwogICAgICAgIH0KCiAgICAgICAgVCB2YWx1ZTsKICAgIH07CgogICAgc3RkOjpzaXplX3Qgc2l6ZSgpIGNvbnN0CiAgICB7CiAgICAgICAgcmV0dXJuIGxhc3QgLSBmaXJzdDsKICAgIH0KCiAgICBjb25zdCBpdGVyYXRvciBiZWdpbigpY29uc3Qgbm9leGNlcHQKICAgIHsKICAgICAgICByZXR1cm57IGZpcnN0IH07CiAgICB9CgogICAgICAgIGNvbnN0IGl0ZXJhdG9yIGVuZCgpY29uc3Qgbm9leGNlcHQKICAgIHsKICAgICAgICByZXR1cm57IGxhc3QgfTsKICAgIH0KCiAgICBUIGZpcnN0OwogICAgVCBsYXN0Owp9OwoKdGVtcGxhdGU8dHlwZW5hbWUgVD4Kc3RydWN0IHJhbmdlX2ltcGw8VCwgZmFsc2U+CnsKICAgIHJhbmdlX2ltcGwoVCBmaXJzdCwgVCBsYXN0KQogICAgICAgIDogZmlyc3QoZmlyc3QpCiAgICAgICAgLCBsYXN0KGxhc3QpCiAgICB7fQoKICAgIHN0ZDo6c2l6ZV90IHNpemUoKSBjb25zdAogICAgewogICAgICAgIHJldHVybiBzdGQ6OmRpc3RhbmNlKGZpcnN0LCBsYXN0KTsKICAgIH0KCiAgICBjb25zdCBUIGJlZ2luKCljb25zdCBub2V4Y2VwdAogICAgewogICAgICAgIHJldHVybnsgZmlyc3QgfTsKICAgIH0KCiAgICAgICAgY29uc3QgVCBlbmQoKWNvbnN0IG5vZXhjZXB0CiAgICB7CiAgICAgICAgcmV0dXJueyBsYXN0IH07CiAgICB9CgogICAgVCBmaXJzdDsKICAgIFQgbGFzdDsKfTsKCnRlbXBsYXRlPHR5cGVuYW1lIFQ+CnJhbmdlX2ltcGw8VD4gIHJhbmdlKFQgZmlyc3QsIFQgbGFzdCkgbm9leGNlcHQKewogICAgcmV0dXJueyBmaXJzdCwgbGFzdCB9Owp9CgppbnQgbWFpbigpCnsKICAgIGZvciAoY29uc3QgYXV0byYgaSA6IHJhbmdlKEJsb2NrX0VkZ2VzOjpGUk9NLCBCbG9ja19FZGdlczo6VE8pKQogICAgewogICAgICAgIHN0ZDo6Y291dCA8PCAnXG4nIDw8IGkgPDwgJzonOwogICAgICAgIGZvciAoY29uc3QgYXV0byYgaiA6IHJhbmdlKEJsb2NrX0VkZ2VzOjpGUk9NLCBCbG9ja19FZGdlczo6VE8pKQogICAgICAgIHsKICAgICAgICAgICAgc3RkOjpjb3V0IDw8IGogPDwgJyAnOwogICAgICAgIH0KICAgIH0KfQo=