View mode: basic / threaded / horizontal-split · Log in · Help
September 12, 2008
CTFE determination?
Hi i was messing around in D2 and noticed that the following always is saying that it is only at runtime even when the input is a constant... was wondering if there was a right way to do this.

import std.stdio;

void main(char[][] args)
{
	
	writefln("test");
	auto ct = test(cast(char[])"123");
	auto rt = test(args[0]);
	writefln(ct);
	writefln(rt);

}

pure char[] test(char[] src)
{
//	foo!(src);
	static if(__traits(compiles,foo!(src)/*check for something only available at compile time...*/))
	{
		return ((cast(char[])"argument available at compiletime of '")~src~cast(char[])"'");
	}
	else
	{
		return (cast(char[])"argument available at runtime of '")~src~(cast(char[])"'");
	}
}

pure template foo(char[] src)
{
	const uint foo = src.length;
}
September 12, 2008
Re: CTFE determination?
bmeck wrote:
> Hi i was messing around in D2 and noticed that the following always is saying that it is only at runtime even when the input is a constant... was wondering if there was a right way to do this.

CTFE only kicks in when the function is called in a context which 
requires a compile-time constant, such as passing the return value from 
the function as the parameter to a template.

If you don't use the function in that context, then CTFE is *not* 
active.  Thus, your test() function is *not* compile-time evaluated.

The basic reason for this is that if you write a long-running scientific 
program with fixed inputs you don't want CTFE to kick in just because 
the inputs are hard-coded.
September 12, 2008
Re: CTFE determination?
well any suggestion on how to determine if a parameter is constant at run time? that is my goal overall... right now it seems casting to invariant ruins anything I can come up with.
September 12, 2008
Re: CTFE determination?
bmeck:

> well any suggestion on how to determine if a parameter is constant at run time?

How do you plan to use such information once you have it?

Bye,
bearophile
September 12, 2008
Re: CTFE determination?
bmeck <bmeck@stedwards.edu> wrote:
> well any suggestion on how to determine if a parameter is constant at 
> run time? that is my goal overall... right now it seems casting to 
> invariant ruins anything I can come up with.

I cannot quite understand what are you trying to achieve here.  This is 
my solution if I got you right:

---
import std.stdio;

void main(string[] args)
{
	
	writefln("test");

	static if (__traits(compiles, CompileTime!("123")))
		writeln("123 compile");
	else
		writeln("123 run");

	static if (__traits(compiles, CompileTime!(args[0])))
		writeln("args[0] compile");
	else
		writeln("args[0] run");

}

template CompileTime(alias Expr)
{
}
---
September 12, 2008
Re: CTFE determination?
I just get both at run time with your example. I was hoping to encapsulate it somehow so you could just have:

import std.stdio;

void main(string[] args)
{
       
       writefln("test");

       static if (CompileTimeAvailable!("123"))
               writeln("123 compile");
       else
               writeln("123 run");

       static if (CompileTimeAvailable!(args[0]))
               writeln("args[0] compile");
       else
               writeln("args[0] run");

}
template CompileTimeAvailable(alias expr)
{
   static if(__traits(compiles, CompileTime!(expr)))
       CompileTimeAvailable = false;
   else
       CompileTimeAvailable = false;
}
template CompileTime(alias Expr)
{
  auto CompileTime = Expr;//Need this to force it to check for CTFE
}

unfortunately args[0] is not constant so no go...
September 12, 2008
Re: CTFE determination?
Well if it is available at CTFE I want to hash out as much as possible calculations and store the result, if its not, dont mess with the data and send it to a functions that does the same calculations and stores the result at run time but in a different manner, namely allowing pointers heap etc.

IE: if args = ["\w+$"] // gets last word

auto reg1 = Regex("\w+$"); // woot got enough to make the struct at Compile time , use structs as needed and hard code that sucker!
auto reg2 = Regex(args[0]); // uh oh, dont know at compile time, leave it to a run time call and use pointers and heap as needed!
September 12, 2008
Re: CTFE determination?
bmeck <bmeck@stedwards.edu> wrote:
> I just get both at run time with your example.

Again I cannot understand what you are trying to say.  Does my example 
prints wrong results?  I'm using DMD 2.019 and get the following:

>dmd -run test.d
test
123 compile
args[0] run

so it says that "123" is available at run time, args[0] is not.  As 
expected.

> I was hoping to encapsulate it somehow so you could just have:
> 
> import std.stdio;
> 
> void main(string[] args)
> {
>         
>         writefln("test");
> 
>         static if (CompileTimeAvailable!("123"))
>                 writeln("123 compile");
>         else
>                 writeln("123 run");
> 
>         static if (CompileTimeAvailable!(args[0]))
>                 writeln("args[0] compile");
>         else
>                 writeln("args[0] run");
> 
> }
> template CompileTimeAvailable(alias expr)
> {
>     static if(__traits(compiles, CompileTime!(expr)))
>         CompileTimeAvailable = false;
>     else
>         CompileTimeAvailable = false;
> }
> template CompileTime(alias Expr)
> {
>    auto CompileTime = Expr;//Need this to force it to check for CTFE
> }
> 
> unfortunately args[0] is not constant so no go...

Are you sure you've posted the right example?  I can see no attempts at 
encapsulation.  Maybe you wanted

> void main(string[] args)
> {
> 	writeln("123 at compile time: ", CompileTimeAvailable!("123"));
> 	writeln("args[0] at compile time: ", CompileTimeAvailable!(args[0]));
> }
September 12, 2008
Re: CTFE determination?
bmeck <bmeck@stedwards.edu> wrote:
> Well if it is available at CTFE I want to hash out as much as possible 
> calculations and store the result, if its not, dont mess with the data 
> and send it to a functions that does the same calculations and stores 
> the result at run time but in a different manner, namely allowing 
> pointers heap etc.

Got it.
This is the best I could come up with to the moment, but it works:

---
import std.stdio;

void main(string[] args)
{
	mixin CtfeIfPossible!( q{auto r1 =} , q{foo("test")} );
	mixin CtfeIfPossible!( q{auto r2 =} , q{foo(args[0])} );

	writeln(r1);
	writeln(r2);
}

string foo(string s)
{
	return s ~ "-modified";
}

template CompileTime(alias Expr)
{
	enum CompileTime = Expr;
}

template CtfeIfPossible(string Decl, string Expr)
{
	static if (__traits(compiles, CompileTime!(mixin(Expr))))
	{
		pragma(msg, "compile time ", Expr);
		mixin(Decl ~ "CompileTime!(" ~ Expr ~ ");");
	}
	else
	{
		pragma(msg, "runtime ", Expr);
		mixin(Decl ~ Expr ~ ";");
	}
}
---

It prints:

>dmd -run "test.d"
compile time foo("test")
runtime foo(args[0])
test-modified
C:\tmp\test.exe-modified
September 14, 2008
Re: CTFE determination?
bmeck wrote:
> well any suggestion on how to determine if a parameter is constant at run time? that is my goal overall... right now it seems casting to invariant ruins anything I can come up with.

Remember that when a function is not run through CTFE, then it doesn't 
really know anything about the arguments that it is passed.  It could be 
called several times, sometimes with compile-time-constant args, and 
sometimes without.

In order to tell the difference, you have to take on the responsibility 
to specialize the function yourself.  One option is to make the function 
a template, and then pass the compile-time-constant arguments as 
template parameters:

	void myFunc(int CompileTime1, char[] CompileTime2)
	           (int runtime)

...but that only works if you know that the same args will be compile 
time args.
« First   ‹ Prev
1 2
Top | Discussion index | About this forum | D home