March 09, 2016 Re: How to sort a range | ||||
---|---|---|---|---|
| ||||
Posted in reply to rcorre | On Wednesday, 9 March 2016 at 15:39:55 UTC, rcorre wrote:
> Still curious as to why it fails; maybe the range is getting copied at some point? I guess I need to step through it.
That's my suspicion as well. It seems that OnlyResult is pass-by-value so every time it gets passed to another function, it creates a copy of all the elements. A simple solution is to provide a wrapper type which refers to the elements in the original container.
However, I'm going to argue that the sort function is fine but the modifications you made to OnlyResult are incorrect. I tried running your example of only(...).sort but got a compilation error. Similarly, trying to sort a static array also gives a compilation error. However, if I slice the static array before passing it to sort (thus passing by reference), then it works just fine.
|
March 09, 2016 Re: How to sort a range | ||||
---|---|---|---|---|
| ||||
Posted in reply to cym13 | On Wed, 09 Mar 2016 14:28:11 +0000, cym13 wrote:
> Note that an input range isn't even remotely a container
Which is why sort() has template constraints beyond isInputRange. The constraints ensure that it is possible to swap values in the range.
|
March 10, 2016 Re: How to sort a range | ||||
---|---|---|---|---|
| ||||
Posted in reply to Xinok | On Wednesday, 9 March 2016 at 16:53:08 UTC, Xinok wrote:
> On Wednesday, 9 March 2016 at 15:39:55 UTC, rcorre wrote:
>> Still curious as to why it fails; maybe the range is getting copied at some point? I guess I need to step through it.
>
> That's my suspicion as well. It seems that OnlyResult is pass-by-value so every time it gets passed to another function, it creates a copy of all the elements. A simple solution is to provide a wrapper type which refers to the elements in the original container.
>
> However, I'm going to argue that the sort function is fine but the modifications you made to OnlyResult are incorrect. I tried running your example of only(...).sort but got a compilation error. Similarly, trying to sort a static array also gives a compilation error. However, if I slice the static array before passing it to sort (thus passing by reference), then it works just fine.
Got it. sort calls to quicksort (for unstable, at least) which uses swapAt. swapAt takes the range by value, so it just swaps the values in its local copy. The original OnlyResult is untouched. I guess a static array slice maintains a pointer to the underlying array (which is why returning one from a function errors with 'escaping reference to local variable').
Meanwhile, I've realized my code probably doensn't need to remove duplicates anyways, so its a moot point, but still an interesting discovery :)
|
March 09, 2016 Re: How to sort a range | ||||
---|---|---|---|---|
| ||||
Posted in reply to rcorre | On 03/09/2016 06:50 PM, rcorre wrote: > sort calls to quicksort (for unstable, at least) which uses > swapAt. swapAt takes the range by value, so it just swaps the values in > its local copy. Remembering that a range is not the collection, swapAt takes the range by value but it does not copy the elements. So, sort() does sort the original array: import std.algorithm; void main() { auto a = [ 9, -1, 2, 0 ]; a.sort(); assert(a == [ -1, 0, 2, 9 ]); } > The original OnlyResult is untouched. I guess a static > array slice maintains a pointer to the underlying array (which is why > returning one from a function errors with 'escaping reference to local > variable'). Yes: A static array is just a collection of elements, which implicitly converts to a slice and a slice is nothing but a pair of "pointer to the first element" and "number of elements". Ali |
Copyright © 1999-2021 by the D Language Foundation