www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - reflection over templates

reply "Adam D. Ruppe" <destructionator gmail.com> writes:
Given:

template Foo(string T) { enum Foo = to!int(T); }

(or anything else, really)

Is there anything we can do with static if to identify it as a 
template?

I tried:

static if(is(Foo == template)) {} // nope, basic type expected, 
not template

Note that is(typeof(Foo) == function) {} is how we check for 
regular functions.


static if(is(typeof(Foo) == template)) {} // nope


In fact, typeof(Foo) == void... is that something we can use?


I know we can break down a template instantiation with one of the 
arcane is expressions, but I don't have that here, I just want to 
identify the template Foo as a template.

This is in the context of doing __traits(allMembers) over a 
module and trying to categorize every member.


Checking for a void type seems to be the closest I've gotten, but 
that seems awfully strange. I guess other variables can't be 
declared with type void, so maybe that is a unique 
differentiator, but still, idk about it.


And after we determine it is a template, can we extract the 
required arguments list like we can with a regular function at 
all?
Mar 19 2014
next sibling parent reply "Dicebot" <public dicebot.lv> writes:
Wait just a bit more 
https://github.com/D-Programming-Language/dmd/pull/3380 :)
Mar 19 2014
next sibling parent "Dicebot" <public dicebot.lv> writes:
As a workaround one can use set of relevant trait checks:
1) type is void
2) is not a variable or callable
3) .stringof fits "NAME(ARGS)" pattern
Mar 19 2014
prev sibling parent reply "Adam D. Ruppe" <destructionator gmail.com> writes:
On Wednesday, 19 March 2014 at 16:10:52 UTC, Dicebot wrote:
 Wait just a bit more 
 https://github.com/D-Programming-Language/dmd/pull/3380 :)
megarox. Make it so.
Mar 19 2014
parent simendsjo <simendsjo gmail.com> writes:
On 03/19/2014 05:34 PM, Adam D. Ruppe wrote:
 On Wednesday, 19 March 2014 at 16:10:52 UTC, Dicebot wrote:
 Wait just a bit more
 https://github.com/D-Programming-Language/dmd/pull/3380 :)
megarox. Make it so.
Nice. I have some ugly hacks that's probably full of bugs for this (look at the bottom): template isLValue(T) { enum isLValue = false; } /// ditto template isLValue(alias T) { enum isLValue = !isType!T && isAddressable!T && __traits(compiles, { Unqual!(TypeOf!T) t = TypeOf!(T).init; }); } /// ditto template isRValue(T) { enum isRValue = false; } /// ditto template isRValue(alias T) { static if(isType!T) enum isRValue = false; else enum isRValue = __traits(compiles, { typeof(T) t = T; }) && !isAddressable!T; } template isValue(T) { enum isValue = false; } /// ditto template isValue(alias T) { enum isValue = isLValue!T || isRValue!T; } /// ditto template isType(T) { enum isType = is(T); } /// ditto template isType(alias T) { enum isType = is(T) || isCallable!T; } template isTemplate(T) { enum isTemplate = !(isValue!T || isType!T); } template isTemplate(alias T) { enum isTemplate = !(isValue!T || isType!T); }
Mar 19 2014
prev sibling parent reply Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
On 3/19/14, Adam D. Ruppe <destructionator gmail.com> wrote:
 Is there anything we can do with static if to identify it as a
 template?
https://github.com/D-Programming-Language/dmd/pull/3380
 And after we determine it is a template, can we extract the
 required arguments list like we can with a regular function at
 all?
Well there's TemplateArgsOf for *instantiations*, but I'm not sure how one would do it with non-instantiations. In particular how would we create a tuple of template parameter types where one of the parameters was an alias? E.g.: template Foo(int, alias X); alias Args = TypeTuple!(int, ???); There is no "alias" type you could use in this case.
Mar 19 2014
parent "Dicebot" <public dicebot.lv> writes:
On Wednesday, 19 March 2014 at 16:18:17 UTC, Andrej Mitrovic 
wrote:
 And after we determine it is a template, can we extract the
 required arguments list like we can with a regular function at
 all?
Well there's TemplateArgsOf for *instantiations*, but I'm not sure how one would do it with non-instantiations. In particular how would we create a tuple of template parameter types where one of the parameters was an alias? E.g.: template Foo(int, alias X); alias Args = TypeTuple!(int, ???); There is no "alias" type you could use in this case.
One can use value instead of a type, like "alias".
Mar 19 2014