Skip to content

Commit

Permalink
Make AllocaAppender forward compatible with current std.experimental.…
Browse files Browse the repository at this point in the history
…allocator.

Up to now, was relying on the old stdx.allocator interface that used IAllocator for passing around allocators as objects. The current version uses RCIAllocator instead.
  • Loading branch information
s-ludwig committed Feb 15, 2024
1 parent dfa4998 commit ae2a541
Showing 1 changed file with 24 additions and 4 deletions.
28 changes: 24 additions & 4 deletions source/vibe/internal/array.d
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@ struct AllocAppender(ArrayType : E[], E) {
ElemType[] m_data;
ElemType[] m_remaining;
IAllocator m_alloc;
static if (is(RCIAllocator))
RCIAllocator m_rcAlloc;
bool m_allocatedBuffer = false;
}

Expand All @@ -56,14 +58,23 @@ struct AllocAppender(ArrayType : E[], E) {
m_remaining = initial_buffer;
}

static if (is(RCIAllocator)) {
this(RCIAllocator alloc, ElemType[] initial_buffer = null)
@safe {
m_rcAlloc = alloc;
m_data = initial_buffer;
m_remaining = initial_buffer;
}
}

@disable this(this);

@property ArrayType data() { return cast(ArrayType)m_data[0 .. m_data.length - m_remaining.length]; }

void reset(AppenderResetMode reset_mode = AppenderResetMode.keepData)
{
if (reset_mode == AppenderResetMode.keepData) m_data = null;
else if (reset_mode == AppenderResetMode.freeData) { if (m_allocatedBuffer) m_alloc.deallocate(m_data); m_data = null; }
else if (reset_mode == AppenderResetMode.freeData) { if (m_allocatedBuffer) withAlloc!"deallocate"(m_data); m_data = null; }
m_remaining = m_data;
}

Expand All @@ -78,7 +89,7 @@ struct AllocAppender(ArrayType : E[], E) {
@safe {
size_t nelems = m_data.length - m_remaining.length;
if (!m_data.length) {
m_data = () @trusted { return cast(ElemType[])m_alloc.allocate(amount*E.sizeof); } ();
m_data = () @trusted { return cast(ElemType[])withAlloc!"allocate"(amount*E.sizeof); } ();
m_remaining = m_data;
m_allocatedBuffer = true;
}
Expand All @@ -89,10 +100,10 @@ struct AllocAppender(ArrayType : E[], E) {
}
if (m_allocatedBuffer) () @trusted {
auto vdata = cast(void[])m_data;
m_alloc.reallocate(vdata, (nelems+amount)*E.sizeof);
withAlloc!"reallocate"(vdata, (nelems+amount)*E.sizeof);
m_data = cast(ElemType[])vdata;
} (); else {
auto newdata = () @trusted { return cast(ElemType[])m_alloc.allocate((nelems+amount)*E.sizeof); } ();
auto newdata = () @trusted { return cast(ElemType[])withAlloc!"allocate"((nelems+amount)*E.sizeof); } ();
newdata[0 .. nelems] = m_data[0 .. nelems];
m_data = newdata;
m_allocatedBuffer = true;
Expand Down Expand Up @@ -173,6 +184,15 @@ struct AllocAppender(ArrayType : E[], E) {
new_size = (new_size * 3) / 2;
reserve(new_size - m_data.length + m_remaining.length);
}

private auto withAlloc(string method, ARGS...)(ARGS args)
{
static if (is(RCIAllocator)) {
if (!m_rcAlloc.isNull) return __traits(getMember, m_rcAlloc, method)(args);
}
if (m_alloc) return __traits(getMember, m_alloc, method)(args);
assert(false, "Using AllocAppender with no allocator set");
}
}

unittest {
Expand Down

0 comments on commit ae2a541

Please sign in to comment.