/*
 * Copyright: 2014 by Digital Mars
 * License: $(LINK2 http://boost.org/LICENSE_1_0.txt, Boost License 1.0).
 * Authors: Walter Bright
 * Source: $(PHOBOSSRC std/internal/scopebuffer.d)
 */

module std.internal.scopebuffer;


//debug=ScopeBuffer;

import core.stdc.stdlib : realloc;
import std.traits;
import std.internal.attributes : betterC;

/**************************************
 * ScopeBuffer encapsulates using a local array as a temporary buffer.
 * It is initialized with a local array that should be large enough for
 * most uses. If the need exceeds that size, ScopeBuffer will reallocate
 * the data using its `realloc` function.
 *
 * ScopeBuffer cannot contain more than `(uint.max-16)/2` elements.
 *
 * ScopeBuffer is an Output Range.
 *
 * Since ScopeBuffer may store elements of type `T` in `malloc`'d memory,
 * those elements are not scanned when the GC collects. This can cause
 * memory corruption. Do not use ScopeBuffer when elements of type `T` point
 * to the GC heap, except when a `realloc` function is provided which supports this.
 *
 * Example:
---
import core.stdc.stdio;
import std.internal.scopebuffer;
void main()
{
    char[2] buf = void;
    auto textbuf = ScopeBuffer!char(buf);
    scope(exit) textbuf.free(); // necessary for cleanup

    // Put characters and strings into textbuf, verify they got there
    textbuf.put('a');
    textbuf.put('x');
    textbuf.put("abc");
    assert(textbuf.length == 5);
    assert(textbuf[1 .. 3] == "xa");
    assert(textbuf[3] == 'b');

    // Can shrink it
    textbuf.length = 3;
    assert(textbuf[0 .. textbuf.length] == "axa");
    assert(textbuf[textbuf.length - 1] == 'a');
    assert(textbuf[1 .. 3] == "xa");

    textbuf.put('z');
    assert(textbuf[] == "axaz");

    // Can shrink it to 0 size, and reuse same memory
    textbuf.length = 0;
}
---
 * It is invalid to access ScopeBuffer's contents when ScopeBuffer goes out of scope.
 * Hence, copying the contents are necessary to keep them around:
---
import std.internal.scopebuffer;
string cat(string s1, string s2)
{
    char[10] tmpbuf = void;
    auto textbuf = ScopeBuffer!char(tmpbuf);
    scope(exit) textbuf.free();
    textbuf.put(s1);
    textbuf.put(s2);
    textbuf.put("even more");
    return textbuf[].idup;
}
---
 * ScopeBuffer is intended for high performance usages in `@system` and `@trusted` code.
 * It is designed to fit into two 64 bit registers, again for high performance use.
 * If used incorrectly, memory leaks and corruption can result. Be sure to use
 * $(D scope(exit) textbuf.free();) for proper cleanup, and do not refer to a ScopeBuffer
 * instance's contents after `ScopeBuffer.free()` has been called.
 *
 * The `realloc` parameter defaults to C's `realloc()`. Another can be supplied to override it.
 *
 * ScopeBuffer instances may be copied, as in:
---
textbuf = doSomething(textbuf, args);
---
 * which can be very efficent, but these must be regarded as a move rather than a copy.
 * Additionally, the code between passing and returning the instance must not throw
 * exceptions, otherwise when `ScopeBuffer.free()` is called, memory may get corrupted.
 */

@system
struct ScopeBuffer(T, alias realloc = /*core.stdc.stdlib*/.realloc)
if (isAssignable!T &&
    !hasElaborateDestructor!T &&
    !hasElaborateCopyConstructor!T &&
    !hasElaborateAssign!T)
{
    import core.exception : onOutOfMemoryError;
    import core.stdc.string : memcpy;


    /**************************
     * Initialize with buf to use as scratch buffer space.
     * Params:
     *  buf = Scratch buffer space, must have length that is even
     * Example:
     * ---
     * ubyte[10] tmpbuf = void;
     * auto sbuf = ScopeBuffer!ubyte(tmpbuf);
     * ---
     * Note:
     * If buf was created by the same `realloc` passed as a parameter
     * to `ScopeBuffer`, then the contents of `ScopeBuffer` can be extracted without needing
     * to copy them, and `ScopeBuffer.free()` will not need to be called.
     */
    this(T[] buf)
        in
        {
            assert(!(buf.length & wasResized));    // assure even length of scratch buffer space
            assert(buf.length <= uint.max);     // because we cast to uint later
        }
    do
    {
        this.buf = buf.ptr;
        this.bufLen = cast(uint) buf.length;
    }

    @system @betterC unittest
    {
        ubyte[10] tmpbuf = void;
        auto sbuf = ScopeBuffer!ubyte(tmpbuf);
    }

    /**************************
     * Releases any memory used.
     * This will invalidate any references returned by the `[]` operator.
     * A destructor is not used, because that would make it not POD
     * (Plain Old Data) and it could not be placed in registers.
     */
    void free()
    {
        debug(ScopeBuffer) buf[0 .. bufLen] = 0;
        if (bufLen & wasResized)
            realloc(buf, 0);
        buf = null;
        bufLen = 0;
        used = 0;
    }

    /************************
     * Append element c to the buffer.
     * This member function makes `ScopeBuffer` an Output Range.
     */
    void put(T c)
    {
        /* j will get enregistered, while used will not because resize() may change used
         */
        const j = used;
        if (j == bufLen)
        {
            assert(j <= (uint.max - 16) / 2);
            resize(j * 2 + 16);
        }
        buf[j] = c;
        used = j + 1;
    }

    /************************
     * Append array s to the buffer.
     *
     * If `const(T)` can be converted to `T`, then put will accept
     * `const(T)[]` as input. It will accept a `T[]` otherwise.
     */
    package alias CT = Select!(is(const(T) : T), const(T), T);
    /// ditto
    void put(CT[] s)
    {
        const newlen = used + s.length;
        assert((cast(ulong) used + s.length) <= uint.max);
        const len = bufLen;
        if (newlen > len)
        {
            assert(len <= uint.max / 2);
            resize(newlen <= len * 2 ? len * 2 : newlen);
        }
        buf[used .. newlen] = s[];
        used = cast(uint) newlen;
    }

    /******
     * Returns:
     *  A slice into the temporary buffer.
     * Warning:
     *  The result is only valid until the next `put()` or `ScopeBuffer` goes out of scope.
     */
    @system inout(T)[] opSlice(size_t lower, size_t upper) inout
        in
        {
            assert(lower <= bufLen);
            assert(upper <= bufLen);
            assert(lower <= upper);
        }
    do
    {
        return buf[lower .. upper];
    }

    /// ditto
    @system inout(T)[] opSlice() inout
    {
        assert(used <= bufLen);
        return buf[0 .. used];
    }

    /*******
     * Returns:
     *  The element at index i.
     */
    ref inout(T) opIndex(size_t i) inout
    {
        assert(i < bufLen);
        return buf[i];
    }

    /***
     * Returns:
     *  The number of elements in the `ScopeBuffer`.
     */
    @property size_t length() const
    {
        return used;
    }

    /***
     * Used to shrink the length of the buffer,
     * typically to `0` so the buffer can be reused.
     * Cannot be used to extend the length of the buffer.
     */
    @property void length(size_t i)
        in
        {
            assert(i <= this.used);
        }
    do
    {
        this.used = cast(uint) i;
    }

    alias opDollar = length;

  private:
    T* buf;
    // Using uint instead of size_t so the struct fits in 2 registers in 64 bit code
    uint bufLen;
    enum wasResized = 1;         // this bit is set in bufLen if we control the memory
    uint used;

    void resize(size_t newsize)
        in
        {
            assert(newsize <= uint.max);
        }
    do
    {
        //writefln("%s: oldsize %s newsize %s", id, buf.length, newsize);
        newsize |= wasResized;
        void *newBuf = realloc((bufLen & wasResized) ? buf : null, newsize * T.sizeof);
        if (!newBuf)
            onOutOfMemoryError();
        if (!(bufLen & wasResized))
        {
            memcpy(newBuf, buf, used * T.sizeof);
            debug(ScopeBuffer) buf[0 .. bufLen] = 0;
        }
        buf = cast(T*) newBuf;
        bufLen = cast(uint) newsize;

        /* This function is called only rarely,
         * inlining results in poorer register allocation.
         */
        version (DigitalMars)
            /* With dmd, a fake loop will prevent inlining.
             * Using a hack until a language enhancement is implemented.
             */
            while (1) { break; }
    }
}

@system @betterC unittest
{
    import core.stdc.stdio;
    import std.range;

    char[2] tmpbuf = void;
    {
    // Exercise all the lines of code except for assert(0)'s
    auto textbuf = ScopeBuffer!char(tmpbuf);
    scope(exit) textbuf.free();

    static assert(isOutputRange!(ScopeBuffer!char, char));

    textbuf.put('a');
    textbuf.put('x');
    textbuf.put("abc");         // tickle put([])'s resize
    assert(textbuf.length == 5);
    assert(textbuf[1 .. 3] == "xa");
    assert(textbuf[3] == 'b');

    textbuf.length = textbuf.length - 1;
    assert(textbuf[0 .. textbuf.length] == "axab");

    textbuf.length = 3;
    assert(textbuf[0 .. textbuf.length] == "axa");
    assert(textbuf[textbuf.length - 1] == 'a');
    assert(textbuf[1 .. 3] == "xa");

    textbuf.put(cast(dchar)'z');
    assert(textbuf[] == "axaz");

    textbuf.length = 0;                 // reset for reuse
    assert(textbuf.length == 0);

    foreach (char c; "asdf;lasdlfaklsdjfalksdjfa;lksdjflkajsfdasdfkja;sdlfj")
    {
        textbuf.put(c); // tickle put(c)'s resize
    }
    assert(textbuf[] == "asdf;lasdlfaklsdjfalksdjfa;lksdjflkajsfdasdfkja;sdlfj");
    } // run destructor on textbuf here

}

@system unittest
{
    string cat(string s1, string s2)
    {
        char[10] tmpbuf = void;
        auto textbuf = ScopeBuffer!char(tmpbuf);
        scope(exit) textbuf.free();
        textbuf.put(s1);
        textbuf.put(s2);
        textbuf.put("even more");
        return textbuf[].idup;
    }

    auto s = cat("hello", "betty");
    assert(s == "hellobettyeven more");
}

// const
@system @betterC unittest
{
    char[10] tmpbuf = void;
    auto textbuf = ScopeBuffer!char(tmpbuf);
    scope(exit) textbuf.free();
    foreach (i; 0 .. 10) textbuf.put('w');
    const csb = textbuf;
    const elem = csb[3];
    const slice0 = csb[0 .. 5];
    const slice1 = csb[];
}

/*********************************
 * Creates a `ScopeBuffer` instance using type deduction - see
 * $(LREF .ScopeBuffer.this) for details.
 * Params:
 *      tmpbuf = the initial buffer to use
 * Returns:
 *      An instance of `ScopeBuffer`.
 */

auto scopeBuffer(T)(T[] tmpbuf)
{
    return ScopeBuffer!T(tmpbuf);
}

///
@system @betterC unittest
{
    ubyte[10] tmpbuf = void;
    auto sb = scopeBuffer(tmpbuf);
    scope(exit) sb.free();
}

@system @betterC unittest
{
    ScopeBuffer!(int*) b;
    int*[] s;
    b.put(s);

    ScopeBuffer!char c;
    string s1;
    char[] s2;
    c.put(s1);
    c.put(s2);
}
