Mixin and function template?

Frits van Bommel fvbommel at REMwOVExCAPSs.nl
Wed Feb 28 02:31:57 PST 2007

renoX wrote:
> I have a template which contain a single function:

Let's start with that code...

> template sputf(A...)
> {
> 	char[] call()
> 	{
> 		auto fd=std.c.stdio.fopen("tmp_file", "w+");

> 		mixin(`fwritef(fd,`~Fmt!(A)~`);`);	

This line is equivalent to:
		fwritef(fd, Fmt!(A));
no mixin() required.

> 		std.c.stdio.fclose(fd);
> 		auto res = cast(char[])read("tmp_file");

So basically, you're creating a temporary file, write some formatted 
output to it, then open it and put the contents in an allocated buffer?
Why not just:
		auto res = std.string.format(Fmt!(A));
That should allocate a string and fill it with with the formatted data. 
AFAICT it's equivalent to the above code, except the code above creates 
a file to do it, and so can get into trouble if multiple versions of it 
get run at the same time from the same directory...

> 		return res;

Also, you forgot to delete the file before returning. Unless that was 
intended? (I didn't think so :P)

> 	}
> }

template sputf(A...)
	char[] call()
		return std.string.format(Fmt!(A));
should be pretty much identical to your code, except for 
tempfile-related issues in your version.

> At the call site, I have to do the following:
> 	mixin sputf!("%d{x}") P1;
> 	res = P1.call();
> which is quite ugly, so I'd like to convert the code in a 'function template' but when I do this, I don't manage to call the function without failure..
> Does someone knows how to do it?

Well, presumably the function needs to access (local?) variable 'x'. 
That means you can't avoid using some kind of mixin if you want to do this.

But I don't think the code left in the template is very ugly, so you 
could also just use it directly, like this:
import std.string;

// ... some stuff here ...

// example function using Fmt!()
char[] func(int x) {
         char[] res = format(Fmt!("%d{x}"));
	return res;
Which is probably cleaner than anything you'll get without:
a) changing format() to be compile-time executable, or
b) waiting until Walter sufficiently improves compile-time execution to 
allow current format() to be usable, or
c) implementing a compile-time format-like function yourself (either as 
a compile-time executable function or through template meta programming).

More information about the Digitalmars-d-learn mailing list