/**
 * Implementation of array assignment support routines.
 *
 *
 * Copyright: Copyright Digital Mars 2010 - 2016.
 * License:   Distributed under the
 *            $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost Software License 1.0).
 * Authors:   Walter Bright, Kenji Hara
 * Source:    $(DRUNTIMESRC rt/_arrayassign.d)
 */

module rt.arrayassign;

private
{
    import core.internal.util.array;
    import core.stdc.string;
    import core.stdc.stdlib;
    debug(PRINTF) import core.stdc.stdio;
}

/**
 * Keep for backward binary compatibility. This function can be removed in the future.
 */
extern (C) void[] _d_arrayassign(TypeInfo ti, void[] from, void[] to)
{
    debug(PRINTF) printf("_d_arrayassign(from = %p,%d, to = %p,%d) size = %d\n", from.ptr, from.length, to.ptr, to.length, ti.tsize);

    immutable elementSize = ti.tsize;

    // Need a temporary buffer tmp[] big enough to hold one element
    void[16] buf = void;
    void* ptmp = (elementSize > buf.sizeof) ? malloc(elementSize) : buf.ptr;
    scope (exit)
    {
        if (ptmp != buf.ptr)
            free(ptmp);
    }
    return _d_arrayassign_l(ti, from, to, ptmp);
}

/**
 * Does array assignment (not construction) from another
 * lvalue array of the same element type.
 * Handles overlapping copies.
 * Input:
 *      ti      TypeInfo of the element type.
 *      dst     Points target memory. Its .length is equal to the element count, not byte length.
 *      src     Points source memory. Its .length is equal to the element count, not byte length.
 *      ptmp    Temporary memory for element swapping.
 */
extern (C) void[] _d_arrayassign_l(TypeInfo ti, void[] src, void[] dst, void* ptmp)
{
    debug(PRINTF) printf("_d_arrayassign_l(src = %p,%d, dst = %p,%d) size = %d\n", src.ptr, src.length, dst.ptr, dst.length, ti.tsize);

    immutable elementSize = ti.tsize;

    enforceRawArraysConformable("copy", elementSize, src, dst, true);

    if (src.ptr < dst.ptr && dst.ptr < src.ptr + elementSize * src.length)
    {
        // If dst is in the middle of src memory, use reverse order.
        for (auto i = dst.length; i--; )
        {
            void* pdst = dst.ptr + i * elementSize;
            void* psrc = src.ptr + i * elementSize;
            memcpy(ptmp, pdst, elementSize);
            memcpy(pdst, psrc, elementSize);
            ti.postblit(pdst);
            ti.destroy(ptmp);
        }
    }
    else
    {
        // Otherwise, use normal order.
        foreach (i; 0 .. dst.length)
        {
            void* pdst = dst.ptr + i * elementSize;
            void* psrc = src.ptr + i * elementSize;
            memcpy(ptmp, pdst, elementSize);
            memcpy(pdst, psrc, elementSize);
            ti.postblit(pdst);
            ti.destroy(ptmp);
        }
    }
    return dst;
}

unittest    // Bugzilla 14024
{
    string op;

    struct S
    {
        char x = 'x';
        this(this) { op ~= x-0x20; }    // upper case
        ~this()    { op ~= x; }         // lower case
    }

    S[4] mem;
    ref S[2] slice(int a, int b) { return mem[a .. b][0 .. 2]; }

    op = null;
    mem[0].x = 'a';
    mem[1].x = 'b';
    mem[2].x = 'x';
    mem[3].x = 'y';
    slice(0, 2) = slice(2, 4);  // [ab] = [xy]
    assert(op == "XaYb", op);

    op = null;
    mem[0].x = 'x';
    mem[1].x = 'y';
    mem[2].x = 'a';
    mem[3].x = 'b';
    slice(2, 4) = slice(0, 2);  // [ab] = [xy]
    assert(op == "XaYb", op);

    op = null;
    mem[0].x = 'a';
    mem[1].x = 'b';
    mem[2].x = 'c';
    slice(0, 2) = slice(1, 3);  // [ab] = [bc]
    assert(op == "BaCb", op);

    op = null;
    mem[0].x = 'x';
    mem[1].x = 'y';
    mem[2].x = 'z';
    slice(1, 3) = slice(0, 2);  // [yz] = [xy]
    assert(op == "YzXy", op);
}

/**
 * Does array assignment (not construction) from another
 * rvalue array of the same element type.
 * Input:
 *      ti      TypeInfo of the element type.
 *      dst     Points target memory. Its .length is equal to the element count, not byte length.
 *      src     Points source memory. Its .length is equal to the element count, not byte length.
 *              It is always allocated on stack and never overlapping with dst.
 *      ptmp    Temporary memory for element swapping.
 */
extern (C) void[] _d_arrayassign_r(TypeInfo ti, void[] src, void[] dst, void* ptmp)
{
    debug(PRINTF) printf("_d_arrayassign_r(src = %p,%d, dst = %p,%d) size = %d\n", src.ptr, src.length, dst.ptr, dst.length, ti.tsize);

    immutable elementSize = ti.tsize;

    enforceRawArraysConformable("copy", elementSize, src, dst, false);

    // Always use normal order, because we can assume that
    // the rvalue src has no overlapping with dst.
    foreach (i; 0 .. dst.length)
    {
        void* pdst = dst.ptr + i * elementSize;
        void* psrc = src.ptr + i * elementSize;
        memcpy(ptmp, pdst, elementSize);
        memcpy(pdst, psrc, elementSize);
        ti.destroy(ptmp);
    }
    return dst;
}

/**
 * Does array initialization (not assignment) from another
 * array of the same element type.
 * ti is the element type.
 */
extern (C) void[] _d_arrayctor(TypeInfo ti, void[] from, void[] to)
{
    debug(PRINTF) printf("_d_arrayctor(from = %p,%d, to = %p,%d) size = %d\n", from.ptr, from.length, to.ptr, to.length, ti.tsize);


    auto element_size = ti.tsize;

    enforceRawArraysConformable("initialization", element_size, from, to);

    size_t i;
    try
    {
        for (i = 0; i < to.length; i++)
        {
            // Copy construction is defined as bit copy followed by postblit.
            memcpy(to.ptr + i * element_size, from.ptr + i * element_size, element_size);
            ti.postblit(to.ptr + i * element_size);
        }
    }
    catch (Throwable o)
    {
        /* Destroy, in reverse order, what we've constructed so far
         */
        while (i--)
        {
            ti.destroy(to.ptr + i * element_size);
        }

        throw o;
    }
    return to;
}


/**
 * Do assignment to an array.
 *      p[0 .. count] = value;
 */
extern (C) void* _d_arraysetassign(void* p, void* value, int count, TypeInfo ti)
{
    void* pstart = p;

    auto element_size = ti.tsize;

    // Need a temporary buffer tmp[] big enough to hold one element
    immutable maxAllocaSize = 512;
    void *ptmp = (element_size > maxAllocaSize) ? malloc(element_size) : alloca(element_size);

    foreach (i; 0 .. count)
    {
        memcpy(ptmp, p, element_size);
        memcpy(p, value, element_size);
        ti.postblit(p);
        ti.destroy(ptmp);
        p += element_size;
    }
    if (element_size > maxAllocaSize)
        free(ptmp);
    return pstart;
}

/**
 * Do construction of an array.
 *      ti[count] p = value;
 */
extern (C) void* _d_arraysetctor(void* p, void* value, int count, TypeInfo ti)
{
    void* pstart = p;
    auto element_size = ti.tsize;

    try
    {
        foreach (i; 0 .. count)
        {
            // Copy construction is defined as bit copy followed by postblit.
            memcpy(p, value, element_size);
            ti.postblit(p);
            p += element_size;
        }
    }
    catch (Throwable o)
    {
        // Destroy, in reverse order, what we've constructed so far
        while (p > pstart)
        {
            p -= element_size;
            ti.destroy(p);
        }

        throw o;
    }
    return pstart;
}
