Zip sequence should provide non-tuple version foreach like this:
----
foreach (i, c; zip(sequence!"n"(), "str"))
{
if (i==0) assert(c == 's');
else if (i==1) assert(c == 't');
else if (i==2) assert(c == 'r');
else assert(0);
}
----
Patch:
std/range.d | 15 +++++++++++++++
1 files changed, 15 insertions(+), 0 deletions(-)
diff --git a/std/range.d b/std/range.d
index 7e7916c..0a24500 100644
--- a/std/range.d
+++ b/std/range.d
@@ -3209,6 +3209,21 @@ if(Ranges.length && allSatisfy!(isInputRange, staticMap!(Unqual, Ranges)))
}
}
}
+
+/**
+ Iterate zip elements with directry named heads of ranges.
+ */
+ int opApply(int delegate(ref ElementType.Types) dg)
+ {
+ auto r = this;
+ for (; !r.empty; r.popFront())
+ {
+ auto e = r.front;
+ if (auto result = dg(e.field))
+ return result;
+ }
+ return 0;
+ }
}
/// Ditto
Comment #1 by kennytm — 2011-05-06T09:24:10Z
What about std.range.lockstep?
Comment #2 by k.hara.pg — 2011-05-06T11:09:07Z
(In reply to comment #1)
> What about std.range.lockstep?
Oh, I have been overlooked. Thanks.
But..., why can't we merge Zip and Lockstep?
Comment #3 by andrei — 2011-05-06T11:18:36Z
I'm worried about this development. Before long we could get to the point where a lot of ranges get bloated to support two iteration methods because opApply has capabilities that ranges don't.
To prevent that we should improve range-based iteration to provide good support for foreach, and leave opApply to entities that need internal iteration.
Comment #4 by kennytm — 2011-05-06T11:26:58Z
(In reply to comment #3)
> I'm worried about this development. Before long we could get to the point where
> a lot of ranges get bloated to support two iteration methods because opApply
> has capabilities that ranges don't.
>
> To prevent that we should improve range-based iteration to provide good support
> for foreach, and leave opApply to entities that need internal iteration.
Implement (a subset of) issue 4579?
Comment #5 by lutger.blijdestijn — 2011-05-09T10:18:44Z
If no language changes for range iteration and tuple unpacking will be made, perhaps it's worth to consider a generic wrapper for this purpose as a compromise?
I couldn't think of a good name:
auto iterUntupled(R)(R input)
if ( isInputRange!R &&
is( typeof( { auto x = input.front.tupleof; }() ) ) )
{
static struct IterUntupled(R)
{
this(R input)
{
_input = input;
}
int opApply( int delegate( ref typeof(_input.front.tupleof) ) dg )
{
while( !_input.empty)
{
auto front = _input.front;
if ( auto result = dg(front.tupleof) )
return result;
_input.popFront();
}
return 0;
}
R _input;
}
return IterUntupled!R(input);
}
This will also unpack arbitrary structs and classes, is that too loose?
Comment #6 by verylonglogin.reg — 2012-08-09T02:35:50Z
"front tuple expansion" by Kenji Hara fixed this issue.
But it still isn't documented.
See Issue 7361 - No documentation for front tuple expansion in foreach over range