https://issues.dlang.org/show_bug.cgi?id=259
Dominikus Dittes Scherkl <[email protected]> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |[email protected] --- Comment #58 from Dominikus Dittes Scherkl <[email protected]> --- The problem is still there, and the behaviour is completely inconsistent, so braking any code isn't a problem I think because I cannot imagine that anybody really relies on the strange behaviour: unittest { byte a = -3; ubyte b = 2; short c = -3; ushort d = 2; int e = -3; uint f = 2; long g = -3; ulong h = 2; assert(a < b); assert(c < d); assert(e < f); // fails!! assert(g < h); // fails!! assert(a < h); // fails!! assert(b > g); assert(d > e); } So why don't we change to something that simply always works? int opCmp(T, U)(const(T) a, const(U) b) pure @safe @nogc nothrow if(is(Unqual!T == Unqual!U) || isFloatingPoint!T || isFloatingPoint!U) { // Should be buildin. Naive implementation: return a <= b ? a != b ? -1 : 0 : 1; } /// Returns negative value if a < b, 0 if they are equal or positive value if a > b. /// This will always yield a correct result, no matter which integral types are compared. /// It uses one extra comparison operation if and only if /// one type is signed and the other unsigned but has bigger max. int opCmp(T, U)(const(T) a, const(U) b) pure @safe @nogc nothrow if(isIntegral!T && isIntegral!U && !is(Unqual!T == Unqual!U)) { static if(T.sizeof == U.sizeof) alias C = Unsigned!T; else alias C = CommonType!(T, U); // this will be the larger type static if(isSigned!T && isUnsigned!U && T.sizeof <= U.sizeof) { return (a < 0) ? -1 : opCmp(cast(Unsigned!C)a, cast(C)b); } else static if(isUnsigned!T && isSigned!U && T.sizeof >= U.sizeof) { return (b < 0) ? 1 : opCmp(cast(C)a, cast(Unsigned!C)b); } else { // both signed or both unsigned or the unsigned type is smaller // and can therefore be safely cast to the signed type return opCmp(cast(C)a, cast(C)b); } } --
