Hi all,
I'm wondering if we should also support slice(1) or slice(1, 10, 3), i.e.:
views::slice(1) -> views::drop(1)
views::slice(1, 10) -> views::drop(1) | views::take(9)
views::slice(1, 10, 3) -> views::drop(1) | views::take(9) | views::strde(3)
Although this may be confused with std::strided_slice ([mdspan.submdspan.strided.slice]) (or std::slice [class.slice.overview]), because the second argument of the latter is not the end but the extent, so views::slice(1, 10, 3) will get 1, 4, 7, while strided_slice(1, 10, 3) will get 1, 4, 7, 10.
What do you think? Would it make sense to provide two more variants for views::slice?
If you do, they should certainly have "extent" not "end" semantics. This also matches `substr`. This also matches the expansion you gave: `views::slice(a, b)` should expand to `views::drop(a) | views::take(b)`, not `views::drop(a) | views::take(b - a)`.
Although if that's all it is... then why have this in the STL at all? Is there going to be some performance benefit to writing
rg | views::slice(1, 10, 3)
versus just writing
rg | views::slice(1, 10) | views::stride(3)
which is definitely more explicit about what the third parameter is doing? In fact, is there any benefit to writing
rg | views::slice(1, 10)
instead of just
rg | views::drop(1) | views::take(10)
?
Bonus: Note that you can get "end" semantics by rewriting `views::slice(start=a, end=b)` into
rg | views::take(b) | views::drop(a)
If I have the choice between writing the line above, or writing
rg | views::drop(a) | views::take(b - a)
, is there a performance cost to one or the other? Naïvely it seems like the latter might be faster, but the answer could also be "it doesn't matter, they both compile to the same thing."
–Arthur