4

In the following function

namespace r = std::ranges;
namespace rv = std::ranges::views;

std::optional<int> find_first_adjacent_duplicate(std::span<int> vals) {
    auto pairs = vals | rv::slide(2);
    auto adj_dup = r::find_if(pairs, [](auto&& r) {return r[0] == r[1]; });
    if (adj_dup != pairs.end()) {
        return (*adj_dup)[0];
    } else {
        return {};
    }
}

The only reason I store vals | rv::slide(2) in a local variable is because I need a name for the range view so that I can test the result of find_if against its end iterator.

I was wondering if there is way to tell if adj_dup is pairs.end() just given adj_dup?

jwezorek
  • 8,592
  • 1
  • 29
  • 46
  • No, this is not possible. You need another iterator to compare to. – Remy Lebeau Jun 03 '23 at 23:08
  • 1
    Are you trying to implement [std::ranges::adjacent_find](https://en.cppreference.com/w/cpp/algorithm/ranges/adjacent_find) or is it just an example? – Bob__ Jun 05 '23 at 08:44

1 Answers1

2

That is not possible. But you can express the find_if as a filter instead:

auto adj_dup = vals 
             | rv::slide(2)
             | rv::filter([](auto&& r) {return r[0] == r[1]; });
if (adj_dup) {
    return adj_dup.front()[0];
} else {
    return {};
} 
T.C.
  • 133,968
  • 17
  • 288
  • 421