www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Can you use RTTI to determine a union member?

reply "Janice Caron" <caron800 googlemail.com> writes:
Suppose I have

union U
{
    A a;
    B b;
    C c;
}

and a function f(U u)

is there any way to determine at runtime, which union member has been
assigned? I guess I want to do something like

void f(U u)
{
    if (is(u.a.typeof == A)) /* stuff */
    else if (is(u.a.typeof == B)) /* stuff */
    else if (is(u.a.typeof == C)) /* stuff */
}

except obviously that won't work because typeof is a compile time
thing, not a run time thing, and so it will always return A.

I don't suppose there's a runtime solution? If not, I guess I'll just
do what I've been doing all along (that is, store the choice in an
enum outside the union).
Oct 16 2007
next sibling parent reply Kirk McDonald <kirklin.mcdonald gmail.com> writes:
Janice Caron wrote:
 Suppose I have
 
 union U
 {
     A a;
     B b;
     C c;
 }
 
 and a function f(U u)
 
 is there any way to determine at runtime, which union member has been
 assigned? I guess I want to do something like
 
 void f(U u)
 {
     if (is(u.a.typeof == A)) /* stuff */
     else if (is(u.a.typeof == B)) /* stuff */
     else if (is(u.a.typeof == C)) /* stuff */
 }
 
 except obviously that won't work because typeof is a compile time
 thing, not a run time thing, and so it will always return A.
 
 I don't suppose there's a runtime solution? If not, I guess I'll just
 do what I've been doing all along (that is, store the choice in an
 enum outside the union).
enum + union is the age-old solution to this. D doesn't store this information for you (which I think is a good thing). -- Kirk McDonald http://kirkmcdonald.blogspot.com Pyd: Connecting D and Python http://pyd.dsource.org
Oct 16 2007
parent Daniel Keep <daniel.keep.lists gmail.com> writes:
Kirk McDonald wrote:
 Janice Caron wrote:
 Suppose I have

 union U
 {
     A a;
     B b;
     C c;
 }

 and a function f(U u)

 is there any way to determine at runtime, which union member has been
 assigned? I guess I want to do something like

 void f(U u)
 {
     if (is(u.a.typeof == A)) /* stuff */
     else if (is(u.a.typeof == B)) /* stuff */
     else if (is(u.a.typeof == C)) /* stuff */
 }

 except obviously that won't work because typeof is a compile time
 thing, not a run time thing, and so it will always return A.

 I don't suppose there's a runtime solution? If not, I guess I'll just
 do what I've been doing all along (that is, store the choice in an
 enum outside the union).
enum + union is the age-old solution to this. D doesn't store this information for you (which I think is a good thing).
Another solution is to use a variant datatype which will take care of checking you're unboxing the right type. -- Daniel
Oct 16 2007
prev sibling parent reply BCS <ao pathlink.com> writes:
Reply to Janice,

 Suppose I have
 
 union U
 {
 A a;
 B b;
 C c;
 }
 and a function f(U u)
 
 is there any way to determine at runtime, which union member has been
 assigned? I guess I want to do something like
 
 void f(U u)
 {
 if (is(u.a.typeof == A)) /* stuff */
 else if (is(u.a.typeof == B)) /* stuff */
 else if (is(u.a.typeof == C)) /* stuff */
 }
 except obviously that won't work because typeof is a compile time
 thing, not a run time thing, and so it will always return A.
 
 I don't suppose there's a runtime solution? If not, I guess I'll just
 do what I've been doing all along (that is, store the choice in an
 enum outside the union).
 
if A, B and C are classes then you can uses (cast(A)(cast(Object)u.b) !is null) (cast(B)(cast(Object)u.c) !is null) (cast(C)(cast(Object)u.a) !is null) note the twist of the types. this is to force DMD to actually do the cast. It might work without it but might not.
Oct 16 2007
parent reply Christian Kamm <kamm.incasoftware shift-at-left-and-remove-this.de> writes:
 if A, B and C are classes then you can uses
 
 (cast(A)(cast(Object)u.b) !is null)
 (cast(B)(cast(Object)u.c) !is null)
 (cast(C)(cast(Object)u.a) !is null)
If A, B, C are classes, you could also check with u.a.classinfo is A.classinfo u.a.classinfo is B.classinfo u.a.classinfo is C.classinfo. Christian
Oct 16 2007
next sibling parent reply "Janice Caron" <caron800 googlemail.com> writes:
On 10/16/07, Christian Kamm <kamm.incasoftware shift-at-left-and-remove-this.de
 If A, B, C are classes, you could also check with

 u.a.classinfo is A.classinfo
 u.a.classinfo is B.classinfo
 u.a.classinfo is C.classinfo.
That's really cool, but I can't find any documentation on .classinfo. I looked on the DigitalMars site in the pages "Classes", "Expressions" and "Properties", and after that I got stuck. Where is this documented?
Oct 16 2007
parent reply BCS <ao pathlink.com> writes:
Reply to Janice,

 On 10/16/07, Christian Kamm
 <kamm.incasoftware shift-at-left-and-remove-this.de
 
 If A, B, C are classes, you could also check with
 
 u.a.classinfo is A.classinfo
 u.a.classinfo is B.classinfo
 u.a.classinfo is C.classinfo.
That's really cool, but I can't find any documentation on .classinfo. I looked on the DigitalMars site in the pages "Classes", "Expressions" and "Properties", and after that I got stuck. Where is this documented?
look under the phobos docs
Oct 16 2007
parent Bill Baxter <dnewsgroup billbaxter.com> writes:
BCS wrote:
 Reply to Janice,
 
 On 10/16/07, Christian Kamm
 <kamm.incasoftware shift-at-left-and-remove-this.de

 If A, B, C are classes, you could also check with

 u.a.classinfo is A.classinfo
 u.a.classinfo is B.classinfo
 u.a.classinfo is C.classinfo.
That's really cool, but I can't find any documentation on .classinfo. I looked on the DigitalMars site in the pages "Classes", "Expressions" and "Properties", and after that I got stuck. Where is this documented?
look under the phobos docs
Specifically under "object", right at the top. There's a bunch of useful stuff documented in there. --bb
Oct 16 2007
prev sibling parent reply Frits van Bommel <fvbommel REMwOVExCAPSs.nl> writes:
Christian Kamm wrote:
 If A, B, C are classes, you could also check with
 
 u.a.classinfo is A.classinfo
 u.a.classinfo is B.classinfo
 u.a.classinfo is C.classinfo.
Only if the union never stores references to subclasses.
Oct 16 2007
parent 0ffh <spam frankhirsch.net> writes:
Frits van Bommel wrote:
 Christian Kamm wrote:
 If A, B, C are classes, you could also check with

 u.a.classinfo is A.classinfo
 u.a.classinfo is B.classinfo
 u.a.classinfo is C.classinfo.
Only if the union never stores references to subclasses.
Righto, AFAIK; in that case one might consider to have all classes implement an interface with a member that holds an identifier for the class. Or use, as has been mentioned already, the classical variant of adding the type info in a struct wrapped around the union. Regards, Frank
Oct 16 2007