| Index: pkg/dev_compiler/tool/input_sdk/lib/collection/queue.dart
|
| diff --git a/pkg/dev_compiler/tool/input_sdk/lib/collection/queue.dart b/pkg/dev_compiler/tool/input_sdk/lib/collection/queue.dart
|
| deleted file mode 100644
|
| index db7160d0fe1557f01425bf088aa48f307483f0c0..0000000000000000000000000000000000000000
|
| --- a/pkg/dev_compiler/tool/input_sdk/lib/collection/queue.dart
|
| +++ /dev/null
|
| @@ -1,842 +0,0 @@
|
| -// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file
|
| -// for details. All rights reserved. Use of this source code is governed by a
|
| -// BSD-style license that can be found in the LICENSE file.
|
| -
|
| -part of dart.collection;
|
| -
|
| -/**
|
| - * A [Queue] is a collection that can be manipulated at both ends. One
|
| - * can iterate over the elements of a queue through [forEach] or with
|
| - * an [Iterator].
|
| - *
|
| - * It is generally not allowed to modify the queue (add or remove entries) while
|
| - * an operation on the queue is being performed, for example during a call to
|
| - * [forEach].
|
| - * Modifying the queue while it is being iterated will most likely break the
|
| - * iteration.
|
| - * This goes both for using the [iterator] directly, or for iterating an
|
| - * `Iterable` returned by a method like [map] or [where].
|
| - */
|
| -abstract class Queue<E> implements Iterable<E>, EfficientLength {
|
| -
|
| - /**
|
| - * Creates a queue.
|
| - */
|
| - factory Queue() = ListQueue<E>;
|
| -
|
| - /**
|
| - * Creates a queue containing all [elements].
|
| - *
|
| - * The element order in the queue is as if the elements were added using
|
| - * [addLast] in the order provided by [elements.iterator].
|
| - */
|
| - factory Queue.from(Iterable elements) = ListQueue<E>.from;
|
| -
|
| - /**
|
| - * Removes and returns the first element of this queue.
|
| - *
|
| - * The queue must not be empty when this method is called.
|
| - */
|
| - E removeFirst();
|
| -
|
| - /**
|
| - * Removes and returns the last element of the queue.
|
| - *
|
| - * The queue must not be empty when this method is called.
|
| - */
|
| - E removeLast();
|
| -
|
| - /**
|
| - * Adds [value] at the beginning of the queue.
|
| - */
|
| - void addFirst(E value);
|
| -
|
| - /**
|
| - * Adds [value] at the end of the queue.
|
| - */
|
| - void addLast(E value);
|
| -
|
| - /**
|
| - * Adds [value] at the end of the queue.
|
| - */
|
| - void add(E value);
|
| -
|
| - /**
|
| - * Remove a single instance of [value] from the queue.
|
| - *
|
| - * Returns `true` if a value was removed, or `false` if the queue
|
| - * contained no element equal to [value].
|
| - */
|
| - bool remove(Object value);
|
| -
|
| - /**
|
| - * Adds all elements of [iterable] at the end of the queue. The
|
| - * length of the queue is extended by the length of [iterable].
|
| - */
|
| - void addAll(Iterable<E> iterable);
|
| -
|
| - /**
|
| - * Removes all elements matched by [test] from the queue.
|
| - *
|
| - * The `test` function must not throw or modify the queue.
|
| - */
|
| - void removeWhere(bool test(E element));
|
| -
|
| - /**
|
| - * Removes all elements not matched by [test] from the queue.
|
| - *
|
| - * The `test` function must not throw or modify the queue.
|
| - */
|
| - void retainWhere(bool test(E element));
|
| -
|
| - /**
|
| - * Removes all elements in the queue. The size of the queue becomes zero.
|
| - */
|
| - void clear();
|
| -}
|
| -
|
| -
|
| -class _DoubleLink<E extends _DoubleLink> {
|
| - E _previousLink;
|
| - E _nextLink;
|
| -
|
| - void _link(E previous, E next) {
|
| - _nextLink = next;
|
| - _previousLink = previous;
|
| - if (previous != null) previous._nextLink = this;
|
| - if (next != null) next._previousLink = this;
|
| - }
|
| -
|
| - void _unlink() {
|
| - if (_previousLink != null) _previousLink._nextLink = _nextLink;
|
| - if (_nextLink != null) _nextLink._previousLink = _previousLink;
|
| - _nextLink = null;
|
| - _previousLink = null;
|
| - }
|
| -}
|
| -
|
| -/**
|
| - * An entry in a doubly linked list. It contains a pointer to the next
|
| - * entry, the previous entry, and the boxed element.
|
| - */
|
| -abstract class DoubleLinkedQueueEntry<E> {
|
| - factory DoubleLinkedQueueEntry(E element) = _UserDoubleLinkedQueueEntry<E>;
|
| -
|
| - /// 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();
|
| -}
|
| -
|
| -/// 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;
|
| -
|
| - _UserDoubleLinkedQueueEntry(this.element);
|
| -
|
| - void append(E e) {
|
| - new _UserDoubleLinkedQueueEntry<E>(e)._link(this, _nextLink);
|
| - }
|
| -
|
| - void prepend(E e) {
|
| - new _UserDoubleLinkedQueueEntry<E>(e)._link(_previousLink, this);
|
| - }
|
| -
|
| - E remove() {
|
| - _unlink();
|
| - return element;
|
| - }
|
| -
|
| - DoubleLinkedQueueEntry<E> previousEntry() => _previousLink;
|
| -
|
| - DoubleLinkedQueueEntry<E> nextEntry() => _nextLink;
|
| -}
|
| -
|
| -/**
|
| - * Interface for the link classes used by [DoubleLinkedQueue].
|
| - *
|
| - * Both the [_DoubleLinkedQueueElement] and [_DoubleLinkedQueueSentinel]
|
| - * 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<_DoubleLinkedQueueEntry<E>> {
|
| - DoubleLinkedQueue<E> _queue;
|
| - _DoubleLinkedQueueEntry(this._queue);
|
| -
|
| - DoubleLinkedQueueEntry<E> _asNonSentinelEntry();
|
| -
|
| - void _append(E e) {
|
| - new _DoubleLinkedQueueElement<E>(e, _queue)._link(this, _nextLink);
|
| - }
|
| -
|
| - void _prepend(E e) {
|
| - new _DoubleLinkedQueueElement<E>(e, _queue)._link(_previousLink, this);
|
| - }
|
| -
|
| - E _remove();
|
| -
|
| - E get element;
|
| -
|
| - DoubleLinkedQueueEntry<E> nextEntry() {
|
| - return _nextLink._asNonSentinelEntry();
|
| - }
|
| -
|
| - DoubleLinkedQueueEntry<E> previousEntry() {
|
| - return _previousLink._asNonSentinelEntry();
|
| - }
|
| -}
|
| -
|
| -/**
|
| - * The actual entry type used by the [DoubleLinkedQueue].
|
| - *
|
| - * The entry contains a reference to the queue, allowing
|
| - * [append]/[prepend] to update the list length.
|
| - */
|
| -class _DoubleLinkedQueueElement<E> extends _DoubleLinkedQueueEntry<E>
|
| - implements DoubleLinkedQueueEntry<E> {
|
| - E element;
|
| - _DoubleLinkedQueueElement(this.element, DoubleLinkedQueue<E> queue)
|
| - : super(queue);
|
| -
|
| - void append(E e) {
|
| - _append(e);
|
| - if (_queue != null) _queue._elementCount++;
|
| - }
|
| -
|
| - void prepend(E e) {
|
| - _prepend(e);
|
| - if (_queue != null) _queue._elementCount++;
|
| - }
|
| -
|
| - E _remove() {
|
| - _queue = null;
|
| - _unlink();
|
| - return element;
|
| - }
|
| -
|
| - E remove() {
|
| - if (_queue != null) _queue._elementCount--;
|
| - return _remove();
|
| - }
|
| -
|
| - _DoubleLinkedQueueElement<E> _asNonSentinelEntry() {
|
| - return this;
|
| - }
|
| -}
|
| -
|
| -/**
|
| - * A sentinel in a double linked list is used to manipulate the list
|
| - * at both ends.
|
| - * A double linked list has exactly one sentinel,
|
| - * which is the only entry when the list is constructed.
|
| - * Initially, a sentinel has its next and previous entry point to itself.
|
| - * A sentinel does not box any user element.
|
| - */
|
| -class _DoubleLinkedQueueSentinel<E> extends _DoubleLinkedQueueEntry<E> {
|
| - _DoubleLinkedQueueSentinel(DoubleLinkedQueue<E> queue) : super(queue) {
|
| - _previousLink = this;
|
| - _nextLink = this;
|
| - }
|
| -
|
| - DoubleLinkedQueueEntry<E> _asNonSentinelEntry() {
|
| - return null;
|
| - }
|
| -
|
| - /** Hit by, e.g., [DoubleLinkedQueue.removeFirst] if the queue is empty. */
|
| - E _remove() {
|
| - throw IterableElementError.noElement();
|
| - }
|
| -
|
| - /** Hit by, e.g., [DoubleLinkedQueue.first] if the queue is empty. */
|
| - E get element {
|
| - throw IterableElementError.noElement();
|
| - }
|
| -}
|
| -
|
| -/**
|
| - * A [Queue] implementation based on a double-linked list.
|
| - *
|
| - * Allows constant time add, remove-at-ends and peek operations.
|
| - */
|
| -class DoubleLinkedQueue<E> extends Iterable<E> implements Queue<E> {
|
| - _DoubleLinkedQueueSentinel<E> _sentinel;
|
| - int _elementCount = 0;
|
| -
|
| - DoubleLinkedQueue() {
|
| - _sentinel = new _DoubleLinkedQueueSentinel<E>(this);
|
| - }
|
| -
|
| - /**
|
| - * Creates a double-linked queue containing all [elements].
|
| - *
|
| - * The element order in the queue is as if the elements were added using
|
| - * [addLast] in the order provided by [elements.iterator].
|
| - */
|
| - factory DoubleLinkedQueue.from(Iterable elements) {
|
| - Queue<E> list = new DoubleLinkedQueue<E>();
|
| - for (final e in elements) {
|
| - E element = e as Object/*=E*/;
|
| - list.addLast(element);
|
| - }
|
| - return list;
|
| - }
|
| -
|
| - int get length => _elementCount;
|
| -
|
| - void addLast(E value) {
|
| - _sentinel._prepend(value);
|
| - _elementCount++;
|
| - }
|
| -
|
| - void addFirst(E value) {
|
| - _sentinel._append(value);
|
| - _elementCount++;
|
| - }
|
| -
|
| - void add(E value) {
|
| - _sentinel._prepend(value);
|
| - _elementCount++;
|
| - }
|
| -
|
| - void addAll(Iterable<E> iterable) {
|
| - for (final E value in iterable) {
|
| - _sentinel._prepend(value);
|
| - _elementCount++;
|
| - }
|
| - }
|
| -
|
| - E removeLast() {
|
| - _DoubleLinkedQueueEntry<E> lastEntry = _sentinel._previousLink;
|
| - E result = lastEntry._remove();
|
| - _elementCount--;
|
| - return result;
|
| - }
|
| -
|
| - E removeFirst() {
|
| - _DoubleLinkedQueueEntry<E> firstEntry = _sentinel._nextLink;
|
| - E result = firstEntry._remove();
|
| - _elementCount--;
|
| - return result;
|
| - }
|
| -
|
| - bool remove(Object o) {
|
| - _DoubleLinkedQueueEntry<E> entry = _sentinel._nextLink;
|
| - while (!identical(entry, _sentinel)) {
|
| - if (entry.element == o) {
|
| - entry._remove();
|
| - _elementCount--;
|
| - return true;
|
| - }
|
| - entry = entry._nextLink;
|
| - }
|
| - return false;
|
| - }
|
| -
|
| - void _filter(bool test(E element), bool removeMatching) {
|
| - _DoubleLinkedQueueEntry<E> entry = _sentinel._nextLink;
|
| - while (!identical(entry, _sentinel)) {
|
| - _DoubleLinkedQueueEntry<E> next = entry._nextLink;
|
| - if (identical(removeMatching, test(entry.element))) {
|
| - entry._remove();
|
| - _elementCount--;
|
| - }
|
| - entry = next;
|
| - }
|
| - }
|
| -
|
| - void removeWhere(bool test(E element)) {
|
| - _filter(test, true);
|
| - }
|
| -
|
| - void retainWhere(bool test(E element)) {
|
| - _filter(test, false);
|
| - }
|
| -
|
| - E get first {
|
| - _DoubleLinkedQueueEntry<E> firstEntry = _sentinel._nextLink;
|
| - return firstEntry.element;
|
| - }
|
| -
|
| - E get last {
|
| - _DoubleLinkedQueueEntry<E> lastEntry = _sentinel._previousLink;
|
| - return lastEntry.element;
|
| - }
|
| -
|
| - E get single {
|
| - // Note that this throws correctly if the queue is empty
|
| - // because reading element on the sentinel throws.
|
| - if (identical(_sentinel._nextLink, _sentinel._previousLink)) {
|
| - _DoubleLinkedQueueEntry<E> entry = _sentinel._nextLink;
|
| - return entry.element;
|
| - }
|
| - throw IterableElementError.tooMany();
|
| - }
|
| -
|
| - DoubleLinkedQueueEntry<E> lastEntry() {
|
| - return _sentinel.previousEntry();
|
| - }
|
| -
|
| - DoubleLinkedQueueEntry<E> firstEntry() {
|
| - return _sentinel.nextEntry();
|
| - }
|
| -
|
| - bool get isEmpty {
|
| - return (identical(_sentinel._nextLink, _sentinel));
|
| - }
|
| -
|
| - void clear() {
|
| - _sentinel._nextLink = _sentinel;
|
| - _sentinel._previousLink = _sentinel;
|
| - _elementCount = 0;
|
| - }
|
| -
|
| - void forEachEntry(void f(DoubleLinkedQueueEntry<E> element)) {
|
| - _DoubleLinkedQueueEntry<E> entry = _sentinel._nextLink;
|
| - while (!identical(entry, _sentinel)) {
|
| - _DoubleLinkedQueueEntry<E> nextEntry = entry._nextLink;
|
| - _DoubleLinkedQueueElement<E> element = entry;
|
| - f(element);
|
| - entry = nextEntry;
|
| - }
|
| - }
|
| -
|
| - _DoubleLinkedQueueIterator<E> get iterator {
|
| - return new _DoubleLinkedQueueIterator<E>(_sentinel);
|
| - }
|
| -
|
| - String toString() => IterableBase.iterableToFullString(this, '{', '}');
|
| -}
|
| -
|
| -class _DoubleLinkedQueueIterator<E> implements Iterator<E> {
|
| - _DoubleLinkedQueueSentinel<E> _sentinel;
|
| - _DoubleLinkedQueueEntry<E> _nextEntry = null;
|
| - E _current;
|
| -
|
| - _DoubleLinkedQueueIterator(_DoubleLinkedQueueSentinel<E> sentinel)
|
| - : _sentinel = sentinel,
|
| - _nextEntry = sentinel._nextLink;
|
| -
|
| - bool moveNext() {
|
| - if (identical(_nextEntry, _sentinel)) {
|
| - _current = null;
|
| - _nextEntry = null;
|
| - _sentinel = null;
|
| - return false;
|
| - }
|
| - _DoubleLinkedQueueElement<E> elementEntry = _nextEntry;
|
| - if (elementEntry._queue == null) {
|
| - throw new ConcurrentModificationError(_sentinel._queue);
|
| - }
|
| - _current = elementEntry.element;
|
| - _nextEntry = elementEntry._nextLink;
|
| - return true;
|
| - }
|
| -
|
| - E get current => _current;
|
| -}
|
| -
|
| -/**
|
| - * List based [Queue].
|
| - *
|
| - * Keeps a cyclic buffer of elements, and grows to a larger buffer when
|
| - * it fills up. This guarantees constant time peek and remove operations, and
|
| - * amortized constant time add operations.
|
| - *
|
| - * The structure is efficient for any queue or stack usage.
|
| - */
|
| -class ListQueue<E> extends Iterable<E> implements Queue<E> {
|
| - static const int _INITIAL_CAPACITY = 8;
|
| - List<E> _table;
|
| - int _head;
|
| - int _tail;
|
| - int _modificationCount = 0;
|
| -
|
| - /**
|
| - * Create an empty queue.
|
| - *
|
| - * If [initialCapacity] is given, prepare the queue for at least that many
|
| - * elements.
|
| - */
|
| - ListQueue([int initialCapacity]) : _head = 0, _tail = 0 {
|
| - if (initialCapacity == null || initialCapacity < _INITIAL_CAPACITY) {
|
| - initialCapacity = _INITIAL_CAPACITY;
|
| - } else if (!_isPowerOf2(initialCapacity)) {
|
| - initialCapacity = _nextPowerOf2(initialCapacity);
|
| - }
|
| - assert(_isPowerOf2(initialCapacity));
|
| - _table = new List<E>(initialCapacity);
|
| - }
|
| -
|
| - /**
|
| - * Create a `ListQueue` containing all [elements].
|
| - *
|
| - * The elements are added to the queue, as by [addLast], in the order given by
|
| - * `elements.iterator`.
|
| - *
|
| - * All `elements` should be assignable to [E].
|
| - */
|
| - factory ListQueue.from(Iterable elements) {
|
| - if (elements is List) {
|
| - int length = elements.length;
|
| - ListQueue<E> queue = new ListQueue(length + 1);
|
| - assert(queue._table.length > length);
|
| - for (int i = 0; i < length; i++) {
|
| - queue._table[i] = elements[i] as Object/*=E*/;
|
| - }
|
| - queue._tail = length;
|
| - return queue;
|
| - } else {
|
| - int capacity = _INITIAL_CAPACITY;
|
| - if (elements is EfficientLength) {
|
| - capacity = elements.length;
|
| - }
|
| - ListQueue<E> result = new ListQueue<E>(capacity);
|
| - for (final element in elements) {
|
| - result.addLast(element as Object/*=E*/);
|
| - }
|
| - return result;
|
| - }
|
| - }
|
| -
|
| - // Iterable interface.
|
| -
|
| - Iterator<E> get iterator => new _ListQueueIterator<E>(this);
|
| -
|
| - void forEach(void action (E element)) {
|
| - int modificationCount = _modificationCount;
|
| - for (int i = _head; i != _tail; i = (i + 1) & (_table.length - 1)) {
|
| - action(_table[i]);
|
| - _checkModification(modificationCount);
|
| - }
|
| - }
|
| -
|
| - bool get isEmpty => _head == _tail;
|
| -
|
| - int get length => (_tail - _head) & (_table.length - 1);
|
| -
|
| - E get first {
|
| - if (_head == _tail) throw IterableElementError.noElement();
|
| - return _table[_head];
|
| - }
|
| -
|
| - E get last {
|
| - if (_head == _tail) throw IterableElementError.noElement();
|
| - return _table[(_tail - 1) & (_table.length - 1)];
|
| - }
|
| -
|
| - E get single {
|
| - if (_head == _tail) throw IterableElementError.noElement();
|
| - if (length > 1) throw IterableElementError.tooMany();
|
| - return _table[_head];
|
| - }
|
| -
|
| - E elementAt(int index) {
|
| - RangeError.checkValidIndex(index, this);
|
| - return _table[(_head + index) & (_table.length - 1)];
|
| - }
|
| -
|
| - List<E> toList({ bool growable: true }) {
|
| - List<E> list;
|
| - if (growable) {
|
| - list = new List<E>()..length = length;
|
| - } else {
|
| - list = new List<E>(length);
|
| - }
|
| - _writeToList(list);
|
| - return list;
|
| - }
|
| -
|
| - // Collection interface.
|
| -
|
| - void add(E value) {
|
| - _add(value);
|
| - }
|
| -
|
| - void addAll(Iterable<E> elements) {
|
| - if (elements is List/*<E>*/) {
|
| - List<E> list = elements;
|
| - int addCount = list.length;
|
| - int length = this.length;
|
| - if (length + addCount >= _table.length) {
|
| - _preGrow(length + addCount);
|
| - // After preGrow, all elements are at the start of the list.
|
| - _table.setRange(length, length + addCount, list, 0);
|
| - _tail += addCount;
|
| - } else {
|
| - // Adding addCount elements won't reach _head.
|
| - int endSpace = _table.length - _tail;
|
| - if (addCount < endSpace) {
|
| - _table.setRange(_tail, _tail + addCount, list, 0);
|
| - _tail += addCount;
|
| - } else {
|
| - int preSpace = addCount - endSpace;
|
| - _table.setRange(_tail, _tail + endSpace, list, 0);
|
| - _table.setRange(0, preSpace, list, endSpace);
|
| - _tail = preSpace;
|
| - }
|
| - }
|
| - _modificationCount++;
|
| - } else {
|
| - for (E element in elements) _add(element);
|
| - }
|
| - }
|
| -
|
| - bool remove(Object value) {
|
| - for (int i = _head; i != _tail; i = (i + 1) & (_table.length - 1)) {
|
| - E element = _table[i];
|
| - if (element == value) {
|
| - _remove(i);
|
| - _modificationCount++;
|
| - return true;
|
| - }
|
| - }
|
| - return false;
|
| - }
|
| -
|
| - void _filterWhere(bool test(E element), bool removeMatching) {
|
| - int modificationCount = _modificationCount;
|
| - int i = _head;
|
| - while (i != _tail) {
|
| - E element = _table[i];
|
| - bool remove = identical(removeMatching, test(element));
|
| - _checkModification(modificationCount);
|
| - if (remove) {
|
| - i = _remove(i);
|
| - modificationCount = ++_modificationCount;
|
| - } else {
|
| - i = (i + 1) & (_table.length - 1);
|
| - }
|
| - }
|
| - }
|
| -
|
| - /**
|
| - * Remove all elements matched by [test].
|
| - *
|
| - * This method is inefficient since it works by repeatedly removing single
|
| - * elements, each of which can take linear time.
|
| - */
|
| - void removeWhere(bool test(E element)) {
|
| - _filterWhere(test, true);
|
| - }
|
| -
|
| - /**
|
| - * Remove all elements not matched by [test].
|
| - *
|
| - * This method is inefficient since it works by repeatedly removing single
|
| - * elements, each of which can take linear time.
|
| - */
|
| - void retainWhere(bool test(E element)) {
|
| - _filterWhere(test, false);
|
| - }
|
| -
|
| - void clear() {
|
| - if (_head != _tail) {
|
| - for (int i = _head; i != _tail; i = (i + 1) & (_table.length - 1)) {
|
| - _table[i] = null;
|
| - }
|
| - _head = _tail = 0;
|
| - _modificationCount++;
|
| - }
|
| - }
|
| -
|
| - String toString() => IterableBase.iterableToFullString(this, "{", "}");
|
| -
|
| - // Queue interface.
|
| -
|
| - void addLast(E value) { _add(value); }
|
| -
|
| - void addFirst(E value) {
|
| - _head = (_head - 1) & (_table.length - 1);
|
| - _table[_head] = value;
|
| - if (_head == _tail) _grow();
|
| - _modificationCount++;
|
| - }
|
| -
|
| - E removeFirst() {
|
| - if (_head == _tail) throw IterableElementError.noElement();
|
| - _modificationCount++;
|
| - E result = _table[_head];
|
| - _table[_head] = null;
|
| - _head = (_head + 1) & (_table.length - 1);
|
| - return result;
|
| - }
|
| -
|
| - E removeLast() {
|
| - if (_head == _tail) throw IterableElementError.noElement();
|
| - _modificationCount++;
|
| - _tail = (_tail - 1) & (_table.length - 1);
|
| - E result = _table[_tail];
|
| - _table[_tail] = null;
|
| - return result;
|
| - }
|
| -
|
| - // Internal helper functions.
|
| -
|
| - /**
|
| - * Whether [number] is a power of two.
|
| - *
|
| - * Only works for positive numbers.
|
| - */
|
| - static bool _isPowerOf2(int number) => (number & (number - 1)) == 0;
|
| -
|
| - /**
|
| - * Rounds [number] up to the nearest power of 2.
|
| - *
|
| - * If [number] is a power of 2 already, it is returned.
|
| - *
|
| - * Only works for positive numbers.
|
| - */
|
| - static int _nextPowerOf2(int number) {
|
| - assert(number > 0);
|
| - number = (number << 1) - 1;
|
| - for(;;) {
|
| - int nextNumber = number & (number - 1);
|
| - if (nextNumber == 0) return number;
|
| - number = nextNumber;
|
| - }
|
| - }
|
| -
|
| - /** Check if the queue has been modified during iteration. */
|
| - void _checkModification(int expectedModificationCount) {
|
| - if (expectedModificationCount != _modificationCount) {
|
| - throw new ConcurrentModificationError(this);
|
| - }
|
| - }
|
| -
|
| - /** Adds element at end of queue. Used by both [add] and [addAll]. */
|
| - void _add(E element) {
|
| - _table[_tail] = element;
|
| - _tail = (_tail + 1) & (_table.length - 1);
|
| - if (_head == _tail) _grow();
|
| - _modificationCount++;
|
| - }
|
| -
|
| - /**
|
| - * Removes the element at [offset] into [_table].
|
| - *
|
| - * Removal is performed by linerarly moving elements either before or after
|
| - * [offset] by one position.
|
| - *
|
| - * Returns the new offset of the following element. This may be the same
|
| - * offset or the following offset depending on how elements are moved
|
| - * to fill the hole.
|
| - */
|
| - int _remove(int offset) {
|
| - int mask = _table.length - 1;
|
| - int startDistance = (offset - _head) & mask;
|
| - int endDistance = (_tail - offset) & mask;
|
| - if (startDistance < endDistance) {
|
| - // Closest to start.
|
| - int i = offset;
|
| - while (i != _head) {
|
| - int prevOffset = (i - 1) & mask;
|
| - _table[i] = _table[prevOffset];
|
| - i = prevOffset;
|
| - }
|
| - _table[_head] = null;
|
| - _head = (_head + 1) & mask;
|
| - return (offset + 1) & mask;
|
| - } else {
|
| - _tail = (_tail - 1) & mask;
|
| - int i = offset;
|
| - while (i != _tail) {
|
| - int nextOffset = (i + 1) & mask;
|
| - _table[i] = _table[nextOffset];
|
| - i = nextOffset;
|
| - }
|
| - _table[_tail] = null;
|
| - return offset;
|
| - }
|
| - }
|
| -
|
| - /**
|
| - * Grow the table when full.
|
| - */
|
| - void _grow() {
|
| - List<E> newTable = new List<E>(_table.length * 2);
|
| - int split = _table.length - _head;
|
| - newTable.setRange(0, split, _table, _head);
|
| - newTable.setRange(split, split + _head, _table, 0);
|
| - _head = 0;
|
| - _tail = _table.length;
|
| - _table = newTable;
|
| - }
|
| -
|
| - int _writeToList(List<E> target) {
|
| - assert(target.length >= length);
|
| - if (_head <= _tail) {
|
| - int length = _tail - _head;
|
| - target.setRange(0, length, _table, _head);
|
| - return length;
|
| - } else {
|
| - int firstPartSize = _table.length - _head;
|
| - target.setRange(0, firstPartSize, _table, _head);
|
| - target.setRange(firstPartSize, firstPartSize + _tail, _table, 0);
|
| - return _tail + firstPartSize;
|
| - }
|
| - }
|
| -
|
| - /** Grows the table even if it is not full. */
|
| - void _preGrow(int newElementCount) {
|
| - assert(newElementCount >= length);
|
| -
|
| - // Add some extra room to ensure that there's room for more elements after
|
| - // expansion.
|
| - newElementCount += newElementCount >> 1;
|
| - int newCapacity = _nextPowerOf2(newElementCount);
|
| - List<E> newTable = new List<E>(newCapacity);
|
| - _tail = _writeToList(newTable);
|
| - _table = newTable;
|
| - _head = 0;
|
| - }
|
| -}
|
| -
|
| -/**
|
| - * Iterator for a [ListQueue].
|
| - *
|
| - * Considers any add or remove operation a concurrent modification.
|
| - */
|
| -class _ListQueueIterator<E> implements Iterator<E> {
|
| - final ListQueue<E> _queue;
|
| - final int _end;
|
| - final int _modificationCount;
|
| - int _position;
|
| - E _current;
|
| -
|
| - _ListQueueIterator(ListQueue<E> queue)
|
| - : _queue = queue,
|
| - _end = queue._tail,
|
| - _modificationCount = queue._modificationCount,
|
| - _position = queue._head;
|
| -
|
| - E get current => _current;
|
| -
|
| - bool moveNext() {
|
| - _queue._checkModification(_modificationCount);
|
| - if (_position == _end) {
|
| - _current = null;
|
| - return false;
|
| - }
|
| - _current = _queue._table[_position];
|
| - _position = (_position + 1) & (_queue._table.length - 1);
|
| - return true;
|
| - }
|
| -}
|
|
|