remove manual memory management from queue

This commit is contained in:
Cameron Ross 2018-04-20 20:44:53 -03:00
parent 04e2c3baab
commit b16a3338b5
No known key found for this signature in database
GPG key ID: 777897D98DC91C54

View file

@ -47,9 +47,6 @@ struct Queue(T)
/// Cursor pointing to the current node in iteration. /// Cursor pointing to the current node in iteration.
Node* cursor_ = null; Node* cursor_ = null;
/// The first element of a linked list of freed Nodes available for recycling.
Node* freeList_ = null;
/// Length of the queue. /// Length of the queue.
size_t length_ = 0; size_t length_ = 0;
@ -58,20 +55,6 @@ struct Queue(T)
@disable bool opEquals(ref Queue); @disable bool opEquals(ref Queue);
@disable int opCmp(ref Queue); @disable int opCmp(ref Queue);
/// Destroy the queue, deallocating all its elements.
@trusted nothrow ~this()
{
while(!empty) { pop(); }
while(freeList_ !is null)
{
auto toFree = freeList_;
freeList_ = toFree.next_;
free(toFree);
}
cursor_ = last_ = first_ = null;
length_ = 0;
}
/// Start iterating over the queue. /// Start iterating over the queue.
void startIteration() @safe pure nothrow @nogc void startIteration() @safe pure nothrow @nogc
{ {
@ -147,9 +130,6 @@ struct Queue(T)
Node* popped = first_; Node* popped = first_;
first_ = first_.next_; first_ = first_.next_;
Node* oldFree = freeList_;
freeList_ = popped;
freeList_.next_ = oldFree;
if(--length_ == 0) if(--length_ == 0)
{ {
assert(first_ is null); assert(first_ is null);
@ -181,43 +161,6 @@ struct Queue(T)
{ {
return length_; return length_;
} }
private:
/// Get a new (or recycled) node with specified item and next node pointer.
///
/// Tries to reuse a node from freeList_, allocates a new node if not possible.
Node* newNode(ref T item, Node* next) @trusted nothrow
{
if(freeList_ !is null)
{
auto node = freeList_;
freeList_ = freeList_.next_;
*node = Node(item, next);
return node;
}
return allocate!Node(item, next);
}
}
private:
/// Allocate a struct, passing arguments to its constructor or default initializer.
T* allocate(T, Args...)(Args args) @system nothrow
{
T* ptr = cast(T*)malloc(T.sizeof);
*ptr = T(args);
// The struct might contain references to GC-allocated memory, so tell the GC about it.
static if(hasIndirections!T) { GC.addRange(cast(void*)ptr, T.sizeof); }
return ptr;
}
/// Deallocate struct pointed at by specified pointer.
void free(T)(T* ptr) @system nothrow
{
// GC doesn't need to care about any references in this struct anymore.
static if(hasIndirections!T) { GC.removeRange(cast(void*)ptr); }
core.stdc.stdlib.free(ptr);
} }
@safe unittest @safe unittest