Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I write a range pipeline that uses temporary containers?

Tags:

c++

range-v3

I have a third-party function with this signature:

std::vector<T> f(T t); 

I also have an existing potentially infinite range (of the range-v3 sort) of T named src. I want to create a pipeline that maps f to all elements of that range and flattens all the vectors into a single range with all their elements.

Instinctively, I would write the following.

 auto rng = src | view::transform(f) | view::join; 

However, this won't work, because we cannot create views of temporary containers.

How does range-v3 support such a range pipeline?

like image 757
R. Martinho Fernandes Avatar asked Apr 24 '16 07:04

R. Martinho Fernandes


1 Answers

It looks like there are now test cases in the range-v3 library that show how to do this correctly. It is necessary to add the views::cache1 operator into the pipeline:

auto rng = views::iota(0,4)         | views::transform([](int i) {return std::string(i, char('a'+i));})         | views::cache1         | views::join('-'); check_equal(rng, {'-','b','-','c','c','-','d','d','d'}); CPP_assert(input_range<decltype(rng)>); CPP_assert(!range<const decltype(rng)>); CPP_assert(!forward_range<decltype(rng)>); CPP_assert(!common_range<decltype(rng)>); 

so the solutions for the OP's question would be to write

auto rng = src | views::transform(f) | views::cache1 | views::join; 
like image 169
bradgonesurfing Avatar answered Oct 07 '22 12:10

bradgonesurfing