I have a custom container implementing begin
and end
. How can I pipe this container to ranges-v3 views?
std::vector is pipeable, so I tried piping my custom class in the same way, but pipe operator is not found for my container.
I looked into documentation, but I couldn't find any way other then reimplementing a wrapper class with Range interface. I have multiple such classes and I believe this might be a fairly common case, so I'd rather use some function (or class base) offered by the library, but I couldn't figure it out from the documentation.
Here is a minimal example:
#include <iostream>
#include <iterator>
#include <range/v3/all.hpp>
struct Test {
struct iterator;
struct sentinel {};
int counter;
Test() = default;
iterator begin();
sentinel end() const { return {}; }
iterator begin() const;
};
struct Test::iterator {
using value_type = int;
using reference = int&;
using pointer = int*;
using iterator_category = std::input_iterator_tag;
using difference_type = void;
Test* test;
iterator& operator++() {
test->counter++;
return *this;
}
iterator operator++(int) {
auto it = *this;
++*this;
return it;
}
int operator*() { return test->counter; }
int operator*() const { return test->counter; }
bool operator!=(const iterator& rhs) const {
return rhs.test != test;
}
bool operator!=(sentinel) const {
return true;
}
};
Test::iterator Test::begin() { return iterator {this}; }
Test::iterator Test::begin() const { return iterator {const_cast<Test*>(this)}; }
int main() {
auto container = Test();
static_assert(ranges::range<Test>, "It is not a range");
static_assert(ranges::viewable_range<Test>, "It is not a viewable range");
auto rng = container | ranges::views::take(10);
for (auto n : rng) { std::cerr << n << std::endl;}
return 0;
}
This is the error I'm getting with this code:
~/tmp/range$ g++ main.cpp -Irange-v3/include -o main 2>&1 | grep error
main.cpp:46:19: error: static assertion failed: It is not a range
main.cpp:47:19: error: static assertion failed: It is not a viewable range
range-v3/include/range/v3/functional/pipeable.hpp:63:53: error: no matching function for call to ‘ranges::pipeable_access::impl<ranges::views::view<ranges::make_pipeable_fn::operator()(Fun) const [with Fun = ranges::detail::bind_back_fn_<ranges::views::take_fn, int>]::_> >::pipe(Test&, ranges::views::view<ranges::make_pipeable_fn::operator()(Fun) const [with Fun = ranges::detail::bind_back_fn_<ranges::views::take_fn, int>]::_>&)’
main.cpp:48:10: error: ‘void rng’ has incomplete type
main.cpp:49:19: error: unable to deduce ‘auto&&’ from ‘rng’