printf() metaprogramming challenge

ag0aep6g anonymous at example.com
Fri May 24 00:24:38 UTC 2019


On 23.05.19 21:33, Walter Bright wrote:
> But what I'd like it to do is to extend it to convert a `string s` 
> argument into `cast(int)s.length, s.ptr` tuple and use the "%.*s" 
> specifier for it.
[...]
> Does anyone see a way to make this work?

I don't know if this satisfies the "no extra overhead" rule. Maybe when 
`arrlen` and `arrptr` are inlined?

int dprintf(string f, A ...)(A args)
{
     enum Fmts = Formats!(A);
     enum string s = formatString(f, Fmts);
     __gshared const(char)* s2 = s.ptr;
     import std.meta: staticMap;
     return printf(Seq!(s2, staticMap!(arg, args)));
}

template arg(alias a)
{
     static if (is(typeof(a) == string))
         alias arg = Seq!(arrlen!a, arrptr!a);
     else alias arg = a;
}

auto arrlen(alias a)() { return a.length; }
auto arrptr(alias a)() { return a.ptr; }

template Spec(T : string) { enum Spec = "%.*s"; }

void main()
{
     int i;
     dprintf!"hello %s %s %s %s betty %s\n"(3, 4.0, &i,
         "abc".ptr, "foobar");
}

// ... rest of the code unchanged ...


More information about the Digitalmars-d mailing list