std.internal.scopebuffer
Types 1
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.
T * bufuint bufLen1 wasResizeduint usedvoid 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)dittoinout(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.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)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
auto 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`.