www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - How to test templates for equality?

reply "Uranuz" <neuranuz gmail.com> writes:
I have a question. How could I know if some alias or template 
parameter is some template symbol. I want to not that I want to 
know that symbol is template symbol itself but not instance of 
template (std.traits.isInstanceOf give answer for that question). 
I'll give some example


template Foo(T...)
{

}

template isFoo(alias F)
{


}
Jun 30 2014
parent reply "Uranuz" <neuranuz gmail.com> writes:
I suddenly posted it for somehow. But I hope idea is clear. How 
could I test if symbol is equal to some concrete template. I 
tried these examples:

template isFoo(alias F)
{
     enum bool isFoo = is( F == Foo );
}

template isFoo(alias F)
{
     enum bool isFoo = F == Foo;
}

Could you advise something to solve this?
Jun 30 2014
parent reply "Peter Alexander" <peter.alexander.au gmail.com> writes:
template Foo(T...) {}
template Bar(T...) {}

template isFoo(alias F)
{
	enum isFoo = __traits(isSame, F, Foo);
}

pragma(msg, isFoo!Foo); // true
pragma(msg, isFoo!Bar); // false
Jun 30 2014
parent reply "Uranuz" <neuranuz gmail.com> writes:
On Tuesday, 1 July 2014 at 05:51:17 UTC, Peter Alexander wrote:
 template Foo(T...) {}
 template Bar(T...) {}

 template isFoo(alias F)
 {
 	enum isFoo = __traits(isSame, F, Foo);
 }

 pragma(msg, isFoo!Foo); // true
 pragma(msg, isFoo!Bar); // false
Thanks for quick response. I really forget to look into language __traits statement.
Jun 30 2014
parent reply "Rene Zwanenburg" <renezwanenburg gmail.com> writes:
On Tuesday, 1 July 2014 at 05:58:19 UTC, Uranuz wrote:
 Thanks for quick response. I really forget to look into 
 language __traits statement.
Another option: enum isFoo(T) = is(T == Foo!P, P...); By using such an is-expression you get the parameters Foo was instantiated with as an added bonus. struct Foo(T) { T val; } auto createAFoo(T)(string s) if(is(T == Foo!P, P)) { return T(s.to!P); }
Jul 01 2014
parent reply "Uranuz" <neuranuz gmail.com> writes:
I have another question about testing if given symbol is instance 
of the given template and geting it's template arguments. I'm 
talking about raw template symbols, but not struct or class 
templates. For case with struct or class template 
std.traits.isInstanceOf is working well. But using *raw* template 
is not possible for it. There is an example.

import std.stdio, std.traits;


template WrapperTemplate(T)
{}

void main()
{
	writeln( isInstanceOf!(WrapperTemplate, WrapperTemplate!(int)) );
}

Because isInstanceOf implemented as *is* expression it expects 
type arguments, but template is not type at all. So this is not 
working. As we have __traits(isSame, ...) we could make such a 
test, but I need to have tuple of template arguments. But I don't 
understand how to get them

template isMyInstanceOf(alias Templ, alias Inst)
{

}
Jul 05 2014
next sibling parent reply "Uranuz" <neuranuz gmail.com> writes:
Suddenly posted. I don't know why it's happened))

template isMyInstanceOf(alias Templ, alias Inst)
{
     alias Args = ???; //I don't have idea how to get it

     enum bool isMyInstanceOf = __traits(isSame, Templ!(Args), 
Inst);
}

Do you have any idea how to solve this? May be standad library 
could be improved with such type of test for template instance?
Jul 05 2014
parent "Uranuz" <neuranuz gmail.com> writes:
 template isMyInstanceOf(alias Templ, alias Inst)
 {
     alias Args = ???; //I don't have idea how to get it

     enum bool isMyInstanceOf = __traits(isSame, Templ!(Args), 
 Inst);
 }

 Do you have any idea how to solve this? May be standad library 
 could be improved with such type of test for template instance?
Is new compiler trait is needed for solving this like alias Args = __traits(getTemplateArgumentList, Inst); or it could be solved with existing tools?
Jul 05 2014
prev sibling parent reply =?UTF-8?B?QWxpIMOHZWhyZWxp?= <acehreli yahoo.com> writes:
On 07/05/2014 10:33 PM, Uranuz wrote:
 I have another question about testing if given symbol is instance of the
 given template and geting it's template arguments.
Applying Rene Zwanenburg's message... It is not complete because integral template parameters don't work yet. import std.typetuple; template instanceArgsOf(alias S, T) { import std.traits : isInstanceOf; static if (isInstanceOf!(S, T)) { static if (is(T == S!Args, Args...)) { alias instanceArgsOf = Args; } else { alias instanceArgsOf = void; } } else { alias instanceArgsOf = void; } } unittest { // Adapting the unittests of std.traits.isInstanceOf static struct Foo(T...) { } static struct Bar(T...) { } static struct Doo(T) { } static struct ABC(int x) { } static assert(is (instanceArgsOf!(Foo, Foo!(int, double)) == TypeTuple!(int, double))); static assert(is (instanceArgsOf!(Foo, Bar!int) == void)); static assert(is (instanceArgsOf!(Foo, int) == void)); static assert(is (instanceArgsOf!(Doo, Doo!int) == TypeTuple!(int))); /* * The following needs more work because what comes back is something * called a 'tuple(1)' (Yes, in lowercase.) * * static assert(is (instanceArgsOf!(ABC, ABC!1) == TypeTuple!(1))); */ static assert(!__traits(compiles, instanceArgsOf!(Foo, Foo))); } void main() {} Ali
Jul 06 2014
parent reply Philippe Sigaud via Digitalmars-d-learn writes:
Seeing his example, the OP wants a solution that works even for templates:

template Test1(T) {}

pragma(msg, instanceArgsOf!(Test1, Test1!int));

which fails because Test1!int is not a type (std.traits.isInstanceOf
fails also, for the same reason).
And is(symbol == Name!Args, Args...) does not work if Name!Args and
symbol are not types.

In this particular case, the only solution I know of is an awful hack:
using .stringof and __traits(identifier, x) and then parse the
strings:

"Name!(int, double[string])" and "Name(T, U[V], U, V)"

and then the fun begins: in the general case, you must then equate the
arguments lists (recursively).

Philippe
Jul 06 2014
parent "Uranuz" <neuranuz gmail.com> writes:
 In this particular case, the only solution I know of is an 
 awful hack:
 using .stringof and __traits(identifier, x) and then parse the
 strings:

 "Name!(int, double[string])" and "Name(T, U[V], U, V)"

 and then the fun begins: in the general case, you must then 
 equate the
 arguments lists (recursively).

 Philippe
Yes. This is possible solution but looks very complicated. For now I changed it for struct template. But there are could be some cases where you don't want to make it class or struct (theoreticaly). If someone else experience the same problem, so may be new __traits(...) needs to be proposed. We have the only trait isSame that helps working with templates. May be we could add trait that will help get template arguments list for instantiated template. I think it could be useful.
Jul 06 2014