www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Getting a template parameter list

reply "Philippe Sigaud" <philippe.sigaud gmail.com> writes:
As an aside to a reflection-related train of thought, I tired 
again to get a templated type's parameter list.

I mean, given

class C(T) { T t; }
Jul 23 2012
next sibling parent "Philippe Sigaud" <philippe.sigaud gmail.com> writes:
On Monday, 23 July 2012 at 13:32:54 UTC, Philippe Sigaud wrote:
 As an aside to a reflection-related train of thought, I tired 
 again to get a templated type's parameter list.

 I mean, given

 class C(T) { T t; }

Drat, 'tab' is dangerous with the forum interface, sorry for that. So given C above and auto c = new C!(int)(); I want a template that, given typeof(c), gives me back 'C' and 'int'. is() is our friend here, notably the new T... extension: import std.typetuple; template Composition(T) if (isComposite!T) { static if (is(T comp == Name!(U), alias Name, U) || is (T comp == Name!(U), alias Name, U...)) alias TypeTuple!(Name, U) Composition; } (isComposite!T is the same check with is()) Works beautifully: auto t = tuple(1,"abc", 'c'); writeln(Composition!(typeof(t)).stringof); // ("Tuple(Specs...)", int, string, char) So, I get "Tuple(Specs...)" (the template name) and the arguments. Nice! Except, this does not work for 2-args templates. I thought the U... branch would get them, but apparently, U... means 'with a template param tuple' very strictly. No problem, I'll just add the 2, 3 and 4-args cases, that should be enough. template Composition(T) if (isComposite!T) { static if (is(T comp == Name!(U), alias Name, U) || is (T comp == Name!(U), alias Name, U...)) alias TypeTuple!(Name, U) Composition; else static if (is(T comp == Name!(U,V), alias Name, U, V)) alias TypeTuple!(Name, U,V) Composition; else static if (is(T comp == Name!(U,V,W), alias Name, U, V, W)) alias TypeTuple!(Name, U,V,W) Composition; ... } (and isComposite accordingly). Right. Except, this only gets template instantiations with pure types as parameters. Things like std.algorithm.map which take a function by name are out. OK... So, I'll add also alias overloads. Hmm, Pure Type / Alias : 2 possibilities, so for 3 args that's 8 different tests to do + 4 for 2-params, + 2 for the single param and the tuple... Except, you can have a tuple also in 2-params and 3-params templates. Also, what about value template parameters? I tested, this does not work when passed strings or ints, or whatever. I should test for them also. Argh, so it's more 10 different possibilities per slot, the n-th power for n args. No way am I generating a template with more than a thousand(!) is() tests in it! Can someone offer me some advice on this? My old version that cheated with the type .stringof suddenly seems so much better. Philippe
Jul 23 2012
prev sibling next sibling parent "Simen Kjaeraas" <simen.kjaras gmail.com> writes:
On Mon, 23 Jul 2012 15:46:37 +0200, Philippe Sigaud  
<philippe.sigaud gmail.com> wrote:

 Can someone offer me some advice on this? My old version that cheated  
 with the type .stringof suddenly seems so much better.

This was filed as bug 3608[1], but that report was insufficiently specific, and so T... matching both a TemplateParameterList and a variadic TemplateParameter apparently did not make it into the patch. I'm unsure if I should mark the old bug report as reopened, or file a new one. [1]: http://d.puremagic.com/issues/show_bug.cgi?id=3608 -- Simen
Jul 23 2012
prev sibling next sibling parent Philippe Sigaud <philippe.sigaud gmail.com> writes:
On Mon, Jul 23, 2012 at 4:08 PM, Simen Kjaeraas <simen.kjaras gmail.com> wrote:

 This was filed as bug 3608[1], but that report was insufficiently specific,
 and so T... matching both a TemplateParameterList and a variadic
 TemplateParameter apparently did not make it into the patch.

 I'm unsure if I should mark the old bug report as reopened, or file a new
 one.

In a sense, it's cleaner that way: is() trailing params (or template specializations, as you used in the bug report) are exactly the ones present in the template. class C(T,U) {} // does not work on class C template dissect1(T : Name!(Params), alias Name, Params...) {} // works on class C template dissect2(T : Name!(Param1, Param2), alias Name, Param1, Param2) {} No ambiguity. But hell, a lot less power also. Sigh... I'll go back to parsing a .stringof representation. Philippe
Jul 23 2012
prev sibling next sibling parent "Simen Kjaeraas" <simen.kjaras gmail.com> writes:
On Tue, 24 Jul 2012 08:08:19 +0200, Philippe Sigaud  
<philippe.sigaud gmail.com> wrote:

 class C(T,U) {}

 // does not work on class C
 template dissect1(T : Name!(Params), alias Name, Params...) {}
 // works on class C
 template dissect2(T : Name!(Param1, Param2), alias Name, Param1, Param2)  
 {}

 No ambiguity. But hell, a lot less power also.

 Sigh... I'll go back to parsing a .stringof representation.

I went ahead and filed a new bug[1], and (90) minutes after, Kenji Hara responded this is already implemented for 2.060. [1]: http://d.puremagic.com/issues/show_bug.cgi?id=8420 -- Simen
Jul 24 2012
prev sibling parent Philippe Sigaud <philippe.sigaud gmail.com> writes:
On Tue, Jul 24, 2012 at 11:08 AM, Simen Kjaeraas <simen.kjaras gmail.com> wrote:

 Sigh... I'll go back to parsing a .stringof representation.

I went ahead and filed a new bug[1], and (90) minutes after, Kenji Hara responded this is already implemented for 2.060. [1]: http://d.puremagic.com/issues/show_bug.cgi?id=8420

I'm getting used to being kenji'ed on a regular basis. Thanks Kenji! Geez, I guess I didn't thank you this week, that was a long time without yet another miraculous and instantaneous bug correction :) Philippe
Jul 24 2012