Compile time variadic functions

Don Clugston dac at nospam.com.au
Tue Mar 14 08:42:34 PST 2006


Oskar Linde wrote:
> Hello,
> 
> I recently found out a way to use D's new implicit function template 
> instantiation support to do compile time variadic functions 
> (http://www.digitalmars.com/drn-bin/wwwnews?digitalmars.D/35151).I think 
> it is cool enough to deserve its own post. :) I've added a slightly 
> clumsy vararg declaration mixin to declare vararg functions.
> 
> Here is a simple variadic function:
> 
> template myFuncImpl(T) {
>   void myFuncImpl(T) {
>     static if (is (T == Empty)) {
>       writefln("Done");
>     } else {
>       writefln("Got argument %s of type %s",args.head,
>                typeid(typeof(args.head)));
>       .myFuncImpl(T.tail); // tail-recurse
>     }
>   }
> }
> 
> struct myFuncImplDummy { mixin decl_vararg_func!(myFuncImpl); }
> alias myFuncImplDummy.func myFunc;
> 
> And here is how it's called:
> 
> void main() {
>   myFunc(1.0,2,3L);
>   myFunc();
> }
> 
> Is there any better way to do the decl_vararg_func and dummy struct 
> thing? An identifier name template parameter type would be awesome* (I 
> would have other uses for that as well).

// Just change the 'func' to decl_vararg_func to take advantage
// of implicit template name promotion.
template decl_vararg_func(alias realFunc) {
   template decl_vararg_func(A = Empty, B = Empty, C = Empty, D = Empty, 
E = Empty, F = Empty, G = Empty /*, ...*/) {
     static void decl_vararg_func(A a = A.init, B b = B.init, C c = 
C.init, D d = D.init, E e = E.init, F f = F.init, G g = G.init /*,...*/) {
       realFunc(Tuple(a,b,c,d,e,f,g /*,...*/));
     }
   }
}

// and there's no need for a mixin.
alias decl_vararg_func!(funcImpl) myFunc;


Which means the best effort so far is:


 > import variadic;
 >
 > template myFuncImpl(T) {
 >   void myFuncImpl(T) {
 >     static if (is (T == Empty)) {
 >       writefln("Done");
 >     } else {
 >       writefln("Got argument %s of type %s",args.head,
 >                typeid(typeof(args.head)));
 >       .myFuncImpl(T.tail); // tail-recurse
 >     }
 >   }
 > }
 >
 > alias decl_vararg_func!(myFuncImpl) myFunc;
 >
  > void main() {
 >   myFunc(1.0,2,3L);
 >   myFunc();
 > }



More information about the Digitalmars-d mailing list