Automatic Foreach
Koroskin Denis
2korden at gmail.com
Sun Apr 27 00:49:19 PDT 2008
On Sun, 27 Apr 2008 10:45:36 +0400, janderson <askme at me.com> wrote:
>
> //////////////////////////////////////////////////
> //Example 3
> //////////////////////////////////////////////////
> // Multiple array inputs should work like nested arrays.
>
> vector[] vertex = dot(array1, array2);
>
> Equivalent too:
>
> vector[] vertex;
> vector.length = array1.length * array2.length;
> int i=0;
> foreach (auto val1; array1)
> {
> foreach (auto val2; array2)
> {
> vertex[i++] = sqrt(val1, val2);
> }
> }
>
Did you mean dot(val1, val2); here?
IMO, it saves you a little of typing, but you loose control over code
execution.
It is hard to debug, it adds additional ambiguity.
f(char[] s);
f(char c);
char[] chars;
f(chars); // f(char[] s) is called, but I need foreach(), what should I do?
It is easy to write a template, that would do what you want:
template ReturnType(CallableType, TList...)
{
CallableType c;
TList u;
static if (is(typeof(c(u)) == void)) {
alias void Value;
} else {
alias typeof(c(u))[] Value;
}
}
template auto_foreach(CallableType, ElementType)
{
ReturnType!(CallableType,ElementType).Value auto_foreach(CallableType
callable, ElementType[] elements)
{
alias ReturnType!(CallableType,ElementType).Value Type;
static if (is(Type == void)) {
foreach(e; elements) {
callable(e);
}
} else {
Type result;
result.length = elements.length;
int i = 0;
foreach (e; elements) {
result[i++] = callable(e);
}
return result;
}
}
}
void putc(char c)
{
printf("%c", c);
}
char shift(char c)
{
return c+1;
}
int main(string[] args)
{
char[] h = "hello";
h = auto_foreach(&shift, h);
auto_foreach(&putc, h);
return 0;
}
You could also change this template to accept multiple arrays as input.
It's easy (use variadic template + recursion).
Make more practice in generic programming, it is worth it!
More information about the Digitalmars-d
mailing list