DConf '22: No-Allocated 0-terminated path strings
Krzysztof Jajeśnica
krzysztof.jajesnica at gmail.com
Fri Oct 21 17:22:56 UTC 2022
On Friday, 21 October 2022 at 14:34:47 UTC, ag0aep6g wrote:
> Nitpick: You cannot iterate a true input range twice. You need
> a forward range for that.
Nitpick²: you don't actually need to iterate the range twice
```d
//version=AllowMalloc;
auto toCStringThen(alias dg, Range)(Range src) /*nothrow*/ if
(isInputRange!Range && !isInfinite!Range) {
char[10] small = void;
size_t i = 0;
while(!src.empty && i < small.length) {
small[i++] = src.front;
src.popFront;
}
if(i == small.length) {
version(AllowMalloc) {
import std.container.array;
Array!char large = small[];
large ~= src;
large ~= '\0';
return dg(large.data);
} else {
throw new Exception(
"C string buffer overflow (%s >= %s)"
.format(i+src.walkLength, small.length-1)
);
}
} else {
small[i] = '\0';
return dg(small[0..i]);
}
}
```
Unfortunately this version does multiple allocations if contents
of the range do not fit into the small buffer, but you could
avoid that by detecting if `src` is a forward range/defines
`.length` and doing `large.reserve` or something similar.
More information about the Digitalmars-d-learn
mailing list