ericniebler/stl2

Unsafe views that are actually safe

JohelEGP opened this issue · 1 comments

Is it okay that views known to be safe_ranges in principle don't even satisfy it?

Consider http://eel.is/c++draft/range.dangling#2 and https://godbolt.org/z/jGgJng which makes it compilable. Calling find with a prvalue drop_view whose iterators are not tied to its lifetime returns dangling because it doesn't specialize enable_safe_range, even thought its base range is a safe_range.

This would be solved with an specialization like

template <class V>
constexpr bool enable_safe_range<drop_view<V>> = enable_safe_range<V>;

and similar for views with iterators equal to the base range or known not to have a parent_ pointer or anything that ties its validity to a particular view object.

Here's another example I ran into recently, trying to implement an eager trim (didn't realize range-v3 had one at the time):

auto trim(std::string const& s) {
    auto isalpha = [](char c) { /* ... */ };
    auto b = ranges::find_if(s, isalpha);
    auto e = ranges::find_if(s | views::reverse, isalpha).base();
    return subrange(b, e);
}

The declaration of b is fine, but the declaration of e is ill-formed because this find_if returns dangling - because reverse_view is never a safe_range. But in this example it would be perfectly safe (and, I think, a fairly nice way to implement this).

One way to get this to compile would be:

template <class V>
constexpr bool enable_safe_range<reverse_view<V>> = enable_safe_range<V>;