-
-
Notifications
You must be signed in to change notification settings - Fork 417
Give TypeInfo_Class/TypeInfo_Interface.isBaseOf like C#/Java isAssignableFrom #2770
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
Added TypeInfo_Class/TypeInfo_Interface.isBaseOf that works like C#/Java isAssignableFrom. | ||
|
||
`TypeInfo_Class.isBaseOf` returns true if the argument and the receiver | ||
are equal or if the class represented by the argument inherits from the | ||
class represented by the receiver. This is called `isBaseOf` instead of | ||
`isAssignableFrom` to avoid confusion for classes that overload | ||
`opAssign` and so may allow assignment from classes outside their | ||
inheritance hierarchy and to match existing terminology in the D | ||
runtime. `TypeInfo_Interface.isBaseOf` is similar with the addition | ||
that the argument may be either `TypeInfo_Class` or | ||
`TypeInfo_Interface`. | ||
------- | ||
class ClassA {} | ||
class ClassB : ClassA {} | ||
|
||
auto a = new ClassA(), b = new ClassB(); | ||
|
||
assert(typeid(a).isBaseOf(typeid(a))); | ||
assert(typeid(a).isBaseOf(typeid(b))); | ||
assert(!typeid(b).isBaseOf(typeid(a))); | ||
------- |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -14,6 +14,9 @@ | |
module rt.cast_; | ||
|
||
extern (C): | ||
@nogc: | ||
nothrow: | ||
pure: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Adding some attributes here so the compiler enforces the same attributes I claim in the |
||
|
||
/****************************************** | ||
* Given a pointer: | ||
|
@@ -74,7 +77,7 @@ void* _d_dynamic_cast(Object o, ClassInfo c) | |
return res; | ||
} | ||
|
||
int _d_isbaseof2(ClassInfo oc, ClassInfo c, ref size_t offset) | ||
int _d_isbaseof2(scope ClassInfo oc, scope const ClassInfo c, scope ref size_t offset) @safe | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ditto recursion |
||
{ | ||
if (oc is c) | ||
return true; | ||
|
@@ -101,7 +104,7 @@ int _d_isbaseof2(ClassInfo oc, ClassInfo c, ref size_t offset) | |
return false; | ||
} | ||
|
||
int _d_isbaseof(ClassInfo oc, ClassInfo c) | ||
int _d_isbaseof(scope ClassInfo oc, scope const ClassInfo c) @safe | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You could use tail recursion and make this There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'd rather not mess with the implementation of |
||
{ | ||
if (oc is c) | ||
return true; | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
// https://issues.dlang.org/show_bug.cgi?id=20178 | ||
n8sh marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
interface I {} | ||
interface J : I {} | ||
interface K(T) {} | ||
class C1 : I {} | ||
class C2 : C1 {} | ||
class C3 : J {} | ||
class C4(T) : C3, K!T {} | ||
class C5(T) : C4!T {} | ||
|
||
void main() @nogc nothrow pure @safe | ||
{ | ||
assert(typeid(C1).isBaseOf(typeid(C1))); | ||
assert(typeid(C1).isBaseOf(typeid(C2))); | ||
|
||
assert(!typeid(C2).isBaseOf(typeid(C1))); | ||
assert(typeid(C2).isBaseOf(typeid(C2))); | ||
|
||
assert(!typeid(C1).isBaseOf(typeid(Object))); | ||
assert(!typeid(C2).isBaseOf(typeid(Object))); | ||
assert(typeid(Object).isBaseOf(typeid(C1))); | ||
assert(typeid(Object).isBaseOf(typeid(C2))); | ||
|
||
assert(typeid(I).isBaseOf(typeid(I))); | ||
assert(typeid(I).isBaseOf(typeid(J))); | ||
assert(typeid(I).isBaseOf(typeid(C1))); | ||
assert(typeid(I).isBaseOf(typeid(C2))); | ||
assert(typeid(I).isBaseOf(typeid(C3))); | ||
assert(!typeid(I).isBaseOf(typeid(Object))); | ||
|
||
assert(!typeid(J).isBaseOf(typeid(I))); | ||
assert(typeid(J).isBaseOf(typeid(J))); | ||
assert(!typeid(J).isBaseOf(typeid(C1))); | ||
assert(!typeid(J).isBaseOf(typeid(C2))); | ||
assert(typeid(J).isBaseOf(typeid(C3))); | ||
assert(!typeid(J).isBaseOf(typeid(Object))); | ||
|
||
assert(typeid(C4!int).isBaseOf(typeid(C5!int))); | ||
assert(typeid(K!int).isBaseOf(typeid(C5!int))); | ||
assert(!typeid(C4!Object).isBaseOf(typeid(C5!int))); | ||
assert(!typeid(K!Object).isBaseOf(typeid(C5!int))); | ||
|
||
static assert(!__traits(compiles, TypeInfo.init.isBaseOf(typeid(C1)))); | ||
static assert(!__traits(compiles, typeid(C1).isBaseOf(TypeInfo.init))); | ||
} |
Uh oh!
There was an error while loading. Please reload this page.