October 05, 2006
Chad J > schrieb:
> I'm trying to write a template that, when instantiated, gives a value that is the same as the last time it was instantiated plus one.  Here is some code I tried, but it doesn't work:
> 
> import std.stdio;
> 
> template GetUID()
> {
>     const ulong accumulator;
> 
>     static if ( ++accumulator != 0 )
>         const ulong GetUID = accumulator;
>     else
>         static assert(0);
> }
> 
> void main()
> {
>     writefln( GetUID!() ); // should print 1
>     writefln( GetUID!() ); // should print 2
> }
> 
> Hopefully that gives a good idea of what I am shooting for.


This is a bit complicated to explain: Compile time constructs (templates) work just like a functional language: They are fully deterministic, the only way you can modify the result is by modifying the parameters.

If you want to use a counter you'd have to use a recursive approach like this:

template counter(uint max, uint i=0)
{
    void initialize()
    {
        writefln(i); // Insert your statement hier
        static if (i<max)
            counter!(max, i+1).initialize();
    }
}

Although that's perhaps not a real speedup compared to initializing the program with a counter at runtime...
October 06, 2006
Markus Dangl wrote:
> Chad J > schrieb:
>> I'm trying to write a template that, when instantiated, gives a value that is the same as the last time it was instantiated plus one.  Here is some code I tried, but it doesn't work:
>>
>> import std.stdio;
>>
>> template GetUID()
>> {
>>     const ulong accumulator;
>>
>>     static if ( ++accumulator != 0 )
>>         const ulong GetUID = accumulator;
>>     else
>>         static assert(0);
>> }
>>
>> void main()
>> {
>>     writefln( GetUID!() ); // should print 1
>>     writefln( GetUID!() ); // should print 2
>> }
>>
>> Hopefully that gives a good idea of what I am shooting for.
> 
> 
> This is a bit complicated to explain: Compile time constructs (templates) work just like a functional language: They are fully deterministic, the only way you can modify the result is by modifying the parameters.
> 
> If you want to use a counter you'd have to use a recursive approach like this:
> 
> template counter(uint max, uint i=0)
> {
>     void initialize()
>     {
>         writefln(i); // Insert your statement hier
>         static if (i<max)
>             counter!(max, i+1).initialize();
>     }
> }
> 
> Although that's perhaps not a real speedup compared to initializing the program with a counter at runtime...

could you elaborate with an example I can compile,
at the moment I don't see how to put it in a working app

thx,
roel
October 06, 2006
>> Although that's perhaps not a real speedup compared to initializing the
>> program with a counter at runtime...
> 
> could you elaborate with an example I can compile,
> at the moment I don't see how to put it in a working app
> 
> thx,
> roel

Here is a full example, it compiles and runs with my DMD 0.168:
=====
module CompileTimeCounter;
import std.stdio;

pragma(msg, "-- This is at compile time");

// Converts an integer i to a string at compile time.
// Needed for pragma(msg).
template itoa(int i)
{
    static if (i < 10)  const char[] itoa = "0123456789"[i..i+1];
    else const char[] itoa = itoa!(i/10) ~ "0123456789"[i%10];
}

// A counter that runs at compile time.
template counter(uint max, uint i=0)
{
    void initialize()
    {
        pragma(msg, itoa!(i));
        writefln(i);

        static if (i<max)
            counter!(max, i+1).initialize();
    }
}

// ncounter has to be const, so it is accessible at compile time.
const int ncounter = 10;

int main(char[][]args)
{
    writefln("-- This is at run time");
    counter!(ncounter).initialize();
    return 0;
}
====
As you can see when you're compiling it counts from 0 to 10 (including 10). When you run the resulting exe file, it will also print the numbers from 0 to 10, but this time there isn't a real counter involved, it's just like having
writefln(0);
writefln(1);
writefln(2);
...
in your code. To be exact, each writefln() is wrapped up in a seperate function, this is why i think that a counter at compile time isn't really efficient.
October 06, 2006
Markus Dangl wrote:
>>> Although that's perhaps not a real speedup compared to initializing the program with a counter at runtime...
>>
>> could you elaborate with an example I can compile,
>> at the moment I don't see how to put it in a working app
>>
>> thx,
>> roel
> 
> Here is a full example, it compiles and runs with my DMD 0.168:
> =====
> module CompileTimeCounter;
> import std.stdio;
> 
> pragma(msg, "-- This is at compile time");
> 
> // Converts an integer i to a string at compile time.
> // Needed for pragma(msg).
> template itoa(int i)
> {
>     static if (i < 10)  const char[] itoa = "0123456789"[i..i+1];
>     else const char[] itoa = itoa!(i/10) ~ "0123456789"[i%10];
> }
> 
> // A counter that runs at compile time.
> template counter(uint max, uint i=0)
> {
>     void initialize()
>     {
>         pragma(msg, itoa!(i));
>         writefln(i);
> 
>         static if (i<max)
>             counter!(max, i+1).initialize();
>     }
> }
> 
> // ncounter has to be const, so it is accessible at compile time. const int ncounter = 10;
> 
> int main(char[][]args)
> {
>     writefln("-- This is at run time");
>     counter!(ncounter).initialize();
>     return 0;
> }
> ====
> As you can see when you're compiling it counts from 0 to 10 (including
> 10). When you run the resulting exe file, it will also print the numbers
> from 0 to 10, but this time there isn't a real counter involved, it's
> just like having
> writefln(0);
> writefln(1);
> writefln(2);
> ...
> in your code. To be exact, each writefln() is wrapped up in a seperate
> function, this is why i think that a counter at compile time isn't
> really efficient.

thx for the itoa stuff, was searching for that!

my problem was indeed that I couldn't come up with a identical reusable statement.

roel
October 08, 2006
rm schrieb:
> 
> thx for the itoa stuff, was searching for that!
> 
> my problem was indeed that I couldn't come up with a identical reusable
> statement.
> 
> roel

I actually took itoa from Tom S' ctrace: http://www-users.mat.uni.torun.pl/~h3r3tic/ctrace/

I have some compile time lists that i designed myself, and some other stuff, if you ever need lists at compile time contact me by mail :)
October 09, 2006
Markus Dangl wrote:
> rm schrieb:
>>
>> thx for the itoa stuff, was searching for that!
>>
>> my problem was indeed that I couldn't come up with a identical reusable
>> statement.
>>
>> roel
> 
> I actually took itoa from Tom S' ctrace: http://www-users.mat.uni.torun.pl/~h3r3tic/ctrace/

And he took it from mine... this stuff goes back a long way.
> 
> I have some compile time lists that i designed myself, and some other stuff, if you ever need lists at compile time contact me by mail :)
1 2
Next ›   Last »