March 02, 2007
Frits van Bommel a écrit :
> renoX wrote:
>> Frits van Bommel a écrit :
>>> renoX wrote:
>>>> char[] sputf(A...)()
>>>> {
>>>>      return "std.string.format("~Fmt!(A) ~ ");";
>>>> }
>>>>
>>>> And still call it like you do above?
>>>> It doesn't work when I try to do this, I don't understand why..
>>>
>>> For one thing, the ';' shouldn't be there.
>>
>> Weird, the template that I had already for the 'writef equivalent' was:
>> template putf(A...)
>> {
>>     const char[] putf = "writef(" ~ Fmt!(A) ~ ");";
>> }
>> Here the ';' didn't create a problem, it's string that in the sputf template function it creates a problem..
> 
> There are three kinds of mixins[1]: mixin declarations, mixin statements and mixin expressions. Your putf string is used as a mixin statement, while the sputf string is used as a mixin expression.
> See http://www.digitalmars.com/d/changelog.html#new1_005 for the spec links, but essentially mixin statements generate statements (including any terminating ';'s) while mixin expressions just generate (sub)expressions, which don't contain ';'s.
> 
> 
> [1] excluding template mixins, which are a different beast altogether.
> 
>>> Then you get this:
>>> ---
>>> import std.stdio;
>>> import std.string;
>>>
>>> /** dummy Fmt!() for testing. This example assumes it accepts a
>>>  *  tuple and returns format() parameters in string form.
>>>  */
>>> template Fmt(A...) {
>>>     const char[] Fmt = `"%d", x`;
>>> }
>>>
>>> char[] sputf(A...)()
>>> {
>>>      return "std.string.format(" ~ Fmt!(A) ~ ")";
>>> }
>>>
>>> void main(char[][] args) {
>>>     char[] ret;
>>>     int x = 2007;
>>>         ret = mixin(sputf!("%d{x}"));
>>>         writefln("%s", ret);
>>> }
>>> ---
>>> which seems to work.
>>
>> Yes, but what is a bit strange is that if x is an int variable
>> res = mixin(sputf!("%d",x)); fails (it works if x is a const int)
>> but mixin(putf!("%d",x)); works (putf being the template given above).
> 
> The behaviors differ? That's a bit weird...
> They both use template parameters, so they should have the exact same restrictions AFAIK.
> 
> [a bit of research later]
> I think this is a restriction of compile-time function evaluation.
>  From http://www.digitalmars.com/d/function.html#interpretation :
> ---
> expressions in the function may not:
> [snip]
>     * reference any global state or variables
>     * reference any local static variables
> [snip]
> ---
> Those /could/ be interpreted to disallow alias template parameter usage...
> 
> Luckily the fix is easy, just transform it to be similar to your putf template to avoid CTFE:
> ---
> template sputf(A...)
> {
>      const sputf = "std.string.format(" ~ Fmt!(A) ~ ")";
> }
> ---
> works perfectly fine, even with non-constant integer variables as parameters.
> 
> And the call syntax didn't even change :).

Great!
Thanks a lot!

renoX
March 02, 2007
Here's the result.

Fixing my problems with sputf! helped me shorten the self-test part in the main function.

So thanks again.

renoX


1 2
Next ›   Last »