1 module kontainer.linkedlist.linkedlist; 2 import kontainer.linkedlist.node; 3 import kontainer.stack; 4 import core.memory; 5 6 struct LinkedList(T) { 7 private { 8 Node!T* _firstNode; 9 Node!T* _thisNode; 10 Node!T* _lastNode; 11 Node!T* swap; 12 } 13 14 @property Node!T* firstNode() { 15 return _firstNode; 16 } 17 18 @property Node!T* thisNode() { 19 return _thisNode; 20 } 21 22 @property Node!T* lastNode() { 23 return _lastNode; 24 } 25 26 void append(T value) { 27 Node!T* newNode = cast(Node!T*)GC.malloc(Node!T.sizeof, GC.BlkAttr.NO_SCAN | GC.BlkAttr.APPENDABLE); 28 29 newNode.value = value; 30 newNode.nextNode = null; 31 32 if (lastNode !is null) { 33 // ALready exists some value. 34 lastNode.nextNode = newNode; 35 newNode.prevNode = lastNode; 36 _lastNode = newNode; 37 } else { 38 _firstNode = _lastNode = _thisNode = newNode; 39 newNode.prevNode = null; 40 newNode.nextNode = null; 41 } 42 } 43 44 void moveFirst() { 45 _thisNode = _firstNode; 46 } 47 48 void removeNode(Node!T* node) { 49 moveFirst; 50 51 if (node == _firstNode) { 52 auto tempNode = _firstNode; 53 _firstNode = _firstNode.nextNode; 54 _firstNode.prevNode = null; 55 56 freeNode(tempNode); 57 return; 58 } else if (node == _lastNode) { 59 auto tempNode = _lastNode; 60 61 _lastNode = _lastNode.prevNode; 62 _lastNode.nextNode = null; 63 64 freeNode(tempNode); 65 return; 66 } 67 68 foreach (tnode; this) { 69 if (tnode == node) { 70 tnode.prevNode.nextNode = tnode.nextNode; 71 tnode.nextNode.prevNode = tnode.prevNode; 72 73 freeNode(tnode); 74 return; 75 } 76 } 77 } 78 79 Node!T* findNode(T key) { 80 _thisNode = _firstNode; 81 82 foreach (tnode; this) { 83 if (tnode.value == key) { 84 return tnode; 85 } 86 } 87 88 return null; 89 } 90 91 void freeNode(Node!T* node) { 92 if (node !is null) { 93 GC.free(node); 94 } 95 } 96 97 void freeAllNode() { 98 Stack!(Node!T*) stack; 99 100 foreach (node; this) { 101 stack.push(node); 102 } 103 104 foreach (node; stack) { 105 GC.free(node); 106 } 107 } 108 109 @property size_t length() { 110 size_t idx; 111 112 foreach (_; this) { 113 idx++; 114 } 115 116 return idx; 117 } 118 119 @property bool empty() { 120 bool ret = thisNode is null; 121 122 if (ret && thisNode != _firstNode) { 123 _thisNode = _firstNode; 124 } 125 126 return ret; 127 } 128 129 @property Node!T* front() { 130 return thisNode; 131 } 132 133 @property void popFront() { 134 _thisNode = thisNode.nextNode; 135 } 136 137 bool find(T value) { 138 foreach (node; this) { 139 if (node.value == value) { 140 return true; 141 } 142 } 143 144 return false; 145 } 146 147 private { 148 void thisToSwap() { 149 swap = _thisNode; 150 } 151 152 void swapToThis() { 153 _thisNode = swap; 154 } 155 } 156 } 157