diff --git a/std/experimental/allocator/building_blocks/kernighan_ritchie.d b/std/experimental/allocator/building_blocks/kernighan_ritchie.d index f335b6a6500..954067f9f4c 100644 --- a/std/experimental/allocator/building_blocks/kernighan_ritchie.d +++ b/std/experimental/allocator/building_blocks/kernighan_ritchie.d @@ -110,11 +110,13 @@ struct KRRegion(ParentAllocator = NullAllocator) this(this) @disable; + pure nothrow @trusted @nogc void[] payload() inout { return (cast(ubyte*) &this)[0 .. size]; } + pure nothrow @trusted @nogc bool adjacent(in Node* right) const { assert(right); @@ -122,6 +124,7 @@ struct KRRegion(ParentAllocator = NullAllocator) return p.ptr < right && right < p.ptr + p.length + Node.sizeof; } + pure nothrow @trusted @nogc bool coalesce(void* memoryEnd = null) { // Coalesce the last node before the memory end with any possible gap @@ -138,6 +141,7 @@ struct KRRegion(ParentAllocator = NullAllocator) return true; } + @safe Tuple!(void[], Node*) allocateHere(size_t bytes) { assert(bytes >= Node.sizeof); @@ -151,7 +155,7 @@ struct KRRegion(ParentAllocator = NullAllocator) if (leftover >= Node.sizeof) { // There's room for another node - auto newNode = cast(Node*) ((cast(ubyte*) &this) + bytes); + auto newNode = (() @trusted => cast(Node*) ((cast(ubyte*) &this) + bytes))(); newNode.size = leftover; newNode.next = next == &this ? newNode : next; assert(next); @@ -395,6 +399,7 @@ struct KRRegion(ParentAllocator = NullAllocator) Returns: A word-aligned buffer of `n` bytes, or `null`. */ + @safe void[] allocate(size_t n) { if (!n || !root) return null; @@ -412,7 +417,7 @@ struct KRRegion(ParentAllocator = NullAllocator) immutable balance = root.size - actualBytes; if (balance >= Node.sizeof) { - auto newRoot = cast(Node*) (result + actualBytes); + auto newRoot = (() @trusted => cast(Node*) (result + actualBytes))(); newRoot.next = root.next; newRoot.size = balance; root = newRoot; @@ -422,7 +427,7 @@ struct KRRegion(ParentAllocator = NullAllocator) root = null; switchToFreeList; } - return result[0 .. n]; + return (() @trusted => result[0 .. n])(); } // Not enough memory, switch to freelist mode and fall through @@ -755,7 +760,7 @@ it actually returns memory to the operating system when possible. n => KRRegion!GCAllocator(max(n * 16, 1024 * 1024)))()); } -@system unittest +@safe unittest { import std.experimental.allocator.gc_allocator : GCAllocator; @@ -764,7 +769,7 @@ it actually returns memory to the operating system when possible. void[][] array; foreach (i; 1 .. 4) { - array ~= alloc.allocate(i); + array ~= (() nothrow @safe => alloc.allocate(i))(); assert(array[$ - 1].length == i); } () nothrow @nogc { alloc.deallocate(array[1]); }(); @@ -779,7 +784,7 @@ it actually returns memory to the operating system when possible. import std.typecons : Ternary; auto alloc = KRRegion!()( cast(ubyte[])(GCAllocator.instance.allocate(1024 * 1024))); - const store = alloc.allocate(KRRegion!().sizeof); + const store = (() pure nothrow @safe @nogc => alloc.allocate(KRRegion!().sizeof))(); auto p = cast(KRRegion!()* ) store.ptr; import core.stdc.string : memcpy; import std.algorithm.mutation : move; @@ -792,7 +797,7 @@ it actually returns memory to the operating system when possible. foreach (i; 0 .. array.length) { auto length = 100 * i + 1; - array[i] = p.allocate(length); + array[i] = (() pure nothrow @safe @nogc => p.allocate(length))(); assert(array[i].length == length, text(array[i].length)); assert((() pure nothrow @safe @nogc => p.owns(array[i]))() == Ternary.yes); } @@ -821,7 +826,7 @@ it actually returns memory to the operating system when possible. assert(p.length == 1024 * 1024); } -@system unittest +@safe unittest { import std.experimental.allocator.building_blocks; import std.random; @@ -848,7 +853,7 @@ it actually returns memory to the operating system when possible. foreach (size; sizes) { - bufs ~= a.allocate(size); + bufs ~= (() pure nothrow @safe @nogc => a.allocate(size))(); } foreach (b; bufs.randomCover) @@ -863,7 +868,7 @@ it actually returns memory to the operating system when possible. test(sizes32); } -@system unittest +@safe unittest { import std.experimental.allocator.building_blocks; import std.random; @@ -890,11 +895,11 @@ it actually returns memory to the operating system when possible. foreach (size; sizes) { - bufs ~= a.allocate(size); + bufs ~= (() pure nothrow @safe @nogc => a.allocate(size))(); } () nothrow @nogc { a.deallocate(bufs[1]); }(); - bufs ~= a.allocate(sizes[1] - word); + bufs ~= (() pure nothrow @safe @nogc => a.allocate(sizes[1] - word))(); () nothrow @nogc { a.deallocate(bufs[0]); }(); foreach (i; 2 .. bufs.length)