module meta.SafeUnqual; import std.traits : Unqual; /** * This helper template strips out const or immutable only if implicit conversion is possible. */ template SafeUnqual(T) { static if (__traits(compiles, (T t) { Unqual!T ut = t; })) { alias SafeUnqual = Unqual!T; } else { alias SafeUnqual = T; } } /// unittest { struct S1 { int i; } // no reference struct S2 { int[] array; } // reference to mutable data struct S3 { immutable(int)[] array; } // no reference to mutable data static assert(is(SafeUnqual!(immutable int) == int)); // can safely unqual S1 because there's no references static assert(is(SafeUnqual!(immutable S1) == S1)); // can't safely unqual S2 because the new type would hold mutable references static assert(is(SafeUnqual!(immutable S2) == immutable(S2))); // can safely unqual S3 because all references point at immutable data anyway static assert(is(SafeUnqual!(immutable S3) == S3)); }