Thread overview
A small trouble with std.range.indexed
Sep 08, 2011
bearophile
Sep 08, 2011
Ali Çehreli
Sep 08, 2011
bearophile
September 08, 2011
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
September 08, 2011
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
September 08, 2011
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