Monday, 13 May 2013

Writing: Bug Hunting

The latest  C Vu magazine from ACCU is out now. It contains my latest Becoming a Better Programer column. This month it's called Bug Hunting and, as you might guess, is about the art of debugging code.

This was inspired by conversations with Greg Law in the lead up to the 2013 ACCU conference.

Sunday, 12 May 2013

C++11: Iterating range-based for backwards

A few weeks ago we upgraded our toolchain with spangly new C++ compilers. Then we flipped the magical switch unleashing C++11 code features. This is a joyful apocalypse.

It's been fun transitioning to some of the new neater C++11 idioms.

Range-based for is one of the first things we adopted, largely due to the clear readability improvements it brings over tedious iterator type juggling.

Soon we stumbled on a shortcoming of range-based for. It allows you to iterate forwards with little syntax fluff, but not backwards. (We have many collections we "apply" by iterating forwards, and then "revert" by iterating backwards).

It's not too hard to iterate backwards in a reasonably readable way, by writing code like this:
for (const auto &i : backwards(collection))
    // ... use i ...
The simplest implementation of this is shown below:
template <typename T>
class iterate_backwards
iterate_backwards(const T &t) : t(t) {}
    typename T::const_reverse_iterator begin() const { return t.rbegin(); }
    typename T::const_reverse_iterator end()   const { return t.rend(); }
    const T &t;
<typename T>
iterate_backwards backwards(const T &t)
Of course, this is simplistic. It can be enhanced by making the class support C++11's move semantics, and allowing the wrapper function to return forwarded iterate_backwards. However, this wonderful new C++11 machinery serves to hide the simple intent somewhat, and doesn't win us much since this code optimises away neatly.

Perhaps there's a better way to do this? I've seen a few other solutions to this problem, but they don't read anywhere near as neatly, nor are they as straightforward to understand. I'm enjoying this new learning journey.

More iterator fun is to come...