it's sometimes useful to emulate dynamic casting in runtime having only TypeInfo_Class at hands. now one has to rely on undocumented (and unexported) `_d_dynamic_cast()` and friends, writing something like this:
// get druntime cast function
private extern(C) void* _d_dynamic_cast (Object o, ClassInfo c);
bool isCastable (Object O, TypeInfo_Class ti) {
return (_d_dynamic_cast(o, ti) !is null);
}
it would be fine to introduce and use a documented API for that, like this:
ti.dynamicCast(O)
ti.isBaseOf(O)
i.e. we should add these methods to TypeInfo_Class. also, the same methods should be added to TypeInfo_Interface.
Comment #1 by ketmar — 2015-12-09T07:19:24Z
p.s. `ti.dynamicCast(O)` should still return `void*`. not a big deal, it's very internal API anyway.
Comment #2 by ketmar — 2015-12-09T08:01:13Z
sample patch:
diff --git a/src/object.d b/src/object.d
index 097fc5a..6eb9163 100644
--- a/src/object.d
+++ b/src/object.d
@@ -21,6 +21,8 @@ private
{
extern (C) Object _d_newclass(const TypeInfo_Class ci);
extern (C) void rt_finalize(void *data, bool det=true);
+ extern (C) void* _d_dynamic_cast(Object o, ClassInfo c);
+ extern (C) int _d_isbaseof(ClassInfo oc, ClassInfo c);
}
// NOTE: For some reason, this declaration method doesn't work
@@ -860,6 +862,17 @@ unittest
*/
class TypeInfo_Class : TypeInfo
{
+ final void* dynamicCast (Object o)
+ {
+ return (o !is null ? _d_dynamic_cast(o, this) : null);
+ }
+
+ // is this typeinfo base of `o`?
+ final bool baseOf (Object o)
+ {
+ return (o !is null ? (_d_isbaseof(typeid(o), this) != 0) : false);
+ }
+
override string toString() const { return info.name; }
override bool opEquals(Object o)
Comment #3 by robert.schadek — 2024-12-07T13:36:01Z