原文
原位
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)从不泄漏.每个元素(深度独立复制,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 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`