Edmund's blog

Writing code.

Reversed range-based for loop

With a range-based for loop you can easily iterate over all elements in a container.

1
2
3
4
std::list<int> items{1, 2, 3};

for (auto&& item : items)
    std::cout << item << ' ';
1
1 2 3

But what if you want to reverse iterate over the items?

1
2
3
4
#include "ReverseAdapter.h"

for (auto&& item : MakeReverse(items))
    std::cout << item << ' ';
1
3 2 1

The C++ standard library does not provide a reverse adapter, so we have to write our own. This one works for both const and non-const containers.

ReverseAdapter.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
#ifndef REVERSE_ADAPTER_H
#define REVERSE_ADAPTER_H


template<class T>
class ReverseAdapter
{
public:
    ReverseAdapter(T& container) : m_container(container) {}
    typename T::reverse_iterator begin() { return m_container.rbegin(); }
    typename T::reverse_iterator end() { return m_container.rend(); }

private:
    T& m_container;
};

template<class T>
class ConstReverseAdapter
{
public:
    ConstReverseAdapter(const T& container) : m_container(container) {}
    typename T::const_reverse_iterator begin() { return m_container.rbegin(); }
    typename T::const_reverse_iterator end() { return m_container.rend(); }

private:
    const T& m_container;
};


template<class T>
ReverseAdapter<T> MakeReverse(T& container)
{
    return ReverseAdapter<T>(container);
}

template<class T>
ConstReverseAdapter<T> MakeReverse(const T& container)
{
    return ConstReverseAdapter<T>(container);
}


#endif  // REVERSE_ADAPTER_H