-
-
Notifications
You must be signed in to change notification settings - Fork 414
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.