Previous Entry Share Next Entry
std.typecons.wrap Improvements Continued

My last post mentioned that a change to a Structural template caused a unittest failure. The specific details are as follows.

    Human h1 = new Human();
    // structural upcast (two steps)
    Quack qx = h1.wrap!Quack;   // Human -> Quack
    Flyer fx = qx.wrap!Flyer;   // Quack -> Flyer
    // strucural downcast (two steps)
    Quack qy = fx.unwrap!Quack; // Flyer -> Quack
    Human hy = qy.unwrap!Human; // Quack -> Human
    assert(hy is h1);
    // strucural downcast (one step)
    Human hz = fx.unwrap!Human; // Flyer -> Human
    assert(hz is h1); // FAIL

The failure was on the direct step from a Flyer straight back to a Human. The Flyer object did not wrap a Human, instead it was a Quack. But the change to use Structural!T doesn't know anything about Quack. This meant that checking if the Flyer could be cast to a Structural!Human would fail because it was not. Templates in D are not contravariant so the Flyer was also not a Structural!Object, even though for all intents and purposes it is.

I believe there is some classinfo I could obtain and setup appropriate calls to make the appropriate jumps back to the original type. However, I can have the compiler do this for me. So I returned to the original object approach by making classes and interfaces use Structural!Object and leave the specific type only for structs.

This is a workable solution since a structure will never nest. If a struct is wrapped into multiple types, the second wrap will be wrapping the Impl class created from the first

On a similar note, I found a request by Andrei which I think is essentially addressed by this work, Class!T.


Log in