I have an object with functions for getting the begin and end iterators:
const_iterator err_begin() const
const_iterator err_end() const
Because they are not named begin
and end
, I cannot pass my object directly to functions in range-v3.
Is there a simple wrapper I can use to make this object work with the range-v3 library?
For example:
auto hasErrors = !empty(something(x.err_begin(), x.err_end()));
Sounds like you're looking for iterator_range
:
auto hasErrors = !empty(ranges::make_iterator_range(x.err_begin(), x.err_end()));
You clarified that the class in question is part of a library that you cannot change. Fine. Create a facade class:
class FacadeClass {
const RealClassWithErrBeginEnd &r;
public:
FacadeClass(const RealClassWithErrBeginEnd &r) : r(r) {}
auto begin() const { return r.err_begin(); }
auto end() const { return r.err_end(); }
};
This should be good enough to fool most code that expects a container. In the worst case, you might need to provide additional typedefs in the facade, i.e. value_type
, etc...
boost::make_iterator_range
will do the right thing. Now add a little ADL and we find that one free function solves all our problems:
#include <vector>
#include <iostream>
#include <string>
#include <boost/range.hpp>
// simulate the library class
struct X
{
auto err_begin() const { return errors.begin(); }
auto err_end() const { return errors.end(); }
std::vector<std::string> errors;
};
// provide a generator to build an iterator range
auto errors(const X& x)
{
return boost::make_iterator_range(x.err_begin(), x.err_end());
}
// do things with the iterator_range
int main()
{
X x;
for (const auto& err : errors(x))
{
std::cout << err << std::endl;
}
std::cout << empty(errors(x)) << std::endl;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With