Thread overview
how to detect ctfe
Jun 01, 2014
Vlad Levenfeld
Jun 01, 2014
bearophile
Jun 01, 2014
Philpax
Jun 01, 2014
Philippe Sigaud
June 01, 2014
Is there any way that I can detect whether or not a function is being evaluated at compile time? Specifically I want to switch between to use/not to use memoize!func without having to figure out when its CTFE-able and calling it with different syntax.
June 01, 2014
Vlad Levenfeld:

> Is there any way that I can detect whether or not a function is being evaluated at compile time? Specifically I want to switch between to use/not to use memoize!func without having to figure out when its CTFE-able and calling it with different syntax.

Calling it with a different syntax seems not easy to do. But there is a run-time variable __ctfe that can be used to disable/enable the memoization.

Bye,
bearophile
June 01, 2014
__ctfe can be used for this purpose:

"The __ctfe boolean pseudo-variable, which evaluates to true at compile time, but false at run time, can be used to provide an alternative execution path to avoid operations which are forbidden at compile time. Every usage of __ctfe is evaluated before code generation and therefore has no run-time cost, even if no optimizer is used." ( http://dlang.org/function.html )
June 01, 2014
But let's keep in mind it's a *runtime* value. You cannot use it at
compile-time as a boolean for a 'static if'.
So:

if (__ctfe) // yes
{
    // compile-time path
}
else
{
    // runtime path
}

But not:

static if (__ctfe) // no
{
    // compile-time path, including new global declarations
}
else
{
    // runtime path
}

Why would you want to do that? I needed an associative array for my code. AA don't work that well at compile-time. So I wanted to replace them with my own Associative struct, maybe less efficient/generic, but that works at CT. The idea was:

static if (__ctfe)
    alias Type = Associative!(string, string);
else
    alias Type = string[string];

// then, use Type, whatever the path.