D-Programming-Language/phobos — pull request #854 by jmdavis (2012-10-10 07:19:03+00:00)
Title: Improvements to hasSlicing

The primary goal of this pull request is to tighten up `hasSlicing`, since it's too lax. The changes to it are:

1. For finite ranges, the result of `opSlice` must be implicitly convertible to the original to allow you to assume that the slice is reassignable to the original (except when the original was `const` or `immutable`, in which case it can be assigned to a new variable of the same type as the original). It's implicitly convertible rather than exact so that the slice can be tail-const.

2. For infinite ranges, the result of `opSlice` must be the result of `take` or `takeExactly` (they now return the same type for infinite ranges).

3. The result of `opSlice` is required to be a forward range rather than an input range. As slicing is essentially the same as calling `save` except for the fact that the result covers fewer elements, it makes no sense for the result to not be a forward range.

4. The result of `opSlice` must define `length` as it makes no sense to have a slice with an unknown length. The original doesn't have to, even for finite ranges, because it really has no effect on `opSlice` whether the original defines `length` or not. But because the result must have `length` and must be assignable to the original (for finite ranges at least), it probably wouldn't make sense for the original not to have `length` if it's finite. It seemed pointless to check for it though.

Also, in order to facilitate using `take` or `takeExactly` for slicing infiinite ranges, `take` and `takeExactly` have been adjusted. The main difference is that now neither checks `hasSlicing` on infinite ranges (that causes a circular dependency which triggers [bug# 8556](http://d.puremagic.com/issues/show_bug.cgi?id=8556)), but `takeExactly` has also been adjusted to return the same type as `take` wherever possible (i.e. when the range is infinite or defines `length`).