std.internal.scopebuffer

Types 1

structScopeBuffer(T, alias realloc = /*core.stdc.stdlib*/.realloc) if (isAssignable!T && !hasElaborateDestructor!T && !hasElaborateCopyConstructor!T && !hasElaborateAssign!T)
  • 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
  • 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.
Fields
T * buf
uint bufLen
wasResized
uint used
Methods
void free()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...
void put(T c)Append element c to the buffer. This member function makes `ScopeBuffer` an Output Range.
void put(CT[] s)ditto
inout(T)[] opSlice(size_t lower, size_t upper) @system inoutReturns: A slice into the temporary buffer. Warning: The result is only valid until the next `put()` or `ScopeBuffer` goes out of scope.
inout(T)[] opSlice() @system inoutditto
inout(T) opIndex(size_t i) ref inoutReturns: The element at index i.
size_t length() @property constReturns: The number of elements in the `ScopeBuffer`.
void length(size_t i) @propertyUsed 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.
void resize(size_t newsize)
Constructors
this(T[] buf)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); --...

Functions 1

fnauto scopeBuffer(T)(T[] tmpbuf)Creates a `ScopeBuffer` instance using type deduction - see .ScopeBuffer.this for details. Params: tmpbuf = the initial buffer to use Returns: An instance of `ScopeBuffer`.