[Issue 24570] New: printing a range of ranges consumes sub-ranges
d-bugmail at puremagic.com
d-bugmail at puremagic.com
Mon May 27 14:57:08 UTC 2024
https://issues.dlang.org/show_bug.cgi?id=24570
Issue ID: 24570
Summary: printing a range of ranges consumes sub-ranges
Product: D
Version: D2
Hardware: All
OS: All
Status: NEW
Severity: enhancement
Priority: P1
Component: phobos
Assignee: nobody at puremagic.com
Reporter: schveiguy at gmail.com
If you are printing something, you might correctly not expect the act of
printing it to modify that type.
However, printing a range *requires* that you modify it. It's how you get at
the elements inside. For this reason, a range must be treated as a *view* of
data, not the thing to print.
If you print a range whose elements are ranges, those elements should behave as
if you printed them. That is, the act of printing them should not modify the
elements themselves.
However, currently `formatValue` will accept range elements by reference, and
print them by iterating them. This means that a range-of-ranges where the outer
range uses lvalue elements will consume all the nested ranges.
An example:
```d
import std.range;
import std.conv;
import std.algorithm;
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; }
}
void main()
{
import std.conv;
auto intarr = [1, 2, 3];
auto r = R(intarr.ptr, intarr.length);
assert(text(r) == "[1, 2, 3]"); // ok, r is passed by value
assert(text(r) == "[1, 2, 3]"); // still there
auto ndarr = [r, r]; // a range of ranges
assert(text(ndarr) == "[[1, 2, 3], [1, 2, 3]]"); // ok, but this consumed
the subranges
assert(text(ndarr) == "[[], []]"); // now they are gone
ndarr = [r, r];
// what phobos should do, is save every forward range before printing
assert(text(ndarr.map!(e => e.save)) == "[[1, 2, 3], [1, 2, 3]]"); // ok
assert(text(ndarr.map!(e => e.save)) == "[[1, 2, 3], [1, 2, 3]]"); // ok
}
```
Note: I used text instead of writeln so the asserts can be written, but the
same thing happens with writeln.
--
More information about the Digitalmars-d-bugs
mailing list