#include <iostream>
#include <vector>
#include <iterator>
template<typename It>
class Range
{
It b, e;
public:
Range(It b, It e) : b(b), e(e) {}
It begin() const { return b; }
It end() const { return e; }
};
template<typename ORange, typename OIt = decltype(std::begin(std::declval<ORange>())), typename It = std::reverse_iterator<OIt>>
Range<It> reverse(ORange && originalRange) {
return Range<It>(It(std::end(originalRange)), It(std::begin(originalRange)));
}
int main() {
std::vector<int> c = { 1, 2, 3, 4 };
for (auto i : reverse(c)) {
std::cout << i << ' ';
}
std::cout << std::endl;
// Also works with const containers
const std::vector<int> cc = { 1, 2, 3, 4 };
for (auto i : reverse(cc)) {
std::cout << i << ' ';
}
std::cout << std::endl;
// Also works with raw arrays thanks to non-members std::begin/end
int arr[] = { 1, 2, 3, 4 };
for (auto i : reverse(arr)) {
std::cout << i << ' ';
}
std::cout << std::endl;
return 0;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8dmVjdG9yPgojaW5jbHVkZSA8aXRlcmF0b3I+Cgp0ZW1wbGF0ZTx0eXBlbmFtZSBJdD4KY2xhc3MgUmFuZ2UKewogICAgSXQgYiwgZTsKcHVibGljOgogICAgUmFuZ2UoSXQgYiwgSXQgZSkgOiBiKGIpLCBlKGUpIHt9CiAgICBJdCBiZWdpbigpIGNvbnN0IHsgcmV0dXJuIGI7IH0KICAgIEl0IGVuZCgpIGNvbnN0IHsgcmV0dXJuIGU7IH0KfTsKCnRlbXBsYXRlPHR5cGVuYW1lIE9SYW5nZSwgdHlwZW5hbWUgT0l0ID0gZGVjbHR5cGUoc3RkOjpiZWdpbihzdGQ6OmRlY2x2YWw8T1JhbmdlPigpKSksIHR5cGVuYW1lIEl0ID0gc3RkOjpyZXZlcnNlX2l0ZXJhdG9yPE9JdD4+ClJhbmdlPEl0PiByZXZlcnNlKE9SYW5nZSAmJiBvcmlnaW5hbFJhbmdlKSB7CiAgICByZXR1cm4gUmFuZ2U8SXQ+KEl0KHN0ZDo6ZW5kKG9yaWdpbmFsUmFuZ2UpKSwgSXQoc3RkOjpiZWdpbihvcmlnaW5hbFJhbmdlKSkpOwp9CgppbnQgbWFpbigpIHsKCXN0ZDo6dmVjdG9yPGludD4gYyA9IHsgMSwgMiwgMywgNCB9OwoJZm9yIChhdXRvIGkgOiByZXZlcnNlKGMpKSB7CgkJc3RkOjpjb3V0IDw8IGkgPDwgJyAnOwoJfQoJc3RkOjpjb3V0IDw8IHN0ZDo6ZW5kbDsKCQoJLy8gQWxzbyB3b3JrcyB3aXRoIGNvbnN0IGNvbnRhaW5lcnMKCWNvbnN0IHN0ZDo6dmVjdG9yPGludD4gY2MgPSB7IDEsIDIsIDMsIDQgfTsKCWZvciAoYXV0byBpIDogcmV2ZXJzZShjYykpIHsKCQlzdGQ6OmNvdXQgPDwgaSA8PCAnICc7Cgl9CglzdGQ6OmNvdXQgPDwgc3RkOjplbmRsOwoJCgkvLyBBbHNvIHdvcmtzIHdpdGggcmF3IGFycmF5cyB0aGFua3MgdG8gbm9uLW1lbWJlcnMgc3RkOjpiZWdpbi9lbmQKCWludCBhcnJbXSA9IHsgMSwgMiwgMywgNCB9OwoJZm9yIChhdXRvIGkgOiByZXZlcnNlKGFycikpIHsKCQlzdGQ6OmNvdXQgPDwgaSA8PCAnICc7Cgl9CglzdGQ6OmNvdXQgPDwgc3RkOjplbmRsOwoJCglyZXR1cm4gMDsKfQ==