opCast, c bindings and normal casts.

Johannes Pfau spam at example.com
Sat Jul 9 02:47:51 PDT 2011


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?

-- 
Johannes Pfau



More information about the Digitalmars-d-learn mailing list