Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
63 changes: 27 additions & 36 deletions std/internal/scopebuffer.d
Original file line number Diff line number Diff line change
Expand Up @@ -15,18 +15,18 @@ private import std.traits;

/**************************************
* ScopeBuffer encapsulates using a local array as a temporary buffer.
* It is initialized with the local array that should be large enough for
* most uses. If the need exceeds the size, ScopeBuffer will resize it
* using malloc() and friends.
* 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 cannot contain more than `(uint.max-16)/2` elements.
*
* ScopeBuffer is an OutputRange.
* ScopeBuffer is an Output Range.
*
* Since ScopeBuffer potentially stores elements of type T in malloc'd memory,
* 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.
* 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:
---
Expand Down Expand Up @@ -80,15 +80,15 @@ string cat(string s1, string s2)
* $(D scope(exit) textbuf.free();) for proper cleanup, and do not refer to a ScopeBuffer
* instance's contents after $(D ScopeBuffer.free()) has been called.
*
* The realloc parameter defaults to C's realloc(). Another can be supplied to override it.
* 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.
* exceptions, otherwise when `ScopeBuffer.free()` is called, memory may get corrupted.
*/

@system
Expand All @@ -111,9 +111,10 @@ struct ScopeBuffer(T, alias realloc = /*core.stdc.stdlib*/.realloc)
* ubyte[10] tmpbuf = void;
* auto sbuf = ScopeBuffer!ubyte(tmpbuf);
* ---
* 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.
* 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
Expand All @@ -135,7 +136,7 @@ struct ScopeBuffer(T, alias realloc = /*core.stdc.stdlib*/.realloc)

/**************************
* Releases any memory used.
* This will invalidate any references returned by the [] operator.
* 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.
*/
Expand All @@ -149,14 +150,9 @@ struct ScopeBuffer(T, alias realloc = /*core.stdc.stdlib*/.realloc)
used = 0;
}

/****************************
* Copying of ScopeBuffer is not allowed.
*/
//@disable this(this);

/************************
* Append element c to the buffer.
* This member function makes ScopeBuffer an OutputRange.
* This member function makes `ScopeBuffer` an Output Range.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not just delete the docs and the commented out code here

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

now done

*/
void put(T c)
{
Expand All @@ -178,7 +174,7 @@ struct ScopeBuffer(T, alias realloc = /*core.stdc.stdlib*/.realloc)
* If $(D const(T)) can be converted to $(D T), then put will accept
* $(D const(T)[]) as input. It will accept a $(D T[]) otherwise.
*/
private alias CT = Select!(is(const(T) : T), const(T), T);
package alias CT = Select!(is(const(T) : T), const(T), T);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

rationale?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CT has the docs for the following put, which uses ditto. As CT is private, ddoc ignores its docs and the ditto makes put(CT[]) ditto the first overload of put. (Maybe ddoc could be changed to be more helpful here).

/// ditto
void put(CT[] s)
{
Expand All @@ -195,10 +191,10 @@ struct ScopeBuffer(T, alias realloc = /*core.stdc.stdlib*/.realloc)
}

/******
* Retrieve a slice into the result.
* Returns:
* A slice into the temporary buffer that is only
* valid until the next put() or ScopeBuffer goes out of scope.
* 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
Expand All @@ -221,7 +217,7 @@ struct ScopeBuffer(T, alias realloc = /*core.stdc.stdlib*/.realloc)

/*******
* Returns:
* the element at index i.
* The element at index i.
*/
ref inout(T) opIndex(size_t i) inout
{
Expand All @@ -231,7 +227,7 @@ struct ScopeBuffer(T, alias realloc = /*core.stdc.stdlib*/.realloc)

/***
* Returns:
* the number of elements in the ScopeBuffer
* The number of elements in the `ScopeBuffer`.
*/
@property size_t length() const
{
Expand All @@ -240,7 +236,7 @@ struct ScopeBuffer(T, alias realloc = /*core.stdc.stdlib*/.realloc)

/***
* Used to shrink the length of the buffer,
* typically to 0 so the buffer can be reused.
* 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)
Expand Down Expand Up @@ -367,25 +363,20 @@ unittest
}

/*********************************
* This is a slightly simpler way to create a ScopeBuffer instance
* that uses type deduction.
* 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
* Example:
---
ubyte[10] tmpbuf = void;
auto sb = scopeBuffer(tmpbuf);
scope(exit) sp.free();
---
* An instance of `ScopeBuffer`.
*/

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

///
unittest
{
ubyte[10] tmpbuf = void;
Expand Down