www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - A small trouble with std.range.indexed

reply bearophile <bearophileHUGS lycos.com> writes:
std.range.indexed of DMD 2.055 is very nice. But it signature shows constraints
that I have had problems to work with, maybe the error is just mine, I don't
know:


import std.algorithm, std.range, std.array;
void main() {
    auto data = [7, 6, 5, 4, 3, 2, 1, 0];
    auto indices = [6, 1, 7];

    //auto idxSet = array(uniq(indices.sort())); // OK
    auto idxSet = uniq(indices.sort()); // not OK?

    // std.range.indexed() constraints
    static assert(isInputRange!(typeof(idxSet))); // OK
    static assert( is(typeof((int[]).init[ElementType!(typeof(idxSet)).init]))
); // OK

    sort(indexed(data, idxSet));
    assert(data == [7, 0, 5, 4, 3, 2, 1, 6]);
}


Bye and thank you,
bearophile
Sep 08 2011
parent reply Ali =?iso-8859-1?q?=C7ehreli?= <acehreli yahoo.com> writes:
On Thu, 08 Sep 2011 03:33:24 -0400, bearophile wrote:

 std.range.indexed of DMD 2.055 is very nice. But it signature shows
 constraints that I have had problems to work with, maybe the error is
 just mine, I don't know:
 
 
 import std.algorithm, std.range, std.array; void main() {
     auto data = [7, 6, 5, 4, 3, 2, 1, 0]; auto indices = [6, 1, 7];
 
     //auto idxSet = array(uniq(indices.sort())); // OK

In that case, idxSet is a RandomAccessRange.
     auto idxSet = uniq(indices.sort()); // not OK?

indices.sort() is a RandomAccessRange but uniq is not, as it needs to walk the elements lazily. The documentation of indexed() says: "Source must be a random access range. The returned range will be bidirectional or random-access if Indices is bidirectional or random-access, respectively."
     // std.range.indexed() constraints
     static assert(isInputRange!(typeof(idxSet))); // OK static assert(
     is(typeof((int[]).init[ElementType!(typeof(idxSet)).init])) ); // OK
 
     sort(indexed(data, idxSet));

Because idxSet is not RandomAccessRange, indexed() does not provide opIndex() and doesn't match sort()'s requirement. Here is an excerpt of Indexed from range.d: struct Indexed(Source, Indices) if(isRandomAccessRange!Source && isInputRange!Indices && is(typeof(Source.init[ElementType!(Indices).init]))) { // ... static if(isRandomAccessRange!Indices) { /// Ditto auto ref opIndex(size_t index) { return _source[_indices[index]]; } // ... }
     assert(data == [7, 0, 5, 4, 3, 2, 1, 6]);
 }
 
 
 Bye and thank you,
 bearophile

It's unfortunate that template the error messages cannot be more helpful. :-/ Ali
Sep 08 2011
parent bearophile <bearophileHUGS lycos.com> writes:
Ali Çehreli:

 The documentation of indexed() says: "Source must be a random access 
 range. The returned range will be bidirectional or random-access if 
 Indices is bidirectional or random-access, respectively."

 Because idxSet is not RandomAccessRange, indexed() does not provide 
 opIndex() and doesn't match sort()'s requirement.

You are right, I understand, thank you.
 It's unfortunate that template the error messages cannot be more 
 helpful. :-/

In my opinion here it's also a matter of documentation about the kind of range needed for Indices. Bye, bearophile
Sep 08 2011