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 Node
{
/**
* Linked list item.
* Linked list node.
*/
T item;
alias item this;
/**
* Next list entry.
* Next node.
*/
List!T * next;
Node * next;
/**
* Previous node.
*/
Node * prev;
}
/**
* Head node.
*/
public Node * head;
/**
* Tail node.
*/
public Node * tail;
/**
* 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();
List!T * new_entry = A1.allocate!(List!T)();
last_entry.item = item;
last_entry.next = new_entry;
Node * new_node = A1.allocate!Node();
new_node.item = item;
new_node.next = null;
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.
*/
public int opApply(scope int delegate(ref T) dg)
public int opApply(scope int delegate(ref Node) dg)
{
List!T * entry = &this;
while (entry.next != null)
Node * node = head;
while (node != null)
{
int result = dg(entry.item);
Node * current = node;
node = node.next;
int result = dg(*current);
if (result != 0)
{
return result;
}
entry = entry.next;
}
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;
}
}