www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Navigate from ClassInfo to TypeInfo

reply Frank Benoit <keinfarbton googlemail.com> writes:
I need to retrieve an instance of TypeInfo from an object instance at
runtime.

TypeInfo info = typeid(obj) // does not work, only compile time

TypeInfo info = obj.classinfo.????; // how to navigate to TypeInfo?

Is that possible?
If not, why? And can it be added (D1)?
Apr 14 2009
next sibling parent reply Christopher Wright <dhasenan gmail.com> writes:
Frank Benoit wrote:
 I need to retrieve an instance of TypeInfo from an object instance at
 runtime.
 
 TypeInfo info = typeid(obj) // does not work, only compile time
 
 TypeInfo info = obj.classinfo.????; // how to navigate to TypeInfo?
 
 Is that possible?
 If not, why? And can it be added (D1)?

There is no way that I know of to do so, and I've looked into the issue previously. -- I don't know how TypeInfo is instantiated; I imagine it's in the data segment of the executable; so it should be possible to examine all symbols in an executable to find TypeInfo instances and determine what they refer to. However, the language and runtime lack support for this.
Apr 14 2009
parent Tomas Lindquist Olsen <tomas.l.olsen gmail.com> writes:
On Wed, Apr 15, 2009 at 1:35 AM, Christopher Wright <dhasenan gmail.com> wrote:
 Frank Benoit wrote:
 I need to retrieve an instance of TypeInfo from an object instance at
 runtime.

 TypeInfo info = typeid(obj) // does not work, only compile time

 TypeInfo info = obj.classinfo.????; // how to navigate to TypeInfo?

 Is that possible?
 If not, why? And can it be added (D1)?

There is no way that I know of to do so, and I've looked into the issue previously. -- I don't know how TypeInfo is instantiated; I imagine it's in the data segment of the executable; so it should be possible to examine all symbols in an executable to find TypeInfo instances and determine what they refer to. However, the language and runtime lack support for this.

Seems reasonable to me to add a TypeInfo field to ClassInfo.
Apr 14 2009
prev sibling next sibling parent reply davidl <davidl nospam.org> writes:
在 Wed, 15 Apr 2009 02:16:44 +0800,Frank Benoit  
<keinfarbton googlemail.com> 写道:

 I need to retrieve an instance of TypeInfo from an object instance at
 runtime.

 TypeInfo info = typeid(obj) // does not work, only compile time

 TypeInfo info = obj.classinfo.????; // how to navigate to TypeInfo?

 Is that possible?
 If not, why? And can it be added (D1)?

Send this object to vararg func, and retrieve the TypeInfo there and return? -- 使用 Opera 革命性的电子邮件客户程序: http://www.opera.com/mail/
Apr 14 2009
next sibling parent reply Jarrett Billingsley <jarrett.billingsley gmail.com> writes:
2009/4/14 davidl <davidl nospam.org>:
 Send this object to vararg func, and retrieve the TypeInfo there and return?

No. The typeinfo passed to vararg functions is also determined at compile-time.
Apr 14 2009
parent reply Daniel Keep <daniel.keep.lists gmail.com> writes:
davidl wrote:
 在 Wed, 15 Apr 2009 10:14:42 +0800,Jarrett Billingsley
 <jarrett.billingsley gmail.com> 写道:
 
 2009/4/14 davidl <davidl nospam.org>:
 Send this object to vararg func, and retrieve the TypeInfo there and
 return?

No. The typeinfo passed to vararg functions is also determined at compile-time.

so it's a bug? I think vararg funcs always want the real typeinfo of the object

No, they get the typeinfo of what they're passed.
 class A {}
 class B : A {}

 void foo(...) {}

 void bar(A a) { foo(a); }

 void main()
 {
     scope b = new B;
     bar(b);
 }

bar cannot possibly know what the "real" TypeInfo of a is. But that doesn't matter because it's passing an A with A's TypeInfo. And if foo is maybe interested in Bs, then it can just try to up-cast. -- Daniel
Apr 14 2009
next sibling parent reply Frank Benoit <keinfarbton googlemail.com> writes:
Daniel Keep schrieb:
 
 davidl wrote:
 鍦 Wed, 15 Apr 2009 10:14:42 +0800锛孞arrett Billingsley
 <jarrett.billingsley gmail.com> 鍐欓亾:

 2009/4/14 davidl <davidl nospam.org>:
 Send this object to vararg func, and retrieve the TypeInfo there and
 return?

compile-time.

I think vararg funcs always want the real typeinfo of the object

No, they get the typeinfo of what they're passed.
 class A {}
 class B : A {}

 void foo(...) {}

 void bar(A a) { foo(a); }

 void main()
 {
     scope b = new B;
     bar(b);
 }

bar cannot possibly know what the "real" TypeInfo of a is. But that doesn't matter because it's passing an A with A's TypeInfo. And if foo is maybe interested in Bs, then it can just try to up-cast. -- Daniel

Or it can request the classinfo of the passed object. Hey, and now the typeinfo please :)
Apr 14 2009
parent reply Daniel Keep <daniel.keep.lists gmail.com> writes:
Frank Benoit wrote:
 Daniel Keep schrieb:
 davidl wrote:
 鍦 Wed, 15 Apr 2009 10:14:42 +0800锛孞arrett Billingsley
 <jarrett.billingsley gmail.com> 鍐欓亾:

 2009/4/14 davidl <davidl nospam.org>:
 Send this object to vararg func, and retrieve the TypeInfo there and
 return?

compile-time.

I think vararg funcs always want the real typeinfo of the object

 class A {}
 class B : A {}

 void foo(...) {}

 void bar(A a) { foo(a); }

 void main()
 {
     scope b = new B;
     bar(b);
 }

doesn't matter because it's passing an A with A's TypeInfo. And if foo is maybe interested in Bs, then it can just try to up-cast. -- Daniel

Or it can request the classinfo of the passed object. Hey, and now the typeinfo please :)

Ok. What do you propose to do with this TypeInfo? The ONLY thing a given TypeInfo_Class gives you is the ClassInfo, which you already have. The TypeInfo object itself gives you getHash, equals and compare, all of which are in Object and thus redundant, tsize which is the size of a pointer, swap which I can't see a use for, next which is useless, init which is also redundant and flags which is already in ClassInfo. Again, why do you even want that specific TypeInfo when it is less useful than the ClassInfo? -- Daniel
Apr 14 2009
parent reply Frank Benoit <keinfarbton googlemail.com> writes:
Daniel Keep schrieb:
 Ok.  What do you propose to do with this TypeInfo?
 
 The ONLY thing a given TypeInfo_Class gives you is the ClassInfo, which
 you already have.  The TypeInfo object itself gives you getHash, equals
 and compare, all of which are in Object and thus redundant, tsize which
 is the size of a pointer, swap which I can't see a use for, next which
 is useless, init which is also redundant and flags which is already in
 ClassInfo.
 
 Again, why do you even want that specific TypeInfo when it is less
 useful than the ClassInfo?
 
   -- Daniel

I need to have a "something" to retrieve and pass around to hold all available information about a type. Including classes, interfaces and primitives. Because of ClassInfo cannot have information about primitives, I need to work with TypeInfo. Because of I have that need to retrieve that "something" from any object reference also, i need a way from classinfo to typeinfo.
Apr 14 2009
parent reply Daniel Keep <daniel.keep.lists gmail.com> writes:
Frank Benoit wrote:
 Daniel Keep schrieb:
 Ok.  What do you propose to do with this TypeInfo?

 The ONLY thing a given TypeInfo_Class gives you is the ClassInfo, which
 you already have.  The TypeInfo object itself gives you getHash, equals
 and compare, all of which are in Object and thus redundant, tsize which
 is the size of a pointer, swap which I can't see a use for, next which
 is useless, init which is also redundant and flags which is already in
 ClassInfo.

 Again, why do you even want that specific TypeInfo when it is less
 useful than the ClassInfo?

   -- Daniel

I need to have a "something" to retrieve and pass around to hold all available information about a type. Including classes, interfaces and primitives. Because of ClassInfo cannot have information about primitives, I need to work with TypeInfo. Because of I have that need to retrieve that "something" from any object reference also, i need a way from classinfo to typeinfo.

I remember having to do something similar once. I think I solved it by carrying around these:
 struct ExTypeInfo
 {
     TypeInfo ti;
     ClassInfo ci;
 }

That, or you could store them as Objects, and then use upcasts to work out which it is.
 if( auto ti = cast(TypeInfo) info )
     // It's a general type info

 else if( auto ci = cast(ClassInfo) info )
     // It's a class

 else
     assert(false);

-- Daniel
Apr 14 2009
parent Frank Benoit <keinfarbton googlemail.com> writes:
Daniel Keep schrieb:
 
 Frank Benoit wrote:
 Daniel Keep schrieb:
 Ok.  What do you propose to do with this TypeInfo?

 The ONLY thing a given TypeInfo_Class gives you is the ClassInfo, which
 you already have.  The TypeInfo object itself gives you getHash, equals
 and compare, all of which are in Object and thus redundant, tsize which
 is the size of a pointer, swap which I can't see a use for, next which
 is useless, init which is also redundant and flags which is already in
 ClassInfo.

 Again, why do you even want that specific TypeInfo when it is less
 useful than the ClassInfo?

   -- Daniel

available information about a type. Including classes, interfaces and primitives. Because of ClassInfo cannot have information about primitives, I need to work with TypeInfo. Because of I have that need to retrieve that "something" from any object reference also, i need a way from classinfo to typeinfo.

I remember having to do something similar once. I think I solved it by carrying around these:
 struct ExTypeInfo
 {
     TypeInfo ti;
     ClassInfo ci;
 }

That, or you could store them as Objects, and then use upcasts to work out which it is.
 if( auto ti = cast(TypeInfo) info )
     // It's a general type info

 else if( auto ci = cast(ClassInfo) info )
     // It's a class

 else
     assert(false);

-- Daniel

Ick! Right, that is doable. But still, D lacks this navigation and it should be added. Working with Object is really the ugly way.
Apr 15 2009
prev sibling parent reply Fawzi Mohamed <fmohamed mac.com> writes:
On 2009-04-16 12:18:31 +0200, davidl <davidl nospam.org> said:

 鍦 Wed, 15 Apr 2009 13:56:20 +0800锛孌aniel Keep  
 <daniel.keep.lists gmail.com> 鍐欓亾:
 
 
 
 davidl wrote:
 鍦 Wed, 15 Apr 2009 10:14:42 +0800锛孞arrett Billingsley
 <jarrett.billingsley gmail.com> 鍐欓亾:
 
 2009/4/14 davidl <davidl nospam.org>:
 
 Send this object to vararg func, and retrieve the TypeInfo there and
 return?

No. The typeinfo passed to vararg functions is also determined at compile-time.

so it's a bug? I think vararg funcs always want the real typeinfo of the object

No, they get the typeinfo of what they're passed.
 class A {}
 class B : A {}
 
 void foo(...) {}
 
 void bar(A a) { foo(a); }
 
 void main()
 {
     scope b = new B;
     bar(b);
 }

bar cannot possibly know what the "real" TypeInfo of a is. But that doesn't matter because it's passing an A with A's TypeInfo. And if foo is maybe interested in Bs, then it can just try to up-cast. -- Daniel

If the caller only sends the object typeinfo, then the vararg typeinfo is so limited to be valid for primitives. It's definitely useless for classes cases.

For people interested in runtime introspection tango.core.RuntimeTraits might be interesting. Fawzi
Apr 16 2009
parent Frank Benoit <keinfarbton googlemail.com> writes:
Fawzi Mohamed schrieb:

 For people interested in runtime introspection tango.core.RuntimeTraits
 might be interesting.
 
 Fawzi
 

After the next tango release :)
Apr 16 2009
prev sibling next sibling parent davidl <davidl nospam.org> writes:
在 Wed, 15 Apr 2009 10:14:42 +0800,Jarrett Billingsley  
<jarrett.billingsley gmail.com> 写道:

 2009/4/14 davidl <davidl nospam.org>:
 Send this object to vararg func, and retrieve the TypeInfo there and  
 return?

No. The typeinfo passed to vararg functions is also determined at compile-time.

so it's a bug? I think vararg funcs always want the real typeinfo of the object -- 使用 Opera 革命性的电子邮件客户程序: http://www.opera.com/mail/
Apr 14 2009
prev sibling next sibling parent "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Wed, 15 Apr 2009 02:41:50 -0400, Frank Benoit  
<keinfarbton googlemail.com> wrote:

 Daniel Keep schrieb:
 Ok.  What do you propose to do with this TypeInfo?

 The ONLY thing a given TypeInfo_Class gives you is the ClassInfo, which
 you already have.  The TypeInfo object itself gives you getHash, equals
 and compare, all of which are in Object and thus redundant, tsize which
 is the size of a pointer, swap which I can't see a use for, next which
 is useless, init which is also redundant and flags which is already in
 ClassInfo.

 Again, why do you even want that specific TypeInfo when it is less
 useful than the ClassInfo?

   -- Daniel

I need to have a "something" to retrieve and pass around to hold all available information about a type. Including classes, interfaces and primitives. Because of ClassInfo cannot have information about primitives, I need to work with TypeInfo. Because of I have that need to retrieve that "something" from any object reference also, i need a way from classinfo to typeinfo.

Frank, Daniel is right, TypeInfo_Class simply adds a classinfo member. Each class type does not use a different TypeInfo derivative, it simply uses a different *instance*. For everything that doesn't use the classinfo member in TypeInfo_Class, you can use Object's typeinfo, which should be accurate. For everything else, use the classinfo. Functions that you can use from Object's typeinfo: getHash equals compare tsize flags swap next init Functions that use classinfo: offTi toString opCmp opEquals Which you can simply call classinfo's appropriate functions. You can also easily build a TypeInfo_Class based on the object: scope info = new TypeInfo_Class(); info.info = obj.classinfo; -Steve
Apr 15 2009
prev sibling parent davidl <davidl nospam.org> writes:
在 Wed, 15 Apr 2009 13:56:20 +0800,Daniel Keep  
<daniel.keep.lists gmail.com> 写道:

 davidl wrote:
 在 Wed, 15 Apr 2009 10:14:42 +0800,Jarrett Billingsley
 <jarrett.billingsley gmail.com> 写道:

 2009/4/14 davidl <davidl nospam.org>:
 Send this object to vararg func, and retrieve the TypeInfo there and
 return?

No. The typeinfo passed to vararg functions is also determined at compile-time.

so it's a bug? I think vararg funcs always want the real typeinfo of the object

No, they get the typeinfo of what they're passed.
 class A {}
 class B : A {}

 void foo(...) {}

 void bar(A a) { foo(a); }

 void main()
 {
     scope b = new B;
     bar(b);
 }

bar cannot possibly know what the "real" TypeInfo of a is. But that doesn't matter because it's passing an A with A's TypeInfo. And if foo is maybe interested in Bs, then it can just try to up-cast. -- Daniel

If the caller only sends the object typeinfo, then the vararg typeinfo is so limited to be valid for primitives. It's definitely useless for classes cases. -- 使用 Opera 革命性的电子邮件客户程序: http://www.opera.com/mail/
Apr 16 2009
prev sibling next sibling parent Frank Benoit <keinfarbton googlemail.com> writes:
Frank Benoit schrieb:
 I need to retrieve an instance of TypeInfo from an object instance at
 runtime.
 
 TypeInfo info = typeid(obj) // does not work, only compile time
 
 TypeInfo info = obj.classinfo.????; // how to navigate to TypeInfo?
 
 Is that possible?
 If not, why? And can it be added (D1)?

See also: http://d.puremagic.com/issues/show_bug.cgi?id=2836
Apr 15 2009
prev sibling parent grauzone <none example.net> writes:
Frank Benoit wrote:
 I need to retrieve an instance of TypeInfo from an object instance at
 runtime.
 
 TypeInfo info = typeid(obj) // does not work, only compile time
 
 TypeInfo info = obj.classinfo.????; // how to navigate to TypeInfo?
 
 Is that possible?
 If not, why? And can it be added (D1)?

I also did hit this issue. Fortunately, I never get a ClassInfo of a class whose static type I didn't see at least once before. This means I can get both the TypeInfo and ClassInfo from the static type, and put them into a global AA like ClassInfo[TypeInfo].
Apr 15 2009