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));
}
-------

Reply via email to