| OLD | NEW |
| 1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 /** | 5 /** |
| 6 * A [Queue] is a collection that can be manipulated at both ends. One | 6 * A [Queue] is a collection that can be manipulated at both ends. One |
| 7 * can iterate over the elements of a queue through [forEach] or with | 7 * can iterate over the elements of a queue through [forEach] or with |
| 8 * an [Iterator]. | 8 * an [Iterator]. |
| 9 */ | 9 */ |
| 10 abstract class Queue<E> extends Collection<E> { | 10 abstract class Queue<E> extends Collection<E> { |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 63 * Returns the last element of the queue. Throws an | 63 * Returns the last element of the queue. Throws an |
| 64 * [StateError] exception if this queue is empty. | 64 * [StateError] exception if this queue is empty. |
| 65 */ | 65 */ |
| 66 E get last; | 66 E get last; |
| 67 | 67 |
| 68 /** | 68 /** |
| 69 * Removes all elements in the queue. The size of the queue becomes zero. | 69 * Removes all elements in the queue. The size of the queue becomes zero. |
| 70 */ | 70 */ |
| 71 void clear(); | 71 void clear(); |
| 72 } | 72 } |
| 73 |
| 74 |
| 75 /** |
| 76 * An entry in a doubly linked list. It contains a pointer to the next |
| 77 * entry, the previous entry, and the boxed element. |
| 78 * |
| 79 * WARNING: This class is temporary located in dart:core. It'll be removed |
| 80 * at some point in the near future. |
| 81 */ |
| 82 class DoubleLinkedQueueEntry<E> { |
| 83 DoubleLinkedQueueEntry<E> _previous; |
| 84 DoubleLinkedQueueEntry<E> _next; |
| 85 E _element; |
| 86 |
| 87 DoubleLinkedQueueEntry(E e) { |
| 88 _element = e; |
| 89 } |
| 90 |
| 91 void _link(DoubleLinkedQueueEntry<E> p, |
| 92 DoubleLinkedQueueEntry<E> n) { |
| 93 _next = n; |
| 94 _previous = p; |
| 95 p._next = this; |
| 96 n._previous = this; |
| 97 } |
| 98 |
| 99 void append(E e) { |
| 100 new DoubleLinkedQueueEntry<E>(e)._link(this, _next); |
| 101 } |
| 102 |
| 103 void prepend(E e) { |
| 104 new DoubleLinkedQueueEntry<E>(e)._link(_previous, this); |
| 105 } |
| 106 |
| 107 E remove() { |
| 108 _previous._next = _next; |
| 109 _next._previous = _previous; |
| 110 _next = null; |
| 111 _previous = null; |
| 112 return _element; |
| 113 } |
| 114 |
| 115 DoubleLinkedQueueEntry<E> _asNonSentinelEntry() { |
| 116 return this; |
| 117 } |
| 118 |
| 119 DoubleLinkedQueueEntry<E> previousEntry() { |
| 120 return _previous._asNonSentinelEntry(); |
| 121 } |
| 122 |
| 123 DoubleLinkedQueueEntry<E> nextEntry() { |
| 124 return _next._asNonSentinelEntry(); |
| 125 } |
| 126 |
| 127 E get element { |
| 128 return _element; |
| 129 } |
| 130 |
| 131 void set element(E e) { |
| 132 _element = e; |
| 133 } |
| 134 } |
| 135 |
| 136 /** |
| 137 * A sentinel in a double linked list is used to manipulate the list |
| 138 * at both ends. A double linked list has exactly one sentinel, which |
| 139 * is the only entry when the list is constructed. Initially, a |
| 140 * sentinel has its next and previous entry point to itself. A |
| 141 * sentinel does not box any user element. |
| 142 */ |
| 143 class _DoubleLinkedQueueEntrySentinel<E> extends DoubleLinkedQueueEntry<E> { |
| 144 _DoubleLinkedQueueEntrySentinel() : super(null) { |
| 145 _link(this, this); |
| 146 } |
| 147 |
| 148 E remove() { |
| 149 throw new StateError("Empty queue"); |
| 150 } |
| 151 |
| 152 DoubleLinkedQueueEntry<E> _asNonSentinelEntry() { |
| 153 return null; |
| 154 } |
| 155 |
| 156 void set element(E e) { |
| 157 // This setter is unreachable. |
| 158 assert(false); |
| 159 } |
| 160 |
| 161 E get element { |
| 162 throw new StateError("Empty queue"); |
| 163 } |
| 164 } |
| 165 |
| 166 /** |
| 167 * Implementation of a double linked list that box list elements into |
| 168 * DoubleLinkedQueueEntry objects. |
| 169 * |
| 170 * WARNING: This class is temporary located in dart:core. It'll be removed |
| 171 * at some point in the near future. |
| 172 */ |
| 173 class DoubleLinkedQueue<E> implements Queue<E> { |
| 174 _DoubleLinkedQueueEntrySentinel<E> _sentinel; |
| 175 |
| 176 DoubleLinkedQueue() { |
| 177 _sentinel = new _DoubleLinkedQueueEntrySentinel<E>(); |
| 178 } |
| 179 |
| 180 factory DoubleLinkedQueue.from(Iterable<E> other) { |
| 181 Queue<E> list = new DoubleLinkedQueue(); |
| 182 for (final e in other) { |
| 183 list.addLast(e); |
| 184 } |
| 185 return list; |
| 186 } |
| 187 |
| 188 void addLast(E value) { |
| 189 _sentinel.prepend(value); |
| 190 } |
| 191 |
| 192 void addFirst(E value) { |
| 193 _sentinel.append(value); |
| 194 } |
| 195 |
| 196 void add(E value) { |
| 197 addLast(value); |
| 198 } |
| 199 |
| 200 void addAll(Collection<E> collection) { |
| 201 for (final e in collection) { |
| 202 add(e); |
| 203 } |
| 204 } |
| 205 |
| 206 E removeLast() { |
| 207 return _sentinel._previous.remove(); |
| 208 } |
| 209 |
| 210 E removeFirst() { |
| 211 return _sentinel._next.remove(); |
| 212 } |
| 213 |
| 214 E get first { |
| 215 return _sentinel._next.element; |
| 216 } |
| 217 |
| 218 E get last { |
| 219 return _sentinel._previous.element; |
| 220 } |
| 221 |
| 222 DoubleLinkedQueueEntry<E> lastEntry() { |
| 223 return _sentinel.previousEntry(); |
| 224 } |
| 225 |
| 226 DoubleLinkedQueueEntry<E> firstEntry() { |
| 227 return _sentinel.nextEntry(); |
| 228 } |
| 229 |
| 230 int get length { |
| 231 int counter = 0; |
| 232 forEach(void _(E element) { counter++; }); |
| 233 return counter; |
| 234 } |
| 235 |
| 236 bool get isEmpty { |
| 237 return (_sentinel._next === _sentinel); |
| 238 } |
| 239 |
| 240 void clear() { |
| 241 _sentinel._next = _sentinel; |
| 242 _sentinel._previous = _sentinel; |
| 243 } |
| 244 |
| 245 void forEach(void f(E element)) { |
| 246 DoubleLinkedQueueEntry<E> entry = _sentinel._next; |
| 247 while (entry !== _sentinel) { |
| 248 DoubleLinkedQueueEntry<E> nextEntry = entry._next; |
| 249 f(entry._element); |
| 250 entry = nextEntry; |
| 251 } |
| 252 } |
| 253 |
| 254 void forEachEntry(void f(DoubleLinkedQueueEntry<E> element)) { |
| 255 DoubleLinkedQueueEntry<E> entry = _sentinel._next; |
| 256 while (entry !== _sentinel) { |
| 257 DoubleLinkedQueueEntry<E> nextEntry = entry._next; |
| 258 f(entry); |
| 259 entry = nextEntry; |
| 260 } |
| 261 } |
| 262 |
| 263 bool every(bool f(E element)) { |
| 264 DoubleLinkedQueueEntry<E> entry = _sentinel._next; |
| 265 while (entry !== _sentinel) { |
| 266 DoubleLinkedQueueEntry<E> nextEntry = entry._next; |
| 267 if (!f(entry._element)) return false; |
| 268 entry = nextEntry; |
| 269 } |
| 270 return true; |
| 271 } |
| 272 |
| 273 bool some(bool f(E element)) { |
| 274 DoubleLinkedQueueEntry<E> entry = _sentinel._next; |
| 275 while (entry !== _sentinel) { |
| 276 DoubleLinkedQueueEntry<E> nextEntry = entry._next; |
| 277 if (f(entry._element)) return true; |
| 278 entry = nextEntry; |
| 279 } |
| 280 return false; |
| 281 } |
| 282 |
| 283 Queue map(f(E element)) { |
| 284 Queue other = new Queue(); |
| 285 DoubleLinkedQueueEntry<E> entry = _sentinel._next; |
| 286 while (entry !== _sentinel) { |
| 287 DoubleLinkedQueueEntry<E> nextEntry = entry._next; |
| 288 other.addLast(f(entry._element)); |
| 289 entry = nextEntry; |
| 290 } |
| 291 return other; |
| 292 } |
| 293 |
| 294 Dynamic reduce(Dynamic initialValue, |
| 295 Dynamic combine(Dynamic previousValue, E element)) { |
| 296 return Collections.reduce(this, initialValue, combine); |
| 297 } |
| 298 |
| 299 Queue<E> filter(bool f(E element)) { |
| 300 Queue<E> other = new Queue<E>(); |
| 301 DoubleLinkedQueueEntry<E> entry = _sentinel._next; |
| 302 while (entry !== _sentinel) { |
| 303 DoubleLinkedQueueEntry<E> nextEntry = entry._next; |
| 304 if (f(entry._element)) other.addLast(entry._element); |
| 305 entry = nextEntry; |
| 306 } |
| 307 return other; |
| 308 } |
| 309 |
| 310 _DoubleLinkedQueueIterator<E> iterator() { |
| 311 return new _DoubleLinkedQueueIterator<E>(_sentinel); |
| 312 } |
| 313 |
| 314 String toString() { |
| 315 return Collections.collectionToString(this); |
| 316 } |
| 317 } |
| 318 |
| 319 class _DoubleLinkedQueueIterator<E> implements Iterator<E> { |
| 320 final _DoubleLinkedQueueEntrySentinel<E> _sentinel; |
| 321 DoubleLinkedQueueEntry<E> _currentEntry; |
| 322 |
| 323 _DoubleLinkedQueueIterator(_DoubleLinkedQueueEntrySentinel this._sentinel) { |
| 324 _currentEntry = _sentinel; |
| 325 } |
| 326 |
| 327 bool get hasNext { |
| 328 return _currentEntry._next !== _sentinel; |
| 329 } |
| 330 |
| 331 E next() { |
| 332 if (!hasNext) { |
| 333 throw new StateError("No more elements"); |
| 334 } |
| 335 _currentEntry = _currentEntry._next; |
| 336 return _currentEntry.element; |
| 337 } |
| 338 } |
| OLD | NEW |