On Saturday, 2 July 2016 at 15:15:39 UTC, Guillaume Boucher wrote:
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);
}

I got to something similar (probably with some typos), assuming .sizeof exists:


U opCast(U, T)(T payload)
{
    import std.traits;

    enum unsigned_to_signed =  isUnsigned!T && !isUnsigned!U;
    enum signed_to_unsigned =  !isUnsigned!T && isUnsigned!U;
    enum maybe_to_smaller = T.sizeof >= U.sizeof;
    enum to_smaller = T.sizeof > U.sizeof;

    static assert( !unsigned_to_signed || maybe_to_smaller);

    if( !signed_to_unsigned || to_smaller || payload >= 0 )
    {
        auto result = cast(U) payload;
if (result == payload && !( unsigned_to_signed && result < 0))
            return result;
    }

    return hook!U(payload);
}



Reply via email to