#include <vector>
#include <iostream>

template <typename T>
void foo(T begin, T end)
{
  for (; begin != end; ++begin)
  {
    std::cout << " " << *begin;
  }
}

template <typename T>
void foo(T begin, std::reverse_iterator<T> end)
{
  foo(begin, end.base());
}

template <typename T>
void foo(std::reverse_iterator<T> begin, T end)
{
  foo(end, begin.base());
}

template <typename T>
void foo(std::reverse_iterator<T> begin, std::reverse_iterator<T> end)
{
  foo(end.base(), begin.base());
}

int main()
{
  std::vector<int> v { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
  foo(v.begin(), v.end()); std::cout << std::endl;
  foo(v.begin(), v.rbegin()); std::cout << std::endl;
  foo(v.rbegin(), v.begin()); std::cout << std::endl;
  foo(v.rbegin(), v.rend()); std::cout << std::endl;
}
