// Written in the D programming language.
/**
$(SCRIPT inhibitQuickIndex = 1;)

This module defines facilities for efficient checking of integral operations
against overflow, casting with loss of precision, unexpected change of sign,
etc. The checking (and possibly correction) can be done at operation level, for
example $(LREF opChecked)$(D !"+"(x, y, overflow)) adds two integrals `x` and
`y` and sets `overflow` to `true` if an overflow occurred. The flag `overflow`
(a `bool` passed by reference) is not touched if the operation succeeded, so the
same flag can be reused for a sequence of operations and tested at the end.

Issuing individual checked operations is flexible and efficient but often
tedious. The $(LREF Checked) facility offers encapsulated integral wrappers that
do all checking internally and have configurable behavior upon erroneous
results. For example, `Checked!int` is a type that behaves like `int` but aborts
execution immediately whenever involved in an operation that produces the
arithmetically wrong result. The accompanying convenience function $(LREF
checked) uses type deduction to convert a value `x` of integral type `T` to
`Checked!T` by means of `checked(x)`. For example:

---
void main()
{
    import std.checkedint, std.stdio;
    writeln((checked(5) + 7).get); // 12
    writeln((checked(10) * 1000 * 1000 * 1000).get); // Overflow
}
---

Similarly, $(D checked(-1) > uint(0)) aborts execution (even though the built-in
comparison $(D int(-1) > uint(0)) is surprisingly true due to language's
conversion rules modeled after C). Thus, `Checked!int` is a virtually drop-in
replacement for `int` useable in debug builds, to be replaced by `int` in
release mode if efficiency demands it.

`Checked`  has customizable behavior with the help of a second type parameter,
`Hook`. Depending on what methods `Hook` defines, core operations on the
underlying integral may be verified for overflow or completely redefined. If
`Hook` defines no method at all and carries no state, there is no change in
behavior, i.e. $(D Checked!(int, void)) is a wrapper around `int` that adds no
customization at all.

This module provides a few predefined hooks (below) that add useful behavior to
`Checked`:

$(BOOKTABLE ,
    $(TR $(TD $(LREF Abort)) $(TD
        fails every incorrect operation with a message to $(REF
        stderr, std, stdio) followed by a call to `assert(0)`. It is the default
        second parameter, i.e. `Checked!short` is the same as
        $(D Checked!(short, Abort)).
    ))
    $(TR $(TD $(LREF Throw)) $(TD
        fails every incorrect operation by throwing an exception.
    ))
    $(TR $(TD $(LREF Warn)) $(TD
        prints incorrect operations to $(REF stderr, std, stdio)
        but otherwise preserves the built-in behavior.
    ))
    $(TR $(TD $(LREF ProperCompare)) $(TD
        fixes the comparison operators `==`, `!=`, `<`, `<=`, `>`, and `>=`
        to return correct results in all circumstances,
        at a slight cost in efficiency. For example,
        $(D Checked!(uint, ProperCompare)(1) > -1) is `true`,
        which is not the case for the built-in comparison. Also, comparing
        numbers for equality with floating-point numbers only passes if the
        integral can be converted to the floating-point number precisely,
        so as to preserve transitivity of equality.
    ))
    $(TR $(TD $(LREF WithNaN)) $(TD
        reserves a special "Not a Number" (NaN) value akin to the homonym value
        reserved for floating-point values. Once a $(D Checked!(X, WithNaN))
        gets this special value, it preserves and propagates it until
        reassigned. $(LREF isNaN) can be used to query whether the object
        is not a number.
    ))
    $(TR $(TD $(LREF Saturate)) $(TD
        implements saturating arithmetic, i.e. $(D Checked!(int, Saturate))
        "stops" at `int.max` for all operations that would cause an `int` to
        overflow toward infinity, and at `int.min` for all operations that would
        correspondingly overflow toward negative infinity.
    ))
)


These policies may be used alone, e.g. $(D Checked!(uint, WithNaN)) defines a
`uint`-like type that reaches a stable NaN state for all erroneous operations.
They may also be "stacked" on top of each other, owing to the property that a
checked integral emulates an actual integral, which means another checked
integral can be built on top of it. Some combinations of interest include:

$(BOOKTABLE ,
    $(TR $(TD $(D Checked!(Checked!int, ProperCompare))))
    $(TR $(TD
defines an `int` with fixed
comparison operators that will fail with `assert(0)` upon overflow. (Recall that
`Abort` is the default policy.) The order in which policies are combined is
important because the outermost policy (`ProperCompare` in this case) has the
first crack at intercepting an operator. The converse combination $(D
Checked!(Checked!(int, ProperCompare))) is meaningless because `Abort` will
intercept comparison and will fail without giving `ProperCompare` a chance to
intervene.
    ))
    $(TR $(TD))
    $(TR $(TDNW $(D Checked!(Checked!(int, ProperCompare), WithNaN))))
    $(TR $(TD
defines an `int`-like
type that supports a NaN value. For values that are not NaN, comparison works
properly. Again the composition order is important; $(D Checked!(Checked!(int,
WithNaN), ProperCompare)) does not have good semantics because `ProperCompare`
intercepts comparisons before the numbers involved are tested for NaN.
    ))
)

The hook's members are looked up statically in a Design by Introspection manner
and are all optional. The table below illustrates the members that a hook type
may define and their influence over the behavior of the `Checked` type using it.
In the table, `hook` is an alias for `Hook` if the type `Hook` does not
introduce any state, or an object of type `Hook` otherwise.

$(TABLE ,
$(TR $(TH `Hook` member) $(TH Semantics in $(D Checked!(T, Hook)))
)
$(TR $(TD `defaultValue`) $(TD If defined, `Hook.defaultValue!T` is used as the
default initializer of the payload.)
)
$(TR $(TD `min`) $(TD If defined, `Hook.min!T` is used as the minimum value of
the payload.)
)
$(TR $(TD `max`) $(TD If defined, `Hook.max!T` is used as the maximum value of
the payload.)
)
$(TR $(TD `hookOpCast`) $(TD If defined, `hook.hookOpCast!U(get)` is forwarded
to unconditionally when the payload is to be cast to type `U`.)
)
$(TR $(TD `onBadCast`) $(TD If defined and `hookOpCast` is $(I not) defined,
`onBadCast!U(get)` is forwarded to when the payload is to be cast to type `U`
and the cast would lose information or force a change of sign.)
)
$(TR $(TD `hookOpEquals`) $(TD If defined, $(D hook.hookOpEquals(get, rhs)) is
forwarded to unconditionally when the payload is compared for equality against
value `rhs` of integral, floating point, or Boolean type.)
)
$(TR $(TD `hookOpCmp`) $(TD If defined, $(D hook.hookOpCmp(get, rhs)) is
forwarded to unconditionally when the payload is compared for ordering against
value `rhs` of integral, floating point, or Boolean type.)
)
$(TR $(TD `hookOpUnary`) $(TD If defined, `hook.hookOpUnary!op(get)` (where `op`
is the operator symbol) is forwarded to for unary operators `-` and `~`. In
addition, for unary operators `++` and `--`, `hook.hookOpUnary!op(payload)` is
called, where `payload` is a reference to the value wrapped by `Checked` so the
hook can change it.)
)
$(TR $(TD `hookOpBinary`) $(TD If defined, $(D hook.hookOpBinary!op(get, rhs))
(where `op` is the operator symbol and `rhs` is the right-hand side operand) is
forwarded to unconditionally for binary operators `+`,  `-`, `*`, `/`, `%`,
`^^`, `&`, `|`, `^`, `<<`, `>>`, and `>>>`.)
)
$(TR $(TD `hookOpBinaryRight`) $(TD If defined, $(D
hook.hookOpBinaryRight!op(lhs, get)) (where `op` is the operator symbol and
`lhs` is the left-hand side operand) is forwarded to unconditionally for binary
operators `+`,  `-`, `*`, `/`, `%`, `^^`, `&`, `|`, `^`, `<<`, `>>`, and `>>>`.)
)
$(TR $(TD `onOverflow`) $(TD If defined, `hook.onOverflow!op(get)` is forwarded
to for unary operators that overflow but only if `hookOpUnary` is not defined.
Unary `~` does not overflow; unary `-` overflows only when the most negative
value of a signed type is negated, and the result of the hook call is returned.
When the increment or decrement operators overflow, the payload is assigned the
result of `hook.onOverflow!op(get)`. When a binary operator overflows, the
result of $(D hook.onOverflow!op(get, rhs)) is returned, but only if `Hook` does
not define `hookOpBinary`.)
)
$(TR $(TD `hookOpOpAssign`) $(TD If defined, $(D hook.hookOpOpAssign!op(payload,
rhs)) (where `op` is the operator symbol and `rhs` is the right-hand side
operand) is forwarded to unconditionally for binary operators `+=`,  `-=`, `*=`, `/=`, `%=`,
`^^=`, `&=`, `|=`, `^=`, `<<=`, `>>=`, and `>>>=`.)
)
$(TR $(TD `onLowerBound`) $(TD If defined, $(D hook.onLowerBound(value, bound))
(where `value` is the value being assigned) is forwarded to when the result of
binary operators `+=`,  `-=`, `*=`, `/=`, `%=`, `^^=`, `&=`, `|=`, `^=`, `<<=`, `>>=`,
and `>>>=` is smaller than the smallest value representable by `T`.)
)
$(TR $(TD `onUpperBound`) $(TD If defined, $(D hook.onUpperBound(value, bound))
(where `value` is the value being assigned) is forwarded to when the result of
binary operators `+=`,  `-=`, `*=`, `/=`, `%=`, `^^=`, `&=`, `|=`, `^=`, `<<=`, `>>=`,
and `>>>=` is larger than the largest value representable by `T`.)
)
$(TR $(TD `hookToHash`) $(TD If defined, $(D hook.hookToHash(payload))
(where `payload` is a reference to the value wrapped by Checked) is forwarded
to when `toHash` is called on a Checked type. Custom hashing can be implemented
in a `Hook`, otherwise the built-in hashing is used.)
)
)

Source: $(PHOBOSSRC std/checkedint.d)
*/
module std.checkedint;
import std.traits : isFloatingPoint, isIntegral, isNumeric, isUnsigned, Unqual;

///
@safe unittest
{
    int[] concatAndAdd(int[] a, int[] b, int offset)
    {
        // Aborts on overflow on size computation
        auto r = new int[(checked(a.length) + b.length).get];
        // Aborts on overflow on element computation
        foreach (i; 0 .. a.length)
            r[i] = (a[i] + checked(offset)).get;
        foreach (i; 0 .. b.length)
            r[i + a.length] = (b[i] + checked(offset)).get;
        return r;
    }
    assert(concatAndAdd([1, 2, 3], [4, 5], -1) == [0, 1, 2, 3, 4]);
}


/// `Saturate` stops at an overflow
@safe unittest
{
    auto x = (cast(byte) 127).checked!Saturate;
    assert(x == 127);
    x++;
    assert(x == 127);
}

/// `WithNaN` has a special "Not a Number" (NaN) value akin to the homonym value reserved for floating-point values
@safe unittest
{
    auto x = 100.checked!WithNaN;
    assert(x == 100);
    x /= 0;
    assert(x.isNaN);
}

/// `ProperCompare` fixes the comparison operators ==, !=, <, <=, >, and >= to return correct results
@safe unittest
{
    uint x = 1;
    auto y = x.checked!ProperCompare;
    assert(x < -1); // built-in comparison
    assert(y > -1); // ProperCompare
}

/// `Throw` fails every incorrect operation by throwing an exception
@safe unittest
{
    import std.exception : assertThrown;
    auto x = -1.checked!Throw;
    assertThrown(x / 0);
    assertThrown(x + int.min);
    assertThrown(x == uint.max);
}

/**
Checked integral type wraps an integral `T` and customizes its behavior with the
help of a `Hook` type. The type wrapped must be one of the predefined integrals
(unqualified), or another instance of `Checked`.

Params:
    T    = type that is wrapped in the `Checked` type
    Hook = hook type that customizes the behavior of the `Checked` type
*/
struct Checked(T, Hook = Abort)
if (isIntegral!T || is(T == Checked!(U, H), U, H))
{
    import std.algorithm.comparison : among;
    import std.experimental.allocator.common : stateSize;
    import std.format.spec : FormatSpec;
    import std.range.primitives : isInputRange, ElementType;
    import std.traits : hasMember, isSomeChar;

    /**
    The type of the integral subject to checking.
    */
    alias Representation = T;

    // state {
    static if (hasMember!(Hook, "defaultValue"))
        private T payload = Hook.defaultValue!T;
    else
        private T payload;
    /**
    `hook` is a member variable if it has state, or an alias for `Hook`
    otherwise.
    */
    static if (stateSize!Hook > 0) Hook hook;
    else alias hook = Hook;
    // } state

    // get
    /**
    Returns:
        A copy of the underlying value.
    */
    auto get() inout { return payload; }
    ///
    @safe unittest
    {
        auto x = checked(ubyte(42));
        static assert(is(typeof(x.get()) == ubyte));
        assert(x.get == 42);
        const y = checked(ubyte(42));
        static assert(is(typeof(y.get()) == const ubyte));
        assert(y.get == 42);
    }

    /**
    Defines the minimum and maximum. These values are hookable by defining
    `Hook.min` and/or `Hook.max`.
    */
    static if (hasMember!(Hook, "min"))
    {
        enum Checked!(T, Hook) min = Checked!(T, Hook)(Hook.min!T);
        ///
        @safe unittest
        {
            assert(Checked!short.min == -32768);
            assert(Checked!(short, WithNaN).min == -32767);
            assert(Checked!(uint, WithNaN).max == uint.max - 1);
        }
    }
    else
    {
        /// ditto
        enum Checked!(T, Hook) min = Checked(T.min);
    }
    static if (hasMember!(Hook, "max"))
    {
        /// ditto
        enum Checked!(T, Hook) max = Checked(Hook.max!T);
    }
    else
    {
        /// ditto
        enum Checked!(T, Hook) max = Checked(T.max);
    }

    /**
    Constructor taking a value properly convertible to the underlying type. `U`
    may be either an integral that can be converted to `T` without a loss, or
    another `Checked` instance whose representation may be in turn converted to
    `T` without a loss.
    */
    this(U)(U rhs)
    if (valueConvertible!(U, T) ||
        !isIntegral!T && is(typeof(T(rhs))) ||
        is(U == Checked!(V, W), V, W) &&
            is(typeof(Checked!(T, Hook)(rhs.get))))
    {
        static if (isIntegral!U)
            payload = rhs;
        else
            payload = rhs.payload;
    }
    ///
    @safe unittest
    {
        auto a = checked(42L);
        assert(a == 42);
        auto b = Checked!long(4242); // convert 4242 to long
        assert(b == 4242);
    }

    /**
    Assignment operator. Has the same constraints as the constructor.

    Params:
        rhs = The value to assign

    Returns:
        A reference to `this`
    */
    ref Checked opAssign(U)(U rhs) return
    if (is(typeof(Checked!(T, Hook)(rhs))))
    {
        static if (isIntegral!U)
            payload = rhs;
        else
            payload = rhs.payload;
        return this;
    }
    ///
    @safe unittest
    {
        Checked!long a;
        a = 42L;
        assert(a == 42);
        a = 4242;
        assert(a == 4242);
    }

    ///
    @safe unittest
    {
        Checked!long a, b;
        a = b = 3;
        assert(a == 3 && b == 3);
    }

    /**
    Construct from a decimal string. The conversion follows the same rules as
    $(REF to, std, conv) converting a string to the wrapped `T` type.

    Params:
        str = an $(REF_ALTTEXT input range, isInputRange, std,range,primitives)
              of characters
    */
    this(Range)(Range str)
    if (isInputRange!Range && isSomeChar!(ElementType!Range))
    {
        import std.conv : to;

        this(to!T(str));
    }

    /**
    $(REF to, std, conv) can convert a string to a `Checked!T`:
    */
    @system unittest
    {
        import std.conv : to;

        const a = to!long("1234");
        const b = to!(Checked!long)("1234");
        assert(a == b);
    }

    // opCast
    /**
    Casting operator to integral, `bool`, or floating point type.

    If a cast to a floating-point type is requested and `Hook` defines
    `onBadCast`, the cast is verified by ensuring $(D get == cast(T)
    U(get)). If that is not `true`, `hook.onBadCast!U(get)` is returned.

    If a cast to an integral type is requested and `Hook` defines `onBadCast`,
    the cast is verified by ensuring `get` and $(D cast(U)
    get) are the same arithmetic number. (Note that `int(-1)` and
    `uint(1)` are different values arithmetically although they have the same
    bitwise representation and compare equal by language rules.) If the numbers
    are not arithmetically equal, `hook.onBadCast!U(get)` is
    returned.

    Params:
        U = The type to cast to

    Returns:
        If `Hook`     defines `hookOpCast`, the call immediately returns
        `hook.hookOpCast!U(get)`. Otherwise, casting to `bool` yields $(D
        get != 0) and casting to another integral that can represent all
        values of `T` returns `get` promoted to `U`.
    */
    U opCast(U, this _)()
    if (isIntegral!U || isFloatingPoint!U || is(U == bool))
    {
        static if (hasMember!(Hook, "hookOpCast"))
        {
            return hook.hookOpCast!U(payload);
        }
        else static if (is(U == bool))
        {
            return payload != 0;
        }
        else static if (valueConvertible!(T, U))
        {
            return payload;
        }
        // may lose bits or precision
        else static if (!hasMember!(Hook, "onBadCast"))
        {
            return cast(U) payload;
        }
        else
        {
            if (isUnsigned!T || !isUnsigned!U ||
                    T.sizeof > U.sizeof || payload >= 0)
            {
                auto result = cast(U) payload;
                // If signedness is different, we need additional checks
                if (result == payload &&
                        (!isUnsigned!T || isUnsigned!U || result >= 0))
                    return result;
            }
            return hook.onBadCast!U(payload);
        }
    }
    ///
    @safe unittest
    {
        assert(cast(uint) checked(42) == 42);
        assert(cast(uint) checked!WithNaN(-42) == uint.max);
    }

    // opEquals
    /**
    Compares `this` against `rhs` for equality.

    If `U` is also an instance of `Checked`, both hooks (left- and right-hand
    side) are introspected for the method `hookOpEquals`. If both define it,
    priority is given to the left-hand side.

    Params:
        rhs = Right-hand side to compare for equality

    Returns:
        If `Hook` defines `hookOpEquals`, the function forwards to $(D
        hook.hookOpEquals(get, rhs)). Otherwise, the result of the
        built-in operation $(D get == rhs) is returned.

    */
    bool opEquals(U, this _)(U rhs)
    if (isIntegral!U || isFloatingPoint!U || is(U == bool) ||
        is(U == Checked!(V, W), V, W) && is(typeof(this == rhs.payload)))
    {
        static if (is(U == Checked!(V, W), V, W))
        {
            alias R = typeof(payload + rhs.payload);
            static if (is(Hook == W))
            {
                // Use the lhs hook if there
                return this == rhs.payload;
            }
            else static if (valueConvertible!(T, R) && valueConvertible!(V, R))
            {
                return payload == rhs.payload;
            }
            else static if (hasMember!(Hook, "hookOpEquals"))
            {
                return hook.hookOpEquals(payload, rhs.payload);
            }
            else static if (hasMember!(W, "hookOpEquals"))
            {
                return rhs.hook.hookOpEquals(rhs.payload, payload);
            }
            else
            {
                return payload == rhs.payload;
            }
        }
        else static if (hasMember!(Hook, "hookOpEquals"))
            return hook.hookOpEquals(payload, rhs);
        else static if (isIntegral!U || isFloatingPoint!U || is(U == bool))
            return payload == rhs;
    }

    ///
    static if (is(T == int) && is(Hook == void)) @safe unittest
    {
        import std.traits : isUnsigned;

        static struct MyHook
        {
            static bool thereWereErrors;
            static bool hookOpEquals(L, R)(L lhs, R rhs)
            {
                if (lhs != rhs) return false;
                static if (isUnsigned!L && !isUnsigned!R)
                {
                    if (lhs > 0 && rhs < 0) thereWereErrors = true;
                }
                else static if (isUnsigned!R && !isUnsigned!L)
                    if (lhs < 0 && rhs > 0) thereWereErrors = true;
                // Preserve built-in behavior.
                return true;
            }
        }
        auto a = checked!MyHook(-42);
        assert(a == uint(-42));
        assert(MyHook.thereWereErrors);
        MyHook.thereWereErrors = false;
        assert(checked!MyHook(uint(-42)) == -42);
        assert(MyHook.thereWereErrors);
        static struct MyHook2
        {
            static bool hookOpEquals(L, R)(L lhs, R rhs)
            {
                return lhs == rhs;
            }
        }
        MyHook.thereWereErrors = false;
        assert(checked!MyHook2(uint(-42)) == a);
        // Hook on left hand side takes precedence, so no errors
        assert(!MyHook.thereWereErrors);
    }

    // toHash
    /**
    Generates a hash for `this`. If `Hook` defines `hookToHash`, the call
    immediately returns `hook.hookToHash(payload)`. If `Hook` does not
    implement `hookToHash`, but it has state, a hash will be generated for
    the `Hook` using the built-in function and it will be xored with the
    hash of the `payload`.

    Returns:
        The hash of `this` instance.

    */
    size_t toHash() const nothrow @safe
    {
        static if (hasMember!(Hook, "hookToHash"))
        {
            return hook.hookToHash(payload);
        }
        else static if (stateSize!Hook > 0)
        {
            static if (hasMember!(typeof(payload), "toHash"))
            {
                return payload.toHash() ^ hashOf(hook);
            }
            else
            {
                return hashOf(payload) ^ hashOf(hook);
            }
        }
        else static if (hasMember!(typeof(payload), "toHash"))
        {
            return payload.toHash();
        }
        else
        {
            return .hashOf(payload);
        }
    }

    /// ditto
    size_t toHash(this _)() shared const nothrow @safe
    {
        import core.atomic : atomicLoad, MemoryOrder;
        static if (is(typeof(this.payload.atomicLoad!(MemoryOrder.acq)) P))
        {
            auto localPayload = __ctfe ? cast(P) this.payload
                                  : this.payload.atomicLoad!(MemoryOrder.acq);
        }
        else
        {
            alias localPayload = this.payload;
        }

        static if (hasMember!(Hook, "hookToHash"))
        {
            return hook.hookToHash(localPayload);
        }
        else static if (stateSize!Hook > 0)
        {
            static if (hasMember!(typeof(localPayload), "toHash"))
            {
                return localPayload.toHash() ^ hashOf(hook);
            }
            else
            {
                return hashOf(localPayload) ^ hashOf(hook);
            }
        }
        else static if (hasMember!(typeof(localPayload), "toHash"))
        {
            return localPayload.toHash();
        }
        else
        {
            return .hashOf(localPayload);
        }
    }

    /**
    Writes a string representation of this to a `sink`.

    Params:
      sink = A `Char` accepting
             $(REF_ALTTEXT output range, isOutputRange, std,range,primitives).
      fmt  = A $(REF FormatSpec, std, format) which controls how this
             is formatted.
    */
    void toString(Writer, Char)(scope ref Writer sink, scope const ref FormatSpec!Char fmt) const
    {
        import std.format.write : formatValue;
        if (fmt.spec == 's')
            return formatValue(sink, this, fmt);
        else
            return formatValue(sink, payload, fmt);
    }

    /**
    `toString` is rarely directly invoked; the usual way of using it is via
    $(REF format, std, format):
    */
    @system unittest
    {
        import std.format;

        assert(format("%04d", checked(15)) == "0015");
        assert(format("0x%02x", checked(15)) == "0x0f");
    }

    // opCmp
    /**

    Compares `this` against `rhs` for ordering. If `Hook` defines `hookOpCmp`,
    the function forwards to $(D 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.

    Params:
        rhs   = The right-hand side operand
        U     = either the type of `rhs` or the underlying type
                if `rhs` is a `Checked` instance
        Hook1 = If `rhs` is a `Checked` instance, `Hook1` represents
                the instance's behavior hook

    Returns:
        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.
    */
    auto opCmp(U, this _)(const U rhs) //const pure @safe nothrow @nogc
    if (isIntegral!U || isFloatingPoint!U || is(U == bool))
    {
        static if (hasMember!(Hook, "hookOpCmp"))
        {
            return hook.hookOpCmp(payload, rhs);
        }
        else static if (valueConvertible!(T, U) || valueConvertible!(U, T))
        {
            return payload < rhs ? -1 : payload > rhs;
        }
        else static if (isFloatingPoint!U)
        {
            U lhs = payload;
            return lhs < rhs ? U(-1.0)
                : lhs > rhs ? U(1.0)
                : lhs == rhs ? U(0.0) : U.init;
        }
        else
        {
            return payload < rhs ? -1 : payload > rhs;
        }
    }

    /// ditto
    auto opCmp(U, Hook1, this _)(Checked!(U, Hook1) rhs)
    {
        alias R = typeof(payload + rhs.payload);
        static if (valueConvertible!(T, R) && valueConvertible!(U, R))
        {
            return payload < rhs.payload ? -1 : payload > rhs.payload;
        }
        else static if (is(Hook == Hook1))
        {
            // Use the lhs hook
            return this.opCmp(rhs.payload);
        }
        else static if (hasMember!(Hook, "hookOpCmp"))
        {
            return hook.hookOpCmp(get, rhs.get);
        }
        else static if (hasMember!(Hook1, "hookOpCmp"))
        {
            return -rhs.hook.hookOpCmp(rhs.payload, get);
        }
        else
        {
            return payload < rhs.payload ? -1 : payload > rhs.payload;
        }
    }

    ///
    static if (is(T == int) && is(Hook == void)) @safe unittest
    {
        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);
    }

    // For coverage
    static if (is(T == int) && is(Hook == void)) @safe unittest
    {
        assert(checked(42) <= checked!void(42));
        assert(checked!void(42) <= checked(42u));
        assert(checked!void(42) <= checked!(void*)(42u));
    }

    // opUnary
    /**

    Defines unary operators `+`, `-`, `~`, `++`, and `--`. Unary `+` is not
    overridable and always has built-in behavior (returns `this`). For the
    others, if `Hook` defines `hookOpUnary`, `opUnary` forwards to $(D
    Checked!(typeof(hook.hookOpUnary!op(get)),
    Hook)(hook.hookOpUnary!op(get))).

    If `Hook` does not define `hookOpUnary` but defines `onOverflow`, `opUnary`
    forwards to `hook.onOverflow!op(get)` in case an overflow occurs.
    For `++` and `--`, the payload is assigned from the result of the call to
    `onOverflow`.

    Note that unary `-` is considered to overflow if `T` is a signed integral of
    32 or 64 bits and is equal to the most negative value. This is because that
    value has no positive negation.

    Params:
        op = The unary operator

    Returns:
        A `Checked` instance representing the result of the unary
        operation
    */
    auto opUnary(string op, this _)()
    if (op == "+" || op == "-" || op == "~")
    {
        static if (op == "+")
            return Checked(this); // "+" is not hookable
        else static if (hasMember!(Hook, "hookOpUnary"))
        {
            auto r = hook.hookOpUnary!op(payload);
            return Checked!(typeof(r), Hook)(r);
        }
        else static if (op == "-" && isIntegral!T && T.sizeof >= 4 &&
                !isUnsigned!T && hasMember!(Hook, "onOverflow"))
        {
            static assert(is(typeof(-payload) == typeof(payload)));
            bool overflow;
            import core.checkedint : negs;
            auto r = negs(payload, overflow);
            if (overflow) r = hook.onOverflow!op(payload);
            return Checked(r);
        }
        else
            return Checked(mixin(op ~ "payload"));
    }

    /// ditto
    ref Checked opUnary(string op)() return
    if (op == "++" || op == "--")
    {
        static if (hasMember!(Hook, "hookOpUnary"))
            hook.hookOpUnary!op(payload);
        else static if (hasMember!(Hook, "onOverflow"))
        {
            static if (op == "++")
            {
                if (payload == max.payload)
                    payload = hook.onOverflow!"++"(payload);
                else
                    ++payload;
            }
            else
            {
                if (payload == min.payload)
                    payload = hook.onOverflow!"--"(payload);
                else
                    --payload;
            }
        }
        else
            mixin(op ~ "payload;");
        return this;
    }

    ///
    static if (is(T == int) && is(Hook == void)) @safe unittest
    {
        static struct MyHook
        {
            static bool thereWereErrors;
            static L hookOpUnary(string x, L)(L lhs)
            {
                if (x == "-" && lhs == -lhs) thereWereErrors = true;
                return -lhs;
            }
        }
        auto a = checked!MyHook(long.min);
        assert(a == -a);
        assert(MyHook.thereWereErrors);
        auto b = checked!void(42);
        assert(++b == 43);
    }

    // opBinary
    /**

    Defines binary operators `+`, `-`, `*`, `/`, `%`, `^^`, `&`, `|`, `^`, `<<`, `>>`,
    and `>>>`. If `Hook` defines `hookOpBinary`, `opBinary` forwards to $(D
    Checked!(typeof(hook.hookOpBinary!op(get, rhs)),
    Hook)(hook.hookOpBinary!op(get, rhs))).

    If `Hook` does not define `hookOpBinary` but defines `onOverflow`,
    `opBinary` forwards to `hook.onOverflow!op(get, rhs)` in case an
    overflow occurs.

    If two `Checked` instances are involved in a binary operation and both
    define `hookOpBinary`, the left-hand side hook has priority. If both define
    `onOverflow`, a compile-time error occurs.

    Params:
        op    = The binary operator
        rhs   = The right hand side operand
        U     = If `rhs` is a `Checked` instance, `U` represents
                the underlying instance type
        Hook1 = If `rhs` is a `Checked` instance, `Hook1` represents
                the instance's behavior hook

    Returns:
        A `Checked` instance representing the result of the binary
        operation
    */
    auto opBinary(string op, Rhs)(const Rhs rhs)
    if (isIntegral!Rhs || isFloatingPoint!Rhs || is(Rhs == bool))
    {
        return opBinaryImpl!(op, Rhs, typeof(this))(rhs);
    }

    /// ditto
    auto opBinary(string op, Rhs)(const Rhs rhs) const
    if (isIntegral!Rhs || isFloatingPoint!Rhs || is(Rhs == bool))
    {
        return opBinaryImpl!(op, Rhs, typeof(this))(rhs);
    }

    private auto opBinaryImpl(string op, Rhs, this _)(const Rhs rhs)
    {
        alias R = typeof(mixin("payload" ~ op ~ "rhs"));
        static assert(is(typeof(mixin("payload" ~ op ~ "rhs")) == R));
        static if (isIntegral!R) alias Result = Checked!(R, Hook);
        else alias Result = R;

        static if (hasMember!(Hook, "hookOpBinary"))
        {
            auto r = hook.hookOpBinary!op(payload, rhs);
            return Checked!(typeof(r), Hook)(r);
        }
        else static if (is(Rhs == bool))
        {
            return mixin("this" ~ op ~ "ubyte(rhs)");
        }
        else static if (isFloatingPoint!Rhs)
        {
            return mixin("payload" ~ op ~ "rhs");
        }
        else static if (hasMember!(Hook, "onOverflow"))
        {
            bool overflow;
            auto r = opChecked!op(payload, rhs, overflow);
            if (overflow) r = hook.onOverflow!op(payload, rhs);
            return Result(r);
        }
        else
        {
            // Default is built-in behavior
            return Result(mixin("payload" ~ op ~ "rhs"));
        }
    }

    /// ditto
    auto opBinary(string op, U, Hook1)(Checked!(U, Hook1) rhs)
    {
        return opBinaryImpl2!(op, U, Hook1, typeof(this))(rhs);
    }

    /// ditto
    auto opBinary(string op, U, Hook1)(Checked!(U, Hook1) rhs) const
    {
        return opBinaryImpl2!(op, U, Hook1, typeof(this))(rhs);
    }

    private
    auto opBinaryImpl2(string op, U, Hook1, this _)(Checked!(U, Hook1) rhs)
    {
        alias R = typeof(get + rhs.payload);
        static if (valueConvertible!(T, R) && valueConvertible!(U, R) ||
            is(Hook == Hook1))
        {
            // Delegate to lhs
            return mixin("this" ~ op ~ "rhs.payload");
        }
        else static if (hasMember!(Hook, "hookOpBinary"))
        {
            return hook.hookOpBinary!op(payload, rhs);
        }
        else static if (hasMember!(Hook1, "hookOpBinary"))
        {
            // Delegate to rhs
            return mixin("this.payload" ~ op ~ "rhs");
        }
        else static if (hasMember!(Hook, "onOverflow") &&
            !hasMember!(Hook1, "onOverflow"))
        {
            // Delegate to lhs
            return mixin("this" ~ op ~ "rhs.payload");
        }
        else static if (hasMember!(Hook1, "onOverflow") &&
            !hasMember!(Hook, "onOverflow"))
        {
            // Delegate to rhs
            return mixin("this.payload" ~ op ~ "rhs");
        }
        else
        {
            static assert(0, "Conflict between lhs and rhs hooks," ~
                " use .get on one side to disambiguate.");
        }
    }

    static if (is(T == int) && is(Hook == void)) @safe unittest
    {
        const a = checked(42);
        assert(a + 1 == 43);
        assert(a + checked(uint(42)) == 84);
        assert(checked(42) + checked!void(42u) == 84);
        assert(checked!void(42) + checked(42u) == 84);

        static struct MyHook
        {
            static uint tally;
            static auto hookOpBinary(string x, L, R)(L lhs, R rhs)
            {
                ++tally;
                return mixin("lhs" ~ x ~ "rhs");
            }
        }
        assert(checked!MyHook(42) + checked(42u) == 84);
        assert(checked!void(42) + checked!MyHook(42u) == 84);
        assert(MyHook.tally == 2);
    }

    // opBinaryRight
    /**

    Defines binary operators `+`, `-`, `*`, `/`, `%`, `^^`, `&`, `|`, `^`, `<<`,
    `>>`, and `>>>` for the case when a built-in numeric or Boolean type is on
    the left-hand side, and a `Checked` instance is on the right-hand side.

    Params:
        op  = The binary operator
        lhs = The left hand side operand

    Returns:
        A `Checked` instance representing the result of the binary
        operation

    */
    auto opBinaryRight(string op, Lhs)(const Lhs lhs)
    if (isIntegral!Lhs || isFloatingPoint!Lhs || is(Lhs == bool))
    {
        return opBinaryRightImpl!(op, Lhs, typeof(this))(lhs);
    }

    /// ditto
    auto opBinaryRight(string op, Lhs)(const Lhs lhs) const
    if (isIntegral!Lhs || isFloatingPoint!Lhs || is(Lhs == bool))
    {
        return opBinaryRightImpl!(op, Lhs, typeof(this))(lhs);
    }

    private auto opBinaryRightImpl(string op, Lhs, this _)(const Lhs lhs)
    {
        static if (hasMember!(Hook, "hookOpBinaryRight"))
        {
            auto r = hook.hookOpBinaryRight!op(lhs, payload);
            return Checked!(typeof(r), Hook)(r);
        }
        else static if (hasMember!(Hook, "hookOpBinary"))
        {
            auto r = hook.hookOpBinary!op(lhs, payload);
            return Checked!(typeof(r), Hook)(r);
        }
        else static if (is(Lhs == bool))
        {
            return mixin("ubyte(lhs)" ~ op ~ "this");
        }
        else static if (isFloatingPoint!Lhs)
        {
            return mixin("lhs" ~ op ~ "payload");
        }
        else static if (hasMember!(Hook, "onOverflow"))
        {
            bool overflow;
            auto r = opChecked!op(lhs, T(payload), overflow);
            if (overflow) r = hook.onOverflow!op(lhs, payload);
            return Checked!(typeof(r), Hook)(r);
        }
        else
        {
            // Default is built-in behavior
            auto r = mixin("lhs" ~ op ~ "T(payload)");
            return Checked!(typeof(r), Hook)(r);
        }
    }

    static if (is(T == int) && is(Hook == void)) @safe unittest
    {
        assert(1 + checked(1) == 2);
        static uint tally;
        static struct MyHook
        {
            static auto hookOpBinaryRight(string x, L, R)(L lhs, R rhs)
            {
                ++tally;
                return mixin("lhs" ~ x ~ "rhs");
            }
        }
        assert(1 + checked!MyHook(1) == 2);
        assert(tally == 1);

        immutable x1 = checked(1);
        assert(1 + x1 == 2);
        immutable x2 = checked!MyHook(1);
        assert(1 + x2 == 2);
        assert(tally == 2);
    }

    // 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 $(D auto result =
    opBinary!op(payload, rhs).payload), which is subject to the hooks in
    `opBinary`. Then, if `result` is less than $(D Checked!(T, Hook).min) and if
    `Hook` defines `onLowerBound`, the payload is assigned from $(D
    hook.onLowerBound(result, min)). If `result` is greater than $(D Checked!(T,
    Hook).max) and if `Hook` defines `onUpperBound`, the payload is assigned
    from $(D 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.

    Params:
    op = The operator involved (without the `"="`, e.g. `"+"` for `"+="` etc)
    rhs = The right-hand side of the operator (left-hand side is `this`)

    Returns: A reference to `this`.
    */
    ref Checked opOpAssign(string op, Rhs)(const Rhs rhs) return
    if (isIntegral!Rhs || isFloatingPoint!Rhs || is(Rhs == bool))
    {
        static assert(is(typeof(mixin("payload" ~ op ~ "=rhs")) == T));

        static if (hasMember!(Hook, "hookOpOpAssign"))
        {
            hook.hookOpOpAssign!op(payload, rhs);
        }
        else
        {
            alias R = typeof(get + rhs);
            auto r = opBinary!op(rhs).get;
            import std.conv : unsigned;

            static if (ProperCompare.hookOpCmp(R.min, min.get) < 0 &&
                hasMember!(Hook, "onLowerBound"))
            {
                if (ProperCompare.hookOpCmp(r, min.get) < 0)
                {
                    // Example: Checked!uint(1) += int(-3)
                    payload = hook.onLowerBound(r, min.get);
                    return this;
                }
            }
            static if (ProperCompare.hookOpCmp(max.get, R.max) < 0 &&
                hasMember!(Hook, "onUpperBound"))
            {
                if (ProperCompare.hookOpCmp(r, max.get) > 0)
                {
                    // Example: Checked!uint(1) += long(uint.max)
                    payload = hook.onUpperBound(r, max.get);
                    return this;
                }
            }
            payload = cast(T) r;
        }
        return this;
    }

    /// ditto
    ref Checked opOpAssign(string op, Rhs)(const Rhs rhs) return
    if (is(Rhs == Checked!(RhsT, RhsHook), RhsT, RhsHook))
    {
        return opOpAssign!(op, typeof(rhs.payload))(rhs.payload);
    }

    ///
    static if (is(T == int) && is(Hook == void)) @safe unittest
    {
        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);
    }
}

///
@safe @nogc pure nothrow unittest
{
    // Hook that ignores all problems.
    static struct Ignore
    {
        @nogc nothrow pure @safe static:
        Dst onBadCast(Dst, Src)(Src src) { return cast(Dst) src; }
        Lhs onLowerBound(Rhs, T)(Rhs rhs, T bound) { return cast(T) rhs; }
        T onUpperBound(Rhs, T)(Rhs rhs, T bound) { return cast(T) rhs; }
        bool hookOpEquals(Lhs, Rhs)(Lhs lhs, Rhs rhs) { return lhs == rhs; }
        int hookOpCmp(Lhs, Rhs)(Lhs lhs, Rhs rhs) { return (lhs > rhs) - (lhs < rhs); }
        typeof(~Lhs()) onOverflow(string x, Lhs)(ref Lhs lhs) { return mixin(x ~ "lhs"); }
        typeof(Lhs() + Rhs()) onOverflow(string x, Lhs, Rhs)(Lhs lhs, Rhs rhs)
        {
            static if (x == "/")
                return typeof(lhs / rhs).min;
            else
                return mixin("lhs" ~ x ~ "rhs");
        }
    }

    auto x = Checked!(int, Ignore)(5) + 7;
}


/**

Convenience function that turns an integral into the corresponding `Checked`
instance by using template argument deduction. The hook type may be specified
(by default `Abort`).

Params:
    Hook  = type that customizes the behavior, by default `Abort`
    T     = type represetinfg the underlying represantion of the `Checked` instance
    value = the actual value of the representation

Returns:
    A `Checked` instance customized by the provided `Hook` and `value`
*/
Checked!(T, Hook) checked(Hook = Abort, T)(const T value)
if (is(typeof(Checked!(T, Hook)(value))))
{
    return Checked!(T, Hook)(value);
}

///
@safe unittest
{
    static assert(is(typeof(checked(42)) == Checked!int));
    assert(checked(42) == Checked!int(42));
    static assert(is(typeof(checked!WithNaN(42)) == Checked!(int, WithNaN)));
    assert(checked!WithNaN(42) == Checked!(int, WithNaN)(42));
}

// get
@safe unittest
{
    void test(T)()
    {
        assert(Checked!(T, void)(ubyte(22)).get == 22);
    }
    test!ubyte;
    test!(const ubyte);
    test!(immutable ubyte);
}

@system unittest
{
    // https://issues.dlang.org/show_bug.cgi?id=21758
    assert(4 * checked(5L) == 20);
    assert(20 / checked(5L) == 4);
    assert(2 ^^ checked(3L) == 8);
    assert(12 % checked(5L) == 2);
    assert((0xff & checked(3L)) == 3);
    assert((0xf0 | checked(3L)) == 0xf3);
    assert((0xff ^ checked(3L)) == 0xfc);
}

// Abort
/**

Force all integral errors to fail by printing an error message to `stderr` and
then abort the program. `Abort` is the default second argument for `Checked`.

*/
struct Abort
{
static:
    /**

    Called automatically upon a bad cast (one that loses precision or attempts
    to convert a negative value to an unsigned type). The source type is `Src`
    and the destination type is `Dst`.

    Params:
        src = Souce operand

    Returns:
        Nominally the result is the desired value of the cast operation,
        which will be forwarded as the result of the cast. For `Abort`, the
        function never returns because it aborts the program.
    */
    Dst onBadCast(Dst, Src)(Src src)
    {
        Warn.onBadCast!Dst(src);
        assert(0);
    }

    /**

    Called automatically upon a bounds error.

    Params:
    rhs = The right-hand side value in the assignment, after the operator has
    been evaluated
    bound = The value of the bound being violated

    Returns: Nominally the result is the desired value of the operator, which
    will be forwarded as result. For `Abort`, the function never returns because
    it aborts the program.

    */
    T onLowerBound(Rhs, T)(Rhs rhs, T bound)
    {
        Warn.onLowerBound(rhs, bound);
        assert(0);
    }
    /// ditto
    T onUpperBound(Rhs, T)(Rhs rhs, T bound)
    {
        Warn.onUpperBound(rhs, bound);
        assert(0);
    }

    /**

    Called automatically upon a comparison for equality. In case of a erroneous
    comparison (one that would make a signed negative value appear equal to an
    unsigned positive value), this hook issues `assert(0)` which terminates the
    application.

    Params:
    lhs = The first argument of `Checked`, e.g. `int` if the left-hand side of
      the operator is `Checked!int`
    rhs = The right-hand side type involved in the operator

    Returns: Upon a correct comparison, returns the result of the comparison.
    Otherwise, the function terminates the application so it never returns.

    */
    static bool hookOpEquals(Lhs, Rhs)(Lhs lhs, Rhs rhs)
    {
        bool error;
        auto result = opChecked!"=="(lhs, rhs, error);
        if (error)
        {
            Warn.hookOpEquals(lhs, rhs);
            assert(0);
        }
        return result;
    }

    /**

    Called automatically upon a comparison for ordering using one of the
    operators `<`, `<=`, `>`, or `>=`. In case the comparison is erroneous (i.e.
    it would make a signed negative value appear greater than or equal to an
    unsigned positive value), then application is terminated with `assert(0)`.
    Otherwise, the three-state result is returned (positive if $(D lhs > rhs),
    negative if $(D lhs < rhs), `0` otherwise).

    Params:
    lhs = The first argument of `Checked`, e.g. `int` if the left-hand side of
      the operator is `Checked!int`
    rhs = The right-hand side type involved in the operator

    Returns: For correct comparisons, returns a positive integer if $(D lhs >
    rhs), a negative integer if  $(D lhs < rhs), `0` if the two are equal. Upon
    a mistaken comparison such as $(D int(-1) < uint(0)), the function never
    returns because it aborts the program.

    */
    int hookOpCmp(Lhs, Rhs)(Lhs lhs, Rhs rhs)
    {
        bool error;
        auto result = opChecked!"cmp"(lhs, rhs, error);
        if (error)
        {
            Warn.hookOpCmp(lhs, rhs);
            assert(0);
        }
        return result;
    }

    /**

    Called automatically upon an overflow during a unary or binary operation.

    Params:
    x = The operator, e.g. `-`
    lhs = The left-hand side (or sole) argument
    rhs = The right-hand side type involved in the operator

    Returns: Nominally the result is the desired value of the operator, which
    will be forwarded as result. For `Abort`, the function never returns because
    it aborts the program.

    */
    typeof(~Lhs()) onOverflow(string x, Lhs)(Lhs lhs)
    {
        Warn.onOverflow!x(lhs);
        assert(0);
    }
    /// ditto
    typeof(Lhs() + Rhs()) onOverflow(string x, Lhs, Rhs)(Lhs lhs, Rhs rhs)
    {
        Warn.onOverflow!x(lhs, rhs);
        assert(0);
    }
}

///
@safe unittest
{
    void test(T)()
    {
        Checked!(int, Abort) x;
        x = 42;
        auto x1 = cast(T) x;
        assert(x1 == 42);
        //x1 += long(int.max);
    }
    test!short;
    test!(const short);
    test!(immutable short);
}


// Throw
/**

Force all integral errors to fail by throwing an exception of type
`Throw.CheckFailure`. The message coming with the error is similar to the one
printed by `Warn`.

*/
struct Throw
{
    /**
    Exception type thrown upon any failure.
    */
    static class CheckFailure : Exception
    {
        /**
        Params:
            f    = format specifier
            vals = actual values for the format specifier
        */
        this(T...)(string f, T vals)
        {
            import std.format : format;
            super(format(f, vals));
        }
    }

    /**

    Called automatically upon a bad cast (one that loses precision or attempts
    to convert a negative value to an unsigned type). The source type is `Src`
    and the destination type is `Dst`.

    Params:
        src = source operand

    Returns:
        Nominally the result is the desired value of the cast operation,
        which will be forwarded as the result of the cast. For `Throw`, the
        function never returns because it throws an exception.

    Throws:
        `CheckFailure` on bad cast
    */
    static Dst onBadCast(Dst, Src)(Src src)
    {
        throw new CheckFailure("Erroneous cast: cast(%s) %s(%s)",
            Dst.stringof, Src.stringof, src);
    }

    /**

    Called automatically upon a bounds error.

    Params:
        rhs = The right-hand side value in the assignment, after the operator has
        been evaluated
        bound = The value of the bound being violated

    Returns:
        Nominally the result is the desired value of the operator, which
        will be forwarded as result. For `Throw`, the function never returns because
        it throws.

    Throws:
        `CheckFailure` on overflow

    */
    static T onLowerBound(Rhs, T)(Rhs rhs, T bound)
    {
        throw new CheckFailure("Lower bound error: %s(%s) < %s(%s)",
            Rhs.stringof, rhs, T.stringof, bound);
    }
    /// ditto
    static T onUpperBound(Rhs, T)(Rhs rhs, T bound)
    {
        throw new CheckFailure("Upper bound error: %s(%s) > %s(%s)",
            Rhs.stringof, rhs, T.stringof, bound);
    }

    /**

    Called automatically upon a comparison for equality. Throws upon an
    erroneous comparison (one that would make a signed negative value appear
    equal to an unsigned positive value).

    Params:
    lhs = The first argument of `Checked`, e.g. `int` if the left-hand side of
      the operator is `Checked!int`
    rhs = The right-hand side type involved in the operator

    Returns: The result of the comparison.

    Throws: `CheckFailure` if the comparison is mathematically erroneous.

    */
    static bool hookOpEquals(L, R)(L lhs, R rhs)
    {
        bool error;
        auto result = opChecked!"=="(lhs, rhs, error);
        if (error)
        {
            throw new CheckFailure("Erroneous comparison: %s(%s) == %s(%s)",
                L.stringof, lhs, R.stringof, rhs);
        }
        return result;
    }

    /**

    Called automatically upon a comparison for ordering using one of the
    operators `<`, `<=`, `>`, or `>=`. In case the comparison is erroneous (i.e.
    it would make a signed negative value appear greater than or equal to an
    unsigned positive value), throws a `Throw.CheckFailure` exception.
    Otherwise, the three-state result is returned (positive if $(D lhs > rhs),
    negative if $(D lhs < rhs), `0` otherwise).

    Params:
    lhs = The first argument of `Checked`, e.g. `int` if the left-hand side of
      the operator is `Checked!int`
    rhs = The right-hand side type involved in the operator

    Returns: For correct comparisons, returns a positive integer if $(D lhs >
    rhs), a negative integer if  $(D lhs < rhs), `0` if the two are equal.

    Throws: Upon a mistaken comparison such as $(D int(-1) < uint(0)), the
    function never returns because it throws a `Throw.CheckedFailure` exception.

    */
    static int hookOpCmp(Lhs, Rhs)(Lhs lhs, Rhs rhs)
    {
        bool error;
        auto result = opChecked!"cmp"(lhs, rhs, error);
        if (error)
        {
            throw new CheckFailure("Erroneous ordering comparison: %s(%s) and %s(%s)",
                Lhs.stringof, lhs, Rhs.stringof, rhs);
        }
        return result;
    }

    /**

    Called automatically upon an overflow during a unary or binary operation.

    Params:
        x = The operator, e.g. `-`
        lhs = The left-hand side (or sole) argument
        rhs = The right-hand side type involved in the operator

    Returns:
        Nominally the result is the desired value of the operator, which
        will be forwarded as result. For `Throw`, the function never returns because
        it throws an exception.

    Throws:
        `CheckFailure` on overflow

    */
    static typeof(~Lhs()) onOverflow(string x, Lhs)(Lhs lhs)
    {
        throw new CheckFailure("Overflow on unary operator: %s%s(%s)",
            x, Lhs.stringof, lhs);
    }
    /// ditto
    static typeof(Lhs() + Rhs()) onOverflow(string x, Lhs, Rhs)(Lhs lhs, Rhs rhs)
    {
        throw new CheckFailure("Overflow on binary operator: %s(%s) %s %s(%s)",
            Lhs.stringof, lhs, x, Rhs.stringof, rhs);
    }
}

///
@safe unittest
{
    void test(T)()
    {
        Checked!(int, Throw) x;
        x = 42;
        auto x1 = cast(T) x;
        assert(x1 == 42);
        x = T.max + 1;
        import std.exception : assertThrown, assertNotThrown;
        assertThrown(cast(T) x);
        x = x.max;
        assertThrown(x += 42);
        assertThrown(x += 42L);
        x = x.min;
        assertThrown(-x);
        assertThrown(x -= 42);
        assertThrown(x -= 42L);
        x = -1;
        assertNotThrown(x == -1);
        assertThrown(x == uint(-1));
        assertNotThrown(x <= -1);
        assertThrown(x <= uint(-1));
    }
    test!short;
    test!(const short);
    test!(immutable short);
}

// Warn
/**
Hook that prints to `stderr` a trace of all integral errors, without affecting
default behavior.
*/
struct Warn
{
    import std.stdio : writefln;
static:
    /**

    Called automatically upon a bad cast from `src` to type `Dst` (one that
    loses precision or attempts to convert a negative value to an unsigned
    type).

    Params:
    src = The source of the cast
    Dst = The target type of the cast

    Returns: `cast(Dst) src`

    */
    Dst onBadCast(Dst, Src)(Src src)
    {
        trustedStderr.writefln("Erroneous cast: cast(%s) %s(%s)",
            Dst.stringof, Src.stringof, src);
        return cast(Dst) src;
    }

    /**

    Called automatically upon a bad `opOpAssign` call (one that loses precision
    or attempts to convert a negative value to an unsigned type).

    Params:
    rhs = The right-hand side value in the assignment, after the operator has
    been evaluated
    bound = The bound being violated

    Returns: `cast(T) rhs`
    */
    T onLowerBound(Rhs, T)(Rhs rhs, T bound)
    {
        trustedStderr.writefln("Lower bound error: %s(%s) < %s(%s)",
            Rhs.stringof, rhs, T.stringof, bound);
        return cast(T) rhs;
    }
    /// ditto
    T onUpperBound(Rhs, T)(Rhs rhs, T bound)
    {
        trustedStderr.writefln("Upper bound error: %s(%s) > %s(%s)",
            Rhs.stringof, rhs, T.stringof, bound);
        return cast(T) rhs;
    }

    /**

    Called automatically upon a comparison for equality. In case of an Erroneous
    comparison (one that would make a signed negative value appear equal to an
    unsigned positive value), writes a warning message to `stderr` as a side
    effect.

    Params:
    lhs = The first argument of `Checked`, e.g. `int` if the left-hand side of
      the operator is `Checked!int`
    rhs = The right-hand side type involved in the operator

    Returns: In all cases the function returns the built-in result of $(D lhs ==
    rhs).

    */
    bool hookOpEquals(Lhs, Rhs)(Lhs lhs, Rhs rhs)
    {
        bool error;
        auto result = opChecked!"=="(lhs, rhs, error);
        if (error)
        {
            trustedStderr.writefln("Erroneous comparison: %s(%s) == %s(%s)",
                Lhs.stringof, lhs, Rhs.stringof, rhs);
            return lhs == rhs;
        }
        return result;
    }

    ///
    @safe unittest
    {
        auto x = checked!Warn(-42);
        // Passes
        assert(x == -42);
        // Passes but prints a warning
        // assert(x == uint(-42));
    }

    /**

    Called automatically upon a comparison for ordering using one of the
    operators `<`, `<=`, `>`, or `>=`. In case the comparison is erroneous (i.e.
    it would make a signed negative value appear greater than or equal to an
    unsigned positive value), then a warning message is printed to `stderr`.

    Params:
    lhs = The first argument of `Checked`, e.g. `int` if the left-hand side of
      the operator is `Checked!int`
    rhs = The right-hand side type involved in the operator

    Returns: In all cases, returns $(D lhs < rhs ? -1 : lhs > rhs). The result
    is  not autocorrected in case of an erroneous comparison.

    */
    int hookOpCmp(Lhs, Rhs)(Lhs lhs, Rhs rhs)
    {
        bool error;
        auto result = opChecked!"cmp"(lhs, rhs, error);
        if (error)
        {
            trustedStderr.writefln("Erroneous ordering comparison: %s(%s) and %s(%s)",
                Lhs.stringof, lhs, Rhs.stringof, rhs);
            return lhs < rhs ? -1 : lhs > rhs;
        }
        return result;
    }

    ///
    @safe unittest
    {
        auto x = checked!Warn(-42);
        // Passes
        assert(x <= -42);
        // Passes but prints a warning
        // assert(x <= uint(-42));
    }

    /**

    Called automatically upon an overflow during a unary or binary operation.

    Params:
        x   = The operator involved
        Lhs = The first argument of `Checked`, e.g. `int` if the left-hand side of
              the operator is `Checked!int`
        Rhs = The right-hand side type involved in the operator

    Returns:
        $(D mixin(x ~ "lhs")) for unary, $(D mixin("lhs" ~ x ~ "rhs")) for
        binary

    */
    typeof(~Lhs()) onOverflow(string x, Lhs)(ref Lhs lhs)
    {
        trustedStderr.writefln("Overflow on unary operator: %s%s(%s)",
            x, Lhs.stringof, lhs);
        return mixin(x ~ "lhs");
    }
    /// ditto
    typeof(Lhs() + Rhs()) onOverflow(string x, Lhs, Rhs)(Lhs lhs, Rhs rhs)
    {
        trustedStderr.writefln("Overflow on binary operator: %s(%s) %s %s(%s)",
            Lhs.stringof, lhs, x, Rhs.stringof, rhs);
        static if (x == "/")               // Issue 20743: mixin below would cause SIGFPE on POSIX
            return typeof(lhs / rhs).min;  // or EXCEPTION_INT_OVERFLOW on Windows
        else
            return mixin("lhs" ~ x ~ "rhs");
    }

    // This is safe because we do not assign to the reference returned by
    // `stderr`. The ability for the caller to do that is why `stderr` is not
    // safe in the general case.
    private @property auto ref trustedStderr() @trusted
    {
        import std.stdio : stderr;

        return stderr;
    }
}

///
@safe unittest
{
    auto x = checked!Warn(42);
    short x1 = cast(short) x;
    //x += long(int.max);
    auto y = checked!Warn(cast(const int) 42);
    short y1 = cast(const byte) y;
}

@system unittest
{
    auto a = checked!Warn(int.min);
    auto b = checked!Warn(-1);
    auto x = checked!Abort(int.min);
    auto y = checked!Abort(-1);

    // Temporarily redirect output to stderr to make sure we get the right output.
    import std.file : exists, remove;
    import std.process : uniqueTempPath;
    import std.stdio : stderr;
    auto tmpname = uniqueTempPath;
    scope(exit) if (exists(tmpname)) remove(tmpname);
    auto t = stderr;
    stderr.open(tmpname, "w");
    // Open a new scope to minimize code ran with stderr redirected.
    {
        scope(exit) stderr = t;
        assert(a / b == a * b);
        import std.exception : assertThrown;
        import core.exception : AssertError;
        assertThrown!AssertError(x / y);
    }
    import std.file : readText;
    import std.ascii : newline;
    auto witness = readText(tmpname);
    auto expected =
"Overflow on binary operator: int(-2147483648) / const(int)(-1)" ~ newline ~
"Overflow on binary operator: int(-2147483648) * const(int)(-1)" ~ newline ~
"Overflow on binary operator: int(-2147483648) / const(int)(-1)" ~ newline;
    assert(witness == expected, "'" ~ witness ~ "'");
}

// https://issues.dlang.org/show_bug.cgi?id=22249
@safe unittest
{
    alias _ = Warn.onLowerBound!(int, int);
}

// ProperCompare
/**

Hook that provides arithmetically correct comparisons for equality and ordering.
Comparing an object of type $(D 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 $(D 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.

*/
struct ProperCompare
{
    /**
    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 $(D uint.max == -1) or $(D -1_294_967_296 ==
    3_000_000_000u). The call $(D hookOpEquals(x, y)) returns `true` if and only
    if `x` and `y` represent the same arithmetic number.

    If one of the numbers is an integral and the other is a floating-point
    number, $(D hookOpEquals(x, y)) returns `true` if and only if the integral
    can be converted exactly (without approximation) to the floating-point
    number. This is in order to preserve transitivity of equality: if $(D
    hookOpEquals(x, y)) and $(D hookOpEquals(y, z)) then $(D hookOpEquals(y,
    z)), in case `x`, `y`, and `z` are a mix of integral and floating-point
    numbers.

    Params:
    lhs = The left-hand side of the comparison for equality
    rhs = The right-hand side of the comparison for equality

    Returns:
    The result of the comparison, `true` if the values are equal
    */
    static bool hookOpEquals(L, R)(L lhs, R rhs)
    {
        alias C = typeof(lhs + rhs);
        static if (isFloatingPoint!C)
        {
            static if (!isFloatingPoint!L)
            {
                return hookOpEquals(rhs, lhs);
            }
            else static if (!isFloatingPoint!R)
            {
                static assert(isFloatingPoint!L && !isFloatingPoint!R);
                auto rhs1 = C(rhs);
                return lhs == rhs1 && cast(R) rhs1 == rhs;
            }
            else
                return lhs == rhs;
        }
        else
        {
            bool error;
            auto result = opChecked!"=="(lhs, rhs, error);
            if (error)
            {
                // Only possible error is a wrong "true"
                return false;
            }
            return result;
        }
    }

    /**
    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 $(D 0u < -1). The call $(D hookOpCmp(x, y))
    returns `-1` if and only if `x` is smaller than `y` in abstract arithmetic
    sense.

    If one of the numbers is an integral and the other is a floating-point
    number, $(D hookOpEquals(x, y)) returns a floating-point number that is `-1`
    if `x < y`, `0` if `x == y`, `1` if `x > y`, and `NaN` if the floating-point
    number is `NaN`.

    Params:
    lhs = The left-hand side of the comparison for ordering
    rhs = The right-hand side of the comparison for ordering

    Returns:
    The result of the comparison (negative if $(D lhs < rhs), positive if $(D
    lhs > rhs), `0` if the values are equal)
    */
    static auto hookOpCmp(L, R)(L lhs, R rhs)
    {
        alias C = typeof(lhs + rhs);
        static if (isFloatingPoint!C)
        {
            return lhs < rhs
                ? C(-1)
                : lhs > rhs ? C(1) : lhs == rhs ? C(0) : C.init;
        }
        else
        {
            static if (!valueConvertible!(L, C) || !valueConvertible!(R, C))
            {
                static assert(isUnsigned!C);
                static assert(isUnsigned!L != isUnsigned!R);
                if (!isUnsigned!L && lhs < 0)
                    return -1;
                if (!isUnsigned!R && rhs < 0)
                    return 1;
            }
            return lhs < rhs ? -1 : lhs > rhs;
        }
    }
}

///
@safe unittest
{
    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));
}

@safe unittest
{
    alias opCmpProper = ProperCompare.hookOpCmp;
    assert(opCmpProper(42, 42) == 0);
    assert(opCmpProper(42, 42.0) == 0);
    assert(opCmpProper(41, 42.0) < 0);
    assert(opCmpProper(42, 41.0) > 0);
    import std.math.traits : isNaN;
    assert(isNaN(opCmpProper(41, double.init)));
    assert(opCmpProper(42u, 42) == 0);
    assert(opCmpProper(42, 42u) == 0);
    assert(opCmpProper(-1, uint(-1)) < 0);
    assert(opCmpProper(uint(-1), -1) > 0);
    assert(opCmpProper(-1.0, -1) == 0);
}

@safe unittest
{
    auto x1 = Checked!(uint, ProperCompare)(42u);
    assert(x1.get < -1);
    assert(x1 > -1);
}

// WithNaN
/**

Hook that reserves a special value as a "Not a Number" representative. For
signed integrals, the reserved value is `T.min`. For unsigned integrals, the
reserved value is `T.max`.

The default value of a $(D Checked!(X, WithNaN)) is its NaN value, so care must
be taken that all variables are explicitly initialized. Any arithmetic and logic
operation involving at least on NaN becomes NaN itself. All of $(D a == b), $(D
a < b), $(D a > b), $(D a <= b), $(D a >= b) yield `false` if at least one of
`a` and `b` is NaN.

*/
struct WithNaN
{
static:
    /**
    The default value used for values not explicitly initialized. It is the NaN
    value, i.e. `T.min` for signed integrals and `T.max` for unsigned integrals.
    */
    enum T defaultValue(T) = T.min == 0 ? T.max : T.min;
    /**
    The maximum value representable is `T.max` for signed integrals, $(D
    T.max - 1) for unsigned integrals. The minimum value representable is $(D
    T.min + 1) for signed integrals, `0` for unsigned integrals.
    */
    enum T max(T) = cast(T) (T.min == 0 ? T.max - 1 : T.max);
    /// ditto
    enum T min(T) = cast(T) (T.min == 0 ? T(0) : T.min + 1);

    /**
    If `rhs` is `WithNaN.defaultValue!Rhs`, returns
    `WithNaN.defaultValue!Lhs`. Otherwise, returns $(D cast(Lhs) rhs).

    Params:
    rhs = the value being cast (`Rhs` is the first argument to `Checked`)
    Lhs = the target type of the cast

    Returns: The result of the cast operation.
    */
    Lhs hookOpCast(Lhs, Rhs)(Rhs rhs)
    {
        static if (is(Lhs == bool))
        {
            return rhs != defaultValue!Rhs && rhs != 0;
        }
        else static if (valueConvertible!(Rhs, Lhs))
        {
            return rhs != defaultValue!Rhs ? Lhs(rhs) : defaultValue!Lhs;
        }
        else
        {
            // Not value convertible, only viable option is rhs fits within the
            // bounds of Lhs
            static if (ProperCompare.hookOpCmp!(Rhs, Lhs)(lhs: Rhs.min, rhs: Lhs.min) < 0)
            {
                // Example: hookOpCast!short(int(42)), hookOpCast!uint(int(42))
                if (ProperCompare.hookOpCmp!(Rhs, Lhs)(lhs: rhs, rhs: Lhs.min) < 0)
                    return defaultValue!Lhs;
            }
            static if (ProperCompare.hookOpCmp!(Rhs, Lhs)(lhs: Rhs.max, rhs: Lhs.max) > 0)
            {
                // Example: hookOpCast!int(uint(42))
                if (ProperCompare.hookOpCmp!(Rhs, Lhs)(lhs: rhs, rhs: Lhs.max) > 0)
                    return defaultValue!Lhs;
            }
            return cast(Lhs) rhs;
        }
    }

    ///
    @safe unittest
    {
        auto x = checked!WithNaN(422);
        assert((cast(ubyte) x) == 255);
        x = checked!WithNaN(-422);
        assert((cast(byte) x) == -128);
        assert(cast(short) x == -422);
        assert(cast(bool) x);
        x = x.init; // set back to NaN
        assert(x != true);
        assert(x != false);
    }

    /**

    Returns `false` if $(D lhs == WithNaN.defaultValue!Lhs), $(D lhs == rhs)
    otherwise.

    Params:
    lhs = The left-hand side of the comparison (`Lhs` is the first argument to
    `Checked`)
    rhs = The right-hand side of the comparison

    Returns: `lhs != WithNaN.defaultValue!Lhs && lhs == rhs`
    */
    bool hookOpEquals(Lhs, Rhs)(Lhs lhs, Rhs rhs)
    {
        return lhs != defaultValue!Lhs && lhs == rhs;
    }

    /**

    If $(D lhs == WithNaN.defaultValue!Lhs), returns `double.init`. Otherwise,
    has the same semantics as the default comparison.

    Params:
    lhs = The left-hand side of the comparison (`Lhs` is the first argument to
    `Checked`)
    rhs = The right-hand side of the comparison

    Returns: `double.init` if `lhs == WitnNaN.defaultValue!Lhs`, `-1.0` if $(D
    lhs < rhs), `0.0` if $(D lhs == rhs), `1.0` if $(D lhs > rhs).

    */
    double hookOpCmp(Lhs, Rhs)(Lhs lhs, Rhs rhs)
    {
        if (lhs == defaultValue!Lhs) return double.init;
        return lhs < rhs
            ? -1.0
            : lhs > rhs ? 1.0 : lhs == rhs ? 0.0 : double.init;
    }

    ///
    @safe unittest
    {
        Checked!(int, WithNaN) x;
        assert(!(x < 0) && !(x > 0) && !(x == 0));
        x = 1;
        assert(x > 0 && !(x < 0) && !(x == 0));
    }

    /**
    Defines hooks for unary operators `-`, `~`, `++`, and `--`.

    For `-` and `~`, if $(D v == WithNaN.defaultValue!T), returns
    `WithNaN.defaultValue!T`. Otherwise, the semantics is the same as for the
    built-in operator.

    For `++` and `--`, if $(D v == WithNaN.defaultValue!Lhs) or the operation
    would result in an overflow, sets `v` to `WithNaN.defaultValue!T`.
    Otherwise, the semantics is the same as for the built-in operator.

    Params:
    x = The operator symbol
    v = The left-hand side of the comparison (`T` is the first argument to
    `Checked`)

    Returns: $(UL $(LI For $(D x == "-" || x == "~"): If  $(D v ==
    WithNaN.defaultValue!T), the function returns `WithNaN.defaultValue!T`.
    Otherwise it returns the normal result of the operator.) $(LI For $(D x ==
    "++" || x == "--"): The function returns `void`.))

    */
    auto hookOpUnary(string x, T)(ref T v)
    {
        static if (x == "-" || x == "~")
        {
            return v != defaultValue!T ? mixin(x ~ "v") : v;
        }
        else static if (x == "++")
        {
            static if (defaultValue!T == T.min)
            {
                if (v != defaultValue!T)
                {
                    if (v == T.max) v = defaultValue!T;
                    else ++v;
                }
            }
            else
            {
                static assert(defaultValue!T == T.max);
                if (v != defaultValue!T) ++v;
            }
        }
        else static if (x == "--")
        {
            if (v != defaultValue!T) --v;
        }
    }

    ///
    @safe unittest
    {
        Checked!(int, WithNaN) x;
        ++x;
        assert(x.isNaN);
        x = 1;
        assert(!x.isNaN);
        x = -x;
        ++x;
        assert(!x.isNaN);
    }

    @safe unittest // for coverage
    {
        Checked!(uint, WithNaN) y;
        ++y;
        assert(y.isNaN);
    }

    /**
    Defines hooks for binary operators `+`, `-`, `*`, `/`, `%`, `^^`, `&`, `|`,
     `^`, `<<`, `>>`, and `>>>` for cases where a `Checked` object is the
    left-hand side operand. If $(D lhs == WithNaN.defaultValue!Lhs), returns
    $(D WithNaN.defaultValue!(typeof(lhs + rhs))) without evaluating the
    operand. Otherwise, evaluates the operand. If evaluation does not overflow,
    returns the result. Otherwise, returns $(D WithNaN.defaultValue!(typeof(lhs +
    rhs))).

    Params:
    x = The operator symbol
    lhs = The left-hand side operand (`Lhs` is the first argument to `Checked`)
    rhs = The right-hand side operand

    Returns: If $(D lhs != WithNaN.defaultValue!Lhs) and the operator does not
    overflow, the function returns the same result as the built-in operator. In
    all other cases, returns $(D WithNaN.defaultValue!(typeof(lhs + rhs))).
    */
    auto hookOpBinary(string x, L, R)(L lhs, R rhs)
    {
        alias Result = typeof(lhs + rhs);
        if (lhs != defaultValue!L)
        {
            bool error;
            auto result = opChecked!x(lhs, rhs, error);
            if (!error) return result;
        }
        return defaultValue!Result;
    }

    ///
    @safe unittest
    {
        Checked!(int, WithNaN) x;
        assert((x + 1).isNaN);
        x = 100;
        assert(!(x + 1).isNaN);
    }

    /**
    Defines hooks for binary operators `+`, `-`, `*`, `/`, `%`, `^^`, `&`, `|`,
     `^`, `<<`, `>>`, and `>>>` for cases where a `Checked` object is the
    right-hand side operand. If $(D rhs == WithNaN.defaultValue!Rhs), returns
    $(D WithNaN.defaultValue!(typeof(lhs + rhs))) without evaluating the
    operand. Otherwise, evaluates the operand. If evaluation does not overflow,
    returns the result. Otherwise, returns $(D WithNaN.defaultValue!(typeof(lhs +
    rhs))).

    Params:
    x = The operator symbol
    lhs = The left-hand side operand
    rhs = The right-hand side operand (`Rhs` is the first argument to `Checked`)

    Returns: If $(D rhs != WithNaN.defaultValue!Rhs) and the operator does not
    overflow, the function returns the same result as the built-in operator. In
    all other cases, returns $(D WithNaN.defaultValue!(typeof(lhs + rhs))).
    */
    auto hookOpBinaryRight(string x, L, R)(L lhs, R rhs)
    {
        alias Result = typeof(lhs + rhs);
        if (rhs != defaultValue!R)
        {
            bool error;
            auto result = opChecked!x(lhs, rhs, error);
            if (!error) return result;
        }
        return defaultValue!Result;
    }
    ///
    @safe unittest
    {
        Checked!(int, WithNaN) x;
        assert((1 + x).isNaN);
        x = 100;
        assert(!(1 + x).isNaN);
    }

    /**

    Defines hooks for binary operators `+=`, `-=`, `*=`, `/=`, `%=`, `^^=`,
    `&=`, `|=`, `^=`, `<<=`, `>>=`, and `>>>=` for cases where a `Checked`
    object is the left-hand side operand. If $(D lhs ==
    WithNaN.defaultValue!Lhs), no action is carried. Otherwise, evaluates the
    operand. If evaluation does not overflow and fits in `Lhs` without loss of
    information or change of sign, sets `lhs` to the result. Otherwise, sets
    `lhs` to `WithNaN.defaultValue!Lhs`.

    Params:
    x = The operator symbol (without the `=`)
    lhs = The left-hand side operand (`Lhs` is the first argument to `Checked`)
    rhs = The right-hand side operand

    Returns: `void`
    */
    void hookOpOpAssign(string x, L, R)(ref L lhs, R rhs)
    {
        if (lhs == defaultValue!L)
            return;
        bool error;
        auto temp = opChecked!x(lhs, rhs, error);
        lhs = error
            ? defaultValue!L
            : hookOpCast!L(temp);
    }

    ///
    @safe unittest
    {
        Checked!(int, WithNaN) x;
        x += 4;
        assert(x.isNaN);
        x = 0;
        x += 4;
        assert(!x.isNaN);
        x += int.max;
        assert(x.isNaN);
    }
}

///
@safe unittest
{
    auto x1 = Checked!(int, WithNaN)();
    assert(x1.isNaN);
    assert(x1.get == int.min);
    assert(x1 != x1);
    assert(!(x1 < x1));
    assert(!(x1 > x1));
    assert(!(x1 == x1));
    ++x1;
    assert(x1.isNaN);
    assert(x1.get == int.min);
    --x1;
    assert(x1.isNaN);
    assert(x1.get == int.min);
    x1 = 42;
    assert(!x1.isNaN);
    assert(x1 == x1);
    assert(x1 <= x1);
    assert(x1 >= x1);
    static assert(x1.min == int.min + 1);
    x1 += long(int.max);
}

/**
Queries whether a $(D Checked!(T, WithNaN)) object is not a number (NaN).

Params:
    x = the `Checked` instance queried

Returns:
    `true` if `x` is a NaN, `false` otherwise
*/
bool isNaN(T)(const Checked!(T, WithNaN) x)
{
    return x.get == x.init.get;
}

///
@safe unittest
{
    auto x1 = Checked!(int, WithNaN)();
    assert(x1.isNaN);
    x1 = 1;
    assert(!x1.isNaN);
    x1 = x1.init;
    assert(x1.isNaN);
}

@safe unittest
{
    void test1(T)()
    {
        auto x1 = Checked!(T, WithNaN)();
        assert(x1.isNaN);
        assert(x1.get == int.min);
        assert(x1 != x1);
        assert(!(x1 < x1));
        assert(!(x1 > x1));
        assert(!(x1 == x1));
        assert(x1.get == int.min);
        auto x2 = Checked!(T, WithNaN)(42);
        assert(!x2.isNaN);
        assert(x2 == x2);
        assert(x2 <= x2);
        assert(x2 >= x2);
        static assert(x2.min == T.min + 1);
    }
    test1!int;
    test1!(const int);
    test1!(immutable int);

    void test2(T)()
    {
        auto x1 = Checked!(T, WithNaN)();
        assert(x1.get == T.min);
        assert(x1 != x1);
        assert(!(x1 < x1));
        assert(!(x1 > x1));
        assert(!(x1 == x1));
        ++x1;
        assert(x1.get == T.min);
        --x1;
        assert(x1.get == T.min);
        x1 = 42;
        assert(x1 == x1);
        assert(x1 <= x1);
        assert(x1 >= x1);
        static assert(x1.min == T.min + 1);
        x1 += long(T.max);
    }
    test2!int;
}

@safe unittest
{
    alias Smart(T) = Checked!(Checked!(T, ProperCompare), WithNaN);
    Smart!int x1;
    assert(x1 != x1);
    x1 = -1;
    assert(x1 < 1u);
    auto x2 = Smart!(const int)(42);
}

// Saturate
/**

Hook that implements $(I saturation), i.e. any arithmetic operation that would
overflow leaves the result at its extreme value (`min` or `max` depending on the
direction of the overflow).

Saturation is not sticky; if a value reaches its saturation value, another
operation may take it back to normal range.

*/
struct Saturate
{
static:
    /**

    Implements saturation for operators `+=`, `-=`, `*=`, `/=`, `%=`, `^^=`, `&=`, `|=`, `^=`, `<<=`, `>>=`,
    and `>>>=`. This hook is called if the result of the binary operation does
    not fit in `Lhs` without loss of information or a change in sign.

    Params:
    Rhs = The right-hand side type in the assignment, after the operation has
    been computed
    bound = The bound being violated

    Returns: `Lhs.max` if $(D rhs >= 0), `Lhs.min` otherwise.

    */
    T onLowerBound(Rhs, T)(Rhs, T bound)
    {
        return bound;
    }
    /// ditto
    T onUpperBound(Rhs, T)(Rhs, T bound)
    {
        return bound;
    }
    ///
    @safe unittest
    {
        auto x = checked!Saturate(short(100));
        x += 33000;
        assert(x == short.max);
        x -= 70000;
        assert(x == short.min);
    }

    /**

    Implements saturation for operators `+`, `-` (unary and binary), `*`, `/`,
    `%`, `^^`, `&`, `|`, `^`, `<<`, `>>`, and `>>>`.

    For unary `-`, `onOverflow` is called if $(D lhs == Lhs.min) and `Lhs` is a
    signed type. The function returns `Lhs.max`.

    For binary operators, the result is as follows: $(UL $(LI `Lhs.max` if the
    result overflows in the positive direction, on division by `0`, or on
    shifting right by a negative value) $(LI `Lhs.min` if the result overflows
    in the negative direction) $(LI `0` if `lhs` is being shifted left by a
    negative value, or shifted right by a large positive value))

    Params:
        x   = The operator involved in the `opAssign` operation
        Lhs = The left-hand side type of the operator (`Lhs` is the first argument to
              `Checked`)
        Rhs = The right-hand side type in the operator

    Returns: The saturated result of the operator.

    */
    auto onOverflow(string x, Lhs)(Lhs)
    {
        static assert(x == "-" || x == "++" || x == "--");
        return x == "--" ? Lhs.min : Lhs.max;
    }
    /// ditto
    typeof(Lhs() + Rhs()) onOverflow(string x, Lhs, Rhs)(Lhs lhs, Rhs rhs)
    {
        static if (x == "+")
            return rhs >= 0 ? Lhs.max : Lhs.min;
        else static if (x == "*")
            return (lhs >= 0) == (rhs >= 0) ? Lhs.max : Lhs.min;
        else static if (x == "^^")
            return lhs > 0 || !(rhs & 1) ? Lhs.max : Lhs.min;
        else static if (x == "-")
            return rhs >= 0 ? Lhs.min : Lhs.max;
        else static if (x == "/" || x == "%")
            return Lhs.max;
        else static if (x == "<<")
            return rhs >= 0 ? Lhs.max : 0;
        else static if (x == ">>" || x == ">>>")
            return rhs >= 0 ? 0 : Lhs.max;
        else
            static assert(false);
    }
    ///
    @safe unittest
    {
        assert(checked!Saturate(int.max) + 1 == int.max);
        assert(checked!Saturate(100) ^^ 10 == int.max);
        assert(checked!Saturate(-100) ^^ 10 == int.max);
        assert(checked!Saturate(100) / 0 == int.max);
        assert(checked!Saturate(100) << -1 == 0);
        assert(checked!Saturate(100) << 33 == int.max);
        assert(checked!Saturate(100) >> -1 == int.max);
        assert(checked!Saturate(100) >> 33 == 0);
    }
}

///
@safe unittest
{
    auto x = checked!Saturate(int.max);
    ++x;
    assert(x == int.max);
    --x;
    assert(x == int.max - 1);
    x = int.min;
    assert(-x == int.max);
    x -= 42;
    assert(x == int.min);
    assert(x * -2 == int.max);
}

/*
Yields `true` if `T1` is "value convertible" (by C's "value preserving" rule,
see $(HTTP c-faq.com/expr/preservingrules.html)) to `T2`, where the two are
integral types. That is, all of values in `T1` are also in `T2`. For example
`int` is value convertible to `long` but not to `uint` or `ulong`.
*/
private enum valueConvertible(T1, T2) = isIntegral!T1 && isIntegral!T2 &&
    is(T1 : T2) && (
        isUnsigned!T1 == isUnsigned!T2 || // same signedness
        !isUnsigned!T2 && T2.sizeof > T1.sizeof // safely convertible
    );

/**

Defines binary operations with overflow checking for any two integral types.
The result type obeys the language rules (even when they may be
counterintuitive), and `overflow` is set if an overflow occurs (including
inadvertent change of signedness, e.g. `-1` is converted to `uint`).
Conceptually the behavior is:

$(OL $(LI Perform the operation in infinite precision)
$(LI If the infinite-precision result fits in the result type, return it and
do not touch `overflow`)
$(LI Otherwise, set `overflow` to `true` and return an unspecified value)
)

The implementation exploits properties of types and operations to minimize
additional work.

Params:
x = The binary operator involved, e.g. `/`
lhs = The left-hand side of the operator
rhs = The right-hand side of the operator
overflow = The overflow indicator (assigned `true` in case there's an error)

Returns:
The result of the operation, which is the same as the built-in operator
*/
typeof(mixin(x == "cmp" ? "0" : ("L() " ~ x ~ " R()")))
opChecked(string x, L, R)(const L lhs, const R rhs, ref bool overflow)
if (isIntegral!L && isIntegral!R)
{
    static if (x == "cmp")
        alias Result = int;
    else
        alias Result = typeof(mixin("L() " ~ x ~ " R()"));

    import core.checkedint : addu, adds, subs, muls, subu, mulu;
    import std.algorithm.comparison : among;
    static if (x == "==")
    {
        alias C = typeof(lhs + rhs);
        static if (valueConvertible!(L, C) && valueConvertible!(R, C))
        {
            // Values are converted to R before comparison, cool.
            return lhs == rhs;
        }
        else
        {
            static assert(isUnsigned!C);
            static assert(isUnsigned!L != isUnsigned!R);
            if (lhs != rhs) return false;
            // R(lhs) and R(rhs) have the same bit pattern, yet may be
            // different due to signedness change.
            static if (!isUnsigned!R)
            {
                if (rhs >= 0)
                    return true;
            }
            else
            {
                if (lhs >= 0)
                    return true;
            }
            overflow = true;
            return true;
        }
    }
    else static if (x == "cmp")
    {
        alias C = typeof(lhs + rhs);
        static if (!valueConvertible!(L, C) || !valueConvertible!(R, C))
        {
            static assert(isUnsigned!C);
            static assert(isUnsigned!L != isUnsigned!R);
            if (!isUnsigned!L && lhs < 0)
            {
                overflow = true;
                return -1;
            }
            if (!isUnsigned!R && rhs < 0)
            {
                overflow = true;
                return 1;
            }
        }
        return lhs < rhs ? -1 : lhs > rhs;
    }
    else static if (x.among("<<", ">>", ">>>"))
    {
        // Handle shift separately from all others. The test below covers
        // negative rhs as well.
        import std.conv : unsigned;
        if (unsigned(rhs) > 8 * Result.sizeof) goto fail;
        return mixin("lhs" ~ x ~ "rhs");
    }
    else static if (x.among("&", "|", "^"))
    {
        // Nothing to check
        return mixin("lhs" ~ x ~ "rhs");
    }
    else static if (x == "^^")
    {
        // Exponentiation is weird, handle separately
        return pow(lhs, rhs, overflow);
    }
    else static if (valueConvertible!(L, Result) &&
            valueConvertible!(R, Result))
    {
        static if (L.sizeof < Result.sizeof && R.sizeof < Result.sizeof &&
            x.among("+", "-", "*"))
        {
            // No checks - both are value converted and result is in range
            return mixin("lhs" ~ x ~ "rhs");
        }
        else static if (x == "+")
        {
            static if (isUnsigned!Result) alias impl = addu;
            else alias impl = adds;
            return impl(Result(lhs), Result(rhs), overflow);
        }
        else static if (x == "-")
        {
            static if (isUnsigned!Result) alias impl = subu;
            else alias impl = subs;
            return impl(Result(lhs), Result(rhs), overflow);
        }
        else static if (x == "*")
        {
            static if (!isUnsigned!L && !isUnsigned!R &&
                is(L == Result))
            {
                if (lhs == Result.min && rhs == -1) goto fail;
            }
            static if (isUnsigned!Result) alias impl = mulu;
            else alias impl = muls;
            return impl(Result(lhs), Result(rhs), overflow);
        }
        else static if (x == "/" || x == "%")
        {
            static if (!isUnsigned!L && !isUnsigned!R &&
                is(L == Result) && x == "/")
            {
                if (lhs == Result.min && rhs == -1) goto fail;
            }
            if (rhs == 0) goto fail;
            return mixin("lhs" ~ x ~ "rhs");
        }
        else static assert(0, x);
    }
    else // Mixed signs
    {
        static assert(isUnsigned!Result);
        static assert(isUnsigned!L != isUnsigned!R);
        static if (x == "+")
        {
            static if (!isUnsigned!L)
            {
                if (lhs < 0)
                    return subu(Result(rhs), Result(-lhs), overflow);
            }
            else static if (!isUnsigned!R)
            {
                if (rhs < 0)
                    return subu(Result(lhs), Result(-rhs), overflow);
            }
            return addu(Result(lhs), Result(rhs), overflow);
        }
        else static if (x == "-")
        {
            static if (!isUnsigned!L)
            {
                if (lhs < 0) goto fail;
            }
            else static if (!isUnsigned!R)
            {
                if (rhs < 0)
                    return addu(Result(lhs), Result(-rhs), overflow);
            }
            return subu(Result(lhs), Result(rhs), overflow);
        }
        else static if (x == "*")
        {
            static if (!isUnsigned!L)
            {
                if (lhs < 0) goto fail;
            }
            else static if (!isUnsigned!R)
            {
                if (rhs < 0) goto fail;
            }
            return mulu(Result(lhs), Result(rhs), overflow);
        }
        else static if (x == "/" || x == "%")
        {
            static if (!isUnsigned!L)
            {
                if (lhs < 0 || rhs == 0) goto fail;
            }
            else static if (!isUnsigned!R)
            {
                if (rhs <= 0) goto fail;
            }
            return mixin("Result(lhs)" ~ x ~ "Result(rhs)");
        }
        else static assert(0, x);
    }
    debug assert(false);
fail:
    overflow = true;
    return Result(0);
}

///
@safe unittest
{
    bool overflow;
    assert(opChecked!"+"(const short(1), short(1), overflow) == 2 && !overflow);
    assert(opChecked!"+"(1, 1, overflow) == 2 && !overflow);
    assert(opChecked!"+"(1, 1u, overflow) == 2 && !overflow);
    assert(opChecked!"+"(-1, 1u, overflow) == 0 && !overflow);
    assert(opChecked!"+"(1u, -1, overflow) == 0 && !overflow);
}

///
@safe unittest
{
    bool overflow;
    assert(opChecked!"-"(1, 1, overflow) == 0 && !overflow);
    assert(opChecked!"-"(1, 1u, overflow) == 0 && !overflow);
    assert(opChecked!"-"(1u, -1, overflow) == 2 && !overflow);
    assert(opChecked!"-"(-1, 1u, overflow) == 0 && overflow);
}

@safe unittest
{
    bool overflow;
    assert(opChecked!"*"(2, 3, overflow) == 6 && !overflow);
    assert(opChecked!"*"(2, 3u, overflow) == 6 && !overflow);
    assert(opChecked!"*"(1u, -1, overflow) == 0 && overflow);
    //assert(mul(-1, 1u, overflow) == uint.max - 1 && overflow);
}

@safe unittest
{
    bool overflow;
    assert(opChecked!"/"(6, 3, overflow) == 2 && !overflow);
    assert(opChecked!"/"(6, 3, overflow) == 2 && !overflow);
    assert(opChecked!"/"(6u, 3, overflow) == 2 && !overflow);
    assert(opChecked!"/"(6, 3u, overflow) == 2 && !overflow);
    assert(opChecked!"/"(11, 0, overflow) == 0 && overflow);
    overflow = false;
    assert(opChecked!"/"(6u, 0, overflow) == 0 && overflow);
    overflow = false;
    assert(opChecked!"/"(-6, 2u, overflow) == 0 && overflow);
    overflow = false;
    assert(opChecked!"/"(-6, 0u, overflow) == 0 && overflow);
    overflow = false;
    assert(opChecked!"cmp"(0u, -6, overflow) == 1 && overflow);
    overflow = false;
    assert(opChecked!"|"(1, 2, overflow) == 3 && !overflow);
}

/*
Exponentiation function used by the implementation of operator `^^`.
*/
private pure @safe nothrow @nogc
auto pow(L, R)(const L lhs, const R rhs, ref bool overflow)
if (isIntegral!L && isIntegral!R)
{
    if (rhs <= 1)
    {
        if (rhs == 0) return 1;
        static if (!isUnsigned!R)
            return rhs == 1
                ? lhs
                : (rhs == -1 && (lhs == 1 || lhs == -1)) ? lhs : 0;
        else
            return lhs;
    }

    typeof(lhs ^^ rhs) b = void;
    static if (!isUnsigned!L && isUnsigned!(typeof(b)))
    {
        // Need to worry about mixed-sign stuff
        if (lhs < 0)
        {
            if (rhs & 1)
            {
                if (lhs < 0) overflow = true;
                return 0;
            }
            b = -lhs;
        }
        else
        {
            b = lhs;
        }
    }
    else
    {
        b = lhs;
    }
    if (b == 1) return 1;
    if (b == -1) return (rhs & 1) ? -1 : 1;
    if (rhs > 63)
    {
        overflow = true;
        return 0;
    }

    assert((b > 1 || b < -1) && rhs > 1);
    return powImpl(b, cast(uint) rhs, overflow);
}

// Inspiration: http://www.stepanovpapers.com/PAM.pdf
pure @safe nothrow @nogc
private T powImpl(T)(T b, uint e, ref bool overflow)
if (isIntegral!T && T.sizeof >= 4)
{
    assert(e > 1);

    import core.checkedint : muls, mulu;
    static if (isUnsigned!T) alias mul = mulu;
    else alias mul = muls;

    T r = b;
    --e;
    // Loop invariant: r * (b ^^ e) is the actual result
    for (;; e /= 2)
    {
        if (e % 2)
        {
            r = mul(r, b, overflow);
            if (e == 1) break;
        }
        b = mul(b, b, overflow);
    }
    return r;
}

@safe unittest
{
    static void testPow(T)(T x, uint e)
    {
        bool overflow;
        assert(opChecked!"^^"(T(0), 0, overflow) == 1);
        assert(opChecked!"^^"(-2, T(0), overflow) == 1);
        assert(opChecked!"^^"(-2, T(1), overflow) == -2);
        assert(opChecked!"^^"(-1, -1, overflow) == -1);
        assert(opChecked!"^^"(-2, 1, overflow) == -2);
        assert(opChecked!"^^"(-2, -1, overflow) == 0);
        assert(opChecked!"^^"(-2, 4u, overflow) == 16);
        assert(!overflow);
        assert(opChecked!"^^"(-2, 3u, overflow) == 0);
        assert(overflow);
        overflow = false;
        assert(opChecked!"^^"(3, 64u, overflow) == 0);
        assert(overflow);
        overflow = false;
        foreach (uint i; 0 .. e)
        {
            assert(opChecked!"^^"(x, i, overflow) == x ^^ i);
            assert(!overflow);
        }
        assert(opChecked!"^^"(x, e, overflow) == x ^^ e);
        assert(overflow);
    }

    testPow!int(3, 21);
    testPow!uint(3, 21);
    testPow!long(3, 40);
    testPow!ulong(3, 41);
}

version (StdUnittest) private struct CountOverflows
{
    uint calls;
    auto onOverflow(string op, Lhs)(Lhs lhs)
    {
        ++calls;
        return mixin(op ~ "lhs");
    }
    auto onOverflow(string op, Lhs, Rhs)(Lhs lhs, Rhs rhs)
    {
        ++calls;
        return mixin("lhs" ~ op ~ "rhs");
    }
    T onLowerBound(Rhs, T)(Rhs rhs, T)
    {
        ++calls;
        return cast(T) rhs;
    }
    T onUpperBound(Rhs, T)(Rhs rhs, T)
    {
        ++calls;
        return cast(T) rhs;
    }
}

// opBinary
@nogc nothrow pure @safe unittest
{
    static struct CountOpBinary
    {
        uint calls;
        auto hookOpBinary(string op, Lhs, Rhs)(Lhs lhs, Rhs rhs)
        {
            ++calls;
            return mixin("lhs" ~ op ~ "rhs");
        }
    }
    auto x = Checked!(const int, void)(42), y = Checked!(immutable int, void)(142);
    assert(x + y == 184);
    assert(x + 100 == 142);
    assert(y - x == 100);
    assert(200 - x == 158);
    assert(y * x == 142 * 42);
    assert(x / 1 == 42);
    assert(x % 20 == 2);

    auto x1 = Checked!(int, CountOverflows)(42);
    assert(x1 + 0 == 42);
    assert(x1 + false == 42);
    assert(is(typeof(x1 + 0.5) == double));
    assert(x1 + 0.5 == 42.5);
    assert(x1.hook.calls == 0);
    assert(x1 + int.max == int.max + 42);
    assert(x1.hook.calls == 1);
    assert(x1 * 2 == 84);
    assert(x1.hook.calls == 1);
    assert(x1 / 2 == 21);
    assert(x1.hook.calls == 1);
    assert(x1 % 20 == 2);
    assert(x1.hook.calls == 1);
    assert(x1 << 2 == 42 << 2);
    assert(x1.hook.calls == 1);
    assert(x1 << 42 == x1.get << x1.get);
    assert(x1.hook.calls == 2);
    x1 = int.min;
    assert(x1 - 1 == int.max);
    assert(x1.hook.calls == 3);

    auto x2 = Checked!(int, CountOpBinary)(42);
    assert(x2 + 1 == 43);
    assert(x2.hook.calls == 1);

    auto x3 = Checked!(uint, CountOverflows)(42u);
    assert(x3 + 1 == 43);
    assert(x3.hook.calls == 0);
    assert(x3 - 1 == 41);
    assert(x3.hook.calls == 0);
    assert(x3 + (-42) == 0);
    assert(x3.hook.calls == 0);
    assert(x3 - (-42) == 84);
    assert(x3.hook.calls == 0);
    assert(x3 * 2 == 84);
    assert(x3.hook.calls == 0);
    assert(x3 * -2 == -84);
    assert(x3.hook.calls == 1);
    assert(x3 / 2 == 21);
    assert(x3.hook.calls == 1);
    assert(x3 / -2 == 0);
    assert(x3.hook.calls == 2);
    assert(x3 ^^ 2 == 42 * 42);
    assert(x3.hook.calls == 2);

    auto x4 = Checked!(int, CountOverflows)(42);
    assert(x4 + 1 == 43);
    assert(x4.hook.calls == 0);
    assert(x4 + 1u == 43);
    assert(x4.hook.calls == 0);
    assert(x4 - 1 == 41);
    assert(x4.hook.calls == 0);
    assert(x4 * 2 == 84);
    assert(x4.hook.calls == 0);
    x4 = -2;
    assert(x4 + 2u == 0);
    assert(x4.hook.calls == 0);
    assert(x4 * 2u == -4);
    assert(x4.hook.calls == 1);

    auto x5 = Checked!(int, CountOverflows)(3);
    assert(x5 ^^ 0 == 1);
    assert(x5 ^^ 1 == 3);
    assert(x5 ^^ 2 == 9);
    assert(x5 ^^ 3 == 27);
    assert(x5 ^^ 4 == 81);
    assert(x5 ^^ 5 == 81 * 3);
    assert(x5 ^^ 6 == 81 * 9);
}

// opBinaryRight
@nogc nothrow pure @safe unittest
{
    auto x1 = Checked!(int, CountOverflows)(42);
    assert(1 + x1 == 43);
    assert(true + x1 == 43);
    assert(0.5 + x1 == 42.5);
    auto x2 = Checked!(int, void)(42);
    assert(x1 + x2 == 84);
    assert(x2 + x1   == 84);
}

// opOpAssign
@safe unittest
{
    auto x1 = Checked!(int, CountOverflows)(3);
    assert((x1 += 2) == 5);
    x1 *= 2_000_000_000L;
    assert(x1.hook.calls == 1);
    x1 *= -2_000_000_000L;
    assert(x1.hook.calls == 2);

    auto x2 = Checked!(ushort, CountOverflows)(ushort(3));
    assert((x2 += 2) == 5);
    assert(x2.hook.calls == 0);
    assert((x2 += ushort.max) == cast(ushort) (ushort(5) + ushort.max));
    assert(x2.hook.calls == 1);

    auto x3 = Checked!(uint, CountOverflows)(3u);
    x3 *= ulong(2_000_000_000);
    assert(x3.hook.calls == 1);
}

// opAssign
@safe unittest
{
    Checked!(int, void) x;
    x = 42;
    assert(x.get == 42);
    x = x;
    assert(x.get == 42);
    x = short(43);
    assert(x.get == 43);
    x = ushort(44);
    assert(x.get == 44);
}

@safe unittest
{
    static assert(!is(typeof(Checked!(short, void)(ushort(42)))));
    static assert(!is(typeof(Checked!(int, void)(long(42)))));
    static assert(!is(typeof(Checked!(int, void)(ulong(42)))));
    assert(Checked!(short, void)(short(42)).get == 42);
    assert(Checked!(int, void)(ushort(42)).get == 42);
}

// opCast
@nogc nothrow pure @safe unittest
{
    static assert(is(typeof(cast(float) Checked!(int, void)(42)) == float));
    assert(cast(float) Checked!(int, void)(42) == 42);

    assert(is(typeof(cast(long) Checked!(int, void)(42)) == long));
    assert(cast(long) Checked!(int, void)(42) == 42);
    static assert(is(typeof(cast(long) Checked!(uint, void)(42u)) == long));
    assert(cast(long) Checked!(uint, void)(42u) == 42);

    auto x = Checked!(int, void)(42);
    if (x) {} else assert(0);
    x = 0;
    if (x) assert(0);

    static struct Hook1
    {
        uint calls;
        Dst hookOpCast(Dst, Src)(Src value)
        {
            ++calls;
            return 42;
        }
    }
    auto y = Checked!(long, Hook1)(long.max);
    assert(cast(int) y == 42);
    assert(cast(uint) y == 42);
    assert(y.hook.calls == 2);

    static struct Hook2
    {
        uint calls;
        Dst onBadCast(Dst, Src)(Src value)
        {
            ++calls;
            return 42;
        }
    }
    auto x1 = Checked!(uint, Hook2)(100u);
    assert(cast(ushort) x1 == 100);
    assert(cast(short) x1 == 100);
    assert(cast(float) x1 == 100);
    assert(cast(double) x1 == 100);
    assert(cast(real) x1 == 100);
    assert(x1.hook.calls == 0);
    assert(cast(int) x1 == 100);
    assert(x1.hook.calls == 0);
    x1 = uint.max;
    assert(cast(int) x1 == 42);
    assert(x1.hook.calls == 1);

    auto x2 = Checked!(int, Hook2)(-100);
    assert(cast(short) x2 == -100);
    assert(cast(ushort) x2 == 42);
    assert(cast(uint) x2 == 42);
    assert(cast(ulong) x2 == 42);
    assert(x2.hook.calls == 3);
}

// opEquals
@nogc nothrow pure @safe unittest
{
    assert(Checked!(int, void)(42) == 42L);
    assert(42UL == Checked!(int, void)(42));

    static struct Hook1
    {
        uint calls;
        bool hookOpEquals(Lhs, Rhs)(const Lhs lhs, const Rhs rhs)
        {
            ++calls;
            return lhs != rhs;
        }
    }
    auto x1 = Checked!(int, Hook1)(100);
    assert(x1 != Checked!(long, Hook1)(100));
    assert(x1.hook.calls == 1);
    assert(x1 != 100u);
    assert(x1.hook.calls == 2);

    static struct Hook2
    {
        uint calls;
        bool hookOpEquals(Lhs, Rhs)(Lhs lhs, Rhs rhs)
        {
            ++calls;
            return false;
        }
    }
    auto x2 = Checked!(int, Hook2)(-100);
    assert(x2 != x1);
    // For coverage: lhs has no hookOpEquals, rhs does
    assert(Checked!(uint, void)(100u) != x2);
    // For coverage: different types, neither has a hookOpEquals
    assert(Checked!(uint, void)(100u) == Checked!(int, void*)(100));
    assert(x2.hook.calls == 0);
    assert(x2 != -100);
    assert(x2.hook.calls == 1);
    assert(x2 != cast(uint) -100);
    assert(x2.hook.calls == 2);
    x2 = 100;
    assert(x2 != cast(uint) 100);
    assert(x2.hook.calls == 3);
    x2 = -100;

    auto x3 = Checked!(uint, Hook2)(100u);
    assert(x3 != 100);
    x3 = uint.max;
    assert(x3 != -1);

    assert(x2 != x3);
}

// opCmp
@nogc nothrow pure @safe unittest
{
    Checked!(int, void) x;
    assert(x <= x);
    assert(x < 45);
    assert(x < 45u);
    assert(x > -45);
    assert(x < 44.2);
    assert(x > -44.2);
    assert(!(x < double.init));
    assert(!(x > double.init));
    assert(!(x <= double.init));
    assert(!(x >= double.init));

    static struct Hook1
    {
        uint calls;
        int hookOpCmp(Lhs, Rhs)(Lhs lhs, Rhs rhs)
        {
            ++calls;
            return 0;
        }
    }
    auto x1 = Checked!(int, Hook1)(42);
    assert(!(x1 < 43u));
    assert(!(43u < x1));
    assert(x1.hook.calls == 2);

    static struct Hook2
    {
        uint calls;
        int hookOpCmp(Lhs, Rhs)(Lhs lhs, Rhs rhs)
        {
            ++calls;
            return ProperCompare.hookOpCmp(lhs, rhs);
        }
    }
    auto x2 = Checked!(int, Hook2)(-42);
    assert(x2 < 43u);
    assert(43u > x2);
    assert(x2.hook.calls == 2);
    x2 = 42;
    assert(x2 > 41u);

    auto x3 = Checked!(uint, Hook2)(42u);
    assert(x3 > 41);
    assert(x3 > -41);
}

// opUnary
@nogc nothrow pure @safe unittest
{
    auto x = Checked!(int, void)(42);
    assert(x == +x);
    static assert(is(typeof(-x) == typeof(x)));
    assert(-x == Checked!(int, void)(-42));
    static assert(is(typeof(~x) == typeof(x)));
    assert(~x == Checked!(int, void)(~42));
    assert(++x == 43);
    assert(--x == 42);

    static struct Hook1
    {
        uint calls;
        auto hookOpUnary(string op, T)(T value)
        if (op == "-")
        {
            ++calls;
            return T(42);
        }
        auto hookOpUnary(string op, T)(T value)
        if (op == "~")
        {
            ++calls;
            return T(43);
        }
    }
    auto x1 = Checked!(int, Hook1)(100);
    assert(is(typeof(-x1) == typeof(x1)));
    assert(-x1 == Checked!(int, Hook1)(42));
    assert(is(typeof(~x1) == typeof(x1)));
    assert(~x1 == Checked!(int, Hook1)(43));
    assert(x1.hook.calls == 2);

    static struct Hook2
    {
        uint calls;
        void hookOpUnary(string op, T)(ref T value)
        if (op == "++")
        {
            ++calls;
            --value;
        }
        void hookOpUnary(string op, T)(ref T value)
        if (op == "--")
        {
            ++calls;
            ++value;
        }
    }
    auto x2 = Checked!(int, Hook2)(100);
    assert(++x2 == 99);
    assert(x2 == 99);
    assert(--x2 == 100);
    assert(x2 == 100);

    auto x3 = Checked!(int, CountOverflows)(int.max - 1);
    assert(++x3 == int.max);
    assert(x3.hook.calls == 0);
    assert(++x3 == int.min);
    assert(x3.hook.calls == 1);
    assert(-x3 == int.min);
    assert(x3.hook.calls == 2);

    x3 = int.min + 1;
    assert(--x3 == int.min);
    assert(x3.hook.calls == 2);
    assert(--x3 == int.max);
    assert(x3.hook.calls == 3);
}

//
@nogc nothrow pure @safe unittest
{
    Checked!(int, void) x;
    assert(x == x);
    assert(x == +x);
    assert(x == -x);
    ++x;
    assert(x == 1);
    x++;
    assert(x == 2);

    x = 42;
    assert(x == 42);
    const short _short = 43;
    x = _short;
    assert(x == _short);
    ushort _ushort = 44;
    x = _ushort;
    assert(x == _ushort);
    assert(x == 44.0);
    assert(x != 44.1);
    assert(x < 45);
    assert(x < 44.2);
    assert(x > -45);
    assert(x > -44.2);

    assert(cast(long) x == 44);
    assert(cast(short) x == 44);

    const Checked!(uint, void) y;
    assert(y <= y);
    assert(y == 0);
    assert(y < x);
    x = -1;
    assert(x > y);
}

@nogc nothrow pure @safe unittest
{
    alias cint = Checked!(int, void);
    cint a = 1, b = 2;
    a += b;
    assert(a == cint(3));

    alias ccint = Checked!(cint, Saturate);
    ccint c = 14;
    a += c;
    assert(a == cint(17));
}

// toHash
@safe unittest
{
    assert(checked(42).toHash() == checked(42).toHash());
    assert(checked(12).toHash() != checked(19).toHash());

    static struct Hook1
    {
        static size_t hookToHash(T)(T payload) nothrow @trusted
        {
            static if (size_t.sizeof == 4)
            {
                return typeid(payload).getHash(&payload) ^ 0xFFFF_FFFF;
            }
            else
            {
                return typeid(payload).getHash(&payload) ^ 0xFFFF_FFFF_FFFF_FFFF;
            }

        }
    }

    auto a = checked!Hook1(78);
    auto b = checked!Hook1(78);
    assert(a.toHash() == b.toHash());

    assert(checked!Hook1(12).toHash() != checked!Hook1(13).toHash());

    static struct Hook2
    {
        static if (size_t.sizeof == 4)
        {
            static size_t hashMask = 0xFFFF_0000;
        }
        else
        {
            static size_t hashMask = 0xFFFF_0000_FFFF_0000;
        }

        static size_t hookToHash(T)(T payload) nothrow @trusted
        {
            return typeid(payload).getHash(&payload) ^ hashMask;
        }
    }

    auto x = checked!Hook2(1901);
    auto y = checked!Hook2(1989);

    assert((() nothrow @safe => x.toHash() == x.toHash())());

    assert(x.toHash() == x.toHash());
    assert(x.toHash() != y.toHash());
    assert(checked!Hook1(1901).toHash() != x.toHash());

    immutable z = checked!Hook1(1901);
    immutable t = checked!Hook1(1901);
    immutable w = checked!Hook2(1901);

    assert(z.toHash() == t.toHash());
    assert(z.toHash() != x.toHash());
    assert(z.toHash() != w.toHash());

    const long c = 0xF0F0F0F0;
    const long d = 0xF0F0F0F0;

    assert(checked!Hook1(c).toHash() != checked!Hook2(c));
    assert(checked!Hook1(c).toHash() != checked!Hook1(d));

    // Hook with state, does not implement hookToHash
    static struct Hook3
    {
        ulong var1 = ulong.max;
        uint var2 = uint.max;
    }

    assert(checked!Hook3(12).toHash() != checked!Hook3(13).toHash());
    assert(checked!Hook3(13).toHash() == checked!Hook3(13).toHash());

    // Hook with no state and no hookToHash, payload has its own hashing function
    auto x1 = Checked!(Checked!int, ProperCompare)(123);
    auto x2 = Checked!(Checked!int, ProperCompare)(123);
    auto x3 = Checked!(Checked!int, ProperCompare)(144);

    assert(x1.toHash() == x2.toHash());
    assert(x1.toHash() != x3.toHash());
    assert(x2.toHash() != x3.toHash());

    // Check shared.
    {
        shared shared0 = checked(12345678);
        shared shared1 = checked!Hook1(123456789);
        shared shared2 = checked!Hook2(234567891);
        shared shared3 = checked!Hook3(345678912);
        assert(shared0.toHash() == hashOf(shared0));
        assert(shared1.toHash() == hashOf(shared1));
        assert(shared2.toHash() == hashOf(shared2));
        assert(shared3.toHash() == hashOf(shared3));
    }
}

///
@safe unittest
{
    struct MyHook
    {
        static size_t hookToHash(T)(const T payload) nothrow @trusted
        {
            return .hashOf(payload);
        }
    }

    int[Checked!(int, MyHook)] aa;
    Checked!(int, MyHook) var = 42;
    aa[var] = 100;

    assert(aa[var] == 100);

    int[Checked!(int, Abort)] bb;
    Checked!(int, Abort) var2 = 42;
    bb[var2] = 100;

    assert(bb[var2] == 100);
}
