digitalmars.D - foreach over pointer to range
- Artur Skawina <art.08.09 gmail.com> Jun 05 2012
- Timon Gehr <timon.gehr gmx.ch> Jun 05 2012
- Artur Skawina <art.08.09 gmail.com> Jun 05 2012
- Artur Skawina <art.08.09 gmail.com> Jun 05 2012
- Artur Skawina <art.08.09 gmail.com> Jun 05 2012
- "Peter Alexander" <peter.alexander.au gmail.com> Jun 05 2012
- simendsjo <simendsjo gmail.com> Jun 05 2012
- simendsjo <simendsjo gmail.com> Jun 05 2012
"foreach (e; pointer_to_range)" currently fails with:
Error: foreach: Range* is not an aggregate type
It can be worked around with
struct RangePtr(R) {
R* ptr;
alias ptr this;
property front()() { return ptr.front; }
}
but this adds unnecessary overhead (unfortunately such struct is not
always treated the same as a real pointer, eg when passing it around).
Is there some reason that makes the is-aggregate check necessary, or could
it be dropped?
Thanks,
artur
Jun 05 2012
On 06/05/2012 08:42 PM, Artur Skawina wrote:"foreach (e; pointer_to_range)" currently fails with: Error: foreach: Range* is not an aggregate type It can be worked around with struct RangePtr(R) { R* ptr; alias ptr this; property front()() { return ptr.front; } } but this adds unnecessary overhead (unfortunately such struct is not always treated the same as a real pointer, eg when passing it around). Is there some reason that makes the is-aggregate check necessary, or could it be dropped? Thanks, artur
It should be dropped. A pointer to range is a perfectly fine range.
Jun 05 2012
On 06/05/12 21:25, Peter Alexander wrote:On Tuesday, 5 June 2012 at 18:46:51 UTC, Timon Gehr wrote:On 06/05/2012 08:42 PM, Artur Skawina wrote:"foreach (e; pointer_to_range)" currently fails with: Error: foreach: Range* is not an aggregate type It can be worked around with...
Why not: foreach(e; *pointer_to_range) Seems like the obvious solution to me, and works.
Works by copying the whole range struct, which is what I don't want to happen. And no, using a class is not an option. :) artur
Jun 05 2012
On 06/05/12 22:23, simendsjo wrote:On Tue, 05 Jun 2012 20:46:51 +0200, Timon Gehr <timon.gehr gmx.ch> wrote:It should be dropped. A pointer to range is a perfectly fine range.
Sure..? I couldn't get it to work either: struct R { string test = "aoeu"; property front() { return test[0]; } property bool empty() { return !test.length; } void popFront(){test = test[0..$];} } void main() { R r; R* p = &r; foreach(ch; p) // invalid foreach aggregate p writeln(ch); }
It /is/ a valid range, but it's /not/ currently accepted by foreach. So you have to write the above as: struct R { string test = "aoeu"; property front() { return test[0]; } property bool empty() { return !test.length; } void popFront(){test = test[0..$];} } struct RangePtr(R) { R* ptr; alias ptr this; property front()() { return ptr.front; } } void main() { R r; auto p = RangePtr!R(&r); foreach(ch; p) writeln(ch); } which works, but only obfuscates the code and can be less efficient. artur
Jun 05 2012
On 06/05/12 22:41, simendsjo wrote:On Tue, 05 Jun 2012 22:38:22 +0200, Artur Skawina <art.08.09 gmail.com> wrote:On 06/05/12 22:23, simendsjo wrote:On Tue, 05 Jun 2012 20:46:51 +0200, Timon Gehr <timon.gehr gmx.ch> wrote:It should be dropped. A pointer to range is a perfectly fine range.
Sure..? I couldn't get it to work either: struct R { string test = "aoeu"; property front() { return test[0]; } property bool empty() { return !test.length; } void popFront(){test = test[0..$];} } void main() { R r; R* p = &r; foreach(ch; p) // invalid foreach aggregate p writeln(ch); }
It /is/ a valid range, but it's /not/ currently accepted by foreach.
which works, but only obfuscates the code and can be less efficient.
Well, then it's not a *perfectly fine* range, is it then :)
It *is* a perfectly fine range; the problem is with 'foreach'. artur
Jun 05 2012
On Tuesday, 5 June 2012 at 18:46:51 UTC, Timon Gehr wrote:On 06/05/2012 08:42 PM, Artur Skawina wrote:"foreach (e; pointer_to_range)" currently fails with: Error: foreach: Range* is not an aggregate type It can be worked around with...
Why not: foreach(e; *pointer_to_range) Seems like the obvious solution to me, and works.
Jun 05 2012
On Tue, 05 Jun 2012 20:46:51 +0200, Timon Gehr <timon.gehr gmx.ch> wrote:It should be dropped. A pointer to range is a perfectly fine range.
Sure..? I couldn't get it to work either: struct R { string test = "aoeu"; property front() { return test[0]; } property bool empty() { return !test.length; } void popFront(){test = test[0..$];} } void main() { R r; R* p = &r; foreach(ch; p) // invalid foreach aggregate p writeln(ch); }
Jun 05 2012
On Tue, 05 Jun 2012 22:38:22 +0200, Artur Skawina <art.08.09 gmail.com> wrote:On 06/05/12 22:23, simendsjo wrote:On Tue, 05 Jun 2012 20:46:51 +0200, Timon Gehr <timon.gehr gmx.ch> wrote:It should be dropped. A pointer to range is a perfectly fine range.
Sure..? I couldn't get it to work either: struct R { string test = "aoeu"; property front() { return test[0]; } property bool empty() { return !test.length; } void popFront(){test = test[0..$];} } void main() { R r; R* p = &r; foreach(ch; p) // invalid foreach aggregate p writeln(ch); }
It /is/ a valid range, but it's /not/ currently accepted by foreach.
which works, but only obfuscates the code and can be less efficient. artur
Well, then it's not a *perfectly fine* range, is it then :)
Jun 05 2012









Artur Skawina <art.08.09 gmail.com> 