Skip to content

Commit

Permalink
chore(allocator): make and makeArray should allocate aligned memory
Browse files Browse the repository at this point in the history
Signed-off-by: Luís Ferreira <[email protected]>
  • Loading branch information
ljmf00 authored and 0xEAB committed Jan 1, 2025
1 parent 262645b commit 4a09c7d
Showing 1 changed file with 28 additions and 4 deletions.
32 changes: 28 additions & 4 deletions std/experimental/allocator/package.d
Original file line number Diff line number Diff line change
Expand Up @@ -1170,7 +1170,10 @@ auto make(T, Allocator, A...)(auto ref Allocator alloc, auto ref A args)
import std.algorithm.comparison : max;
static if (!is(T == class) && !is(T == interface) && A.length == 0
&& __traits(compiles, {T t;}) && __traits(isZeroInit, T)
&& is(typeof(alloc.allocateZeroed(size_t.max))))
&& is(typeof(alloc.allocateZeroed(size_t.max)))
&& (!is(typeof(alloc.alignedAllocate(size_t.max, uint.max))) ||
( is(typeof(alloc.alignedAllocate(size_t.max, uint.max))) && Allocator.alignment == T.alignof)
))
{
auto m = alloc.allocateZeroed(max(T.sizeof, 1));
return (() @trusted => cast(T*) m.ptr)();
Expand All @@ -1180,7 +1183,22 @@ auto make(T, Allocator, A...)(auto ref Allocator alloc, auto ref A args)
import core.internal.lifetime : emplaceRef;
import core.lifetime : emplace;

auto m = alloc.allocate(max(stateSize!T, 1));
static if (is(typeof(alloc.alignedAllocate(size_t.max, uint.max))))
{
static if(is(T == class))
{
import std.traits : classInstanceAlignment;
auto m = alloc.alignedAllocate(max(stateSize!T, 1), classInstanceAlignment!T);
}
else
{
auto m = alloc.alignedAllocate(max(stateSize!T, 1), T.alignof);
}
}
else
{
auto m = alloc.allocate(max(stateSize!T, 1));
}
if (!m.ptr) return null;

// make can only be @safe if emplace or emplaceRef is `pure`
Expand Down Expand Up @@ -1593,14 +1611,20 @@ T[] makeArray(T, Allocator)(auto ref Allocator alloc, size_t length)
if (overflow) return null;
}

static if (__traits(isZeroInit, T) && hasMember!(Allocator, "allocateZeroed"))
static if (__traits(isZeroInit, T)
&& hasMember!(Allocator, "allocateZeroed")
&& !hasMember!(Allocator, "alignedAllocate")
)
{
auto m = alloc.allocateZeroed(nAlloc);
return (() @trusted => cast(T[]) m)();
}
else
{
auto m = alloc.allocate(nAlloc);
static if (hasMember!(Allocator, "alignedAllocate"))
auto m = alloc.alignedAllocate(nAlloc, T.alignof);
else
auto m = alloc.allocate(nAlloc);
if (!m.ptr) return null;
alias U = Unqual!T;
return () @trusted { return cast(T[]) uninitializedFillDefault(cast(U[]) m); }();
Expand Down

0 comments on commit 4a09c7d

Please sign in to comment.