| 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 part of dart.core; | 5 part of dart.core; |
| 6 | 6 |
| 7 /** | 7 /** |
| 8 * A [Queue] is a collection that can be manipulated at both ends. One | 8 * A [Queue] is a collection that can be manipulated at both ends. One |
| 9 * can iterate over the elements of a queue through [forEach] or with | 9 * can iterate over the elements of a queue through [forEach] or with |
| 10 * an [Iterator]. | 10 * an [Iterator]. |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 43 * Adds [value] at the end of the queue. | 43 * Adds [value] at the end of the queue. |
| 44 */ | 44 */ |
| 45 void addLast(E value); | 45 void addLast(E value); |
| 46 | 46 |
| 47 /** | 47 /** |
| 48 * Adds [value] at the end of the queue. | 48 * Adds [value] at the end of the queue. |
| 49 */ | 49 */ |
| 50 void add(E value); | 50 void add(E value); |
| 51 | 51 |
| 52 /** | 52 /** |
| 53 * Adds all elements of [collection] at the end of the queue. The | 53 * Adds all elements of [iterable] at the end of the queue. The |
| 54 * length of the queue is extended by the length of [collection]. | 54 * length of the queue is extended by the length of [iterable]. |
| 55 */ | 55 */ |
| 56 void addAll(Collection<E> collection); | 56 void addAll(Iterable<E> iterable); |
| 57 | |
| 58 /** | |
| 59 * Returns the first element of the queue. Throws an | |
| 60 * [StateError] exception if this queue is empty. | |
| 61 */ | |
| 62 E get first; | |
| 63 | |
| 64 /** | |
| 65 * Returns the last element of the queue. Throws an | |
| 66 * [StateError] exception if this queue is empty. | |
| 67 */ | |
| 68 E get last; | |
| 69 | 57 |
| 70 /** | 58 /** |
| 71 * Removes all elements in the queue. The size of the queue becomes zero. | 59 * Removes all elements in the queue. The size of the queue becomes zero. |
| 72 */ | 60 */ |
| 73 void clear(); | 61 void clear(); |
| 74 } | 62 } |
| 75 | 63 |
| 76 | 64 |
| 77 /** | 65 /** |
| 78 * An entry in a doubly linked list. It contains a pointer to the next | 66 * An entry in a doubly linked list. It contains a pointer to the next |
| (...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 165 } | 153 } |
| 166 } | 154 } |
| 167 | 155 |
| 168 /** | 156 /** |
| 169 * Implementation of a double linked list that box list elements into | 157 * Implementation of a double linked list that box list elements into |
| 170 * DoubleLinkedQueueEntry objects. | 158 * DoubleLinkedQueueEntry objects. |
| 171 * | 159 * |
| 172 * WARNING: This class is temporary located in dart:core. It'll be removed | 160 * WARNING: This class is temporary located in dart:core. It'll be removed |
| 173 * at some point in the near future. | 161 * at some point in the near future. |
| 174 */ | 162 */ |
| 175 class DoubleLinkedQueue<E> implements Queue<E> { | 163 class DoubleLinkedQueue<E> extends Iterable<E> implements Queue<E> { |
| 176 _DoubleLinkedQueueEntrySentinel<E> _sentinel; | 164 _DoubleLinkedQueueEntrySentinel<E> _sentinel; |
| 177 | 165 |
| 178 DoubleLinkedQueue() { | 166 DoubleLinkedQueue() { |
| 179 _sentinel = new _DoubleLinkedQueueEntrySentinel<E>(); | 167 _sentinel = new _DoubleLinkedQueueEntrySentinel<E>(); |
| 180 } | 168 } |
| 181 | 169 |
| 182 factory DoubleLinkedQueue.from(Iterable<E> other) { | 170 factory DoubleLinkedQueue.from(Iterable<E> other) { |
| 183 Queue<E> list = new DoubleLinkedQueue(); | 171 Queue<E> list = new DoubleLinkedQueue(); |
| 184 for (final e in other) { | 172 for (final e in other) { |
| 185 list.addLast(e); | 173 list.addLast(e); |
| 186 } | 174 } |
| 187 return list; | 175 return list; |
| 188 } | 176 } |
| 189 | 177 |
| 190 void addLast(E value) { | 178 void addLast(E value) { |
| 191 _sentinel.prepend(value); | 179 _sentinel.prepend(value); |
| 192 } | 180 } |
| 193 | 181 |
| 194 void addFirst(E value) { | 182 void addFirst(E value) { |
| 195 _sentinel.append(value); | 183 _sentinel.append(value); |
| 196 } | 184 } |
| 197 | 185 |
| 198 void add(E value) { | 186 void add(E value) { |
| 199 addLast(value); | 187 addLast(value); |
| 200 } | 188 } |
| 201 | 189 |
| 202 void addAll(Collection<E> collection) { | 190 void addAll(Iterable<E> iterable) { |
| 203 for (final e in collection) { | 191 for (final e in iterable) { |
| 204 add(e); | 192 add(e); |
| 205 } | 193 } |
| 206 } | 194 } |
| 207 | 195 |
| 208 E removeLast() { | 196 E removeLast() { |
| 209 return _sentinel._previous.remove(); | 197 return _sentinel._previous.remove(); |
| 210 } | 198 } |
| 211 | 199 |
| 212 E removeFirst() { | 200 E removeFirst() { |
| 213 return _sentinel._next.remove(); | 201 return _sentinel._next.remove(); |
| 214 } | 202 } |
| 215 | 203 |
| 216 E get first { | 204 E get first { |
| 217 return _sentinel._next.element; | 205 return _sentinel._next.element; |
| 218 } | 206 } |
| 219 | 207 |
| 220 E get last { | 208 E get last { |
| 221 return _sentinel._previous.element; | 209 return _sentinel._previous.element; |
| 222 } | 210 } |
| 223 | 211 |
| 212 E get single { |
| 213 // Note that this also covers the case where the queue is empty. |
| 214 if (identical(_sentinel._next, _sentinel._previous)) { |
| 215 return _sentinel._next.element; |
| 216 } |
| 217 throw new StateError("More than one element"); |
| 218 } |
| 219 |
| 224 DoubleLinkedQueueEntry<E> lastEntry() { | 220 DoubleLinkedQueueEntry<E> lastEntry() { |
| 225 return _sentinel.previousEntry(); | 221 return _sentinel.previousEntry(); |
| 226 } | 222 } |
| 227 | 223 |
| 228 DoubleLinkedQueueEntry<E> firstEntry() { | 224 DoubleLinkedQueueEntry<E> firstEntry() { |
| 229 return _sentinel.nextEntry(); | 225 return _sentinel.nextEntry(); |
| 230 } | 226 } |
| 231 | 227 |
| 232 int get length { | |
| 233 int counter = 0; | |
| 234 forEach((E element) { counter++; }); | |
| 235 return counter; | |
| 236 } | |
| 237 | |
| 238 bool get isEmpty { | 228 bool get isEmpty { |
| 239 return (identical(_sentinel._next, _sentinel)); | 229 return (identical(_sentinel._next, _sentinel)); |
| 240 } | 230 } |
| 241 | 231 |
| 242 void clear() { | 232 void clear() { |
| 243 _sentinel._next = _sentinel; | 233 _sentinel._next = _sentinel; |
| 244 _sentinel._previous = _sentinel; | 234 _sentinel._previous = _sentinel; |
| 245 } | 235 } |
| 246 | 236 |
| 247 void forEach(void f(E element)) { | |
| 248 DoubleLinkedQueueEntry<E> entry = _sentinel._next; | |
| 249 while (!identical(entry, _sentinel)) { | |
| 250 DoubleLinkedQueueEntry<E> nextEntry = entry._next; | |
| 251 f(entry._element); | |
| 252 entry = nextEntry; | |
| 253 } | |
| 254 } | |
| 255 | |
| 256 void forEachEntry(void f(DoubleLinkedQueueEntry<E> element)) { | 237 void forEachEntry(void f(DoubleLinkedQueueEntry<E> element)) { |
| 257 DoubleLinkedQueueEntry<E> entry = _sentinel._next; | 238 DoubleLinkedQueueEntry<E> entry = _sentinel._next; |
| 258 while (!identical(entry, _sentinel)) { | 239 while (!identical(entry, _sentinel)) { |
| 259 DoubleLinkedQueueEntry<E> nextEntry = entry._next; | 240 DoubleLinkedQueueEntry<E> nextEntry = entry._next; |
| 260 f(entry); | 241 f(entry); |
| 261 entry = nextEntry; | 242 entry = nextEntry; |
| 262 } | 243 } |
| 263 } | 244 } |
| 264 | 245 |
| 265 bool every(bool f(E element)) { | 246 _DoubleLinkedQueueIterator<E> get iterator { |
| 266 DoubleLinkedQueueEntry<E> entry = _sentinel._next; | |
| 267 while (!identical(entry, _sentinel)) { | |
| 268 DoubleLinkedQueueEntry<E> nextEntry = entry._next; | |
| 269 if (!f(entry._element)) return false; | |
| 270 entry = nextEntry; | |
| 271 } | |
| 272 return true; | |
| 273 } | |
| 274 | |
| 275 bool some(bool f(E element)) { | |
| 276 DoubleLinkedQueueEntry<E> entry = _sentinel._next; | |
| 277 while (!identical(entry, _sentinel)) { | |
| 278 DoubleLinkedQueueEntry<E> nextEntry = entry._next; | |
| 279 if (f(entry._element)) return true; | |
| 280 entry = nextEntry; | |
| 281 } | |
| 282 return false; | |
| 283 } | |
| 284 | |
| 285 Queue map(f(E element)) { | |
| 286 Queue other = new Queue(); | |
| 287 DoubleLinkedQueueEntry<E> entry = _sentinel._next; | |
| 288 while (!identical(entry, _sentinel)) { | |
| 289 DoubleLinkedQueueEntry<E> nextEntry = entry._next; | |
| 290 other.addLast(f(entry._element)); | |
| 291 entry = nextEntry; | |
| 292 } | |
| 293 return other; | |
| 294 } | |
| 295 | |
| 296 dynamic reduce(dynamic initialValue, | |
| 297 dynamic combine(dynamic previousValue, E element)) { | |
| 298 return Collections.reduce(this, initialValue, combine); | |
| 299 } | |
| 300 | |
| 301 Queue<E> filter(bool f(E element)) { | |
| 302 Queue<E> other = new Queue<E>(); | |
| 303 DoubleLinkedQueueEntry<E> entry = _sentinel._next; | |
| 304 while (!identical(entry, _sentinel)) { | |
| 305 DoubleLinkedQueueEntry<E> nextEntry = entry._next; | |
| 306 if (f(entry._element)) other.addLast(entry._element); | |
| 307 entry = nextEntry; | |
| 308 } | |
| 309 return other; | |
| 310 } | |
| 311 | |
| 312 _DoubleLinkedQueueIterator<E> iterator() { | |
| 313 return new _DoubleLinkedQueueIterator<E>(_sentinel); | 247 return new _DoubleLinkedQueueIterator<E>(_sentinel); |
| 314 } | 248 } |
| 315 | 249 |
| 316 String toString() { | 250 String toString() { |
| 317 return Collections.collectionToString(this); | 251 return Collections.collectionToString(this); |
| 318 } | 252 } |
| 319 } | 253 } |
| 320 | 254 |
| 321 class _DoubleLinkedQueueIterator<E> implements Iterator<E> { | 255 class _DoubleLinkedQueueIterator<E> implements Iterator<E> { |
| 322 final _DoubleLinkedQueueEntrySentinel<E> _sentinel; | 256 _DoubleLinkedQueueEntrySentinel<E> _sentinel; |
| 323 DoubleLinkedQueueEntry<E> _currentEntry; | 257 DoubleLinkedQueueEntry<E> _currentEntry = null; |
| 258 E _current; |
| 324 | 259 |
| 325 _DoubleLinkedQueueIterator(_DoubleLinkedQueueEntrySentinel this._sentinel) { | 260 _DoubleLinkedQueueIterator(_DoubleLinkedQueueEntrySentinel<E> sentinel) |
| 326 _currentEntry = _sentinel; | 261 : _sentinel = sentinel, _currentEntry = sentinel; |
| 262 |
| 263 bool moveNext() { |
| 264 // When [_currentEntry] it is set to [:null:] then it is at the end. |
| 265 if (_currentEntry == null) { |
| 266 assert(_current == null); |
| 267 return false; |
| 268 } |
| 269 _currentEntry = _currentEntry._next; |
| 270 if (identical(_currentEntry, _sentinel)) { |
| 271 _currentEntry = null; |
| 272 _current = null; |
| 273 _sentinel = null; |
| 274 return false; |
| 275 } |
| 276 _current = _currentEntry.element; |
| 277 return true; |
| 327 } | 278 } |
| 328 | 279 |
| 329 bool get hasNext { | 280 E get current => _current; |
| 330 return !identical(_currentEntry._next, _sentinel); | |
| 331 } | |
| 332 | |
| 333 E next() { | |
| 334 if (!hasNext) { | |
| 335 throw new StateError("No more elements"); | |
| 336 } | |
| 337 _currentEntry = _currentEntry._next; | |
| 338 return _currentEntry.element; | |
| 339 } | |
| 340 } | 281 } |
| OLD | NEW |