Templates, varargs and static foreach

Kirk McDonald kirklin.mcdonald at gmail.com
Sun Jan 14 03:57:03 PST 2007


%u wrote:
> I would like to do the following:
> 
> void foo() {}
> void bar(int a) { foo(); } // 1
> void bar(int a, int b) { foo(); foo(); } // 2
> void bar(int a, int b, int c) { foo(); foo(); foo(); } // 3
> void bar(int[] a) { foreach(b; a) foo(); } // 4
> 
> The forms 1-3 should be called, when the amount of arguments is known at compile time. Otherwise
> 4 is called.
> 
> Ok - this is a major simplification of the design I'm using. I would like to shorten it using
> templates. I have tried this:
> 
> void foo() {}
> void bar(A...)(A a) { foo(); static if (a.length > 1) { bar(a[1..length]); }
> void bar(A)(A[] a) { foreach(t;a) foo(); }
> 
> The problem is that the recursion happens on runtime (unless I specify -O -release -inline). Can
> the compiler guarantee that the recursion is unfolded, when all those optimizations are on or is
> there a static for/foreach for doing this in a better way.

There is a "static foreach," only you do not use the "static" keyword.

void foo() {}

void bar(A...)(A a) {
     foreach(e; a) {
         foo();
     }
}

You could also do this at runtime, using D's typesafe variadics:

void bar(int[] a...) {
     foreach(e; a) {
         foo();
     }
}

Both forms of bar are called in exactly the same way, with the caveat 
that the latter only accepts int arguments, while the former will accept 
any arguments.

bar(1, 2, 3, 4);

-- 
Kirk McDonald
Pyd: Wrapping Python with D
http://pyd.dsource.org


More information about the Digitalmars-d-learn mailing list