Johannes Pfau wrote: >Hi, > >I have a wrapper for a "object aware" c library (cairo). Take for >example two classes, Surface and a subclass, ImageSurface. Now this >code has to be valid: >----------------------- >auto ptr = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, 512, 512); >Surface s = new Surface(ptr); >ImageSurface imgs = cast(ImageSurface)s; >----------------------- > >As D cannot know that 's' really should be an ImageSurface, I have >implemented opCast to get this example working: >----------------------- >class Surface >{ > static Surface castFrom(Surface other) > { > return other; > } > > T opCast(T)() if(isImplicitlyConvertible!(T, Surface)) > { > return T.castFrom(this); > } >} >class ImageSurface : Surface >{ > static ImageSurface castFrom(Surface other) > { > auto type = cairo_surface_get_type(other.nativePointer); > if(type == cairo_surface_type_t.CAIRO_SURFACE_TYPE_IMAGE) > { > return new ImageSurface(other.nativePointer); > } > else > return null; > } >} >----------------------- > >This code works quite well. But it performs unnecessary calls to >cairo_surface_get_type (and allocates unnecessary objects) for simple >cases: >----------------------- >auto surface = new ImageSurface(Format.CAIRO_FORMAT_ARGB32, 400, 400); >Surface tmp = cast(Surface)surface; >ImageSurface test = cast(ImageSurface)as; >----------------------- > >In this case, the first D object already is an ImageSurface so the >custom opCast code isn't needed for the last line. > >So the question is: Is there some way to check in the opCast function >if a normal D object cast would succeed and then just return it's >result? >
In case anyone's interested: I think this could be done with _d_dynamic_cast from rt.cast_ (druntime). I've dropped the opCast/castFrom approach though (not working in some cases), so I haven't tested this. -- Johannes Pfau