diff --git a/std/algorithm.d b/std/algorithm.d index ef4a50f01..3502ae69d 100644 --- a/std/algorithm.d +++ b/std/algorithm.d @@ -2693,8 +2693,8 @@ if (isInputRange!RoR && isInputRange!(ElementType!RoR) } } - private void useItem() - { + private enum useItem = + q{ assert(_currentSep.empty && _current.empty, "joiner: internal error"); // Use the input @@ -2708,13 +2708,13 @@ if (isInputRange!RoR && isInputRange!(ElementType!RoR) // No data in the current item - toggle to use the // separator useSeparator(); - } + }; this(RoR items, Separator sep) { _items = items; _sep = sep; - useItem(); + mixin(useItem); // _current should be initialized in place // We need the separator if the input has at least two // elements if (_current.empty && _items.empty) @@ -2744,7 +2744,7 @@ if (isInputRange!RoR && isInputRange!(ElementType!RoR) { _currentSep.popFront(); if (!_currentSep.empty) return; - useItem(); + mixin(useItem); } else { @@ -2759,7 +2759,7 @@ if (isInputRange!RoR && isInputRange!(ElementType!RoR) { @property auto save() { - Result copy; + Result copy = this; copy._items = _items.save; copy._current = _current.save; copy._sep = _sep.save; @@ -2803,8 +2803,8 @@ if (isInputRange!RoR && isInputRange!(ElementType!RoR)) private: RoR _items; ElementType!RoR _current; - void prepare() - { + enum prepare = + q{ // Skip over empty subranges. if (_items.empty) return; while (_items.front.empty) @@ -2813,12 +2813,12 @@ if (isInputRange!RoR && isInputRange!(ElementType!RoR)) if (_items.empty) return; } _current = _items.front; - } + }; public: this(RoR r) { _items = r; - prepare(); + mixin(prepare); // _current should be initialized in place } static if (isInfinite!RoR) { @@ -2844,14 +2844,14 @@ if (isInputRange!RoR && isInputRange!(ElementType!RoR)) { assert(!_items.empty); _items.popFront(); - prepare(); + mixin(prepare); } } static if (isForwardRange!RoR && isForwardRange!(ElementType!RoR)) { @property auto save() { - Result copy; + Result copy = this; copy._items = _items.save; copy._current = _current.save; return copy; @@ -3154,10 +3154,9 @@ struct Group(alias pred, R) if (isInputRange!R) static if (isForwardRange!R) { @property typeof(this) save() { - typeof(this) ret; + typeof(this) ret = this; ret._input = this._input.save; ret._current = this._current; - return ret; } } @@ -4488,24 +4487,20 @@ struct Until(alias pred, Range, Sentinel) if (isInputRange!Range) static if (!is(Sentinel == void)) @property Until save() { - Until result; - + Until result = this; result._input = _input.save; result._sentinel = _sentinel; result._openRight = _openRight; result._done = _done; - return result; } else @property Until save() { - Until result; - + Until result = this; result._input = _input.save; result._openRight = _openRight; result._done = _done; - return result; } } @@ -9634,14 +9629,13 @@ public: static if (allSatisfy!(isForwardRange, Rs)) { - @property typeof(this) save() + @property auto save() { auto ret = this; foreach (ti, elem; _r) { ret._r[ti] = elem.save; } - return ret; } } @@ -9764,14 +9758,13 @@ public: static if (allSatisfy!(isForwardRange, Rs)) { - @property typeof(this) save() + @property auto save() { auto ret = this; foreach (ti, elem; _input) { ret._input[ti] = elem.save; } - return ret; } } diff --git a/std/range.d b/std/range.d index c652888d2..33dc498b6 100644 --- a/std/range.d +++ b/std/range.d @@ -1978,10 +1978,10 @@ if (Ranges.length > 0 && allSatisfy!(isInputRange, staticMap!(Unqual, Ranges))) static if (allSatisfy!(isForwardRange, R)) @property auto save() { - typeof(this) result; + typeof(this) result = this; foreach (i, Unused; R) { - result.source[i] = source[i].save; + result.source[i] = result.source[i].save; } return result; } @@ -2392,11 +2392,10 @@ if (Rs.length > 1 && allSatisfy!(isInputRange, staticMap!(Unqual, Rs))) static if (allSatisfy!(isForwardRange, staticMap!(Unqual, Rs))) @property auto save() { - Result result; - result._current = _current; + Result result = this; foreach (i, Unused; Rs) { - result.source[i] = source[i].save; + result.source[i] = result.source[i].save; } return result; } @@ -3687,7 +3686,7 @@ struct Cycle(Range) @property Cycle save() { - Cycle ret; + Cycle ret = this; ret._original = this._original.save; ret._current = this._current.save; return ret; @@ -3929,11 +3928,10 @@ if(Ranges.length && allSatisfy!(isInputRange, staticMap!(Unqual, Ranges))) static if (allSatisfy!(isForwardRange, R)) @property Zip save() { - Zip result; - result.stoppingPolicy = stoppingPolicy; + Zip result = this; foreach (i, Unused; R) { - result.ranges[i] = ranges[i].save; + result.ranges[i] = result.ranges[i].save; } return result; } @@ -7038,7 +7036,7 @@ if (isRandomAccessRange!Range && hasLength!Range) @property auto save() { // Avoid the constructor - typeof(this) result; + typeof(this) result = this; result._input = _input.save; return result; } @@ -7078,7 +7076,7 @@ if (isRandomAccessRange!Range && hasLength!Range) auto opSlice(size_t a, size_t b) { assert(a <= b); - typeof(this) result; + typeof(this) result = this; result._input = _input[a .. b];// skip checking return result; } @@ -8363,3 +8361,45 @@ auto refRange(R)(R* 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); +}