Issue 91952
Summary `<algorithm>`: `ranges::ends_with`'s constraint check for bidirectional case is not quite right
Labels new issue
Assignees
Reporter hewillk
    `ranges::ends_with` only checks whether the two sentinel types satisfy `bidirectional_iterator` then unconditionally warps all iterators and sentinels into `reverse_iterator`s.

https://github.com/llvm/llvm-project/blob/19a62fbe00930d7eaa9f948c8dd26d58f5422c00/libcxx/include/__algorithm/ranges_ends_with.h#L67-L69

There are two implicit issues here. First, theoretically, the iterator can still not satisfy `bidirectional_iterator` in such case, which makes the construction of `reverse_iterator` ill-formed. Second, the reference of sentinels and iterators may not be the same, which makes the predicate and projection functions not necessarily applicable to the `reverse_iterator`.

The following demos the issue:

```cpp
#include <algorithm>
#include <list>

struct Proj {
  int operator()(auto&);
  int operator()(const auto&) = delete;
};

int main() {
  std::list<int> l;
 std::ranges::subrange s{l.begin(), l.cend()};
  return std::ranges::ends_with(s, s, {}, Proj{}, Proj{}); // hard error in libc++
}
```
https://godbolt.org/z/xrMdreWEv
_______________________________________________
llvm-bugs mailing list
llvm-bugs@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs

Reply via email to