digitalmars.D.bugs - [Issue 24570] New: printing a range of ranges consumes sub-ranges
- d-bugmail puremagic.com (58/58) May 27 https://issues.dlang.org/show_bug.cgi?id=24570
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 puremagic.com Reporter: schveiguy 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. --
May 27