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