Thread overview
Function meta information
Dec 25, 2009
Eldar Insafutdinov
Dec 25, 2009
Denis Koroskin
Dec 26, 2009
Daniel Keep
Dec 26, 2009
downs
Dec 27, 2009
Lutger
December 25, 2009
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?
December 25, 2009
On Fri, 25 Dec 2009 17:19:42 +0300, Eldar Insafutdinov <e.insafutdinov@gmail.com> 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?

I guess you must parse string representation of the function to get everythig you need as of now.
I know someone already did this and posted his code on dsource.org, but I can't tell where exactly I saw it out of my head.

If you decide to make your own implementation, here is a start:

struct Foo
{
}

void bar(ref Foo foo, int i = 42)
{
}

void Inspect(T)(T t)
{
	pragma(msg, T.stringof);
}

void main()
{
	Inspect(&bar);
}

Output:
void function(ref Foo foo, int i = 42)

Note that function properties are *extremely* bugged ATM - compiler mistakenly thinks that "bar" and typeof(bar)", or "bar.stringof" and "bar().stringof" are interchangeable (omissible parens hell). For example:

template ToString(alias func)
{
	pragma(msg, typeof(func).stringof);
	enum ToString = typeof(func).stringof;
}

void main()
{
	enum s = ToString!(bar);
}

results in the following output:

test.d(11): Error: expected 2 function arguments, not 0
(void(ref Foo foo, int i = 42))() // TADAM!
test.d(12): Error: expected 2 function arguments, not 0
test.d(17): Error: template instance test.ToString!(bar) error instantiating

This one will hopefully resolved once @property feature gets implemented and omissible parens will go away.
December 26, 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?

This might help.

http://gist.github.com/263832
December 26, 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;
}
December 27, 2009
On 12/25/2009 03:19 PM, 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?

In addition we need to be able to get the overloads for non-virtual functions.