
原文原位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;里面有什么基于libcsmemory的(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::vectorbool):每个元素一个位,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/ceilingforeachRange,removeRight消耗前缀区间.4,emplace.map.orderedSet!T,有序集:无值伴集(联/交集/差分/对称差/子集/超集).5,emplace.hashmap.HashMap!(K,V),即unordered_map:开放定位哈希表,带后向移位线性探测删除.6,emplace.hashmap.HashSet!Kunordered_set.每个容器都是RAII和灵针安全的:把元素移动进位置,然后popBack/clear/~this释放每个元素(它的.free()或析构器).所以是一个Vector!(Uniq!T)或Deque!(Shared!T)从不泄漏.每个元素(深度独立复制,Map像std::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 PoolFreeList!(Mallocator,64);示例importemplace.smartptr:Uniq,Shared;importemplace.vector:Vector;nogc nothrow:autoboxUniq!int.make(42);//拥有一个堆整数,在ScopeExit时释放inttakenbox.intoInner();//将值移出(box::into_inner)autorcShared!string.make(hi);autorc2rc;//refcount2,最后为0时释放Vector!ubyte buf;buf.put(cast(const(ubyte)[])hello);//没有每字节循环的一个memcpy