digitalmars.D.bugs - [Issue 3877] New: std.range.chain do not manage infinite ranges correctly
- d-bugmail puremagic.com (206/206) Mar 04 2010 http://d.puremagic.com/issues/show_bug.cgi?id=3877
- d-bugmail puremagic.com (11/11) Jul 29 2010 http://d.puremagic.com/issues/show_bug.cgi?id=3877
- d-bugmail puremagic.com (12/14) Jul 30 2010 http://d.puremagic.com/issues/show_bug.cgi?id=3877
- d-bugmail puremagic.com (12/12) Aug 16 2010 http://d.puremagic.com/issues/show_bug.cgi?id=3877
http://d.puremagic.com/issues/show_bug.cgi?id=3877 Summary: std.range.chain do not manage infinite ranges correctly Product: D Version: 2.040 Platform: All OS/Version: All Status: NEW Severity: minor Priority: P2 Component: Phobos AssignedTo: nobody puremagic.com ReportedBy: philippe.sigaud gmail.com 15:51:21 CET --- std.range.chain opIndex and opIndexAssign do not work for infinite ranges: --- import std.range; void main() { auto c = chain([0,1,2][], cycle([4,5,6][]), [7,8,9][]); // infinite range inside auto c7 = c[7]; // Error, no property .length for cycle([4,5,6][]) } Here is a fix for this: (no improvement to opSlice there. It should be possible: verify if all ranges before the first infinite have a length and slice on them + the infinite range.) --- struct ChainImpl(R...) { private: alias CommonType!(staticMap!(.ElementType, R)) RvalueElementType; template sameET(A) { enum sameET = is(.ElementType!(A) == RvalueElementType); } enum bool allSameType = allSatisfy!(sameET, R); public: Tuple!(R) _input; // This doesn't work yet static if (allSameType) alias ref RvalueElementType ElementType; else alias RvalueElementType ElementType; this(R input) { foreach (i, v; input) { _input.field[i] = v; } } bool empty() { foreach (i, Unused; R) { if (!_input.field[i].empty) return false; } return true; } void popFront() { foreach (i, Unused; R) { if (_input.field[i].empty) continue; _input.field[i].popFront; return; } } // BUG 2597 //auto front() // AWKWARD!!! mixin( (allSameType ? "ref " : "")~ q{ElementType front() { foreach (i, Unused; R) { if (_input.field[i].empty) continue; return _input.field[i].front; } assert(false); } }); static if (allSatisfy!(isBidirectionalRange, R)) { mixin( (allSameType ? "ref " : "")~ q{ElementType back() { foreach_reverse (i, Unused; R) { if (_input.field[i].empty) continue; return _input.field[i].back; } assert(false); } }); void popBack() { foreach_reverse (i, Unused; R) { if (_input.field[i].empty) continue; _input.field[i].popBack; return; } } } static if (allSatisfy!(hasLength, R)) size_t length() { size_t result; foreach (i, Unused; R) { result += _input.field[i].length; } return result; } static if (allSatisfy!(isRandomAccessRange, R)) { mixin( (allSameType ? "ref " : "")~ q{ElementType opIndex(uint index) { foreach (i, Type; R) { static if (hasLength!Type) { immutable length = _input.field[i].length; if (index < length) return _input.field[i][index]; index -= length; } else { static if (isInfinite!Type) { return _input.field[i][index]; } } } assert(false); } }); static if (allSameType && allSatisfy!(hasAssignableElements, R)) void opIndexAssign(ElementType v, uint index) { foreach (i, Type; R) { static if (hasLength!Type) { immutable length = _input.field[i].length; if (index < length) { _input.field[i][index] = v; return; } index -= length; } else { static if (isInfinite!Type) { _input.field[i][index] = v; return; } } } assert(false); } } static if (allSatisfy!(hasLength, R) && allSatisfy!(hasSlicing, R)) ChainImpl opSlice(size_t begin, size_t end) { auto result = this; foreach (i, Unused; R) { immutable len = result._input.field[i].length; if (len < begin) { result._input.field[i] = result._input.field[i] [len .. len]; begin -= len; } else { result._input.field[i] = result._input.field[i] [begin .. len]; break; } } auto cut = length; cut = cut <= end ? 0 : cut - end; foreach_reverse (i, Unused; R) { immutable len = result._input.field[i].length; if (cut > len) { result._input.field[i] = result._input.field[i] [0 .. 0]; cut -= len; } else { result._input.field[i] = result._input.field[i] [0 .. len - cut]; break; } } return result; } } -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Mar 04 2010
http://d.puremagic.com/issues/show_bug.cgi?id=3877 Trass3r <mrmocool gmx.de> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |mrmocool gmx.de Note: It's better to post a diff. Makes it easier to figure out what the actual fix is. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Jul 29 2010
http://d.puremagic.com/issues/show_bug.cgi?id=3877 11:24:29 CEST ---Note: It's better to post a diff. Makes it easier to figure out what the actual fix is.Well, has I said in the text, opIndex and opIndexAssign do not work. The proposed change is in the opIndex and opIndexAssign code, the static if (hasLength) and static if (isInfinite) part. I don't have access to a diff tool right now and wasn't using the Phobos svn repository in march. Philippe -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Jul 30 2010
http://d.puremagic.com/issues/show_bug.cgi?id=3877 David Simcha <dsimcha yahoo.com> changed: What |Removed |Added ---------------------------------------------------------------------------- Status|NEW |RESOLVED CC| |dsimcha yahoo.com Resolution| |FIXED Fixed SVN. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Aug 16 2010