Fix Issue 10460 - auto ref for Union, SetDifference, SetSymmetricDifference

https://issues.dlang.org/show_bug.cgi?id=10460

The rearrangement of SetSymmetricDifference.front was needed since auto ref doesn't deduce correctly when there are multiple return statements (by design), so a single return statement with the ternary operator was used.
This commit is contained in:
Peter Alexander 2014-08-25 13:32:34 +01:00
parent 5fb71bb7d6
commit 5e0532b9e7

View file

@ -5744,7 +5744,7 @@ struct Until(alias pred, Range, Sentinel) if (isInputRange!Range)
return _done; return _done;
} }
@property ElementType!Range front() @property auto ref front()
{ {
assert(!empty); assert(!empty);
return _input.front; return _input.front;
@ -5844,6 +5844,14 @@ unittest // bugzilla 13171
assert(a == [4]); assert(a == [4]);
} }
unittest // Issue 10460
{
auto a = [1, 2, 3, 4];
foreach (ref e; a.until(3))
e = 0;
assert(equal(a, [0, 0, 3, 4]));
}
/** /**
If the range $(D doesThisStart) starts with $(I any) of the $(D If the range $(D doesThisStart) starts with $(I any) of the $(D
withOneOfThese) ranges or elements, returns 1 if it starts with $(D withOneOfThese) ranges or elements, returns 1 if it starts with $(D
@ -12007,7 +12015,7 @@ public:
adjustPosition(); adjustPosition();
} }
@property ElementType!(R1) front() @property auto ref front()
{ {
assert(!empty); assert(!empty);
return r1.front; return r1.front;
@ -12043,12 +12051,25 @@ unittest
static assert(isForwardRange!(typeof(setDifference(a, b)))); static assert(isForwardRange!(typeof(setDifference(a, b))));
} }
unittest // Issue 10460
{
int[] a = [1, 2, 3, 4, 5];
int[] b = [2, 4];
foreach (ref e; setDifference(a, b))
e = 0;
assert(equal(a, [0, 2, 0, 4, 0]));
}
/** /**
Lazily computes the symmetric difference of $(D r1) and $(D r2), Lazily computes the symmetric difference of $(D r1) and $(D r2),
i.e. the elements that are present in exactly one of $(D r1) and $(D i.e. the elements that are present in exactly one of $(D r1) and $(D
r2). The two ranges are assumed to be sorted by $(D less), and the r2). The two ranges are assumed to be sorted by $(D less), and the
output is also sorted by $(D less). The element types of the two output is also sorted by $(D less). The element types of the two
ranges must have a common type. ranges must have a common type.
If both arguments are ranges of L-values of the same type then
$(D SetSymmetricDifference) will also be a range of L-values of
that type.
*/ */
struct SetSymmetricDifference(alias less = "a < b", R1, R2) struct SetSymmetricDifference(alias less = "a < b", R1, R2)
if (isInputRange!(R1) && isInputRange!(R2)) if (isInputRange!(R1) && isInputRange!(R2))
@ -12103,15 +12124,12 @@ public:
adjustPosition(); adjustPosition();
} }
@property ElementType!(R1) front() @property auto ref front()
{ {
assert(!empty); assert(!empty);
if (r2.empty || !r1.empty && comp(r1.front, r2.front)) bool chooseR1 = r2.empty || !r1.empty && comp(r1.front, r2.front);
{ assert(chooseR1 || r1.empty || comp(r2.front, r1.front));
return r1.front; return chooseR1 ? r1.front : r2.front;
}
assert(r1.empty || comp(r2.front, r1.front));
return r2.front;
} }
static if (isForwardRange!R1 && isForwardRange!R2) static if (isForwardRange!R1 && isForwardRange!R2)
@ -12147,6 +12165,21 @@ unittest
static assert(isForwardRange!(typeof(setSymmetricDifference(a, b)))); static assert(isForwardRange!(typeof(setSymmetricDifference(a, b))));
} }
unittest // Issue 10460
{
int[] a = [1, 2];
double[] b = [2.0, 3.0];
int[] c = [2, 3];
alias R1 = typeof(setSymmetricDifference(a, b));
static assert(is(ElementType!R1 == double));
static assert(!hasLvalueElements!R1);
alias R2 = typeof(setSymmetricDifference(a, c));
static assert(is(ElementType!R2 == int));
static assert(hasLvalueElements!R2);
}
// Internal random array generators // Internal random array generators
version(unittest) version(unittest)
{ {