```
     /// Add a single line to an existing header
     auto addLine(T...)(RecordType type, T kvargs)
     if(kvargs.length > 0 && isSomeString!(T[0]))
     {
        static assert (kvargs.length %2 == 0);   // K-V pairs => even number of variadic args

         string varargMagic(size_t len)
         {
             string args = "sam_hdr_add_line(this.h, type.ptr, ";
             for(int i=0; i<len; i++)
                 args ~= "toStringz(kvargs[" ~ i.to!string ~ "]), ";
             args ~= "null)";
             return args;
         }

         return mixin(varargMagic(kvargs.length));
     }
```
[...]
Question:
If a variadic template, despite presenting to the user a "dynamic array", MUST know its parameter list at compile-time, is there a way (other than with mixins as shown) to pass this parameter list to extern(C) linkage function with variadic parameters?

Easy peasy:

        import std.meta: Repeat;
        Repeat!(kvargs.length, const(char)*) zs;
        foreach (i, ref z; zs) z = toStringz(kvargs[i]);
        return sam_hdr_add_line(this.h, type.ptr, zs, null);

By the way, `kvargs` is not a dynamic array. Its length is not dynamic, and it's not an array.

Also, you don't just want to pass the parameters forward. That would be trivial: `sam_hdr_add_line(this.h, type.ptr, kvargs, null)`. You want to run them through another function first. That's where the difficulty comes from.

(bonus question: if yes, can it be done with typesafe variadic function where I believe parameter list is known at either compile time OR runtime, depending on how called)

I don't see when it would matter how the function is called, but you can declare it in two different ways:

1) True typesafe variadic:

    auto addLine(RecordType type, string[] kvargs ...)

2) Template + typesafe variadic:

    auto addLine(size_t n)(RecordType type, string[n] kvargs ...)

In the first one, `kvargs.length` is a dynamic value. You can't use it to generate the arguments for a `sam_hdr_add_line` call.

In the second one, `kvargs.length` is a static value. So you can do the same things as in the `T...` template. And just like the `T...` template, it will generate a new function for every distinct `kvargs.length`.

Reply via email to