Thread overview
How to check for instantiation of specific template?
Oct 10, 2013
H. S. Teoh
Oct 10, 2013
simendsjo
Oct 11, 2013
Jacob Carlborg
Oct 11, 2013
Dicebot
October 10, 2013
I have a template used for storing compile-time values:

	template Def(int x, string y) {
		alias impl = TypeTuple!(x,y);
	}

How do I define a template isDef that, given some template alias A, evaluates to true if A is some instantiation of Def?

	template isDef(alias A) {
		enum A = ... /* what to put here? */
	}

The intent is to be able to write signature constraints like this:

	auto myFunc(alias def)(...)
		if (isDef!def)
	{
		...
	}

	...
	// Pass an instantiation of Def to myFunc
	auto x = myFunc!(Def!(1, "abc"))(args);

I tried using std.traits.isInstanceOf but apparently it expects the second argument to be an actual type, which doesn't work in this case because Def is a typetuple of compile-time values, not an actual type.


T

-- 
Help a man when he is in trouble and he will remember you when he is in trouble again.
October 10, 2013
On Thursday, 10 October 2013 at 17:24:37 UTC, H. S. Teoh wrote:
> I have a template used for storing compile-time values:
>
> 	template Def(int x, string y) {
> 		alias impl = TypeTuple!(x,y);
> 	}
>
> How do I define a template isDef that, given some template alias A,
> evaluates to true if A is some instantiation of Def?
>
> 	template isDef(alias A) {
> 		enum A = ... /* what to put here? */
> 	}
>
> The intent is to be able to write signature constraints like this:
>
> 	auto myFunc(alias def)(...)
> 		if (isDef!def)
> 	{
> 		...
> 	}
>
> 	...
> 	// Pass an instantiation of Def to myFunc
> 	auto x = myFunc!(Def!(1, "abc"))(args);
>
> I tried using std.traits.isInstanceOf but apparently it expects the
> second argument to be an actual type, which doesn't work in this case
> because Def is a typetuple of compile-time values, not an actual type.
>
>
> T

I've used this horrible hack to solve this. Not very generic as you can see:
    else static if(T.stringof.length > 13 && T.stringof[0..13] == "TupleWrapper!")
October 11, 2013
On 2013-10-10 19:23, H. S. Teoh wrote:
> I have a template used for storing compile-time values:
>
> 	template Def(int x, string y) {
> 		alias impl = TypeTuple!(x,y);
> 	}
>
> How do I define a template isDef that, given some template alias A,
> evaluates to true if A is some instantiation of Def?
>
> 	template isDef(alias A) {
> 		enum A = ... /* what to put here? */
> 	}
>
> The intent is to be able to write signature constraints like this:
>
> 	auto myFunc(alias def)(...)
> 		if (isDef!def)
> 	{
> 		...
> 	}
>
> 	...
> 	// Pass an instantiation of Def to myFunc
> 	auto x = myFunc!(Def!(1, "abc"))(args);
>
> I tried using std.traits.isInstanceOf but apparently it expects the
> second argument to be an actual type, which doesn't work in this case
> because Def is a typetuple of compile-time values, not an actual type.

I found this old thread

http://forum.dlang.org/thread/mailman.1382.1371938670.13711.digitalmars-d@puremagic.com

With this code:

template getTemplate(alias T : TI!TP, alias TI, TP...)
{
    alias getTemplate = TI;
}

But I haven't figured out how to do the comparison.

-- 
/Jacob Carlborg
October 11, 2013
This is actually a very interesting question.

Usual approach is to use pattern matching on types but template instance symbol is not a type on its own, it is just a symbol. (with typeof == void)

My second guess was to check __traits(identifier, AliasParam) but it looks like for aliased instance (contrary to aliased template symbol) identifier is its mangled name.

I can't imagine really clean way to do it but comparing __traits(identifier) to that specific mangled name can be a reliable enough hack (better than stringof which has undefined format).