nyarlathotep108
nyarlathotep108

Reputation: 5523

Join a variable number of ranges

I need to concatenate multiple instances of boost::iterator_range. My initial idea was to use boost::join, but it looks like it takes only two ranges as parameters. On another question I found that the most voted answer was "well, just call join again", but that is not working in my case. I realized the reason might be that I do not know at compile time the exact number of ranges I am going to join, resulting in boost::join not knowing its return type. To make it more clear, I need to use it in a ranged for loop, such as the following:

SomeRangeType result;

for ( const auto& a_range : some_list_of_ranges )
{
    result = boost::join( result, a_range );
}

return result;

Does another join-like operation like the one I need exist in boost?

Upvotes: 5

Views: 1613

Answers (2)

Öö Tiib
Öö Tiib

Reputation: 10979

C++ does not have run-time dynamic templates, so the idea does not work with boost::range.

We can have 2 ranges r1 and r2 with types R1 and R2 and when we join those then we get result (lets name it r12) of type boost::joined_range<R1,R2>.

We can have third range (say r3 of type R3) and joining it with r12 we would get result of type boost::joined_range<boost::joined_range<R1,R2>,R3>.

The ranges r1, r2, r3 etc. can be passed to variadic template function as arguments and from list of arguments we can make compiler to figure what is the resulting type. Same is when we have the ranges in fixed length collection (like std::tuple or std::array), we can make compiler to figure what is the resulting type of joining those.

However if we don't have fixed amount of ranges but run-time dynamic amount (like from std::vector) then we don't know what will be the type of joining these and also compiler can't figure it out compile time. Every type however must be known compile time in C++.

So you have either to find a way to fix the amount of ranges you join compile time or you have to use that dynamic, not joined collection (like vector) of ranges as your data type or you have to use some third thing like range-v3.

Upvotes: 1

Jarod42
Jarod42

Reputation: 217273

range-v3 has concat and join views, it seems you want join view here:

std::vector<std::vector<int>> v{{1, 2, 3}, {4}, {5, 6}};

for (auto e : v | ranges::view::join) {
    std::cout << e << " "; // 1 2 3 4 5 6
}

Demo

Upvotes: 5

Related Questions