www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - test if object is instance of class at compile time

reply Elvis Maehren <maehlvis googlemail.com> writes:
This works fine at runtime, but explodes in CTFE:
---
bool isInstanceOf(T, O)(O o) {
	return (cast(T) o) !is null;
}
---

CTFE doesn't like "!is null" ("cannot compare [...] at compile time"). 

Moreover, in CTFE a failed cast terminates the interpretation ("cannot 
reinterpret class from [...] to [...] at compile time"). Is this somehow 
catchable? If so, I could do something along these lines:
---
if(__ctfe) {
	try {
		auto t = cast(T) o;
		return true;
	} catch {
		return false;
	}
}
---
Dec 21 2011
next sibling parent reply "Vladimir Panteleev" <vladimir thecybershadow.net> writes:
On Wednesday, 21 December 2011 at 20:15:36 UTC, Elvis Maehren 
wrote:
 Is this somehow catchable?

I believe that's what __traits(compiles, ...) is for: http://dlang.org/traits.html#compiles
Dec 21 2011
parent Elvis Maehren <maehlvis googlemail.com> writes:
Vladimir Panteleev wrote:
 I believe that's what __traits(compiles, ...) is for:

__traits(compiles, cast(T) o) is true even if the cast blows up in CTFE, so that doesn't work.
Dec 22 2011
prev sibling next sibling parent reply Jacob Carlborg <doob me.com> writes:
On 2011-12-21 21:15, Elvis Maehren wrote:
 This works fine at runtime, but explodes in CTFE:
 ---
 bool isInstanceOf(T, O)(O o) {
 	return (cast(T) o) !is null;
 }
 ---

 CTFE doesn't like "!is null" ("cannot compare [...] at compile time").

 Moreover, in CTFE a failed cast terminates the interpretation ("cannot
 reinterpret class from [...] to [...] at compile time"). Is this somehow
 catchable? If so, I could do something along these lines:
 ---
 if(__ctfe) {
 	try {
 		auto t = cast(T) o;
 		return true;
 	} catch {
 		return false;
 	}
 }
 ---

I don't think you can do a test like that during compile time. In your above function, isInstanceOf, "o" will always be of the type "O". You can always do a comparisons to see if O is the same type as T. -- /Jacob Carlborg
Dec 21 2011
parent Elvis Maehren <maehlvis googlemail.com> writes:
Jacob Carlborg wrote:
 On 2011-12-21 21:15, Elvis Maehren wrote:
 This works fine at runtime, but explodes in CTFE:
 ---
 bool isInstanceOf(T, O)(O o) {
 return (cast(T) o) !is null;
 }
 ---


 I don't think you can do a test like that during compile time. In your
 above function, isInstanceOf, "o" will always be of the type "O". You
 can always do a comparisons to see if O is the same type as T.
 

I don't think testing for equality of O and T gets me anywhere. T is usually derived from O. That makes it a different type, but still o may be castable to T.
Dec 22 2011
prev sibling next sibling parent reply Timon Gehr <timon.gehr gmx.ch> writes:
On 12/21/2011 09:15 PM, Elvis Maehren wrote:
 This works fine at runtime, but explodes in CTFE:
 ---
 bool isInstanceOf(T, O)(O o) {
 	return (cast(T) o) !is null;
 }
 ---

 CTFE doesn't like "!is null" ("cannot compare [...] at compile time").

This will be fixed in the next release: http://d.puremagic.com/issues/show_bug.cgi?id=7143
 Moreover, in CTFE a failed cast terminates the interpretation ("cannot
 reinterpret class from [...] to [...] at compile time").

I don't think this is filed already. Maybe you want to file a bug report?
 Is this somehow
 catchable? If so, I could do something along these lines:
 ---
 if(__ctfe) {
 	try {
 		auto t = cast(T) o;
 		return true;
 	} catch {
 		return false;
 	}
 }
 ---

use traits(__compiles, {...}), where '...' is the exact code that fails. But that is a mere workaround. What you are doing should/will work.
Dec 22 2011
parent Elvis Maehren <maehlvis googlemail.com> writes:
Timon Gehr wrote:
 On 12/21/2011 09:15 PM, Elvis Maehren wrote:

 Moreover, in CTFE a failed cast terminates the interpretation ("cannot
 reinterpret class from [...] to [...] at compile time").

I don't think this is filed already. Maybe you want to file a bug report?

ok, did that: http://d.puremagic.com/issues/show_bug.cgi?id=7154 [...]
 use traits(__compiles, {...}), where '...' is the exact code that fails.
 But that is a mere workaround. What you are doing should/will work.

Vladimir Panteleev pointed me to __traits(compiles, ...), too. I think that doesn't work out: Elvis Maehren wrote:
 Vladimir Panteleev wrote:
 I believe that's what __traits(compiles, ...) is for:

__traits(compiles, cast(T) o) is true even if the cast blows up in CTFE, so that doesn't work.

Or am I missing something?
Dec 22 2011
prev sibling parent reply Trass3r <un known.com> writes:
I'd really like to have 'if (instance is ClassType)' syntax in D.
Dec 22 2011
parent Andrew Wiley <wiley.andrew.j gmail.com> writes:
On Thu, Dec 22, 2011 at 8:35 AM, Trass3r <un known.com> wrote:
 I'd really like to have 'if (instance is ClassType)' syntax in D.

It couldn't use that syntax because 'is' means direct bitwise equality everywhere else. Changing it in this one situation would be awkward.
Dec 22 2011