On Sunday, 27 September 2020 at 05:22:36 UTC, 60rntogo wrote:
How would I check if it is actually a free function?
but this doesn't even compile since I defined add inside my
main function
aaaaah that's not a free function!!
That's a nested function and thus actually has a hidden argument.
Of course, you could add `static` to it if it doesn't use other
local variables, then it will work again.
But to handle nested functions, you can simply add a check for
isNested too.
Bringing me to this:
-----
auto invoke(alias fun, Args...)(Args args)
{
static if(__traits(isStaticFunction, fun) || __traits(isNested,
fun))
return fun(args);
else
return __traits(child, args[0], fun)(args[1 .. $]);
}
// I think the above covers all the cases, what follows
// are just some tests of various situations.
struct Foo
{
bool isValid(int a)
{
return a > 0;
}
struct Bar {
void bar() {}
}
Bar bar;
}
int add3(int a, int b)
{
return a + b;
}
class A {
void test() {}
int item;
class B {
void other(int arg) { import std.stdio;
writeln(item, " nested ", arg); }
}
static class C {
void cool(string) {}
}
}
void main() {
auto a = new A;
a.item = 30;
invoke!(A.C.cool)(new A.C, "ok");
invoke!(A.B.other)(a.new B, 6);
invoke!(A.test)(a);
invoke!(Foo.Bar.bar)(Foo.Bar.init);
int add(int a, int b)
{
return a + b;
}
int add2(int a, int b)
{
return a + b;
}
assert(invoke!add(1, 2) == 3);
assert(invoke!add2(1, 2) == 3);
assert(invoke!add3(1, 2) == 3);
auto foo = Foo();
assert(invoke!(Foo.isValid)(foo, 3));
}
-------