Chromium Code Reviews| Index: sdk/lib/collection/queue.dart |
| diff --git a/sdk/lib/collection/queue.dart b/sdk/lib/collection/queue.dart |
| index af8e07aedf28eadc8102a528e7270fe8291f04d7..db7160d0fe1557f01425bf088aa48f307483f0c0 100644 |
| --- a/sdk/lib/collection/queue.dart |
| +++ b/sdk/lib/collection/queue.dart |
| @@ -96,12 +96,11 @@ abstract class Queue<E> implements Iterable<E>, EfficientLength { |
| } |
| -class _DoubleLink { |
| - _DoubleLink _previousLink; |
| - _DoubleLink _nextLink; |
| +class _DoubleLink<E extends _DoubleLink> { |
| + E _previousLink; |
| + E _nextLink; |
| - void _link(_DoubleLink previous, |
| - _DoubleLink next) { |
| + void _link(E previous, E next) { |
| _nextLink = next; |
| _previousLink = previous; |
| if (previous != null) previous._nextLink = this; |
| @@ -120,17 +119,43 @@ class _DoubleLink { |
| * An entry in a doubly linked list. It contains a pointer to the next |
| * entry, the previous entry, and the boxed element. |
| */ |
| -class DoubleLinkedQueueEntry<E> extends _DoubleLink { |
| +abstract class DoubleLinkedQueueEntry<E> { |
| + factory DoubleLinkedQueueEntry(E element) = _UserDoubleLinkedQueueEntry<E>; |
|
Lasse Reichstein Nielsen
2016/05/13 05:31:09
This changes a generative constructor to a factory
floitsch
2016/05/13 17:12:01
Fixed in https://codereview.chromium.org/197390300
|
| + |
| + /// The element in the queue. |
| + E get element; |
| + |
| + /// Appends the given [e] as entry just after this entry. |
| + void append(E e); |
| + |
| + /// Prepends the given [e] as entry just before this entry. |
| + void prepend(E e); |
| + |
| + /// Returns the previous entry or `null` if there is none. |
| + DoubleLinkedQueueEntry<E> previousEntry(); |
| + |
| + /// Returns the next entry or `null` if there is none. |
| + DoubleLinkedQueueEntry<E> nextEntry(); |
| +} |
|
sra1
2016/05/13 03:00:13
This is a breaking change since DoubleLinkedQueueE
floitsch
2016/05/13 17:12:01
Argh. Missed the 'remove' function.
Fixing in http
|
| + |
| +/// Default implementation of a doubly linked queue entry. |
| +/// |
| +/// This implementation is only used if a user instantiates a |
| +/// [DoubleLinkedQueueEntry] directly. The internal implementations don't use |
| +/// this class. |
| +class _UserDoubleLinkedQueueEntry<E> |
| + extends _DoubleLink<_UserDoubleLinkedQueueEntry<E>> |
| + implements DoubleLinkedQueueEntry<E> { |
| E element; |
| - DoubleLinkedQueueEntry(this.element); |
| + _UserDoubleLinkedQueueEntry(this.element); |
| void append(E e) { |
| - new DoubleLinkedQueueEntry<E>(e)._link(this, _nextLink); |
| + new _UserDoubleLinkedQueueEntry<E>(e)._link(this, _nextLink); |
| } |
| void prepend(E e) { |
| - new DoubleLinkedQueueEntry<E>(e)._link(_previousLink, this); |
| + new _UserDoubleLinkedQueueEntry<E>(e)._link(_previousLink, this); |
| } |
| E remove() { |
| @@ -138,28 +163,25 @@ class DoubleLinkedQueueEntry<E> extends _DoubleLink { |
| return element; |
| } |
| - DoubleLinkedQueueEntry<E> previousEntry() { |
| - return _previousLink; |
| - } |
| + DoubleLinkedQueueEntry<E> previousEntry() => _previousLink; |
| - DoubleLinkedQueueEntry<E> nextEntry() { |
| - return _nextLink; |
| - } |
| + DoubleLinkedQueueEntry<E> nextEntry() => _nextLink; |
| } |
| /** |
| * Interface for the link classes used by [DoubleLinkedQueue]. |
| * |
| * Both the [_DoubleLinkedQueueElement] and [_DoubleLinkedQueueSentinel] |
| - * implements this interface. |
| + * implement this interface. |
| * The entry contains a link back to the queue, so calling `append` |
| * or `prepend` can correctly update the element count. |
| */ |
| -abstract class _DoubleLinkedQueueEntry<E> extends _DoubleLink { |
| +abstract class _DoubleLinkedQueueEntry<E> |
| + extends _DoubleLink<_DoubleLinkedQueueEntry<E>> { |
| DoubleLinkedQueue<E> _queue; |
| _DoubleLinkedQueueEntry(this._queue); |
| - _DoubleLinkedQueueElement _asNonSentinelEntry(); |
| + DoubleLinkedQueueEntry<E> _asNonSentinelEntry(); |
| void _append(E e) { |
| new _DoubleLinkedQueueElement<E>(e, _queue)._link(this, _nextLink); |
| @@ -174,13 +196,11 @@ abstract class _DoubleLinkedQueueEntry<E> extends _DoubleLink { |
| E get element; |
| DoubleLinkedQueueEntry<E> nextEntry() { |
| - _DoubleLinkedQueueEntry next = _nextLink; |
| - return next._asNonSentinelEntry(); |
| + return _nextLink._asNonSentinelEntry(); |
| } |
| DoubleLinkedQueueEntry<E> previousEntry() { |
| - _DoubleLinkedQueueEntry previous = _previousLink; |
| - return previous._asNonSentinelEntry(); |
| + return _previousLink._asNonSentinelEntry(); |
| } |
| } |
| @@ -217,7 +237,7 @@ class _DoubleLinkedQueueElement<E> extends _DoubleLinkedQueueEntry<E> |
| return _remove(); |
| } |
| - _DoubleLinkedQueueElement _asNonSentinelEntry() { |
| + _DoubleLinkedQueueElement<E> _asNonSentinelEntry() { |
| return this; |
| } |
| } |
| @@ -231,12 +251,12 @@ class _DoubleLinkedQueueElement<E> extends _DoubleLinkedQueueEntry<E> |
| * A sentinel does not box any user element. |
| */ |
| class _DoubleLinkedQueueSentinel<E> extends _DoubleLinkedQueueEntry<E> { |
| - _DoubleLinkedQueueSentinel(DoubleLinkedQueue queue) : super(queue) { |
| + _DoubleLinkedQueueSentinel(DoubleLinkedQueue<E> queue) : super(queue) { |
| _previousLink = this; |
| _nextLink = this; |
| } |
| - _DoubleLinkedQueueElement _asNonSentinelEntry() { |
| + DoubleLinkedQueueEntry<E> _asNonSentinelEntry() { |
| return null; |
| } |
| @@ -272,8 +292,9 @@ class DoubleLinkedQueue<E> extends Iterable<E> implements Queue<E> { |
| */ |
| factory DoubleLinkedQueue.from(Iterable elements) { |
| Queue<E> list = new DoubleLinkedQueue<E>(); |
| - for (final E e in elements) { |
| - list.addLast(e); |
| + for (final e in elements) { |
| + E element = e as Object/*=E*/; |
| + list.addLast(element); |
| } |
| return list; |
| } |
| @@ -303,14 +324,14 @@ class DoubleLinkedQueue<E> extends Iterable<E> implements Queue<E> { |
| } |
| E removeLast() { |
| - _DoubleLinkedQueueEntry lastEntry = _sentinel._previousLink; |
| + _DoubleLinkedQueueEntry<E> lastEntry = _sentinel._previousLink; |
| E result = lastEntry._remove(); |
| _elementCount--; |
| return result; |
| } |
| E removeFirst() { |
| - _DoubleLinkedQueueEntry firstEntry = _sentinel._nextLink; |
| + _DoubleLinkedQueueEntry<E> firstEntry = _sentinel._nextLink; |
| E result = firstEntry._remove(); |
| _elementCount--; |
| return result; |
| @@ -350,12 +371,12 @@ class DoubleLinkedQueue<E> extends Iterable<E> implements Queue<E> { |
| } |
| E get first { |
| - _DoubleLinkedQueueEntry firstEntry = _sentinel._nextLink; |
| + _DoubleLinkedQueueEntry<E> firstEntry = _sentinel._nextLink; |
| return firstEntry.element; |
| } |
| E get last { |
| - _DoubleLinkedQueueEntry lastEntry = _sentinel._previousLink; |
| + _DoubleLinkedQueueEntry<E> lastEntry = _sentinel._previousLink; |
| return lastEntry.element; |
| } |
| @@ -363,7 +384,7 @@ class DoubleLinkedQueue<E> extends Iterable<E> implements Queue<E> { |
| // Note that this throws correctly if the queue is empty |
| // because reading element on the sentinel throws. |
| if (identical(_sentinel._nextLink, _sentinel._previousLink)) { |
| - _DoubleLinkedQueueEntry entry = _sentinel._nextLink; |
| + _DoubleLinkedQueueEntry<E> entry = _sentinel._nextLink; |
| return entry.element; |
| } |
| throw IterableElementError.tooMany(); |
| @@ -391,7 +412,7 @@ class DoubleLinkedQueue<E> extends Iterable<E> implements Queue<E> { |
| _DoubleLinkedQueueEntry<E> entry = _sentinel._nextLink; |
| while (!identical(entry, _sentinel)) { |
| _DoubleLinkedQueueEntry<E> nextEntry = entry._nextLink; |
| - _DoubleLinkedQueueElement element = entry; |
| + _DoubleLinkedQueueElement<E> element = entry; |
| f(element); |
| entry = nextEntry; |
| } |
| @@ -410,7 +431,8 @@ class _DoubleLinkedQueueIterator<E> implements Iterator<E> { |
| E _current; |
| _DoubleLinkedQueueIterator(_DoubleLinkedQueueSentinel<E> sentinel) |
| - : _sentinel = sentinel, _nextEntry = sentinel._nextLink; |
| + : _sentinel = sentinel, |
| + _nextEntry = sentinel._nextLink; |
| bool moveNext() { |
| if (identical(_nextEntry, _sentinel)) { |
| @@ -419,7 +441,7 @@ class _DoubleLinkedQueueIterator<E> implements Iterator<E> { |
| _sentinel = null; |
| return false; |
| } |
| - _DoubleLinkedQueueElement elementEntry = _nextEntry; |
| + _DoubleLinkedQueueElement<E> elementEntry = _nextEntry; |
| if (elementEntry._queue == null) { |
| throw new ConcurrentModificationError(_sentinel._queue); |
| } |
| @@ -476,8 +498,9 @@ class ListQueue<E> extends Iterable<E> implements Queue<E> { |
| int length = elements.length; |
| ListQueue<E> queue = new ListQueue(length + 1); |
| assert(queue._table.length > length); |
| - List sourceList = elements; |
| - queue._table.setRange(0, length, sourceList, 0); |
| + for (int i = 0; i < length; i++) { |
| + queue._table[i] = elements[i] as Object/*=E*/; |
| + } |
| queue._tail = length; |
| return queue; |
| } else { |
| @@ -486,8 +509,8 @@ class ListQueue<E> extends Iterable<E> implements Queue<E> { |
| capacity = elements.length; |
| } |
| ListQueue<E> result = new ListQueue<E>(capacity); |
| - for (final E element in elements) { |
| - result.addLast(element); |
| + for (final element in elements) { |
| + result.addLast(element as Object/*=E*/); |
| } |
| return result; |
| } |
| @@ -548,8 +571,8 @@ class ListQueue<E> extends Iterable<E> implements Queue<E> { |
| } |
| void addAll(Iterable<E> elements) { |
| - if (elements is List) { |
| - List list = elements; |
| + if (elements is List/*<E>*/) { |
| + List<E> list = elements; |
| int addCount = list.length; |
| int length = this.length; |
| if (length + addCount >= _table.length) { |
| @@ -792,13 +815,13 @@ class ListQueue<E> extends Iterable<E> implements Queue<E> { |
| * Considers any add or remove operation a concurrent modification. |
| */ |
| class _ListQueueIterator<E> implements Iterator<E> { |
| - final ListQueue _queue; |
| + final ListQueue<E> _queue; |
| final int _end; |
| final int _modificationCount; |
| int _position; |
| E _current; |
| - _ListQueueIterator(ListQueue queue) |
| + _ListQueueIterator(ListQueue<E> queue) |
| : _queue = queue, |
| _end = queue._tail, |
| _modificationCount = queue._modificationCount, |