Fix issue 12007 - cartesianProduct does'nt work with ranges of immutables

https://d.puremagic.com/issues/show_bug.cgi?id=12007

This makes a tweak to `Zip`'s `save`: Now, it *builds* a new `Zip` object
from the saved ranges, rather than assigning each range individually.

This gives 2 advantages:
1. Better support for `save` (which doesn't actaully guarantee assignability)
2. Avoids useless `opAssign` overhead
This commit is contained in:
monarchdodra 2014-02-01 17:12:31 +01:00
parent 7bd1ae66c3
commit 301b42f0de

View file

@ -4684,15 +4684,18 @@ struct Zip(Ranges...)
}
static if (allSatisfy!(isForwardRange, R))
{
private this(ref Zip other)
{
foreach (i, Unused; R)
ranges[i] = other.ranges[i].save;
stoppingPolicy = other.stoppingPolicy;
}
@property Zip save()
{
Zip result = this;
foreach (i, Unused; R)
{
result.ranges[i] = result.ranges[i].save;
}
return result;
return Zip(this);
}
}
private void emplaceIfCan(T)(T* addr)
{
@ -5193,6 +5196,21 @@ unittest
assertThrown(zip(StoppingPolicy.longest, cast(S[]) null, new int[1]).front);
}
unittest //12007
{
static struct R
{
enum empty = false;
void popFront(){}
int front(){return 1;} @property
R save(){return this;} @property
void opAssign(R) @disable;
}
R r;
auto z = zip(r, r);
auto zz = z.save;
}
/*
Generate lockstep's opApply function as a mixin string.
If withIndex is true prepend a size_t index to the delegate.