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