Template for going from Array --> list of args

Kirk McDonald kirklin.mcdonald at gmail.com
Tue Jan 30 02:51:57 PST 2007


Bill Baxter wrote:
> Is there any better way to do this than what I've got below?
> The variadic stuff lets you treat lists of args as arrays, but is there 
> some nice way to go the other direction?  Take the elements of an array 
> and pass them as individual args?
> 
> The code below just does a not-so-slick and not-so-exhaustive 
> case-by-case on the number of arguments.  Kind of looks reminiscent of 
> the problems variadic templates are supposed to solve, but I can't 
> figure out any way to use variadics to handle this one.
> 
> ------
> template NArgs(alias func)
> {
>     static if (is(typeof(func) T == function)) {
>         const uint NArgs = T.length;
>     }
>     else {
>         static assert(0, "Not a function with fixed arguments");
>     }
> }
> 
> template callwithN(alias func, alias A) {
>     static if (NArgs!(func)==0) {
>         void callwithN() {
>             func();
>         }
>     }
>     else static if (NArgs!(func)==1) {
>         void callwithN() {
>             func(A[0]);
>         }
>     }
>     else static if (NArgs!(func)==2) {
>         void callwithN() {
>             func(A[0], A[1]);
>         }
>     }
>     else static if (NArgs!(func)==3) {
>         void callwithN() {
>             func(A[0], A[1], A[2]);
>         }
>     }
>     else static if (NArgs!(func)==4) {
>         void callwithN() {
>             func(A[0], A[1], A[2], A[3]);
>         }
>     }
>     else {
>        static assert(0, "Unsupported number of arguments");
>     }
> }
> 
> void foo(int a, int b) { }
> void bar(int a, int b, int c) { }
> 
> void main()
> {
>   int[5] a=[0,1,2,3,4];
>   callwithN!(foo,a);
>   callwithN!(bar,a);
> }
> -----
> 
> What I was thinking was something like:
> 
> template callwithN(alias func, alias A) {
>         func( array_to_tuple!(NArgs!(func),A) );
>         }
>     }
> 
> but that stalled out because any sort of Tuple!(A[0]) type construct 
> bombs saying that A[0] isn't valid as a template argument.
> 
> --bb
> 

Something like this should work (though I haven't tested it):

import std.traits;

void callwith(alias fn, T)(T[] array) {
     ParameterTypeTuple!(typeof(&fn)) t;
     foreach (i, e; t) {
         t[i] = array[i];
     }
     fn(t);
}

void foo(int a, int b) { }

void main() {
     int[5] a = [0,1,2,3,4];
     callwith!(fn, int)(a);
}

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


More information about the Digitalmars-d-learn mailing list