The future of foreach| arbitrary number of arrays version
bearophile
bearophileHUGS at lycos.com
Sun Dec 23 07:16:46 PST 2007
downs Wrote:
> Finally. This took entirely too long.
I am developing a large functional lib too ;-) I'll add something like this too (I already have two zip-like thingies there, but they aren't lazy).
This is my first try at a solution, but it has a bug still, the index i gives problems still (in your original 2-element solution too, I think). If you want you can fix the problem.
import std.stdio;
static import std.metastrings;
/// Like ArrayType, but it goes down just 1 level.
template ArrayType1(T: T[]) {
alias T ArrayType1;
}
/// ...
template Lets2(string txt, int n) {
static if (n > 0)
const Lets2 = Lets2!(txt, n-1) ~
std.metastrings.Format!(txt,
std.metastrings.ToString!(n-1),
std.metastrings.ToString!(n-1));
else
const Lets2 = "";
}
// ------------------------------------
template SeriesGen1S(string txt, string separator, int max, int min=0) {
static if (min > max)
const SeriesGen1S = "";
else static if (min == max)
const SeriesGen1S = std.metastrings.Format!(txt, std.metastrings.ToString!(max));
else
const SeriesGen1S = SeriesGen1S!(txt, separator, max-1, min) ~ separator ~
std.metastrings.Format!(txt, std.metastrings.ToString!(max));
}
private struct _xzip(TyArrays...) {
mixin( Lets2!("alias ArrayType1!(TyArrays[%s]) T%s;\n", TyArrays.length) );
mixin( Lets2!("T%s[] a%s;\n", TyArrays.length) );
int len = 0;
mixin("
int opApply(int delegate(" ~ SeriesGen1S!("ref T%s", ", ", TyArrays.length-1) ~ ") dg) {
foreach (size_t id, entry; a0[0 .. len])" ~
"if (auto res = dg(entry, "~ SeriesGen1S!("a%s[id]", ", ", TyArrays.length-1, 1) ~ "))
return res;
return 0;
}
");
mixin("
int opApply(int delegate(size_t id, " ~ SeriesGen1S!("ref T%s", ", ", TyArrays.length-1) ~ ") dg) {
foreach (size_t id, entry; a0[0 .. len])" ~
"if (auto res = dg(id, entry, "~ SeriesGen1S!("a%s[id]", ", ", TyArrays.length-1, 1) ~ "))
return res;
return 0;
}
");
}
_xzip!(TyArrays) xzip(TyArrays...)(TyArrays arrays) {
int lenmin = arrays[0].length;
foreach(arr; arrays[1 .. $])
if (arr.length < lenmin)
lenmin = arr.length;
mixin("auto iter = _xzip!(TyArrays)(" ~
SeriesGen1S!("arrays[%s]", ", ", TyArrays.length-1) ~
");");
iter.len = lenmin;
return iter;
}
void main() {
foreach (x, y; xzip([1, 2, 3, 4], [4.1, 5.1, 6.1]))
writefln(x, " - ", y);
writefln();
foreach (x, y, z; xzip([1, 2, 3, 4], [4.1, 5.1, 6.1], "abcd"))
writefln(x, " - ", y, " - ", z);
//foreach (i, x, y; xzip([1, 2, 3, 4], [4.1, 5.1, 6.1])) // BUG
// writefln(i, ": ", x, " - ", y);
}
Bye,
bearophile
More information about the Digitalmars-d
mailing list