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 }