Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In ranges-v3, how do I create a range from a pair of iterators?

How do I create a ranges-v3-compatible range, given a traditional pair of "begin" and "end" iterators?

Let's say that I am writing a generic function that accepts two iterators, for compatibility with legacy code.

struct result;  

bool keep_line(const std::string&);
result parse_line(const std::string&);

template <typename InputIt>
std::vector<result> parse_lines(InputIt begin, InputIt end)
{
    // This is what I want to do...
    auto lines = ranges::make_range_out_of_legacy_iterators(begin, end);

    return lines 
        | ranges::view::filter(keep_line) 
        | ranges::view::transform(parse_line) 
        | ranges::to<std::vector<result>>();
}
like image 675
NicholasM Avatar asked Oct 10 '19 05:10

NicholasM


People also ask

What is Range v3?

Range v3 is a generic library that augments the existing standard library with facilities for working with ranges. A range can be loosely thought of a pair of iterators, although they need not be implemented that way.

Is Range v3 header only?

The library used in the code examples is not really the C++20 ranges, it's the ranges-v3 open-source library from Eric Niebler, which is the basis of the proposal to add ranges to the C++. It's a header-only library compatible with C++11/14/17.


1 Answers

To create a range from a pair of iterators in ranges-v3, use the subrange view:

#include <range/view/subrange.hpp>

auto lines = ranges::subrange(begin, end);       // Requires C++17-style deduction

auto lines = ranges::make_subrange(begin, end);  // If template deduction not available

In old versions of the library, the iterator_range class in range/v3/iterator_range.hpp was apparently used, but that header is marked deprecated in the current ranges-v3 release (0.9.1).

like image 138
NicholasM Avatar answered Oct 19 '22 18:10

NicholasM