Boost logo

Boost Users :

Subject: [Boost-users] [Range] Select forward or reverse traversal at compile time?
From: Alastair Rankine (arsptr_at_[hidden])
Date: 2011-06-29 08:19:59

Given a bidirectional range R, is it possible to select at compile time
whether we want to iterate forwards or backwards?

Below is a test app. At the commented line, I would like to
transparently construct a forward or reverse range, ie either
[begin(range), end(range)] or [rbegin(range), rend(range)] respectively,
depending on the definition of the Reversed template parameter.

Just to be clear, the desired output is:

forward: abc
reversed: abc

I can make this work by using a functor class with partial
specialisation to construct the iterator_range, using begin/end or
rbegin/rend respectively. But it's a bit ugly and it would seem like
something that boost range would provide anyway?

(Note that boost::reverse() is NOT what I am after.)

#include <boost/assign/list_of.hpp>
#include <boost/range/algorithm/copy.hpp>
#include <boost/range.hpp>

#include <vector>
#include <iostream>

template <typename Reversed, typename Range>
std::string Print(const Range& range)
     typedef boost::iterator_range<
         typename boost::mpl::eval_if<
             boost::range_reverse_iterator<const Range>,
             boost::range_iterator<const Range>
>::type> IterRange;

     // want to convert it to a forward range here
     IterRange forwardRange(range);

     std::string result;
     boost::copy(forwardRange, std::back_inserter(result));
     return result;

int main(int argc, char* argv[])
     using boost::assign::list_of;

     std::vector<char> a = list_of('a')('b')('c');
     std::vector<char> b = list_of('c')('b')('a');

     std::cout << "forward: " << Print<boost::mpl::false_>(a)
               << std::endl
               << "reversed: " << Print<boost::mpl::true_>(b)
               << std::endl;

     return 0;

Boost-users list run by williamkempf at, kalb at, bjorn.karlsson at, gregod at, wekempf at