The right-hand side operand
either the type of rhs or the underlying type if rhs is a Checked instance
The result of hookOpCmp if hook defines hookOpCmp. If U is an instance of Checked and hook does not define hookOpCmp, result of rhs.hook.hookOpCmp is returned. If none of the instances specify the behavior via hookOpCmp, -1 is returned if lhs is lesser than rhs, 1 if lhs is greater than rhs and 0 on equality.
import std.traits : isUnsigned; static struct MyHook { static bool thereWereErrors; static int hookOpCmp(L, R)(L lhs, R rhs) { static if (isUnsigned!L && !isUnsigned!R) { if (rhs < 0 && rhs >= lhs) thereWereErrors = true; } else static if (isUnsigned!R && !isUnsigned!L) { if (lhs < 0 && lhs >= rhs) thereWereErrors = true; } // Preserve built-in behavior. return lhs < rhs ? -1 : lhs > rhs; } } auto a = checked!MyHook(-42); assert(a > uint(42)); assert(MyHook.thereWereErrors); static struct MyHook2 { static int hookOpCmp(L, R)(L lhs, R rhs) { // Default behavior return lhs < rhs ? -1 : lhs > rhs; } } MyHook.thereWereErrors = false; assert(Checked!(uint, MyHook2)(uint(-42)) <= a); //assert(Checked!(uint, MyHook2)(uint(-42)) >= a); // Hook on left hand side takes precedence, so no errors assert(!MyHook.thereWereErrors); assert(a <= Checked!(uint, MyHook2)(uint(-42))); assert(MyHook.thereWereErrors);
Compares this against rhs for ordering. If Hook defines hookOpCmp, the function forwards to hook.hookOpCmp(get, rhs). Otherwise, the result of the built-in comparison operation is returned.
If U is also an instance of Checked, both hooks (left- and right-hand side) are introspected for the method hookOpCmp. If both define it, priority is given to the left-hand side.