On 9/13/20 2:35 PM, ag0aep6g wrote:
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);
Great, thank you!
By the way, `kvargs` is not a dynamic array. Its length is not dynamic,
and it's not an array.
I was incorrectly recalling the error message compiler emitted when
using the typesafe variadic FUNCTION (your method 1, below)
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.
Right, I indeed left that out of the problem statement; the trivial
variadic template params pass right on through which is awesome.
I don't see when it would matter how the function is called, but you can
declare it in two different ways:
My assumption is that if called passing a [runtime] dynamic array, of
course the parameter list cannot be known, but the (below) "Type 1 True
typesafe variadic" can also be called with a fixed parameter list known
at compile-time.
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.
My point of surprise was that -- depending on how invoked ( f(anArray)
versus f(1,2,3) the compiler may know at compile-time the parameter
list. But from a complexity standpoint it makes sense that it is
nonetheless not possible to use.
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`.
Great, I never thought of parameterizing as a static array. This looks
the best IMO.