// 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 payload = __ctfe ? cast(P) this.payload
                                  : this.payload.atomicLoad!(MemoryOrder.acq);
        }
        else
        {
            alias payload = this.payload;
        }

        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);
        }
    }

    /**
    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 signed 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.min, Lhs.min) < 0)
            {
                // Example: hookOpCast!short(int(42)), hookOpCast!uint(int(42))
                if (ProperCompare.hookOpCmp(rhs, Lhs.min) < 0)
                    return defaultValue!Lhs;
            }
            static if (ProperCompare.hookOpCmp(Rhs.max, Lhs.max) > 0)
            {
                // Example: hookOpCast!int(uint(42))
                if (ProperCompare.hookOpCmp(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);
}
