Thread overview
how can i use the derive-hierarchy at runtime for typechecking?
Sep 20, 2007
dennis luehring
Sep 20, 2007
Downs
Sep 21, 2007
dennis luehring
Sep 21, 2007
Regan Heath
Sep 23, 2007
Downs
September 20, 2007
is there a way to test at runtime if the type of an object is derived from another object type? maybe with the help of compiletime-reflection and additional information in the class?

class A{}
class B: A{}
class C: B{}

i need something like

B.type.is_derived_from( A.type ) ==> true
A.type.is_derived_from( C.type ) ==> false

B xx = new B;
B yy = new B;

xx.type == yy.type ==> true

is there an elegant way?

why do i need such stuff?
i use the normal D typechecking for the static part of my software
but i've got an GUI system with the ability to "construct" types
at runtime based on my static types (and i need a typesystem based on the class hierachy for it)

thx dennis
September 20, 2007
Just cast it.
If you have class A { } and class B : A { }
and A foo=new B;
then you can do cast(B) foo and it will be non-null.
On the other hand, if you do A bar=new A;
and you do cast(B) bar, it will be null.

Here's a little utility function for this
void ifIs(S, T)(S obj, void delegate(T) dg) {
  auto casted=cast(T) obj;
  if (casted) dg(casted);
}

Use it like thus

ifIs(foo, (B whee) { /* do stuff with whee */ });

Hope that answers your question.
 --downs/FeepingCreature
September 20, 2007
Downs wrote:
> -----BEGIN PGP SIGNED MESSAGE-----
> Hash: SHA1
> 
> Just cast it.
> If you have class A { } and class B : A { }
> and A foo=new B;
> then you can do cast(B) foo and it will be non-null.
> On the other hand, if you do A bar=new A;
> and you do cast(B) bar, it will be null.
> 
> Here's a little utility function for this
> void ifIs(S, T)(S obj, void delegate(T) dg) {
>   auto casted=cast(T) obj;
>   if (casted) dg(casted);
> }
> 
> Use it like thus
> 
> ifIs(foo, (B whee) { /* do stuff with whee */ });
> 

And thanks to an oft-forgotten feature, you could shrink that down a little further to just a one-liner:

void ifIs (S, T) (S obj, void delegate(T) dg) {
  if (auto casted = cast(T) obj) dg(casted);
}

http://digitalmars.com/d/1.0/statement.html#IfStatement

-- Chris Nicholson-Sauls
September 20, 2007
"Chris Nicholson-Sauls" <ibisbasenji@gmail.com> wrote in message news:fcupko$kh7$2@digitalmars.com...

> void ifIs (S, T) (S obj, void delegate(T) dg) {
>   if (auto casted = cast(T) obj) dg(casted);
> }

Or you could skip Downs' confusing way of writing code entirely ( ;) ) and just use:

if(auto b = cast(B)foo)
{
    // do stuff with b
}


September 20, 2007
Jarrett Billingsley wrote:
> "Chris Nicholson-Sauls" <ibisbasenji@gmail.com> wrote in message news:fcupko$kh7$2@digitalmars.com...
> 
>> void ifIs (S, T) (S obj, void delegate(T) dg) {
>>   if (auto casted = cast(T) obj) dg(casted);
>> }
> 
> Or you could skip Downs' confusing way of writing code entirely ( ;) ) and just use:
> 
> if(auto b = cast(B)foo)
> {
>     // do stuff with b
> } 
> 
> 

Or we could add a new '?.' form for member access that becomes a nop on null references and just use:
(cast(B) foo)?.doStuff();

Er.......... okay, that's just insane.

-- Chris Nicholson-Sauls
September 21, 2007
"Chris Nicholson-Sauls" <ibisbasenji@gmail.com> wrote in message news:fcv1d1$vp6$1@digitalmars.com...
>
> Or we could add a new '?.' form for member access that becomes a nop on
> null references and just use:
> (cast(B) foo)?.doStuff();
>
> Er.......... okay, that's just insane.

What do you think this is, Io?


September 21, 2007
Jarrett Billingsley schrieb:
> "Chris Nicholson-Sauls" <ibisbasenji@gmail.com> wrote in message news:fcupko$kh7$2@digitalmars.com...
> 
>> void ifIs (S, T) (S obj, void delegate(T) dg) {
>>   if (auto casted = cast(T) obj) dg(casted);
>> }
> 
> Or you could skip Downs' confusing way of writing code entirely ( ;) ) and just use:
> 
> if(auto b = cast(B)foo)
> {
>     // do stuff with b
> } 
> 
> 

and how can i insert this test in my base-class to hide the type stuff

class base
{
  int base_bla;

  bool is_derived_from( base other )
  {
    auto check = cast(typeof(this))other;
    return !( check is null );

    // why can't i compile this
    // return ( auto check = cast(typeof(this))other );
  }
}

class test: base
{
  int test_bla;
}

class blub: test
{
  int blub_bla;
}

the is_derived_from test is always true
maybe because of the base type parameter in is_derived_from

and the other thing i need to know(show) the derive-hierachy

"the hole story"

in my c++ project i use objects which represents the type of an object
for example

class car // real implementation
{
}

class car_class // object-type of class car
{
  car create_instance(); ...
  bool is_derived_from
  base_class[] derived_from_me();
  base_class[] base_class_of();
}

and many [whatever]_class objects in my known-types-pool

for example:
i can ask which "types" i know
i can create real types of it
i can ask for the derives/bases of an "type"
i can test if an "type" is hierachical "compatible"=derived from with another "type"

and just need to know my base-class interface for doing this
...

all this is done by using my own decription.language (with derive ability) and an c++ code generator...

i hope to find a better (more compiletime based) way to get the same features - i want to get rid of this generator stuff

ciao dennis
September 21, 2007
dennis luehring wrote:
> Jarrett Billingsley schrieb:
>> "Chris Nicholson-Sauls" <ibisbasenji@gmail.com> wrote in message news:fcupko$kh7$2@digitalmars.com...
>>
>>> void ifIs (S, T) (S obj, void delegate(T) dg) {
>>>   if (auto casted = cast(T) obj) dg(casted);
>>> }
>>
>> Or you could skip Downs' confusing way of writing code entirely ( ;) ) and just use:
>>
>> if(auto b = cast(B)foo)
>> {
>>     // do stuff with b
>> }
>>
> 
> and how can i insert this test in my base-class to hide the type stuff
> 
> class base
> {
>   int base_bla;
> 
>   bool is_derived_from( base other )
>   {
>     auto check = cast(typeof(this))other;
>     return !( check is null );
> 
>     // why can't i compile this

Because using 'auto' like this only works in an "if" statement. eg.

if ( auto check = cast(typeof(this))other ) return true;
return false;

>     // return ( auto check = cast(typeof(this))other );
>   }
> }
> 
> class test: base
> {
>   int test_bla;
> }
> 
> class blub: test
> {
>   int blub_bla;
> }
> 
> the is_derived_from test is always true
> maybe because of the base type parameter in is_derived_from

writefln(typeof(this).stringof) shows "base" even when called on an object of type "test" or "blub".  So, even if you say:

test t = new test;
blub b = new blub;

if (t.is_derived_from(b)) {} //is 'test' derived from 'blub'

you're really just asking if t is derived from "base", which it is (has to be to have the is_derived_from method - in this case)

Regan
September 23, 2007
Jarrett Billingsley wrote:
> "Chris Nicholson-Sauls" <ibisbasenji@gmail.com> wrote in message news:fcupko$kh7$2@digitalmars.com...
> 
>> void ifIs (S, T) (S obj, void delegate(T) dg) {
>>   if (auto casted = cast(T) obj) dg(casted);
>> }
> 
> Or you could skip Downs' confusing way of writing code entirely ( ;) ) and just use:
> 
> if(auto b = cast(B)foo)
> {
>     // do stuff with b
> }
> 
> 
Well, I didn't know that! Thanks! :D
:surprised:
 --downs, learning new stuff every day! :)