Help with Ranges

Steven Schveighoffer schveiguy at
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:
>!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:
>!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, 
// 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.


More information about the Digitalmars-d-learn mailing list