Checked.opOpAssign

Defines operators +=, -=, *=, /=, %=, ^^=, &=, |=, ^=, <<=, >>=, and >>>=.

If Hook defines hookOpOpAssign, opOpAssign forwards to hook.hookOpOpAssign!op(payload, rhs), where payload is a reference to the internally held data so the hook can change it.

Otherwise, the operator first evaluates auto result = opBinary!op(payload, rhs).payload, which is subject to the hooks in opBinary. Then, if result is less than Checked!(T, Hook).min and if Hook defines onLowerBound, the payload is assigned from hook.onLowerBound(result, min). If result is greater than Checked!(T, Hook).max and if Hook defines onUpperBound, the payload is assigned from hook.onUpperBound(result, min).

If the right-hand side is also a Checked but with a different hook or underlying type, the hook and underlying type of this Checked takes precedence.

In all other cases, the built-in behavior is carried out.

  1. Checked opOpAssign(Rhs rhs)
    struct Checked(T, Hook = Abort)
    ref return
    opOpAssign
    (
    string op
    Rhs
    )
    (
    const Rhs rhs
    )
    if (
    is(Rhs == bool)
    )
    if (
    is(T == Checked!(U, H),
    U
    H
    )
    )
  2. Checked opOpAssign(Rhs rhs)

Parameters

op

The operator involved (without the "=", e.g. "+" for "+=" etc)

rhs Rhs

The right-hand side of the operator (left-hand side is this)

Return Value

Type: Checked

A reference to this.

Examples

static struct MyHook
{
    static bool thereWereErrors;
    static T onLowerBound(Rhs, T)(Rhs rhs, T bound)
    {
        thereWereErrors = true;
        return bound;
    }
    static T onUpperBound(Rhs, T)(Rhs rhs, T bound)
    {
        thereWereErrors = true;
        return bound;
    }
}
auto x = checked!MyHook(byte.min);
x -= 1;
assert(MyHook.thereWereErrors);
MyHook.thereWereErrors = false;
x = byte.max;
x += 1;
assert(MyHook.thereWereErrors);

Meta