mirror of
https://github.com/dlang/phobos.git
synced 2025-05-04 09:00:22 +03:00
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:
parent
baf5737beb
commit
46b612de08
2 changed files with 68 additions and 35 deletions
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
62
std/range.d
62
std/range.d
|
@ -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);
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue