May 31, 2006 Re: Function pointer argument to function template | ||||
---|---|---|---|---|
| ||||
Posted in reply to Tom S | Tom S skrev: > Daniel Keep wrote: >> Actually, it's quite simple, if utterly evil. It involves abusing IFTI >> in the most gruesome manner imaginable... >> >> Detecting the number of arguments looks like this: >> >> ( ... ) >> > > Neat !! I didn't realize IFTI could do that :D I agree! But how can you call something this beautiful evil? :) >> Thankfully, I have a nifty little Python script that saves me having to >> actually *type* all that out. I give it a maximum number of arguments, >> and it goes off and generates the template for me. Evil was never so easy! > > Hehehe, I use it as well for other sorts of stuff, where I have to generate lots of such code that would be handled by variadic templates if we had them ;) I think you can manage this without needing to resort to autogenerated code by using a generic variadic template list generator. There will still be a hard-coded limit in the maximum number of function arguments though. > How about taking it a step further and doing something like: > > ---- > import std.stdio; > > struct FuncMeta(int NumArgs, Ret, T0=void, T1=void /+, and, so, on+/) { > alias FuncMeta Meta; > > static const int numArgs = NumArgs; > alias Ret RetType; > alias T0 Arg0Type; // these might use static if as well > alias T1 Arg1Type; > /+ > ... and so on > +/ > } [snip the rest] Marvelous! this will be very useful for me in a number of places. /Oskar |
June 03, 2006 Re: Function pointer argument to function template | ||||
---|---|---|---|---|
| ||||
Posted in reply to Tom S | Tom S wrote: > Hey there :) > > I came up with this: > > ---- > > import std.stdio; > > template Deref(T) { > alias typeof(*T) Deref; > } > > template RetType(T) { > static if (is(Deref!(T) U == function)) { > alias U RetType; > } else static assert (false); > } > > template Bar(T, U=RetType!(T)) { > U Bar(T t) { > writefln(typeid(U)); > > // do something :P > return U.init; > } > } > > > cfloat func(int a, float b) { > return 1.f + 0i; > } > > > void main() { > writefln(Bar(&func)); > } > > > -- > Tomasz Stachowiak /+ a.k.a. h3r3tic +/ Just for the record, here's an alternative version, smaller, but less flexible(because you must know the parameters of the T function, and you have worse error messages): template Bar(T, U = typeof(T(0,0)) ) { U Bar(T t) { writefln(typeid(U)); return U.init; } } cfloat func(int a, float b) { return 1.f + 0i; } void main() { writefln(Bar(&func)); } -- Bruno Medeiros - CS/E student http://www.prowiki.org/wiki4d/wiki.cgi?BrunoMedeiros#D |
June 03, 2006 Re: Function pointer argument to function template | ||||
---|---|---|---|---|
| ||||
Posted in reply to Tom S | Tom S wrote: > > How about taking it a step further and doing something like: > > ---- > import std.stdio; > > struct FuncMeta(int NumArgs, Ret, T0=void, T1=void /+, and, so, on+/) { > alias FuncMeta Meta; > > static const int numArgs = NumArgs; > alias Ret RetType; > alias T0 Arg0Type; // these might use static if as well > alias T1 Arg1Type; > /+ > ... and so on > +/ > } > > > template funcInfo(Ret) { > FuncMeta!(0, Ret) funcInfo(Ret function() x) { assert(false); }; > } > > > template funcInfo(Ret, T0) { > FuncMeta!(1, Ret, T0) funcInfo(Ret function(T0) x) { assert(false); }; > } > > > template funcInfo(Ret, T0, T1) { > FuncMeta!(2, Ret, T0, T1) funcInfo(Ret function(T0, T1) x) { assert(false); }; > } > > /+ > .... > > template funcInfo(Ret, T0, T1, ..., Tn) { > ... > } > +/ > > > struct Foo {} > void fooFunc(Foo a, float b) {} > int barFunc(cfloat x) {} > > > void main(char[][] args) { > writefln("Number of args of main: ", funcInfo(&main).numArgs); > > writefln("\nfunc foo:"); > alias typeof(funcInfo(&fooFunc)) FooMeta; > writefln(FooMeta.numArgs); > writefln(typeid(FooMeta.RetType)); > writefln(typeid(FooMeta.Arg0Type)); > writefln(typeid(FooMeta.Arg1Type)); > > writefln("\nfunc bar:"); > alias typeof(funcInfo(&barFunc)) BarMeta; > writefln(BarMeta.numArgs); > writefln(typeid(BarMeta.RetType)); > writefln(typeid(BarMeta.Arg0Type)); > > static if (BarMeta.numArgs >= 2) { > writefln(typeid(BarMeta.Arg1Type)); > } else { > writefln("bar doesn't have Arg1Type"); > } > } > > > Note that the ArgXType could be static if'fed away so one would get an error when trying to access them instead of having them alias to void. > > Hum, pretty nice! -- Bruno Medeiros - CS/E student http://www.prowiki.org/wiki4d/wiki.cgi?BrunoMedeiros#D |
Copyright © 1999-2021 by the D Language Foundation