digitalmars.D.learn - Polymorphism in regular variadic function
- Bill Baxter (22/22) Dec 04 2006 Is there any way to check if an argument is type T or anything derived
- Jarrett Billingsley (33/55) Dec 04 2006 Heheh.. I did something like:
- Bill Baxter (12/84) Dec 05 2006 Thanks Jarrett,
- Jarrett Billingsley (8/16) Dec 05 2006 Hmm.. I don't think it should. TypeInfo_Class is, well, the typeinfo fo...
- Bill Baxter (13/29) Dec 05 2006 Oh, I see, I didn't realize the TypeInfo_Class bits applied to the
- Bill Baxter (4/26) Dec 05 2006 I added this tip to the comments page for Phobos/object.
Is there any way to check if an argument is type T or anything derived from it using the TypeInfo? Basically I want this: class Foo { int x = 3; } class Bar : Foo { long y = 4; } void printargs(...) { printf("%d arguments\n", _arguments.length); for (int i = 0; i < _arguments.length; i++) { _arguments[i].print(); // Want to accept Foo or anything derived from Foo here! if (_arguments[i] == typeid(Foo)) { Foo f = *cast(Foo*)_argptr; _argptr += Foo.sizeof; printf("\t%p\n", f); } else assert(0); } } --bb
Dec 04 2006
"Bill Baxter" <wbaxter gmail.com> wrote in message news:el2iq4$2gb3$1 digitaldaemon.com...Is there any way to check if an argument is type T or anything derived from it using the TypeInfo? Basically I want this: class Foo { int x = 3; } class Bar : Foo { long y = 4; } void printargs(...) { printf("%d arguments\n", _arguments.length); for (int i = 0; i < _arguments.length; i++) { _arguments[i].print(); // Want to accept Foo or anything derived from Foo here! if (_arguments[i] == typeid(Foo)) { Foo f = *cast(Foo*)_argptr; _argptr += Foo.sizeof; printf("\t%p\n", f); } else assert(0); } } --bbHeheh.. I did something like: TypeInfo ti = _arguments[i]; TypeInfo_Class tic = cast(TypeInfo_Class)ti; if(tic) { ClassInfo ci = tic.info; for( ; ci !is null; ci = ci.base) if(ci == Foo.classinfo) { // it's derived, do what you will } if(ci is null) { // we got to the base without finding Foo, // it's not derived from Foo } } I wonder if there's any way to take advantage of the internal casting functions (which are used whenever you do a dynamic downcast). Well, now that I think about it, you might be able to replace the above condition with: if(tic) { Object o = va_arg!(Object)(_argptr); Foo f = cast(Foo)o; if(f !is null) { // it's a Foo } } Which .. would probably work. Give it a shot.
Dec 04 2006
Thanks Jarrett, This TypeInfo_Class thing seems to be undocumented. Incidentally it's a piece of cake with a variadic template, I just wanted to see try it with a regular function first before going all templatey. I haven't tried your code, but it seems like your cast to Object in the second suggestion is not going to be safe if the thing really isn't an Object. The following cast to Foo will try to do some vtable stuff I guess, and that could result in a bad memory access, no? --bb Jarrett Billingsley wrote:"Bill Baxter" <wbaxter gmail.com> wrote in message news:el2iq4$2gb3$1 digitaldaemon.com...--bbIs there any way to check if an argument is type T or anything derived from it using the TypeInfo? Basically I want this: class Foo { int x = 3; } class Bar : Foo { long y = 4; } void printargs(...) { printf("%d arguments\n", _arguments.length); for (int i = 0; i < _arguments.length; i++) { _arguments[i].print(); // Want to accept Foo or anything derived from Foo here! if (_arguments[i] == typeid(Foo)) { Foo f = *cast(Foo*)_argptr; _argptr += Foo.sizeof; printf("\t%p\n", f); } else assert(0); } } --bbHeheh.. I did something like: TypeInfo ti = _arguments[i]; TypeInfo_Class tic = cast(TypeInfo_Class)ti; if(tic) { ClassInfo ci = tic.info; for( ; ci !is null; ci = ci.base) if(ci == Foo.classinfo) { // it's derived, do what you will } if(ci is null) { // we got to the base without finding Foo, // it's not derived from Foo } } I wonder if there's any way to take advantage of the internal casting functions (which are used whenever you do a dynamic downcast). Well, now that I think about it, you might be able to replace the above condition with: if(tic) { Object o = va_arg!(Object)(_argptr); Foo f = cast(Foo)o; if(f !is null) { // it's a Foo } } Which .. would probably work. Give it a shot.
Dec 05 2006
"Bill Baxter" <dnewsgroup billbaxter.com> wrote in message news:el52bq$2dcb$1 digitaldaemon.com...Thanks Jarrett, This TypeInfo_Class thing seems to be undocumented. Incidentally it's a piece of cake with a variadic template, I just wanted to see try it with a regular function first before going all templatey. I haven't tried your code, but it seems like your cast to Object in the second suggestion is not going to be safe if the thing really isn't an Object. The following cast to Foo will try to do some vtable stuff I guess, and that could result in a bad memory access, no?Hmm.. I don't think it should. TypeInfo_Class is, well, the typeinfo for a class, which all derive from Object, so getting the param as an Object shouldn't be a problem, should it? ..oh crap. Interfaces also have a TypeInfo_Class. :S And since they aren't _required_ to be castable to object (i.e. COM interfaces).. Yeah, the other way is necessary.
Dec 05 2006
Jarrett Billingsley wrote:"Bill Baxter" <dnewsgroup billbaxter.com> wrote in message news:el52bq$2dcb$1 digitaldaemon.com...Oh, I see, I didn't realize the TypeInfo_Class bits applied to the second suggestion also. TypeInfo ti = _arguments[i]; TypeInfo_Class tic = cast(TypeInfo_Class)ti; if(tic) { Object o = va_arg!(Object)(_argptr); Foo f = cast(Foo)o; .. So yeh, that does look like it would work, except for, as you say, the fact that it doesn't... :( --bbThanks Jarrett, This TypeInfo_Class thing seems to be undocumented. Incidentally it's a piece of cake with a variadic template, I just wanted to see try it with a regular function first before going all templatey. I haven't tried your code, but it seems like your cast to Object in the second suggestion is not going to be safe if the thing really isn't an Object. The following cast to Foo will try to do some vtable stuff I guess, and that could result in a bad memory access, no?Hmm.. I don't think it should. TypeInfo_Class is, well, the typeinfo for a class, which all derive from Object, so getting the param as an Object shouldn't be a problem, should it?
Dec 05 2006
Jarrett Billingsley wrote:Heheh.. I did something like: TypeInfo ti = _arguments[i]; TypeInfo_Class tic = cast(TypeInfo_Class)ti; if(tic) { ClassInfo ci = tic.info; for( ; ci !is null; ci = ci.base) if(ci == Foo.classinfo) { // it's derived, do what you will } if(ci is null) { // we got to the base without finding Foo, // it's not derived from Foo } }I added this tip to the comments page for Phobos/object. http://www.prowiki.org/wiki4d/wiki.cgi?DocComments/Phobos/Object --bb
Dec 05 2006