Chapter 38. A joining iterator

#include <x/joiniterator.H>

std::list<std::string> stringlist;

// ...

std::string string;

auto b=x::joiniterator<std::list<string>::const_iterator>(stringlist.begin(), stringlist.end());

sd::copy(b, b.end(), std::back_insert_iterator<std::string>(res));

This is an iterator-based alternative to join(). The above example concatenates all the strings in the std::list and places the result into the string.

x::joiniterator's template parameter is an iterator over other containers, and x::joiniterator defines an iterator over the values in the containers, joined together. Advancing the x::joiniterator after the last value in the first container instance puts the x::joiniterator on the first value in the second container instance, and so on. The container iterator class can be an input iterator, a forward iterator, a bidirectional iterator, or a random access iterator. The resulting x::joiniterator gives the same iterator category, except that a random access container iterator results in a bidirectional x::joiniterator

The constructor takes two parameters, the beginning and the ending container iterator, and defines the beginning iterator for the joined values of the underlying containers. end() returns the value of the ending iterator for that sequence. x::joiniterator() also has a default constructor, which produces a universal ending iterator value. This value will work as the ending iterator value for any joined sequence over a matching container value type; with the sole exception that the universal ending iterator will not be a proper bidirectional ending iterator value, it cannot be decremented. However, if proper bidirectional semantics are not required, the default constructor can be used as a convenient ending iterator value.


The template parameter that specifies the iterator over the containers must have a category that's at least as much as the category of the container values' iterator. If the containers' iterator is a bidirectional iterator (or a random access iterator, which is supported as a bidirectional iterator) then the template parameter must also be a bidirectional iterator, for example.