Skip to content

Commit

Permalink
Remove bug section from docs: bug has been fixed in compiler.
Browse files Browse the repository at this point in the history
Add unittest to prevent regressions in the future.
  • Loading branch information
H. S. Teoh committed Jul 21, 2015
1 parent e21c9a5 commit 90ad7e5
Showing 1 changed file with 31 additions and 4 deletions.
35 changes: 31 additions & 4 deletions std/range/package.d
Original file line number Diff line number Diff line change
Expand Up @@ -3975,10 +3975,6 @@ private string lockstepMixin(Ranges...)(bool withIndex)
writefln("Index %s: a = %s, b = %s", index, a, b);
}
-------
BUGS: If a range does not offer lvalue access, but $(D ref) is used in the
$(D foreach) loop, it will be silently accepted but any modifications
to the variable will not be propagated to the underlying range.
*/
struct Lockstep(Ranges...)
if (Ranges.length > 1 && allSatisfy!(isInputRange, Ranges))
Expand Down Expand Up @@ -4125,6 +4121,37 @@ unittest
foreach (x, y; lockstep(iota(0, 10), iota(0, 10))) { }
}

unittest
{
struct RvalueRange
{
int[] impl;
@property bool empty() { return impl.empty; }
@property int front() { return impl[0]; } // N.B. non-ref
void popFront() { impl.popFront(); }
}
auto data1 = [ 1, 2, 3, 4 ];
auto data2 = [ 5, 6, 7, 8 ];
auto r1 = RvalueRange(data1);
auto r2 = data2;
foreach (a, ref b; lockstep(r1, r2))
{
a++;
b++;
}
assert(data1 == [ 1, 2, 3, 4 ]); // changes to a do not propagate to data
assert(data2 == [ 6, 7, 8, 9 ]); // but changes to b do.

// Since r1 is by-value only, the compiler should reject attempts to
// foreach over it with ref.
static assert(!__traits(compiles, {
foreach (ref a, ref b; lockstep(r1, r2)) { a++; }
}));
static assert(__traits(compiles, {
foreach (a, ref b; lockstep(r1, r2)) { a++; }
}));
}

/**
Creates a mathematical sequence given the initial values and a
recurrence function that computes the next value from the existing
Expand Down

0 comments on commit 90ad7e5

Please sign in to comment.