einpoklum
einpoklum

Reputation: 131970

What's a quick-and-dirty way to obtain an adapting iterator?

I have some (templated) iterator pair Iterator begin1 and Iterator end1. I have a function foo, with signature

template <typename ForwardIterator>
void foo(ForwardIterator begin, ForwardIterator end);

which does something on that range. Now, I want to have foo act not on the actual range elements, but rather on a transformation of these elements by some lambda or some function bar. I can't use std::transform or otherwise use temorary storage for the transformed values, since that would take up too much space or since I'm not allowed to allocate anything on the heap.

Now, I know I can implement some kind of adapting iterator myself, but I'd rather use something ready-made and not reinvent the wheel.

So, what's a quick and dirty way to get an appropriate adapting iterator pair I can pass for foo to do what I want? i.e. for me to be able to call

foo(magic(begin), magic(end))

or

auto new_pair = magic(begin, end);
foo(new_pair.first, new_pair.second);

?

Upvotes: 2

Views: 84

Answers (1)

Brian Rodriguez
Brian Rodriguez

Reputation: 4359

Eric Niebler's range-v3 library provides a very nice solution for this, and is planned to be included in a future standard. Here's a simple example:

std::vector<int> vi{1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
using namespace ranges;
auto rng = vi | view::transform([](int x){ return x % 2; });
foo(rng.begin(), rng.end());  // When foo dereferences these iterators, it
                              // will see: [1, 0, 1, 0, 1, 0, 1, 0, 1, 0].

This is all lazy and efficient, by the way. :)

Upvotes: 2

Related Questions