module nullablestore; @safe pure nothrow @nogc: /** A very stupid type that does nothing more than store a `TypeValue` and a key. Is is useful to break cycles in type systems. The value of KeyType.init must equal nullvalue; */ struct NullableStore(T,KType = ulong, KType nullvalue = KType.init) { /// alias TypeValue = T; alias KeyType = KType; static immutable NullValue = nullvalue; /// long key; bool isNull() const { return this.key == NullValue; } static assert(KeyType.init == NullValue); } version(unittest) { private: struct Foo { NullableStore!Bar bar; } struct Bar { Foo foo; NullableStore!Foo nsFoo; } } unittest { Bar b; Foo f; static assert(NullableStore!(Bar).NullValue == ulong.min); assert(f.bar.isNull()); static if(is(typeof(Foo.bar) : NullableStore!F, F)) { assert(is(F == Bar)); assert(is(Foo.bar.TypeValue == Bar)); } else { assert(false); } }