Rework List to allow removing nodes
This commit is contained in:
parent
294500fb70
commit
cd9a3a7284
116
src/hulk/list.d
116
src/hulk/list.d
@ -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;
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user