tags:

views:

426

answers:

3

Boost range library (http://www.boost.org/doc/libs/1_35_0/libs/range/index.html) allows us to abstract a pair of iterators into a range. Now I want to combine two ranges into one, viz:

given two ranges r1 and r2, define r which traverses [r1.begin(), r1.end()[ and then [r2.begin(), r2.end()[. Is there some way to define r as a range using r1 and r2?

A: 

I think you'd have to make a custom iterator that will 'roll over' r1.end() to r2.begin() when r1.end() is reached. Begin() and end() of that iterator would then be combined into your range r. AFAIK there is no standard boost function that will give you this behavior.

Roel
+1  A: 
  • Can't you call the function twice, once for both ranges? Or are there problems with this approach?
  • Copy the two ranges into one container and pass that.
  • Write your own range class, so it iterates through r1 first and and through r2 second.
Peter Stuifzand
+1  A: 

I needed this again so I had a second look. There is a way to concat two ranges using boost/range/join.hpp. Unluckily the output range type is not included in the interface:

#include "boost/range/join.hpp"
#include "boost/foreach.hpp"
#include <iostream>

int main() {
        int a[] = {1, 2, 3, 4};
        int b[] = {7, 2, 3, 4};

        boost::iterator_range<int*> ai(&a[0], &a[4]);
        boost::iterator_range<int*> bi(&b[0], &b[4]);
        boost::iterator_range<
           boost::range_detail::
           join_iterator<int*, int*, int, int&, 
           boost::random_access_traversal_tag> > ci = boost::join(ai, bi); 

        BOOST_FOREACH(int& i, ci) {
                std::cout << i; //prints 12347234
        }
}

I found the output type using the compiler messages. C++0x auto will be relevant there as well.

Amit Kumar