1 /// module containing a doubly linked list class
2 module ydlib.list;
3 
4 /// linked node class
5 class ListNode(T) {
6 	/// value before this entry
7 	ListNode!T previous;
8 	/// value of this entry
9 	T value;
10 	/// value next to this entry
11 	ListNode!T next;
12 
13 	private List!T parent;
14 
15 	this() {
16 		
17 	}
18 
19 	this(T pvalue) {
20 		value = pvalue;
21 	}
22 
23 	/// gets the last entry in the list
24 	ListNode!T GetLastEntry() {
25 		ListNode!T current = this;
26 
27 		while (current.next !is null) {
28 			current = current.next;
29 		}
30 
31 		return current;
32 	}
33 
34 	/// appends the value to the end of the list
35 	void opOpAssign(string op: "~")(T pvalue) {
36 		auto last = GetLastEntry();
37 
38 		last.next          = new ListNode!T(pvalue);
39 		last.next.parent   = parent;
40 		last.next.previous = last;
41 	}
42 
43 	/// inserts a value after this entry
44 	void InsertAfter(List!T pparent, T value) {
45 		auto oldNext = next;
46 
47 		next             = new ListNode!T(value);
48 		next.parent      = pparent;
49 		next.next        = oldNext;
50 		oldNext.previous = next;
51 		next.previous    = this;
52 	}
53 
54 	/// inserts a value before this entry
55 	void InsertBefore(List!T pparent, T value) {
56 		auto oldPrev = previous;
57 
58 		previous          = new ListNode!T(value);
59 		previous.parent   = pparent;
60 		previous.previous = oldPrev;
61 		previous.next     = this;
62 
63 		if (oldPrev is null) {
64 			pparent.head = previous;
65 		}
66 		else {
67 			oldPrev.next = previous;
68 		}
69 	}
70 }
71 
72 /// linked list class
73 class List(T) {
74 	ListNode!T head;
75 
76 	this() {
77 		
78 	}
79 
80 	/// appends the value to the end of the list
81 	void opOpAssign(string op: "~")(T value) {
82 		if (head is null) {
83 			head        = new ListNode!T(value);
84 			head.parent = this;
85 		}
86 		else {
87 			head ~= value;
88 		}
89 	}
90 
91 	/// overrides foreach loops
92 	int opApply(scope int delegate(ListNode!T value) dg) {
93 		ListNode!T current = head;
94 
95 		while (current !is null) {
96 			int result = dg(current);
97 
98 			if (result) {
99 				return result;
100 			}
101 			
102 			current = current.next;
103 		}
104 
105 		return 0;
106 	}
107 }