Boost.Foreach is such a great piece of kit that once you start using it you just can’t stop. Indeed I like working directly with values rather than iterators so much that is feels normal for me to write something like

 

BOOST_FOREACH( value_type x , make_iterator_range( rbegin( seq ) , rend( seq ) )

 

whenever I wish to reverse iterate over a sequence. My co-workers are not big fans of typing though, so they want a REVERSE_FOREACH. At first naïve glance it looks easy to implement in terms of the original FOREACH:

 

template<typename C> inline iterator_range</* something */> make_reverse_iterator_range(C& c)

{

            return make_iterator_range( rbegin(c) , rend(c) );

}

#define REVERSE_FOREACH( x , container ) BOOST_FOREACH( x , make_reverse_iterator_range( container ) )

 

This works fine when container is an lvalue. But then co-workers, used to the wonders of the original FOREACH, inevitably start to use the new macro with rvalues and get a crash due to dangling references (– the iterator_range’s members point to departed quantities…..) and if you could somehow work around that, there is the issue hidden inside the “/* something */” that you have to cope with fact that MSVC has no proper const rvalue detection. Finally the

 

#define MACRO(x,y) ANOTHER_MACRO( f(x) , g(y) )

 

style is not recommended because they are brittle in the face of x and/or y themselves being macros.

 

… but all these issues are exactly the ones that BOOST_FOREACH itself solves! Thus surely it is technically possible to write a REVERSE_FOREACH that works with rvalues as well as lvalues, e.g. by essentially copying and pasting the FOREACH implementation and replacing “begin” and “end” by “rbegin” and “rend” in the vital places. However one feels there may be a better way… has anyone had a go at creating a “fully-functional” REVERSE_FOREACH and could offer me any advice? If indeed the task is fairly intricate and requires re-use of foreach internals, would the library author consider including something in the library itself?

 

Many thanks for reading,

Pete Bartlett