www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - How is std.traits.isInstanceOf supposed to work?

reply "Tommi" <tommitissari hotmail.com> writes:
The documentation says:

template isInstanceOf(alias S, T)
---------------------------
Returns true if T is an instance of the template S.

But, is isInstanceOf supposed to return true if T is a subtype of 
an instance of the template S ? (but is not an instance of the 
template S). Currently it does return true if T is a struct, and 
doesn't if it's a class:

import std.traits;

struct SuperSt(T, int size)
{}

struct SubSt
{
     SuperSt!(short, 4) _super;
     alias _super this;
}

class SuperCl(T, U)
{}

class SubCl : SuperCl!(int, char)
{}

void main()
{
     static assert(isInstanceOf!(SuperSt, SubSt));
     static assert(!isInstanceOf!(SuperCl, SubCl));
}
Nov 10 2013
next sibling parent reply "Dicebot" <public dicebot.lv> writes:
On Sunday, 10 November 2013 at 23:22:01 UTC, Tommi wrote:
 The documentation says:

 template isInstanceOf(alias S, T)
 ---------------------------
 Returns true if T is an instance of the template S.

 But, is isInstanceOf supposed to return true if T is a subtype 
 of an instance of the template S ? (but is not an instance of 
 the template S). Currently it does return true if T is a 
 struct, and doesn't if it's a class:
I'd say "works as expected". 'alias this` is not equivalent to inheritance, it allows to type to completely act as another. And `isInstanceOf` checks for strict matching. It will work with classes if `alias this` is used there.
Nov 10 2013
parent "Tommi" <tommitissari hotmail.com> writes:
On Sunday, 10 November 2013 at 23:34:08 UTC, Dicebot wrote:
 I'd say "works as expected". 'alias this` is not equivalent to 
 inheritance, it allows to type to completely act as another.
According to TDPL, 'alias this' makes the aliasing type a 'subtype' of the aliased type. If type X is a subtype of type Y, it doesn't mean that X can completely act as Y. It means that objects of type X can completely act as objects of type Y. Which is not the same thing.
Nov 10 2013
prev sibling next sibling parent reply "TheFlyingFiddle" <theflyingfiddle gmail.com> writes:
The docs might be a little unclear about this. The template 
isInstanceOf checks to see if the second parameter is a template 
instantiation of the first parameter. It does not have anything 
to do with inheritance.

Like so:

struct S(T) { T t; }

struct S2(T) { T t; }

import std.traits;
unittest
{
     alias inst  = S!(int);
     alias inst2 = S2!(string);

     //S!(int) is an instantiation of S
     static assert(isInstanceOf!(S, inst));
     //S2!(string) is not an instantiation of S
     static assert(!isInstanceOf!(S, inst2));
}

If you would like to see if something is derived from something 
or to see if a struct is convertible to another struct use the is 
keyword.

Like so:


struct S3
{
     S!(int) s;
     alias s this;
}

class C { }

class D : C { }

unittest
{	
     //S3 is convertible to S!(int)
     static assert(is(S3 : S!(int)));
	
     //D is convertible (derived from) C
     static assert(is(D : C));
}
Nov 10 2013
next sibling parent Jonathan M Davis <jmdavisProg gmx.com> writes:
On Monday, November 11, 2013 00:43:17 TheFlyingFiddle wrote:
 The docs might be a little unclear about this. The template
 isInstanceOf checks to see if the second parameter is a template
 instantiation of the first parameter. It does not have anything
 to do with inheritance.
Which implies that it really should have been called isInstantiationOf and not isInstanceOf. - Jonathan M Davis
Nov 10 2013
prev sibling parent reply "Tommi" <tommitissari hotmail.com> writes:
On Sunday, 10 November 2013 at 23:43:21 UTC, TheFlyingFiddle 
wrote:
 The template isInstanceOf checks to see if the second parameter 
 is a template instantiation of the first parameter.
But in this example of mine: isInstanceOf!(SuperSt, SubSt) ...the second parameter is not a template instantiation of the first parameter, yet isInstanceOf evaluates to true. I think what this all boils down to is that this is a compiler-bug: struct A(T) {} struct B { A!int _a; alias _a this; } void main() { static assert(!is(B == A!int)); // OK static assert(is(B == A!T, T)); // BUG (shouldn't compile) }
Nov 10 2013
parent =?UTF-8?B?QWxpIMOHZWhyZWxp?= <acehreli yahoo.com> writes:
On 11/10/2013 05:03 PM, Tommi wrote:
 On Sunday, 10 November 2013 at 23:43:21 UTC, TheFlyingFiddle wrote:
 The template isInstanceOf checks to see if the second parameter is a
 template instantiation of the first parameter.
But in this example of mine: isInstanceOf!(SuperSt, SubSt) ...the second parameter is not a template instantiation of the first parameter, yet isInstanceOf evaluates to true. I think what this all boils down to is that this is a compiler-bug: struct A(T) {} struct B { A!int _a; alias _a this; } void main() { static assert(!is(B == A!int)); // OK static assert(is(B == A!T, T)); // BUG (shouldn't compile) }
The compiler magically deduces T as int: struct A(T) {} struct B { A!int _a; alias _a this; } void main() { static if (is(B == A!T, T)) { pragma(msg, T); // prints int } } Ali
Nov 12 2013
prev sibling parent "Tommi" <tommitissari hotmail.com> writes:
Filed a bug report:
https://d.puremagic.com/issues/show_bug.cgi?id=11499
Nov 11 2013