Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I create a range from a begin and end iterator?

Tags:

c++

range-v3

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())); 
like image 935
sdgfsdh Avatar asked Dec 21 '16 17:12

sdgfsdh


3 Answers

Sounds like you're looking for iterator_range:

auto hasErrors = !empty(ranges::make_iterator_range(x.err_begin(), x.err_end()));
like image 175
Brian Rodriguez Avatar answered Sep 28 '22 13:09

Brian Rodriguez


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...

like image 36
Sam Varshavchik Avatar answered Sep 28 '22 11:09

Sam Varshavchik


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;
}
like image 39
Richard Hodges Avatar answered Sep 28 '22 12:09

Richard Hodges