std.internal.scopebuffer
struct ScopeBuffer
fn 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
reallocfunction. - ScopeBuffer cannot contain more than
(uint.max-16)/2elements. - ScopeBuffer is an Output Range.
- Since ScopeBuffer may store elements of type
Tinmalloc'd memory, - those elements are not scanned when the GC collects. This can cause
- memory corruption. Do not use ScopeBuffer when elements of type
Tpoint - to the GC heap, except when a
reallocfunction 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
@systemand@trustedcode. - 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
reallocparameter defaults to C'srealloc(). 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 * bufuint bufLen wasResizeduint usedMethods
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)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)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
fn
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`.