fix Issue 9060 - std.range.chain and std.range.zip cannot get frame pointer

Changes to avoid following two errors:
* "cannot access frame pointer"
* "field xxx must be initialized in constructor, because it is nested struct"
This commit is contained in:
k-hara 2012-12-12 14:06:52 +09:00
parent baf5737beb
commit 46b612de08
2 changed files with 68 additions and 35 deletions

View file

@ -2693,8 +2693,8 @@ if (isInputRange!RoR && isInputRange!(ElementType!RoR)
} }
} }
private void useItem() private enum useItem =
{ q{
assert(_currentSep.empty && _current.empty, assert(_currentSep.empty && _current.empty,
"joiner: internal error"); "joiner: internal error");
// Use the input // Use the input
@ -2708,13 +2708,13 @@ if (isInputRange!RoR && isInputRange!(ElementType!RoR)
// No data in the current item - toggle to use the // No data in the current item - toggle to use the
// separator // separator
useSeparator(); useSeparator();
} };
this(RoR items, Separator sep) this(RoR items, Separator sep)
{ {
_items = items; _items = items;
_sep = sep; _sep = sep;
useItem(); mixin(useItem); // _current should be initialized in place
// We need the separator if the input has at least two // We need the separator if the input has at least two
// elements // elements
if (_current.empty && _items.empty) if (_current.empty && _items.empty)
@ -2744,7 +2744,7 @@ if (isInputRange!RoR && isInputRange!(ElementType!RoR)
{ {
_currentSep.popFront(); _currentSep.popFront();
if (!_currentSep.empty) return; if (!_currentSep.empty) return;
useItem(); mixin(useItem);
} }
else else
{ {
@ -2759,7 +2759,7 @@ if (isInputRange!RoR && isInputRange!(ElementType!RoR)
{ {
@property auto save() @property auto save()
{ {
Result copy; Result copy = this;
copy._items = _items.save; copy._items = _items.save;
copy._current = _current.save; copy._current = _current.save;
copy._sep = _sep.save; copy._sep = _sep.save;
@ -2803,8 +2803,8 @@ if (isInputRange!RoR && isInputRange!(ElementType!RoR))
private: private:
RoR _items; RoR _items;
ElementType!RoR _current; ElementType!RoR _current;
void prepare() enum prepare =
{ q{
// Skip over empty subranges. // Skip over empty subranges.
if (_items.empty) return; if (_items.empty) return;
while (_items.front.empty) while (_items.front.empty)
@ -2813,12 +2813,12 @@ if (isInputRange!RoR && isInputRange!(ElementType!RoR))
if (_items.empty) return; if (_items.empty) return;
} }
_current = _items.front; _current = _items.front;
} };
public: public:
this(RoR r) this(RoR r)
{ {
_items = r; _items = r;
prepare(); mixin(prepare); // _current should be initialized in place
} }
static if (isInfinite!RoR) static if (isInfinite!RoR)
{ {
@ -2844,14 +2844,14 @@ if (isInputRange!RoR && isInputRange!(ElementType!RoR))
{ {
assert(!_items.empty); assert(!_items.empty);
_items.popFront(); _items.popFront();
prepare(); mixin(prepare);
} }
} }
static if (isForwardRange!RoR && isForwardRange!(ElementType!RoR)) static if (isForwardRange!RoR && isForwardRange!(ElementType!RoR))
{ {
@property auto save() @property auto save()
{ {
Result copy; Result copy = this;
copy._items = _items.save; copy._items = _items.save;
copy._current = _current.save; copy._current = _current.save;
return copy; return copy;
@ -3154,10 +3154,9 @@ struct Group(alias pred, R) if (isInputRange!R)
static if (isForwardRange!R) { static if (isForwardRange!R) {
@property typeof(this) save() { @property typeof(this) save() {
typeof(this) ret; typeof(this) ret = this;
ret._input = this._input.save; ret._input = this._input.save;
ret._current = this._current; ret._current = this._current;
return ret; return ret;
} }
} }
@ -4488,24 +4487,20 @@ struct Until(alias pred, Range, Sentinel) if (isInputRange!Range)
static if (!is(Sentinel == void)) static if (!is(Sentinel == void))
@property Until save() @property Until save()
{ {
Until result; Until result = this;
result._input = _input.save; result._input = _input.save;
result._sentinel = _sentinel; result._sentinel = _sentinel;
result._openRight = _openRight; result._openRight = _openRight;
result._done = _done; result._done = _done;
return result; return result;
} }
else else
@property Until save() @property Until save()
{ {
Until result; Until result = this;
result._input = _input.save; result._input = _input.save;
result._openRight = _openRight; result._openRight = _openRight;
result._done = _done; result._done = _done;
return result; return result;
} }
} }
@ -9634,14 +9629,13 @@ public:
static if (allSatisfy!(isForwardRange, Rs)) static if (allSatisfy!(isForwardRange, Rs))
{ {
@property typeof(this) save() @property auto save()
{ {
auto ret = this; auto ret = this;
foreach (ti, elem; _r) foreach (ti, elem; _r)
{ {
ret._r[ti] = elem.save; ret._r[ti] = elem.save;
} }
return ret; return ret;
} }
} }
@ -9764,14 +9758,13 @@ public:
static if (allSatisfy!(isForwardRange, Rs)) static if (allSatisfy!(isForwardRange, Rs))
{ {
@property typeof(this) save() @property auto save()
{ {
auto ret = this; auto ret = this;
foreach (ti, elem; _input) foreach (ti, elem; _input)
{ {
ret._input[ti] = elem.save; ret._input[ti] = elem.save;
} }
return ret; return ret;
} }
} }

View file

@ -1978,10 +1978,10 @@ if (Ranges.length > 0 && allSatisfy!(isInputRange, staticMap!(Unqual, Ranges)))
static if (allSatisfy!(isForwardRange, R)) static if (allSatisfy!(isForwardRange, R))
@property auto save() @property auto save()
{ {
typeof(this) result; typeof(this) result = this;
foreach (i, Unused; R) foreach (i, Unused; R)
{ {
result.source[i] = source[i].save; result.source[i] = result.source[i].save;
} }
return result; return result;
} }
@ -2392,11 +2392,10 @@ if (Rs.length > 1 && allSatisfy!(isInputRange, staticMap!(Unqual, Rs)))
static if (allSatisfy!(isForwardRange, staticMap!(Unqual, Rs))) static if (allSatisfy!(isForwardRange, staticMap!(Unqual, Rs)))
@property auto save() @property auto save()
{ {
Result result; Result result = this;
result._current = _current;
foreach (i, Unused; Rs) foreach (i, Unused; Rs)
{ {
result.source[i] = source[i].save; result.source[i] = result.source[i].save;
} }
return result; return result;
} }
@ -3687,7 +3686,7 @@ struct Cycle(Range)
@property Cycle save() @property Cycle save()
{ {
Cycle ret; Cycle ret = this;
ret._original = this._original.save; ret._original = this._original.save;
ret._current = this._current.save; ret._current = this._current.save;
return ret; return ret;
@ -3929,11 +3928,10 @@ if(Ranges.length && allSatisfy!(isInputRange, staticMap!(Unqual, Ranges)))
static if (allSatisfy!(isForwardRange, R)) static if (allSatisfy!(isForwardRange, R))
@property Zip save() @property Zip save()
{ {
Zip result; Zip result = this;
result.stoppingPolicy = stoppingPolicy;
foreach (i, Unused; R) foreach (i, Unused; R)
{ {
result.ranges[i] = ranges[i].save; result.ranges[i] = result.ranges[i].save;
} }
return result; return result;
} }
@ -7038,7 +7036,7 @@ if (isRandomAccessRange!Range && hasLength!Range)
@property auto save() @property auto save()
{ {
// Avoid the constructor // Avoid the constructor
typeof(this) result; typeof(this) result = this;
result._input = _input.save; result._input = _input.save;
return result; return result;
} }
@ -7078,7 +7076,7 @@ if (isRandomAccessRange!Range && hasLength!Range)
auto opSlice(size_t a, size_t b) auto opSlice(size_t a, size_t b)
{ {
assert(a <= b); assert(a <= b);
typeof(this) result; typeof(this) result = this;
result._input = _input[a .. b];// skip checking result._input = _input[a .. b];// skip checking
return result; return result;
} }
@ -8363,3 +8361,45 @@ auto refRange(R)(R* range)
{ {
return *range; return *range;
} }
/*****************************************************************************/
unittest // bug 9060
{
// fix for std.algorithm
auto r = map!(x => 0)([1]);
chain(r, r);
zip(r, r);
roundRobin(r, r);
struct NRAR {
typeof(r) input;
@property empty() { return input.empty; }
@property front() { return input.front; }
void popFront() { input.popFront(); }
@property save() { return NRAR(input.save); }
}
auto n1 = NRAR(r);
cycle(n1); // non random access range version
assumeSorted(r);
// fix for std.range
joiner([r], [9]);
struct NRAR2 {
NRAR input;
@property empty() { return true; }
@property front() { return input; }
void popFront() { }
@property save() { return NRAR2(input.save); }
}
auto n2 = NRAR2(n1);
joiner(n2);
group(r);
until(r, 7);
static void foo(R)(R r) { until!(x => x > 7)(r); }
foo(r);
}