Search code examples
d

Is foreach executed at compile time?


I wrote this piece of code to get hold of the types of a function passed by a pointer:

import std.stdio;
import std.traits;

void main()
{
  get_param_types(&f1,"f1");
  get_param_types(&f2,"f2");
  get_param_types(&f3,"f3");
}

void get_param_types(f_t)(f_t f, string f_id){
  writeln("get_param_types ");
  alias ParameterTypeTuple!(f) ptt;
  writeln(f_id, " has ", ptt.length, " parameters");
  static if (ptt.length){
    write("( ");
    foreach (pt; ptt){
      write(typeid(pt), " ");
    }
    writeln(")");
  }
}

void f1() { }
void f2(int x) { }
void f3(int x, double y, string z) { }

My doubt is: 1: Is get_param_types completely evaluated at compile time?

If not: 2: How can I achieve this?

And while I am at it... 3: Is there a way to avoid passing the strings (e.g. "f1") and deduce them from within get_param_types at compile time?


Solution

    1. get_param_types() in your example is evaluated at runtime, as you are calling it at runtime in main(). Note that it cannot be evaluated at compile time as-is, as you are making calls to write() and writeln() which write to stdout, which isn't available at compile time.
    2. What is it you want to achieve at compile time? All the calls to write and writeln can only happen at runtime in your example. The foreach and static if are evaluated at compile time... Essentially any call to that function will, at runtime, just call a combination of write and writeln - no loops or conditionals - is this what you want?
    3. You may like to look into template alias parameters. They look a little like this:
    void getParamTypes(alias fn)() if (isCallable!fn)
    {
        writefln("Getting parameter types for fn: %s", (&fn).stringof[2..$]);
        foreach (param; ParameterTypeTuple!fn) {
            writeln(param.stringof);
        }
    }