digitalmars.D.learn - Sorting a zipped range
- Ben Jones (16/16) Feb 27 2014 One of the cool features of D that I've attempted before in c++
- Tobias Pankrath (6/9) Feb 27 2014 Many items in std.algorithm / std.range make use of static if to
- Ben Jones (10/19) Feb 27 2014 That can be done in C++ too (albeit less elgantly) with tag
- Timon Gehr (13/16) Feb 27 2014 In C++, iterators should implement operator-> which must return a
- bearophile (7/9) Feb 27 2014 You can write that as (untested):
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?
Feb 27 2014
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
Feb 27 2014
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: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.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
Feb 27 2014
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.
Feb 27 2014
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
Feb 27 2014