Function meta information

downs default_357-line at yahoo.de
Sat Dec 26 08:42:27 PST 2009


Eldar Insafutdinov wrote:
> Currently we have ParameterTypeTuple for extracting type list of function arguments. This is not enough. There should be a clean way to extract storage classes and default arguments if there are any. Any thoughts?

Parsing stringof is not required.

There's a trick (see tools.base.[isRef, refToParamList, refToValueList]) that involves "sliding" a constant value over the parameter list and seeing if it works (if not, it's ref).

-------------------
Example usage:

struct YWrapper(C) {
  C callable;
  alias Ret!(C) R;
  mixin("R opCall("~
    refToParamList("" /* no leading parameter */, "Params!(C)[1 .. $]" /* types to check */, isRef!(C)[1 .. $] /* refness string */)~
    ") { return callable(&opCall"~
    refToValueList("," /* &opCall comes first, lead with comma */, isRef!(C)[1 .. $])~
    "); }"
  );
}

-------------------
The complete relevant code:

struct __isRef(C, size_t which) {
  alias ParameterTypeTuple!(C) pt;
  pt[0..which] pre;
  const pt[which] test;
  pt[which+1..$] post;
  const bool r = !is(typeof(C(pre, test, post)));
}

template _isRef(C, size_t which) { static if (__isRef!(C, which).r) const char _isRef='t'; else const char _isRef='f'; }

string refliteral(int len) {
  char[] res;
  for (int i=0; i<len; ++i) {
    res~="~_isRef!(C, "~ctToString(i)~")";
  }
  return "\"\""~res;
}

template isRef(C) { const string isRef=mixin(refliteral(Params!(C).length)); }

string refToParamList(string lead, string TUP, string refs) {
  string res;
  for (int i=0; i<refs.length; ++i) {
    if (refs[i]=='t') res~="ref ";
    res~=TUP~"["~ctToString(i)~"] param_"~ctToString(i);
    if (i<refs.length-1) res~=", ";
  }
  return res;
}

string refToValueList(string lead, string refs) {
  string res="";
  for (int i=0; i<refs.length; ++i) {
    if (i) res ~= ", ";
    else res ~= lead;
    res~="param_"~ctToString(i);
  }
  return res;
}



More information about the Digitalmars-d mailing list