Retreive method given object, name and arguments

ketmar via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Thu Aug 11 14:12:45 PDT 2016


On Thursday, 11 August 2016 at 20:27:51 UTC, Michael Coulombe 
wrote:

here is something for you to play with:


import std.stdio;

enum CallAllowed0;
enum CallAllowed1;

struct S {
   @CallAllowed0 void foo () { writeln("foo()"); }
   @CallAllowed1 void foo (int n) { writeln("foo(", n, ")"); }
}


bool hasGoodMethod(string methodName, UDA, C, Args...) () {
   import std.traits: hasUDA;
   bool res = false;
   alias Identity(T...) = T[0];
   foreach (string mem; __traits(allMembers, C)) {
     static if (mem == methodName) {
       static if (is(typeof(__traits(getMember, C, mem)))) {
         alias mx = Identity!(__traits(getMember, C, mem));
         foreach (auto t; __traits(getOverloads, C, mem)) {
           static if (hasUDA!(t, UDA)) {
             static if (is(typeof((Args args) { auto dg = &t; 
dg(args); }))) {
               res = true;
               break;
             }
           }
         }
       }
     }
   }
   return res;
}

auto doit(string methodName, UDA, C, Args...) (C c, Args args) {
   static if (hasGoodMethod!(methodName, UDA, C, Args)) {
     mixin("return c."~methodName~"(args);");
   } else {
     static assert(0, "can't call method '"~methodName~"' in type 
"~C.stringof);
   }
}


void main () {
   S s;
   version(v0) {
     s.doit!("foo", CallAllowed0)(42);
   } else version(v1) {
     s.doit!("foo", CallAllowed1)(42);
   } else version(v2) {
     s.doit!("foo", CallAllowed0)();
   } else version(v3) {
     s.doit!("foo", CallAllowed1)();
   } else {
     static assert(0, "version?");
   }
}


% rdmd -version=v0 z02.d
z02.d(47): Error: static assert  "can't call method 'foo' in type 
S"
z02.d(55):        instantiated from here: doit!("foo", 
CallAllowed0, S, int)

% rdmd -version=v1 z02.d
foo(42)

% rdmd -version=v2 z02.d
foo()

% rdmd -version=v3 z02.d
z02.d(47): Error: static assert  "can't call method 'foo' in type 
S"
z02.d(61):        instantiated from here: doit!("foo", 
CallAllowed1, S)


More information about the Digitalmars-d-learn mailing list