On Wednesday, May 02, 2012 23:01:21 Jacob Carlborg wrote: > Is there a general function for transforming a range back to the > original type? If not, would it be possible to create one?
You mean that if you have something like auto range = getRangeFromSomewhere(); auto newRange = find(filter!func(range), value); you want to transform newRange back to the same type as range? I don't believe that that's possible in the general case. For example, take Array!int a = getArrayFromSomewhere(0; auto range = a[]; auto newRange = find(filter!"a < 7"(range), 2); The type of a[] is specific to Array!int, cannot be created externally from it, and is tightly coupled with the container. What if the container held the values [1, 7, 2, 9, 42, 0, -2, 4]? newRange would end up having [2 , 0, -2 , 4], which doesn't correspond to any range of elements in the Array. So, how could you convert newRange to the same type as range? The best that you could do as far as I can tell would be to create a new Array!int, put those elements in it, and slice the container. So, I don't see how you could really take an arbitrary range and convert it back to its original type. With a very specific set of types, you might be able to (e.g. take([1, 2, 4, 9], 3) could be converted back to int[] easily enough), but with all of the wrapping that goes on with ranges, even determining what type of range is being wrapped by another can't be done generically AFAIK, let alone getting the whole chain down to the original range, let alone somehow converting the wrapped range back to that type. Take remove in std.container, for example. It will only take the container's range type or the result of take on the container's range type - and it had to special case take. And removing a range from a container would be classic example of where you need the original range type rather than a wrapper. - Jonathan M Davis