2607d,原位

📅 2026/7/19 2:08:47 👁️ 阅读次数 📝 编程学习
2607d,原位

原文

原位

D的C++级,无GC数据结构和灵针.

如今写@nogcD一般表示回到C主义,原始指针,手动分配/释放,手动操作的容器.
原位改进了这一空白:你期望C++的容器和灵针<memory>/<vector>/<map>,分配器相关(std.experimental.allocator),分配器在当前的LDC/DMD正确@nogc.

安装

dub add emplaceimportemplace.smartptr:Uniq,Shared,Weak;importemplace.vector:Vector;importemplace.map:Map,OrderedSet;

里面有什么

基于libc++s<memory>(emplace.smartptr)灵针

1,Uniq!(T, Alloc = Mallocator),即"unique_ptr:单一物主,仅移动,加上Rust风格的借取/取(Option::take)/intoInner(box::into_inner).
2,Shared!(T, Alloc = Mallocator)shared_ptr:引用计数,复制增加计数,带弱计数make_shared内联控制块(一次分配).
3,Weak!(T, Alloc = Mallocator)weak_ptr:非物主观察者,锁()/过期,lock() / expired.

容器

1,emplace.vector.Vector!(T, Alloc = Mallocator),是一个动态数组;块put(slice)是个单一的memcpy(不是每个元素的循环).
ShrinkToFit(shrink_to_fit).'Vector!bool'位打包(std::vector<bool>):每个元素一个位,opIndex返回一个可赋值的代理位引用.

2,emplace.deque.Deque!(T, Alloc = Mallocator),是一个双端队列:一个在连续块上的环形缓冲,O(1)两端压/弹,O(1)随机访问.
内存耗尽时释放(在1/4负载时减半容量,空时释放),对长期运行的先进先出(FIFO)来说安全.

3,'emplace.map.map!'(K,V)',一个基于手动操作红黑树的有序映射O(logn)插入/查找/移除,排序迭代,leftBound/rightBound,floor/ceiling+foreachRange,removeRight消耗前缀区间.

4,'emplace.map.orderedSet!T',有序集:无值伴集(联/交集/差分/对称差/子集/超集).

5,'emplace.hashmap.HashMap!'(K,V)',即unordered_map:开放定位哈希表,带后向移位线性探测删除.
6,'emplace.hashmap.HashSet!K'unordered_set.

每个容器都是RAII灵针安全的:把元素移动进位置,然后popBack/clear/~this释放每个元素(它的.free()析构器).
所以是一个Vector!(Uniq!T)Deque!(Shared!T)从不泄漏.每个元素(深度独立复制,Mapstd::map一样深度复制其树)都可精确复制;

仅移动类型的元素(如Uniq)使整个容器仅移动,因此按位复制不能两次释放.都有D区间(opSlice).

分配器

所有参数都用std.experimental.allocator分配器来参数化,默认使用Mallocator.属性是推导的,因此在Mallocator下,都是``@nogc nothrow;
GCAllocator,FreeList,Region,InSituRegion,或你的,不变.

importstd.experimental.allocator.building_blocks.free_list:FreeList;importstd.experimental.allocator.mallocator:Mallocator;//节点池:在`基准测试`中,每次分配比`分配malloc`便宜`~10-16`倍alias Pool=FreeList!(Mallocator,64);

示例

importemplace.smartptr:Uniq,Shared;importemplace.vector:Vector;@nogc nothrow:autobox=Uniq!int.make(42);//拥有一个堆整数,在`ScopeExit`时释放inttaken=box.intoInner();//将值移出(`box::into_inner`)autorc=Shared!string.make("hi");autorc2=rc;//`refcount==2`,最后为0时释放Vector!ubyte buf;buf.put(cast(const(ubyte)[])"hello");//没有每字节循环的一个`memcpy`