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()的区间函数不是不抛的.

.1,你不能两次迭代真输入区间.为此,你需要前向区间.
你不需要迭代区间两次:

//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]);
    }
}

可惜,如果区间内容不适合小缓冲区,此版本会多次分配,但是可通过检测src是否是前向区间或是否定义.length及执行large.reserve或类似操作来避免.

posted @   zjh6  阅读(14)  评论(0编辑  收藏  举报  
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示