On Sunday, 13 September 2020 at 17:23:42 UTC, Steven Schveighoffer wrote:
On 9/13/20 12:55 PM, James Blachly wrote:

```
     /// 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));
     }
```

Interestingly, compilation fails if the mixin consists only of the comma-separated parameters ("Comma expression" [1])


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?

Was just talking about this exact problem with Adam Ruppe. Unfortunately, because the parameters are an expression tuple, and not a compile-time tuple, you can't use stuff like staticMap.

You actually can, if you define the right kind of helper function:

    /// 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
        immtuable(char)* argToStringz(alias arg)()
        {
            return toStringz(arg);
        }

return sam_hdr_add_line(this.h, this.ptr, staticMap!(argToStringz, kvargs), null);
    }

The clever trick here is that, because of optional parentheses [1], `argToStringz!(kvargs[i])` can be interpreted either as the name of a function or a function call, depending on the context it appears in.

[1] https://dlang.org/spec/function.html#optional-parenthesis

Reply via email to