...ing logging 4.0

はてなブログに移行しました。D言語の話とかいろいろ。

std.traits.isCovariantWith

import std.traits;

interface I { I clone(); }
class C : I
{
    override C clone()   // I.clone() の共変オーバーライド
    {
        return new C;
    }
}

void main()
{
	{
		static assert(isCovariantWith!(typeof(C.clone), typeof(I.clone)));
	}{
		C function() derived;
		I function() base;
//		static assert(is(typeof(derived) == function));
//		static assert(is(typeof(base) == function));
		
		base = derived;
		static assert(isCovariantWith!(typeof(derived), typeof(base)));
	}{
		C delegate() derived;
		I delegate() base;
//		static assert(is(typeof(derived) == function));
//		static assert(is(typeof(base) == function));

		base = derived;
		static assert(isCovariantWith!(typeof(derived), typeof(base)));
	}
}

dmd 2.056から関数とデリゲートのcovarianceが考慮されるようになったので,たまたま見つけたisCovariantWithでも判定できるかと思ってやってみたら動かなかった.
isCovariantWith(F,G)のconstraintを消したら動いたけど,あれって必要なのかな?
そもそも,static assert(is(main == function);がfalseなんだけどis(... == function)ってどういうものだったっけ・・・.

typeof(main) == functionだった.

template isCovariantWith(F, G)
    if (is(F == function) && is(G == function) ||
        is(F == delegate) && is(G == delegate) || isFunctionPointer!F && isFunctionPointer!G)

こうかな.

import std.traits;

interface I { I clone(); }
class C : I
{
    override C clone()   // I.clone() の共変オーバーライド
    {
        return new C;
    }
}

void main()
{
	{
		static assert(isCovariantWith!(typeof(C.clone), typeof(I.clone)));
	}{
		C function() derived;
		I function() base;
		base = derived;
		static assert(isCovariantWith!(typeof(*derived), typeof(*base)));
		static assert(isCovariantWith!(typeof(derived), typeof(base)));
		//static assert(isCovariantWith!(typeof(derived), typeof(*base)));
		//static assert(isCovariantWith!(typeof(*derived), typeof(base)));
	}{
		C delegate() derived;
		I delegate() base;
		base = derived;
		static assert(isCovariantWith!(typeof(derived), typeof(base)));
	}{
		C function() derived;
		I delegate() base;
		//base = derived;
		//static assert(isCovariantWith!(typeof(derived), typeof(base)));
		//static assert(isCovariantWith!(typeof(*derived), typeof(base)));
	}
}