/**
 * Written in the D programming language.
 * This module provides functions to converting different values to const(ubyte)[]
 *
 * Copyright: Copyright Igor Stepanov 2013-2013.
 * License:   $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).
 * Authors:   Igor Stepanov
 * Source: $(DRUNTIMESRC core/internal/_convert.d)
 */
module core.internal.convert;

/+
A @nogc function can allocate memory during CTFE.
+/
@nogc nothrow pure @trusted
private ubyte[] ctfe_alloc(size_t n)
{
    if (!__ctfe)
    {
        assert(0, "CTFE only");
    }
    else
    {
        static ubyte[] alloc(size_t x) nothrow pure
        {
            if (__ctfe) // Needed to prevent _d_newarray from appearing in compiled prorgam.
                return new ubyte[x];
            else
                assert(0);
        }
        return (cast(ubyte[] function(size_t) @nogc nothrow pure) &alloc)(n);
    }
}

@trusted pure nothrow @nogc
const(ubyte)[] toUbyte(T)(const scope ref T val) if (__traits(isFloating, T) && (is(T : real) || is(T : ireal)))
{
    if (__ctfe)
    {
        static if (floatFormat!T == FloatFormat.Float || floatFormat!T == FloatFormat.Double)
        {
            static if (is(T : ireal)) // https://issues.dlang.org/show_bug.cgi?id=19932
                const f = val.im;
            else
                alias f = val;
            static if (T.sizeof == uint.sizeof)
                uint bits = *cast(const uint*) &f;
            else static if (T.sizeof == ulong.sizeof)
                ulong bits = *cast(const ulong*) &f;
            ubyte[] result = ctfe_alloc(T.sizeof);
            version (BigEndian)
            {
                foreach_reverse (ref b; result)
                {
                    b = cast(ubyte) bits;
                    bits >>= 8;
                }
            }
            else
            {
                foreach (ref b; result)
                {
                    b = cast(ubyte) bits;
                    bits >>= 8;
                }
            }
            return result;
        }
        else static if (floatFormat!T == FloatFormat.DoubleDouble)
        {
            // Parse DoubleDoubles as a pair of doubles.
            // The layout of the type is:
            //
            //   [1|    11    |       52      ][1|    11    |       52       ]
            //   [S| Exponent | Fraction (hi) ][S| Exponent | Fraction (low) ]
            //
            // We can get the least significant bits by subtracting the IEEE
            // double precision portion from the real value.

            import core.math : toPrec;

            ubyte[] buff = ctfe_alloc(T.sizeof);
            enum msbSize = double.sizeof;

            static if (is(T : ireal))
                double hi = toPrec!double(val.im);
            else
                double hi = toPrec!double(val);
            buff[0 .. msbSize] = toUbyte(hi)[];

            if (val is cast(T)0.0 || val is cast(T)-0.0 ||
                val is T.nan || val is -T.nan ||
                val is T.infinity || val > T.max ||
                val is -T.infinity || val < -T.max)
            {
                // Zero, NaN, and Inf are all representable as doubles, so the
                // least significant part can be 0.0.
                buff[msbSize .. $] = 0;
            }
            else
            {
                static if (is(T : ireal))
                    double low = toPrec!double(val.im - hi);
                else
                    double low = toPrec!double(val - hi);
                buff[msbSize .. $] = toUbyte(low)[];
            }

            // Arrays don't index differently between little and big-endian targets.
            return buff;
        }
        else
        {
            auto parsed = parse(val);

            ulong mantissa = parsed.mantissa;
            uint exp = parsed.exponent;
            uint sign = parsed.sign;

            ubyte[] buff = ctfe_alloc(T.sizeof);
            size_t off_bytes = 0;
            size_t off_bits  = 0;
            // Quadruples won't fit in one ulong, so check for that.
            enum mantissaMax = FloatTraits!T.MANTISSA < ulong.sizeof*8 ?
                               FloatTraits!T.MANTISSA : ulong.sizeof*8;

            for (; off_bytes < mantissaMax/8; ++off_bytes)
            {
                buff[off_bytes] = cast(ubyte)mantissa;
                mantissa >>= 8;
            }

            static if (floatFormat!T == FloatFormat.Quadruple)
            {
                ulong mantissa2 = parsed.mantissa2;
                off_bytes--; // go back one, since mantissa only stored data in 56
                             // bits, ie 7 bytes
                for (; off_bytes < FloatTraits!T.MANTISSA/8; ++off_bytes)
                {
                    buff[off_bytes] = cast(ubyte)mantissa2;
                    mantissa2 >>= 8;
                }
            }
            else
            {
                off_bits = FloatTraits!T.MANTISSA%8;
                buff[off_bytes] = cast(ubyte)mantissa;
            }

            for (size_t i=0; i<FloatTraits!T.EXPONENT/8; ++i)
            {
                ubyte cur_exp = cast(ubyte)exp;
                exp >>= 8;
                buff[off_bytes] |= (cur_exp << off_bits);
                ++off_bytes;
                buff[off_bytes] |= cur_exp >> 8 - off_bits;
            }


            exp <<= 8 - FloatTraits!T.EXPONENT%8 - 1;
            buff[off_bytes] |= exp;
            sign <<= 7;
            buff[off_bytes] |= sign;

            version (BigEndian)
            {
                for (size_t left = 0, right = buff.length - 1; left < right; left++, right--)
                {
                    const swap = buff[left];
                    buff[left] = buff[right];
                    buff[right] = swap;
                }
            }
            return buff;
        }
    }
    else
    {
        return (cast(const(ubyte)*)&val)[0 .. T.sizeof];
    }
}

@safe pure nothrow @nogc
private Float parse(bool is_denormalized = false, T:ireal)(T x)
{
    return parse(x.im);
}

@safe pure nothrow @nogc
private Float parse(bool is_denormalized = false, T:real)(T x_) if (floatFormat!T != FloatFormat.Real80)
{
    import core.internal.traits : Unqual;
    Unqual!T x = x_;
    static assert(floatFormat!T != FloatFormat.DoubleDouble,
           "doubledouble float format not supported in CTFE");
    if (x is cast(T)0.0) return FloatTraits!T.ZERO;
    if (x is cast(T)-0.0) return FloatTraits!T.NZERO;
    if (x is T.nan) return FloatTraits!T.NAN;
    if (x is -T.nan) return FloatTraits!T.NNAN;
    if (x is T.infinity || x > T.max) return FloatTraits!T.INF;
    if (x is -T.infinity || x < -T.max) return FloatTraits!T.NINF;

    uint sign = x < 0;
    x = sign ? -x : x;
    int e = binLog2(x);
    real x2 = x;
    uint exp = cast(uint)(e + (2^^(FloatTraits!T.EXPONENT-1) - 1));

    if (!exp)
    {
        if (is_denormalized)
            return Float(0, 0, sign);
        else
            return denormalizedMantissa(x, sign);
    }

    x2 /= binPow2(e);

    static if (!is_denormalized)
        x2 -= 1.0;

    static if (floatFormat!T == FloatFormat.Quadruple)
    {
        // Store the 112-bit mantissa in two ulongs, specifically the lower 56
        // bits of each, with the most significant bits in mantissa2. There's
        // an edge case exposed by the labeled test below, where only a subnormal
        // with the highest bit set being the 57th bit will "overflow" to the
        // 57th bit in mantissa2 with the following logic, but that special case
        // is handled by an additional check in denormalizedMantissa for
        // Quadruples below.

        x2 *=  2UL<<(FloatTraits!T.MANTISSA - (ulong.sizeof - 1)*8 - 1);
        ulong mant2 = cast(ulong) x2;
        x2 -= mant2;

        x2 *=  2UL<<((ulong.sizeof - 1)*8 - 1);
        ulong mant = cast(ulong) x2;
        return Float(mant, exp, sign, mant2);
    }
    else
    {
        x2 *=  2UL<<(FloatTraits!T.MANTISSA);
        ulong mant = shiftrRound(cast(ulong)x2);
        return Float(mant, exp, sign);
    }
}

@safe pure nothrow @nogc
private Float parse(bool _ = false, T:real)(T x_) if (floatFormat!T == FloatFormat.Real80)
{
    import core.internal.traits : Unqual;
    Unqual!T x = x_;
    //HACK @@@3632@@@

    if (x == 0.0L)
    {
        real y = 1.0L/x;
        if (y == real.infinity) // -0.0
            return FloatTraits!T.ZERO;
        else
            return FloatTraits!T.NZERO; //0.0
    }

    if (x != x) //HACK: should be if (x is real.nan) and if (x is -real.nan)
    {
        auto y = cast(double)x;
        if (y is double.nan)
            return FloatTraits!T.NAN;
        else
            return FloatTraits!T.NNAN;
    }

    if (x == real.infinity) return FloatTraits!T.INF;
    if (x == -real.infinity) return FloatTraits!T.NINF;

    enum EXPONENT_MED = (2^^(FloatTraits!T.EXPONENT-1) - 1);
    uint sign = x < 0;
    x = sign ? -x : x;

    int e = binLog2(x);
    uint exp = cast(uint)(e + EXPONENT_MED);
    if (!exp)
    {
        return denormalizedMantissa(x, sign);
    }
    int pow = (FloatTraits!T.MANTISSA-1-e);
    x *=  binPow2((pow / EXPONENT_MED)*EXPONENT_MED); //To avoid overflow in 2.0L ^^ pow
    x *=  binPow2(pow % EXPONENT_MED);
    ulong mant = cast(ulong)x;
    return Float(mant, exp, sign);
}

private struct Float
{
    ulong mantissa;
    uint exponent;
    uint sign;
    ulong mantissa2;
}

private template FloatTraits(T) if (floatFormat!T == FloatFormat.Float)
{
    enum DATASIZE = 4;
    enum EXPONENT = 8;
    enum MANTISSA = 23;
    enum ZERO     = Float(0, 0, 0);
    enum NZERO    = Float(0, 0, 1);
    enum NAN      = Float(0x400000UL, 0xff, 0);
    enum NNAN     = Float(0x400000UL, 0xff, 1);
    enum INF      = Float(0, 255, 0);
    enum NINF     = Float(0, 255, 1);
}

private template FloatTraits(T) if (floatFormat!T == FloatFormat.Double)
{
    enum DATASIZE = 8;
    enum EXPONENT = 11;
    enum MANTISSA = 52;
    enum ZERO     = Float(0, 0, 0);
    enum NZERO    = Float(0, 0, 1);
    enum NAN      = Float(0x8000000000000UL, 0x7ff, 0);
    enum NNAN     = Float(0x8000000000000UL, 0x7ff, 1);
    enum INF      = Float(0, 0x7ff, 0);
    enum NINF     = Float(0, 0x7ff, 1);
}

private template FloatTraits(T) if (floatFormat!T == FloatFormat.Real80)
{
    enum DATASIZE = 10;
    enum EXPONENT = 15;
    enum MANTISSA = 64;
    enum ZERO     = Float(0, 0, 0);
    enum NZERO    = Float(0, 0, 1);
    enum NAN      = Float(0xC000000000000000UL, 0x7fff, 0);
    enum NNAN     = Float(0xC000000000000000UL, 0x7fff, 1);
    enum INF      = Float(0x8000000000000000UL, 0x7fff, 0);
    enum NINF     = Float(0x8000000000000000UL, 0x7fff, 1);
}

private template FloatTraits(T) if (floatFormat!T == FloatFormat.DoubleDouble) //Unsupported in CTFE
{
    enum DATASIZE = 16;
    enum EXPONENT = 11;
    enum MANTISSA = 106;
    enum ZERO     = Float(0, 0, 0);
    enum NZERO    = Float(0, 0, 1);
    enum NAN      = Float(0x8000000000000UL, 0x7ff, 0);
    enum NNAN     = Float(0x8000000000000UL, 0x7ff, 1);
    enum INF      = Float(0, 0x7ff, 0);
    enum NINF     = Float(0, 0x7ff, 1);
}

private template FloatTraits(T) if (floatFormat!T == FloatFormat.Quadruple)
{
    enum DATASIZE = 16;
    enum EXPONENT = 15;
    enum MANTISSA = 112;
    enum ZERO     = Float(0, 0, 0);
    enum NZERO    = Float(0, 0, 1);
    enum NAN      = Float(0, 0x7fff, 0, 0x80000000000000UL);
    enum NNAN     = Float(0, 0x7fff, 1, 0x80000000000000UL);
    enum INF      = Float(0, 0x7fff, 0);
    enum NINF     = Float(0, 0x7fff, 1);
}


@safe pure nothrow @nogc
private real binPow2(int pow)
{
    static real binPosPow2(int pow) @safe pure nothrow @nogc
    {
        assert(pow > 0);

        if (pow == 1) return 2.0L;

        int subpow = pow/2;
        real p = binPosPow2(subpow);
        real ret = p*p;

        if (pow%2)
        {
            ret *= 2.0L;
        }

        return ret;
    }

    if (!pow) return 1.0L;
    if (pow > 0) return binPosPow2(pow);
    return 1.0L/binPosPow2(-pow);
}


//Need in CTFE, because CTFE float and double expressions computed more precisely that run-time expressions.
@safe pure nothrow @nogc
private ulong shiftrRound(ulong x)
{
    return (x >> 1) + (x & 1);
}

@safe pure nothrow @nogc
private uint binLog2(T)(const T x)
{
    assert(x > 0);
    int max = 2 ^^ (FloatTraits!T.EXPONENT-1)-1;
    int min = -max+1;
    int med = (min + max) / 2;

    if (x < T.min_normal) return -max;

    while ((max - min) > 1)
    {
        if (binPow2(med) > x)
        {
            max = med;
        }
        else
        {
            min = med;
        }
        med = (min + max) / 2;
    }

    if (x < binPow2(max))
        return min;
    return max;
}

@safe pure nothrow @nogc
private Float denormalizedMantissa(T)(T x, uint sign) if (floatFormat!T == FloatFormat.Real80)
{
    x *= 2.0L^^FloatTraits!T.MANTISSA;
    auto fl = parse(x);
    uint pow = FloatTraits!T.MANTISSA - fl.exponent + 1;
    return Float(fl.mantissa >> pow, 0, sign);
}

@safe pure nothrow @nogc
private Float denormalizedMantissa(T)(T x, uint sign)
    if (floatFormat!T == FloatFormat.Float || floatFormat!T == FloatFormat.Double)
{
    x *= 2.0L^^FloatTraits!T.MANTISSA;
    auto fl = parse!true(x);
    ulong mant = fl.mantissa >> (FloatTraits!T.MANTISSA - fl.exponent);
    return Float(shiftrRound(mant), 0, sign);
}

@safe pure nothrow @nogc
private Float denormalizedMantissa(T)(T x, uint sign) if (floatFormat!T == FloatFormat.Quadruple)
{
    x *= 2.0L^^FloatTraits!T.MANTISSA;
    auto fl = parse!true(x);
    uint offset = FloatTraits!T.MANTISSA - fl.exponent + 1;
    enum mantissaSize = (ulong.sizeof - 1) * 8;

    if (offset < mantissaSize)
    {   // Create a new mantissa ulong with the trailing mantissa2 bits that
        // need to be shifted into mantissa, by shifting the needed bits left,
        // zeroing out the first byte, and then ORing it with mantissa shifted
        // right by offset.

        ulong shiftedMantissa = ((fl.mantissa2 << (mantissaSize - offset)) &
                                 0x00FFFFFFFFFFFFFFUL) | fl.mantissa >> offset;
        return Float(shiftedMantissa, 0, sign, fl.mantissa2 >> offset);
    }
    else if (offset > mantissaSize)
        return Float(fl.mantissa2 >> offset - mantissaSize , 0, sign, 0);
    else
        // Handle special case mentioned in parse() above by zeroing out the
        // 57'th bit of mantissa2, "shifting" it into mantissa, and setting the
        // first bit of mantissa2.
        return Float(fl.mantissa2 & 0x00FFFFFFFFFFFFFFUL , 0, sign, 1);
}

@system unittest
{
    static const(ubyte)[] toUbyte2(T)(T val)
    {
        return toUbyte(val).dup;
    }

    static void testNumberConvert(string v)()
    {
        enum ctval = mixin(v);

        alias TYPE = typeof(ctval);
        auto rtval = ctval;
        auto rtbytes = *cast(ubyte[TYPE.sizeof]*)&rtval;

        enum ctbytes = toUbyte2(ctval);

        // don't test pad bytes because can be anything
        enum testsize =
            (FloatTraits!TYPE.EXPONENT + FloatTraits!TYPE.MANTISSA + 1)/8;
        assert(rtbytes[0..testsize] == ctbytes[0..testsize]);
    }

    static void testConvert()
    {
        /**Test special values*/
        testNumberConvert!("-float.infinity");
        testNumberConvert!("float.infinity");
        testNumberConvert!("-0.0F");
        testNumberConvert!("0.0F");
        //testNumberConvert!("-float.nan"); //BUG @@@3632@@@
        testNumberConvert!("float.nan");

        testNumberConvert!("-double.infinity");
        testNumberConvert!("double.infinity");
        testNumberConvert!("-0.0");
        testNumberConvert!("0.0");
        //testNumberConvert!("-double.nan"); //BUG @@@3632@@@
        testNumberConvert!("double.nan");

        testNumberConvert!("-real.infinity");
        testNumberConvert!("real.infinity");
        testNumberConvert!("-0.0L");
        testNumberConvert!("0.0L");
        //testNumberConvert!("-real.nan"); //BUG @@@3632@@@
        testNumberConvert!("real.nan");

        /**
            Test min and max values values: min value has an '1' mantissa and minimal exponent,
            Max value has an all '1' bits mantissa and max exponent.
        */
        testNumberConvert!("float.min_normal");
        testNumberConvert!("float.max");

        /**Test common values*/
        testNumberConvert!("-0.17F");
        testNumberConvert!("3.14F");

        /**Test immutable and const*/
        testNumberConvert!("cast(const)3.14F");
        testNumberConvert!("cast(immutable)3.14F");

        /**The same tests for double and real*/
        testNumberConvert!("double.min_normal");
        testNumberConvert!("double.max");
        testNumberConvert!("-0.17");
        testNumberConvert!("3.14");
        testNumberConvert!("cast(const)3.14");
        testNumberConvert!("cast(immutable)3.14");

        testNumberConvert!("real.min_normal");
        testNumberConvert!("real.max");
        testNumberConvert!("-0.17L");
        testNumberConvert!("3.14L");
        testNumberConvert!("cast(const)3.14L");
        testNumberConvert!("cast(immutable)3.14L");

        /**Test denormalized values*/

        /**Max denormalized value, first bit is 1*/
        testNumberConvert!("float.min_normal/2");
        /**Min denormalized value, last bit is 1*/
        testNumberConvert!("float.min_normal/2UL^^23");

        /**Denormalized values with round*/
        testNumberConvert!("float.min_normal/19");
        testNumberConvert!("float.min_normal/17");

        testNumberConvert!("double.min_normal/2");
        testNumberConvert!("double.min_normal/2UL^^52");
        testNumberConvert!("double.min_normal/19");
        testNumberConvert!("double.min_normal/17");

        testNumberConvert!("real.min_normal/2");
        testNumberConvert!("real.min_normal/2UL^^63");
        // check subnormal storage edge case for Quadruple
        testNumberConvert!("real.min_normal/2UL^^56");
        testNumberConvert!("real.min_normal/19");
        testNumberConvert!("real.min_normal/17");

        /**True random values*/
        testNumberConvert!("-0x9.0f7ee55df77618fp-13829L");
        testNumberConvert!("0x7.36e6e2640120d28p+8797L");
        testNumberConvert!("-0x1.05df6ce4702ccf8p+15835L");
        testNumberConvert!("0x9.54bb0d88806f714p-7088L");

        testNumberConvert!("-0x9.0f7ee55df7ffp-338");
        testNumberConvert!("0x7.36e6e264012dp+879");
        testNumberConvert!("-0x1.05df6ce4708ep+658");
        testNumberConvert!("0x9.54bb0d888061p-708");

        testNumberConvert!("-0x9.0f7eefp-101F");
        testNumberConvert!("0x7.36e6ep+87F");
        testNumberConvert!("-0x1.05df6p+112F");
        testNumberConvert!("0x9.54bb0p-70F");

        /**Big overflow or underflow*/
        testNumberConvert!("cast(double)-0x9.0f7ee55df77618fp-13829L");
        testNumberConvert!("cast(double)0x7.36e6e2640120d28p+8797L");
        testNumberConvert!("cast(double)-0x1.05df6ce4702ccf8p+15835L");
        testNumberConvert!("cast(double)0x9.54bb0d88806f714p-7088L");

        testNumberConvert!("cast(float)-0x9.0f7ee55df77618fp-13829L");
        testNumberConvert!("cast(float)0x7.36e6e2640120d28p+8797L");
        testNumberConvert!("cast(float)-0x1.05df6ce4702ccf8p+15835L");
        testNumberConvert!("cast(float)0x9.54bb0d88806f714p-7088L");
    }

    testConvert();
}



private enum FloatFormat
{
    Float,
    Double,
    Real80,
    DoubleDouble,
    Quadruple
}

template floatFormat(T) if (is(T:real) || is(T:ireal))
{
    static if (T.mant_dig == 24)
        enum floatFormat = FloatFormat.Float;
    else static if (T.mant_dig == 53)
    {
        // Double precision, or real == double
        static if (T.sizeof == double.sizeof)
            enum floatFormat = FloatFormat.Double;
        // 80-bit real with rounding precision set to 53 bits.
        else static if (T.sizeof == real.sizeof)
            enum floatFormat = FloatFormat.Real80;
    }
    else static if (T.mant_dig == 64)
        enum floatFormat = FloatFormat.Real80;
    else static if (T.mant_dig == 106)
        enum floatFormat = FloatFormat.DoubleDouble;
    else static if (T.mant_dig == 113)
        enum floatFormat = FloatFormat.Quadruple;
    else
        static assert(0);

}

package template floatSize(T) if (is(T:real) || is(T:ireal))
{
    enum floatSize = FloatTraits!(T).DATASIZE;
}

//  all toUbyte functions must be evaluable at compile time
@trusted pure nothrow @nogc
const(ubyte)[] toUbyte(T)(return scope const T[] arr) if (T.sizeof == 1)
{
    pragma(inline, true);
    return cast(const(ubyte)[])arr;
}

private const(ubyte)[] toUbyte_array_ctfe(T)(return scope const T[] arr)
{
    pragma(inline, false);
    ubyte[] ret = ctfe_alloc(T.sizeof * arr.length);
    static if (is(T EType == enum)) // Odd style is to avoid template instantiation in most cases.
        alias E = OriginalType!EType;
    else
        alias E = T;
    static if (is(E == struct) || is(E == union) || __traits(isStaticArray, E) || !is(typeof(arr[0] is null)))
    {
        size_t offset = 0;
        foreach (ref cur; arr)
        {
            ret[offset .. offset + T.sizeof] = toUbyte(cur)[0 .. T.sizeof];
            offset += T.sizeof;
        }
    }
    else
    {
        foreach (cur; arr)
            assert(cur is null, "Unable to compute byte representation of non-null pointer at compile time");
    }
    return ret;
}

@trusted pure nothrow @nogc
const(ubyte)[] toUbyte(T)(return scope const T[] arr) if (T.sizeof > 1)
{
    pragma(inline, true);
    return __ctfe ? toUbyte_array_ctfe(arr)
                  : (cast(const(ubyte)*)(arr.ptr))[0 .. T.sizeof*arr.length];
}

private const(ubyte)[] toUbyte_integral_ctfe(T)(const return ref scope T val)
{
    pragma(inline, false);
    static if (T.sizeof == 1)
    {
        ubyte[] result = ctfe_alloc(1);
        result[0] = cast(ubyte) val;
        return result;
    }
    else
    {
        import core.internal.traits : Unqual;
        ubyte[] tmp = ctfe_alloc(T.sizeof);
        Unqual!T val_ = val;
        for (size_t i = 0; i < T.sizeof; ++i)
        {
            size_t idx;
            version (LittleEndian) idx = i;
            else idx = T.sizeof-i-1;
            tmp[idx] = cast(ubyte)(val_&0xff);
            val_ >>= 8;
        }
        return tmp;
    }
}

@trusted pure nothrow @nogc
const(ubyte)[] toUbyte(T)(const ref scope T val) if (__traits(isIntegral, T) && !is(T == enum) && !is(T == __vector))
{
    pragma(inline, true);
    return __ctfe ? toUbyte_integral_ctfe(val)
                  : (cast(const ubyte*) &val)[0 .. T.sizeof];
}

private const(ubyte)[] toUbyte_vector_ctfe(T)(const return ref scope T val)
{
    pragma(inline, false);
    static if (is(typeof(val[0]) : void))
        assert(0, "Unable to compute byte representation of " ~ T.stringof ~ " at compile time.");
    else
    {
        // This code looks like it should work in CTFE but it segfaults:
        //    auto a = val.array;
        //    return toUbyte(a);
        alias E = typeof(val[0]);
        ubyte[] result = ctfe_alloc(T.sizeof);
        for (size_t i = 0, j = 0; i < T.sizeof; i += E.sizeof, ++j)
        {
            result[i .. i + E.sizeof] = toUbyte(val[j]);
        }
        return result;
    }
}

@trusted pure nothrow @nogc
const(ubyte)[] toUbyte(T)(const ref scope T val) if (is(T == __vector))
{
    pragma(inline, true);
    return __ctfe ? toUbyte_vector_ctfe(val)
                  : (cast(const ubyte*) &val)[0 .. T.sizeof];
}

private const(ubyte)[] toUbyte_enum_ctfe(T)(const return ref scope T val)
{
    pragma(inline, false);
    static if (is(T V == enum)){}
    return toUbyte(*cast(const V*) &val);
}

@trusted pure nothrow @nogc
const(ubyte)[] toUbyte(T)(const ref return scope T val) if (is(T == enum))
{
    pragma(inline, true);
    return __ctfe ? toUbyte_enum_ctfe(val)
                  : (cast(const(ubyte)*)&val)[0 .. T.sizeof];
}

nothrow pure @safe unittest
{
    // Issue 19008 - check toUbyte works on enums.
    enum Month : uint { jan = 1}
    Month m = Month.jan;
    const bytes = toUbyte(m);
    enum ctfe_works = (() { Month x = Month.jan; return toUbyte(x).length > 0; })();
}

private const(ubyte)[] toUbyte_delegate_ctfe(T)(const return ref scope T val)
{
    pragma(inline, false);
    if (val !is null) assert(0, "Unable to compute byte representation of non-null pointer at compile time");
    return ctfe_alloc(T.sizeof);
}

@trusted pure nothrow @nogc
const(ubyte)[] toUbyte(T)(const ref T val) if (is(T == delegate) || is(T : V*, V) && __traits(getAliasThis, T).length == 0)
{
    pragma(inline, true);
    return __ctfe ? toUbyte_delegate_ctfe(val)
                  : (cast(const(ubyte)*)&val)[0 .. T.sizeof];
}

private const(ubyte)[] toUbyte_aggregate_ctfe(T)(const return ref scope T val)
{
    pragma(inline, false);
    ubyte[] bytes = ctfe_alloc(T.sizeof);
    foreach (key, ref cur; val.tupleof)
    {
        static if (is(typeof(cur) EType == enum)) // Odd style is to avoid template instantiation in most cases.
            alias CurType = OriginalType!EType;
        else
            alias CurType = typeof(cur);
        static if (is(CurType == struct) || is(CurType == union) || __traits(isStaticArray, CurType) || !is(typeof(cur is null)))
        {
            bytes[val.tupleof[key].offsetof .. val.tupleof[key].offsetof + CurType.sizeof] = toUbyte(cur)[];
        }
        else
        {
            assert(cur is null, "Unable to compute byte representation of non-null reference field at compile time");
            //skip, because val bytes are zeros
        }
    }
    return bytes;
}

@trusted pure nothrow @nogc
const(ubyte)[] toUbyte(T)(const return ref scope T val) if (is(T == struct) || is(T == union))
{
    pragma(inline, true);
    return __ctfe ? toUbyte_aggregate_ctfe(val)
                  : (cast(const(ubyte)*)&val)[0 .. T.sizeof];
}

// Strips off all `enum`s from type `T`.
// Perhaps move to core.internal.types.
private template OriginalType(T)
{
    static if (is(T EType == enum))
        alias OriginalType = .OriginalType!EType;
    else
        alias OriginalType = T;
}
