annotate doodle/containers/list.d @ 40:1f97022e5c6d

Checkpoint. Development continues...
author daveb
date Mon, 12 Apr 2010 14:01:54 +0930
parents
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
40
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
1 module doodle.containers.list;
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
2
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
3 ///
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
4 /// Doubly-linked list.
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
5 /// Consists of a sequence of cells with references to the previous and next member.
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
6 /// List keeps track of its length.
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
7 ///
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
8 /// The list has two ends:
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
9 /// "head" and "tail".
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
10 /// There are two directions:
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
11 /// "forwards" -> towards the "head" and
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
12 /// "backwards" -> towards the "tail"
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
13 /// opApply works from the head to the tail.
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
14 /// opApplyReverse works from the tail to the head.
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
15 ///
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
16 /// When used as a queue, typically use addTail and removeHead.
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
17 ///
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
18 /// Design goals of list is to be completely symmetric and clear in its
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
19 /// forwards and backwards operations, and to be able to contain immutable types.
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
20 ///
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
21 class List(T) {
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
22
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
23 //
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
24 // Standard operations:
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
25 //
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
26
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
27 /// Construct an empty list
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
28 this() { }
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
29
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
30 /// Return a copy of the list
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
31 List!(T) dup() const {
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
32 auto l = new List!(T);
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
33 for (auto c = &mHead; c; c = &c.mBackward) {
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
34 l.addTail(c.mElement);
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
35 }
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
36 return l;
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
37 }
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
38
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
39 /// Return true if the list is empty
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
40 bool isEmpty() const {
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
41 return mLength == 0;
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
42 }
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
43
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
44 /// Return the length of the list
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
45 uint length() const {
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
46 return mLength;
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
47 }
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
48
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
49 /// Return the head of the list, asserting if the list is empty
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
50 T head() {
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
51 assert(!isEmpty());
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
52 return mHead.mElement;
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
53 }
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
54
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
55 /// Return the tail of the list, asserting if the list is empty
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
56 T tail() {
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
57 assert(!isEmpty());
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
58 return mTail.mElement;
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
59 }
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
60
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
61 /// Add to the head of the list
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
62 void addHead(T t) {
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
63 add(mHead, null, t);
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
64 }
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
65
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
66 /// Add to the tail of the list
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
67 void addTail(T t) {
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
68 add(null, mTail, t);
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
69 }
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
70
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
71 /// Remove the head of the list, asserting if the list is empty
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
72 T removeHead() {
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
73 return remove(mHead).mElement;
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
74 }
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
75
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
76 /// Remove the tail of the list, asserting of the list is empty
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
77 T removeTail() {
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
78 return remove(mTail).mElement;
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
79 }
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
80
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
81 // Clear the list (garbage collector does the rest)
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
82 void clear() {
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
83 mHead = mTail = null;
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
84 mLength = 0;
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
85 }
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
86
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
87 /// Iterate over the list from head to tail - used by foreach
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
88 int opApply(int delegate(ref T) dg) {
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
89 int result;
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
90
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
91 auto c = mHead;
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
92
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
93 while (c !is null) {
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
94 auto t = c.mElement;
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
95 result = dg(t);
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
96 if (result != 0) {
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
97 break;
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
98 }
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
99 c = c.mBackward;
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
100 }
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
101
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
102 return result;
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
103 }
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
104
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
105 /// Iterate over the list from tail to head - used by foreach_reverse
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
106 int opApplyReverse(int delegate(ref T) dg) {
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
107 int result;
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
108
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
109 auto c = mTail;
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
110
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
111 while (c !is null) {
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
112 auto t = c.mElement;
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
113 result = dg(t);
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
114 if (result != 0) {
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
115 break;
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
116 }
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
117 c = c.mForward;
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
118 }
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
119
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
120 return result;
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
121 }
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
122
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
123
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
124 //
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
125 // Iterator operations:
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
126 //
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
127
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
128 /// Return the first matching element going backward from head, or null
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
129 Iterator findHead(T t) {
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
130 for (auto c = mHead; c !is null; c = c.mBackward) {
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
131 if (c.mElement == t) {
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
132 return new Iterator(c);
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
133 }
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
134 }
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
135
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
136 return null;
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
137 }
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
138
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
139 /// Return the first matching element going forward from tail, or null
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
140 Iterator findTail(T t) {
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
141 for (auto c = mTail; c !is null; c = c.mForward) {
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
142 if (c.mElement == t) {
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
143 return new Iterator(c);
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
144 }
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
145 }
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
146
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
147 return null;
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
148 }
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
149
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
150 /// insert a new entry into list, forward of entry specified by iterator
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
151 void insertForward(Iterator i, T t) {
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
152 assert(i !is null);
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
153 add(i.mCell, i.mCell.mForward, t);
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
154 }
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
155
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
156 /// insert a new entry into list, backward of entry specified by iterator
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
157 void insertBackward(Iterator i, T t) {
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
158 assert(i !is null);
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
159 add(i.mCell.mBackward, i.mCell, t);
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
160 }
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
161
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
162 /// Remove specified entry from list, returning iterator to entry forward of removed one
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
163 Iterator eraseForward(Iterator i) {
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
164 assert(i !is null);
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
165 Cell cell = remove(i.mCell);
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
166 return cell.mForward ? new Iterator(cell.mForward) : null;
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
167 }
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
168
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
169 /// Remove specified entry from list, returning iterator to entry backward of removed one
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
170 Iterator eraseBackward(Iterator i) {
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
171 assert(i !is null);
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
172 Cell cell = remove(i.mCell);
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
173 return cell.mBackward ? new Iterator(cell.mBackward) : null;
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
174 }
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
175
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
176 ///
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
177 /// Iterator for a List
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
178 ///
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
179 class Iterator {
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
180
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
181 private Cell mCell;
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
182
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
183 private this(Cell cell) {
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
184 assert(cell !is null);
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
185 mCell = cell;
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
186 }
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
187
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
188 T element() {
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
189 return mCell.mElement;
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
190 }
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
191
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
192 void goForward() {
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
193 assert(mCell.mForward !is null);
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
194 mCell = mCell.mForward;
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
195 }
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
196
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
197 void goBackward() {
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
198 assert(mCell.mBackward !is null);
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
199 mCell = mCell.mBackward;
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
200 }
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
201
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
202 bool forwardValid() const {
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
203 return mCell.mForward !is null;
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
204 }
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
205
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
206 bool backwardValid() const {
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
207 return mCell.mBackward !is null;
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
208 }
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
209
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
210 override bool opEquals(Object other) const {
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
211 Iterator o = cast(Iterator) other;
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
212 if (!o) return 0;
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
213 return mCell is o.mCell;
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
214 }
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
215 }
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
216
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
217 //
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
218 // Implementation:
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
219 //
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
220
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
221 private {
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
222 Cell mHead;
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
223 Cell mTail;
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
224 uint mLength;
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
225
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
226 /// An entry in the list
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
227 class Cell {
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
228 Cell mForward, mBackward;
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
229 T mElement;
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
230
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
231 this(T element, Cell backward, Cell forward) {
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
232 mElement = element;
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
233 mBackward = backward;
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
234 mForward = forward;
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
235 }
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
236 }
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
237
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
238 /// Add new cell between backward and forward
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
239 void add(Cell backward, Cell forward, T t) {
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
240 Cell cell = new Cell(t, backward, forward);
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
241
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
242 if (backward) {
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
243 backward.mForward = cell;
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
244 }
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
245 else {
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
246 mTail = cell;
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
247 }
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
248
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
249 if (forward) {
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
250 forward.mBackward = cell;
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
251 }
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
252 else {
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
253 mHead = cell;
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
254 }
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
255
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
256 ++mLength;
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
257 }
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
258
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
259 /// Remove a cell from the list, returning the removed cell
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
260 Cell remove(Cell cell) {
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
261 if (cell.mBackward) {
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
262 cell.mBackward.mForward = cell.mForward;
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
263 }
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
264 else {
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
265 mTail = cell.mForward;
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
266 }
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
267
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
268 if (cell.mForward) {
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
269 cell.mForward.mBackward = cell.mBackward;
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
270 }
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
271 else {
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
272 mHead = cell.mBackward;
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
273 }
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
274
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
275 --mLength;
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
276
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
277 return cell;
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
278 }
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
279 }
1f97022e5c6d Checkpoint. Development continues...
daveb
parents:
diff changeset
280 }