I have a function that operates on standard iterators of a common type:
template <typename I>
bool next_combination(const I first, I k, const I last)
I'm trying to use it with std::ranges::views
, but I'm not able to pass its iterators as input arguments to the function:
auto view = std::ranges::views::split(';') |
std::ranges::views::transform(
[](auto &&rng)
{
bool ok = next_combination(rng.begin(),rng.begin() 2, rng.end());
// ...
}
The view-iterators does not support operator
for the second input argument of next_combination
, and the begin and end iterator types are different.
How do I adapt function next_combination
to handle ranges/views, or (alternatively) adapt the input arguments in order to make this compile?
Edit: Full example:
#include <string>
#include <ranges>
#include <span>
#include <vector>
#include <algorithm>
template <typename I>
bool next_combination(const I first, I k, const I last)
{
/* Credits: Mark Nelson http://marknelson.us */
if ((first == last) || (first == k) || (last == k))
return false;
I i1 = first;
I i2 = last;
i1;
if (last == i1)
return false;
i1 = last;
--i1;
i1 = k;
--i2;
while (first != i1)
{
if (*--i1 < *i2)
{
I j = k;
while (!(*i1 < *j))
j;
std::iter_swap(i1, j);
i1;
j;
i2 = k;
std::rotate(i1, j, last);
while (last != j)
{
j;
i2;
}
std::rotate(k, i2, last);
return true;
}
}
std::rotate(first, k, last);
return false;
}
int main()
{
std::string line;
std::vector<std::string> lines{"bcd;zac", "cad;c"};
auto strsplit_view =
std::ranges::views::split(';') | std::ranges::views::drop(1) |
std::ranges::views::transform(
[](auto &&rng)
{
bool ok = next_combination(rng.begin(),rng.begin() 2, rng.end());
return std::span(&*rng.begin(), std::ranges::distance(rng)); });
auto filesplit_view = lines | std::ranges::views::transform(
[&](auto &&line)
{ return line | strsplit_view; });
}
CodePudding user response:
You are using a version of gcc that has not yet implemented the P2210, that is, the split subranges obtained by views::split
(renamed views::lazy_split
in the latest standard) can only be a forward_range
.
Since next_combination
requires bidirectional_iterator
s (which support operator--
), you cannot pass an iterator of forward_range
to it.
There is no simple solution until using a compiler that implements P2210.