Rework List to allow removing nodes

This commit is contained in:
Josh Holtrop 2023-11-22 20:46:48 -05:00
parent 294500fb70
commit cd9a3a7284

View File

@ -10,55 +10,119 @@ import hulk.hurl.a1;
*/ */
struct List(T) struct List(T)
{ {
/** struct Node
* Linked list item. {
*/ /**
T item; * Linked list node.
*/
T item;
alias item this;
/**
* Next node.
*/
Node * next;
/**
* Previous node.
*/
Node * prev;
}
/** /**
* Next list entry. * Head node.
*/ */
List!T * next; public Node * head;
/**
* Tail node.
*/
public Node * tail;
/** /**
* Add an item to this linked list. * Add an item to this linked list.
*/ */
public void add(T item) public void add(T)(auto ref T item)
{ {
List!T * last_entry = last_entry(); Node * new_node = A1.allocate!Node();
List!T * new_entry = A1.allocate!(List!T)(); new_node.item = item;
last_entry.item = item; new_node.next = null;
last_entry.next = new_entry; new_node.prev = tail;
if (tail != null)
{
tail.next = new_node;
}
tail = new_node;
if (head == null)
{
head = new_node;
}
}
/**
* Remove an item from this linked list.
*/
public void remove(ref Node node)
{
if (node.prev != null)
{
node.prev.next = node.next;
}
else
{
/* Removing the first list node. */
head = node.next;
}
if (node.next != null)
{
node.next.prev = node.prev;
}
else
{
/* Removing the last list node. */
tail = node.prev;
}
}
/**
* Remove an item from this linked list.
*/
public void remove(Node * node)
{
remove(*node);
}
/**
* Get the number of nodes in this list.
*/
public @property size_t count() const
{
size_t count;
const(Node) * node = head;
while (node != null)
{
count++;
node = node.next;
}
return count;
} }
/** /**
* Allow foreach iteration across a List. * Allow foreach iteration across a List.
*/ */
public int opApply(scope int delegate(ref T) dg) public int opApply(scope int delegate(ref Node) dg)
{ {
List!T * entry = &this; Node * node = head;
while (entry.next != null) while (node != null)
{ {
int result = dg(entry.item); Node * current = node;
node = node.next;
int result = dg(*current);
if (result != 0) if (result != 0)
{ {
return result; return result;
} }
entry = entry.next;
} }
return 0; return 0;
} }
/**
* Get the last linked list entry.
*/
private @property List!T * last_entry()
{
List!T * result = &this;
while (result.next != null)
{
result = result.next;
}
return result;
}
} }