Thread overview | |||||||
---|---|---|---|---|---|---|---|
|
February 27, 2014 Sorting a zipped range | ||||
---|---|---|---|---|
| ||||
One of the cool features of D that I've attempted before in c++ is to sort a set of ranges in lockstep like (not syntactically correct): auto a = [5,4,3,2,1] auto b = [1,2,3,4,5] auto sorter = (Tuple x, Tuple y) => x.get(0) < y.get(0); sort!sorter(zip(a,b)); -> a = [1,2,3,4,5], b = [5,4,3,2,1] In c++ this seems basically impossible to do correctly with std::sort because it seems impossible to make a random access iterator type that can be returned from zip() that has the correct semantics (see here: http://stackoverflow.com/questions/13840998/sorting-zipped-locked-containers-in-c-using-boost-or-the-stl) My question is: which features of the D range abstraction allow zip to work the way we expect? What C++isms were left behind to make this work? |
February 27, 2014 Re: Sorting a zipped range | ||||
---|---|---|---|---|
| ||||
Posted in reply to Ben Jones | On Thursday, 27 February 2014 at 21:09:45 UTC, Ben Jones wrote: > My question is: which features of the D range abstraction allow zip to work the way we expect? What C++isms were left behind to make this work? Many items in std.algorithm / std.range make use of static if to provide the most capable return types. I.e. if you zip to RA ranges than zip will return a random access range, too. See https://github.com/D-Programming-Language/phobos/blob/master/std/range.d#L4988 |
February 27, 2014 Re: Sorting a zipped range | ||||
---|---|---|---|---|
| ||||
Posted in reply to Tobias Pankrath | On Thursday, 27 February 2014 at 21:24:20 UTC, Tobias Pankrath wrote:
> On Thursday, 27 February 2014 at 21:09:45 UTC, Ben Jones wrote:
>
>> My question is: which features of the D range abstraction allow zip to work the way we expect? What C++isms were left behind to make this work?
>
> Many items in std.algorithm / std.range make use of static if to provide the most capable return types. I.e. if you zip to RA ranges than zip will return a random access range, too.
>
> See https://github.com/D-Programming-Language/phobos/blob/master/std/range.d#L4988
That can be done in C++ too (albeit less elgantly) with tag dispatch or enable if, or whatever. The big issue I ran into was dealing with the semantics of iterator dereferencing. I'm not sure anyone has come up with a way to define an iterator whose dereference operator returns a reference type when dealing with a zipped range in C++.
It seems that somehow D's range abstraction avoids that issues somehow, but I don't quite understand how.
|
February 27, 2014 Re: Sorting a zipped range | ||||
---|---|---|---|---|
| ||||
Posted in reply to Ben Jones | On 02/27/2014 10:09 PM, Ben Jones wrote: > > My question is: which features of the D range abstraction allow zip to > work the way we expect? Assignable elements of a range do not need to be addressable. > What C++isms were left behind to make this work? In C++, iterators should implement operator-> which must return a pointer to data, and unary operator*, which should return a reference if it is to be assignable. This makes the iterator abstraction less flexible. I.e. it is a consequence of - desire to use pointer-like syntax for iterators - weak support for hooking into the corresponding syntactic constructs Phobos eg. allows retrieval of and assignment to a range's front element to be implemented in distinct methods that can execute arbitrary code. Zip uses such facilities to distribute assignments to its range elements back to each source range. |
February 27, 2014 Re: Sorting a zipped range | ||||
---|---|---|---|---|
| ||||
Posted in reply to Ben Jones | Ben Jones:
> auto sorter = (Tuple x, Tuple y) => x.get(0) < y.get(0);
> sort!sorter(zip(a,b));
You can write that as (untested):
zip(a, b).sort!((x, y) => x[0] < y[0]);
Or even just:
a.zip(b).sort!q{ a[0] < b[0] };
Bye,
bearophile
|
Copyright © 1999-2021 by the D Language Foundation