Thread overview
to!string(double) at compile time
Aug 21, 2012
Bobby Bingham
Aug 21, 2012
cal
Aug 23, 2012
Philippe Sigaud
Jan 02, 2016
timothee cour
August 21, 2012
I'm just getting started with D, and was playing around with string mixins.  I've hit a snag, and have reduced it to a minimal test case:

    import std.conv;

    string test()
    {
        return to!string(0.0);
    }

    immutable auto testvar = mixin(test());

This gives this result when compiling:

/usr/include/phobos2/std/format.d(1479): Error: snprintf cannot be interpreted at compile time, because it has no available source code
/usr/include/phobos2/std/conv.d(99):        called from here: formatValue(w,src,f)
/usr/include/phobos2/std/conv.d(824):        called from here: toStr(value)
/usr/include/phobos2/std/conv.d(268):        called from here: toImpl(_param_0)
test.d(6):        called from here: to(0)
test.d(9):        called from here: test()
test.d(9): Error: argument to mixin must be a string, not (test())

I guess converting a double to a string can't be done at compile time because it requires calling the C snprintf function?  It compiles fine if I replace the 0.0 with an int literal.  Is there any way around this limitation?
August 21, 2012
On Tuesday, 21 August 2012 at 04:43:09 UTC, Bobby Bingham wrote:
> I'm just getting started with D, and was playing around with string
> mixins.  I've hit a snag, and have reduced it to a minimal test case:
>
>     import std.conv;
>
>     string test()
>     {
>         return to!string(0.0);
>     }
>
>     immutable auto testvar = mixin(test());
>
> This gives this result when compiling:
>
> /usr/include/phobos2/std/format.d(1479): Error: snprintf cannot be interpreted at compile time, because it has no available source code
> /usr/include/phobos2/std/conv.d(99):        called from here: formatValue(w,src,f)
> /usr/include/phobos2/std/conv.d(824):        called from here: toStr(value)
> /usr/include/phobos2/std/conv.d(268):        called from here: toImpl(_param_0)
> test.d(6):        called from here: to(0)
> test.d(9):        called from here: test()
> test.d(9): Error: argument to mixin must be a string, not (test())
>
> I guess converting a double to a string can't be done at compile time
> because it requires calling the C snprintf function?  It compiles fine
> if I replace the 0.0 with an int literal.  Is there any way around
> this limitation?

I have had to work around this also. One way is to first multiply your float by a large factor (say 10000 depending on what precision you want) and then adding a decimal point back in to the string. Kinda hacky, but... Here is an example:

int fx = cast(int) (cos(angle)*1000000.);
string fsx = fx.to!string;

string xprefix;
if (fsx[0] == '-')
{
  xprefix = "-";
  fsx = fsx[1..$];
}

if (fsx.length == 7)
  sx = xprefix ~ fsx[0] ~ "." ~ fsx[1..$];
else
  sx = xprefix ~ "0." ~ fsx;

sx is then the string you want to mixin.
August 23, 2012
On Tue, Aug 21, 2012 at 6:43 AM, Bobby Bingham <uhmmmm@gmail.com> wrote:
> I'm just getting started with D, and was playing around with string mixins.  I've hit a snag, and have reduced it to a minimal test case:
>
>     import std.conv;
>
>     string test()
>     {
>         return to!string(0.0);
>     }
>
>     immutable auto testvar = mixin(test());
>

> I guess converting a double to a string can't be done at compile time because it requires calling the C snprintf function?  It compiles fine if I replace the 0.0 with an int literal.  Is there any way around this limitation?

A possibility is to use a function template, passing the double as a template argument:

string test(double d)() // d is a template argument
{
    return d.stringof;
}

enum testvar = mixin(test!(3.14));

void main()
{
    pragma(msg, testvar);
}
January 02, 2016
On Thursday, 23 August 2012 at 13:56:05 UTC, Philippe Sigaud wrote:
> On Tue, Aug 21, 2012 at 6:43 AM, Bobby Bingham <uhmmmm@gmail.com> wrote:
>>[...]
>
>> [...]
>
> A possibility is to use a function template, passing the double as a template argument:
>
> string test(double d)() // d is a template argument
> {
>     return d.stringof;
> }
>
> enum testvar = mixin(test!(3.14));
>
> void main()
> {
>     pragma(msg, testvar);
> }

https://issues.dlang.org/show_bug.cgi?id=15497