On Saturday, 2 July 2016 at 12:26:34 UTC, Andrei Alexandrescu wrote:
How would you reshape this? It's important that the call to hook is physically at the end of the function and issued just in that place, and that the code does not do any redundant work.

Your function does redundant work. E.g. opCast!(int, ubyte) should not require any checks. I also don't understand why opCast!(int, ubyte) is not allowed.

The following code should do the same as yours, but without unnecessary checks:

U opCast(U, T)(T payload)
{
        import std.traits;
        enum Tsizeof = is(T==bool) ? 0 : T.sizeof;
        enum Usizeof = is(U==bool) ? 0 : U.sizeof;
enum noCheck = isUnsigned!T == isUnsigned!U && Tsizeof <= Usizeof ||
                       isUnsigned!T && Tsizeof < Usizeof;
        enum checkPayload = !isUnsigned!T && isUnsigned!U;
        enum checkResult = isUnsigned!T && !isUnsigned!U;
        static if (checkResult)
        {
static assert(U.sizeof <= T.sizeof); // I don't understand this
        }

        if (!checkPayload || payload >= 0)
        {
                auto result = cast(U) payload;
if (noCheck || result == payload && (!checkResult || result >= 0))
                        return result;
        }
        return hook!U(payload);
}

Reply via email to