Help with Ranges
Steven Schveighoffer
schveiguy at gmail.com
Sun Jul 26 14:56:35 UTC 2020
On 7/26/20 3:10 AM, Charles wrote:
> Suppose I have the following line of code where arr is an array,
> doSomething is some predicate that does a lot of processing on each
> element, sort must come after the mapping, and there are more operations
> done to the range after sort:
>
> arr.map!doSomething.sort. ...;
>
> Sort fails to instantiate because the range it's receiving doesn't
> support element swapping. This may and might be resolved by calling array:
>
> arr.map!doSomething.array.sort. ...;
>
> However, this might trigger an allocation, and there's still more to do!
> Is there something I'm missing with regards to ranges that could help me
> make the first line work without using array, or is it more of an issue
> with my code's design?
That is what you need to do.
A map that returns an lvalue would be sortable, but you would be sorting
the processed elements, and probably not the original elements.
I have found this handy tool quite useful in my code where I need a
temporary array:
// creates a concrete range (std.container.array.Array range) out of the
// original range that is eagerly fetched, and then can be processed,
without
// allocating extra garbage on the heap.
auto concreteRange(Range)(Range r)
{
import std.range : ElementType;
import std.container.array : Array;
return Array!(ElementType!Range)(r)[];
}
Slicing an Array will keep the reference count correctly, and destroy
the memory automatically after you're done using it. So it's perfect for
temporary arrays in pipelining.
-Steve
More information about the Digitalmars-d-learn
mailing list