/**
$(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.experimental.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`.)
)
)

*/
module std.experimental.checkedint;
import std.traits : isFloatingPoint, isIntegral, isNumeric, isUnsigned, Unqual;

///
@system 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]);
}

/**
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`.
*/
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.traits : hasMember;

    /**
    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);
        ///
        @system unittest
        {
            assert(Checked!short.min == -32768);
            assert(Checked!(short, WithNaN).min == -32767);
            assert(Checked!(uint, WithNaN).max == uint.max - 1);
        }
    }
    else
        enum Checked!(T, Hook) min = Checked(T.min);
    /// ditto
    static if (hasMember!(Hook, "max"))
        enum Checked!(T, Hook) max = Checked(Hook.max!T);
    else
        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;
    }
    ///
    @system 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.
    */
    void opAssign(U)(U rhs) if (is(typeof(Checked!(T, Hook)(rhs))))
    {
        static if (isIntegral!U)
            payload = rhs;
        else
            payload = rhs.payload;
    }
    ///
    @system unittest
    {
        Checked!long a;
        a = 42L;
        assert(a == 42);
        a = 4242;
        assert(a == 4242);
    }

    // opCast
    /**
    Casting operator to integral, `bool`, or floating point type. 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`.

    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.

    */
    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);
        }
    }
    ///
    @system unittest
    {
        assert(cast(uint) checked(42) == 42);
        assert(cast(uint) checked!WithNaN(-42) == uint.max);
    }

    // opEquals
    /**
    Compares `this` against `rhs` for equality. 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.

    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.

    */
    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
    {
        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);
    }

    // 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.

    */
    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
    {
        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)) @system 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.

    */
    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.

    */
    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)) @system 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.

    */
    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(42);
            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)) @system 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)).

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

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

/**

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`).

*/
Checked!(T, Hook) checked(Hook = Abort, T)(const T value)
if (is(typeof(Checked!(T, Hook)(value))))
{
    return Checked!(T, Hook)(value);
}

///
@system 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);
}

// 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 = The source of the cast

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

@system 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
    {
        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 = The source of the cast

    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.

    */
    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.

    */
    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.

    */
    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 : stderr;
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)
    {
        stderr.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(Lhs) rhs`
    */
    Lhs onLowerBound(Rhs, T)(Rhs rhs, T bound)
    {
        stderr.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)
    {
        stderr.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)
        {
            stderr.writefln("Erroneous comparison: %s(%s) == %s(%s)",
                Lhs.stringof, lhs, Rhs.stringof, rhs);
            return lhs == rhs;
        }
        return result;
    }

    ///
    @system 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)
        {
            stderr.writefln("Erroneous ordering comparison: %s(%s) and %s(%s)",
                Lhs.stringof, lhs, Rhs.stringof, rhs);
            return lhs < rhs ? -1 : lhs > rhs;
        }
        return result;
    }

    ///
    @system 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)
    {
        stderr.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)
    {
        stderr.writefln("Overflow on binary operator: %s(%s) %s %s(%s)",
            Lhs.stringof, lhs, x, Rhs.stringof, rhs);
        return mixin("lhs" ~ x ~ "rhs");
    }
}

///
@system 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;
}

// 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 : 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 $(D T.max) for signed integrals, $(D
    T.max - 1) for unsigned integrals. The minimum value representable is $(D
    T.min + 1) for signed integrals, $(D 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 rhs, T bound)
    {
        return bound;
    }
    /// ditto
    T onUpperBound(Rhs, T)(Rhs 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 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.

    */
    typeof(~Lhs()) onOverflow(string x, Lhs)(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 (unittest) 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 bound)
    {
        ++calls;
        return cast(T) rhs;
    }
    T onUpperBound(Rhs, T)(Rhs rhs, T bound)
    {
        ++calls;
        return cast(T) rhs;
    }
}

version (unittest) private struct CountOpBinary
{
    uint calls;
    auto hookOpBinary(string op, Lhs, Rhs)(Lhs lhs, Rhs rhs)
    {
        ++calls;
        return mixin("lhs" ~ op ~ "rhs");
    }
}

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