Hook for <, <=, >, and >= that ensures comparison against integral values has the behavior expected by the usual arithmetic rules. The built-in semantics yield surprising behavior when comparing signed values against unsigned values, for example 0u < -1. The call hookOpCmp(x, y) returns -1 if and only if x is smaller than y in abstract arithmetic sense.
Hook for == and != that ensures comparison against integral values has the behavior expected by the usual arithmetic rules. The built-in semantics yield surprising behavior when comparing signed values against unsigned values for equality, for example uint.max == -1 or -1_294_967_296 == 3_000_000_000u. The call hookOpEquals(x, y) returns true if and only if x and y represent the same arithmetic number.
alias opEqualsProper = ProperCompare.hookOpEquals; assert(opEqualsProper(42, 42)); assert(opEqualsProper(42.0, 42.0)); assert(opEqualsProper(42u, 42)); assert(opEqualsProper(42, 42u)); assert(-1 == 4294967295u); assert(!opEqualsProper(-1, 4294967295u)); assert(!opEqualsProper(const uint(-1), -1)); assert(!opEqualsProper(uint(-1), -1.0)); assert(3_000_000_000U == -1_294_967_296); assert(!opEqualsProper(3_000_000_000U, -1_294_967_296));
Hook that provides arithmetically correct comparisons for equality and ordering. Comparing an object of type Checked!(X, ProperCompare) against another integral (for equality or ordering) ensures that no surprising conversions from signed to unsigned integral occur before the comparison. Using Checked!(X, ProperCompare) on either side of a comparison for equality against a floating-point number makes sure the integral can be properly converted to the floating point type, thus making sure equality is transitive.