天天看點

d無配置設定0終止串

​​原文​​​ 通過傳遞​

​InputRange​

​而不是​

​const(char)​

​給​

​toCStringThen​

​來提供無配置設定​

​0終止串​

​.

//version=AllowMalloc;//.1
auto toCStringThen(alias dg, Range)(Range src) /*nothrow*/ if (isInputRange!Range && !isInfinite!Range) {
    const len = src.walkLength;
    char[512] small = void;
    version(AllowMalloc) {
        import dmd.common.string : SmallBuffer;
        auto sb = SmallBuffer!char(len + 1, small[]);
        scope ptr = sb[];
    } else {
        enforce(len < small.length, format!"C串溢出"(len, small.length));
        scope ptr = small[];
    }
    size_t i = 0;
    foreach (char c; src)
        ptr[i++] = c;
    ptr[len] = '\0';
    return dg(ptr);
}
void main() {
    string path = "include/";
    string name = "file";
    string ext = ".ext";

    auto filename = chain(path, name, ext);
    filename.writeln;
    filename.byChar.toCStringThen!(
        (str) => printf("printf: {%s}\n", str.ptr)
    );
}      

可能需要清理​

​符類型​

​​,且如果允許​

​配置設定​

​​,還需要​

​疊代兩次​

​​,而​

​walkLength/chain()​

​​的區間函數不是​

​不抛​

​的.

//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串緩沖溢出(%s >= %s)"
                .format(i+src.walkLength, small.length-1)
            );
        }
    } else {
        small[i] = '\0';
        return dg(small[0..i]);
    }
}