Printing a range of ranges drains them

Steven Schveighoffer schveiguy at gmail.com
Mon May 27 00:25:42 UTC 2024


If you print a range of ranges (that are not arrays) with 
`writeln`, even if the nested range is a forward range, `writeln` 
will drain the nested ranges.

example:

```d
import std.stdio;
import std.range;
struct R
{
     int* ptr;
     size_t len;
     int front() {return  *ptr;}
     void popFront() { ++ptr; --len; }
     bool empty() {return len == 0;}
     typeof(this) save() { return this; }
}

static assert(isForwardRange!R);

void main()
{
     int[] arr = [1, 2, 3];
     auto r = R(arr.ptr, arr.length);
     R[] mdarr = [r, r, r];
     writeln(mdarr);
     writeln(mdarr);
}
```

Output:

```
[[1, 2, 3], [1, 2, 3], [1, 2, 3]]
[[], [], []]
```

If you do this with nested arrays, it does not drain the inner 
arrays.

You can fix by un-reffing the elements of the outer array: 
`writeln(mdarr.map!(e => e));`

So, does anyone expect this behavior? If so, can you explain why 
you think this is intentionally designed this way?

I wanted to file a bug, but I was shocked that this behavior as 
far as I can tell has always existed, and nobody has ever filed a 
bug on it.

-Steve


More information about the Digitalmars-d mailing list