Small-size-optimized Appender

Paul Backus snarwin at gmail.com
Fri Oct 16 20:32:43 UTC 2020


On Friday, 16 October 2020 at 19:06:33 UTC, Per Nordlöw wrote:
> Would appreciated feedback on this small-size-optimized Appender
>
> /** Small-Size-Optimized (SSO) `Appender`.
>  */
> struct SSOAppender(T, size_t smallCapacity)
> if (smallCapacity >= 1)
> {
>     import std.array : Appender;
>     import fixed_array : FixedArray;
>
>     void put(T x) @trusted
>     {
>         if (_isLarge)
>             _large.put(x);

This will call a @system postblit or copy constructor in @safe 
code.

[...]
>     union
>     {
>         Small _small;
>         Large _large;
>     }
>     bool _isLarge;
> }

If you're using a union, you need to define a copy constructor 
and a destructor, because the compiler will not automatically 
insert calls to these functions for your union members.

You could also use a library like sumtype or taggedalgebraic that 
handles these details for you, which would be my recommended 
approach.

> I can inline `FixedArray` into a static array if wanted. It's 
> basically a static array with a length that provides a put API.
>
> Source: 
> https://github.com/nordlow/phobos-next/blob/e914975613e9a5153313acf29b1b183326823ca3/src/nxt/sso_appender.d

FixedArray [1] suffers from the safety issue explained here:

https://gist.github.com/pbackus/39b13e8a2c6aea0e090e4b1fe8046df5#example-short-string

The short version is: because the compiler does not consider an 
integer to be an unsafe type, it will freely allow @safe code to 
corrupt the _length variable, so you must include bounds-checking 
in all of your @trusted code (that is, you must use _store[i] 
instead of _store.ptr[i]).

[1] 
https://github.com/nordlow/phobos-next/blob/e914975613e9a5153313acf29b1b183326823ca3/src/nxt/fixed_array.d#L101


More information about the Digitalmars-d mailing list