#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;
}