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