// 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 EfficientLengthIterable<E> {
  /**
   * 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].
   *
   * All the [elements] should be instances of [E].
   * The `elements` iterable itself may have any element type, so this
   * constructor can be used to down-cast a `Queue`, for example as:
   * ```dart
   * Queue<SuperType> superQueue = ...;
   * Queue<SubType> subQueue =
   *     new Queue<SubType>.from(superSet.whereType<SubType>());
   * ```
   */
  factory Queue.from(Iterable elements) = ListQueue<E>.from;

  /**
   * Creates a queue from [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.of(Iterable<E> elements) = ListQueue<E>.of;

  /**
   * Adapts [source] to be a `Queue<T>`.
   *
   * Any time the queue would produce an element that is not a [T],
   * the element access will throw.
   *
   * Any time a [T] value is attempted stored into the adapted queue,
   * the store will throw unless the value is also an instance of [S].
   *
   * If all accessed elements of [source] are actually instances of [T],
   * and if all elements stored into the returned queue are actually instance
   * of [S],
   * then the returned queue can be used as a `Queue<T>`.
   */
  static Queue<T> castFrom<S, T>(Queue<S> source) =>
      new CastQueue<S, T>(source);

  /**
   * Provides a view of this queue as a queue of [R] instances.
   *
   * If this queue is already a `Queue<R>`, it is returned unchanged.
   *
   * If this queue contains only instances of [R], all read operations
   * will work correctly. If any operation tries to access an element
   * that is not an instance of [R], the access will throw instead.
   *
   * Elements added to the queue (e.g., by using [addFirst] or [addAll])
   * must be instance of [R] to be valid arguments to the adding function,
   * and they must be instances of [E] as well to be accepted by
   * this queue as well.
   */
  Queue<R> cast<R>();

  /**
   * Provides a view of this queue as a queue of [R] instances, if necessary.
   *
   * If this queue contains only instances of [R], all read operations
   * will work correctly. If any operation tries to access an element
   * that is not an instance of [R], the access will throw instead.
   *
   * Elements added to the queue (e.g., by using [addFirst] or [addAll])
   * must be instance of [R] to be valid arguments to the adding function,
   * and they must be instances of [E] as well to be accepted by
   * this queue as well.
   */
  Queue<R> retype<R>();

  /**
   * 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<Link extends _DoubleLink<Link>> {
  Link _previousLink;
  Link _nextLink;

  void _link(Link previous, Link 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.
 */
class DoubleLinkedQueueEntry<E> extends _DoubleLink<DoubleLinkedQueueEntry<E>> {
  /// The element in the queue.
  E element;

  DoubleLinkedQueueEntry(this.element);

  /// Appends the given [e] as entry just after this entry.
  void append(E e) {
    new DoubleLinkedQueueEntry<E>(e)._link(this, _nextLink);
  }

  /// Prepends the given [e] as entry just before this entry.
  void prepend(E e) {
    new DoubleLinkedQueueEntry<E>(e)._link(_previousLink, this);
  }

  E remove() {
    _unlink();
    return element;
  }

  /// Returns the previous entry or `null` if there is none.
  DoubleLinkedQueueEntry<E> previousEntry() => _previousLink;

  /// Returns the next entry or `null` if there is none.
  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 DoubleLinkedQueueEntry<E> {
  DoubleLinkedQueue<E> _queue;
  _DoubleLinkedQueueEntry(E element, this._queue) : super(element);

  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 => element;

  DoubleLinkedQueueEntry<E> nextEntry() {
    _DoubleLinkedQueueEntry<E> entry = _nextLink;
    return entry._asNonSentinelEntry();
  }

  DoubleLinkedQueueEntry<E> previousEntry() {
    _DoubleLinkedQueueEntry<E> entry = _previousLink;
    return entry._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> {
  _DoubleLinkedQueueElement(E element, DoubleLinkedQueue<E> queue)
      : super(element, 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(null, 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].
   *
   * All the [elements] should be instances of [E].
   * The `elements` iterable itself may have any element type, so this
   * constructor can be used to down-cast a `Queue`, for example as:
   * ```dart
   * Queue<SuperType> superQueue = ...;
   * Queue<SubType> subQueue =
   *     new DoubleLinkedQueue<SubType>.from(superQueue.whereType<SubType>());
   * ```
   */
  factory DoubleLinkedQueue.from(Iterable elements) {
    Queue<E> list = new DoubleLinkedQueue<E>();
    for (final e in elements) {
      list.addLast(e);
    }
    return list;
  }

  /**
   * Creates a double-linked queue from [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.of(Iterable<E> elements) =>
      new DoubleLinkedQueue<E>()..addAll(elements);

  Queue<R> cast<R>() {
    Queue<Object> self = this;
    return self is Queue<R> ? self : Queue.castFrom<E, R>(this);
  }

  Queue<R> retype<R>() => Queue.castFrom<E, R>(this);

  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)) {
      bool equals = (entry._element == o);
      if (!identical(this, entry._queue)) {
        // Entry must still be in the queue.
        throw new ConcurrentModificationError(this);
      }
      if (equals) {
        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)) {
      bool matches = test(entry._element);
      if (!identical(this, entry._queue)) {
        // Entry must still be in the queue.
        throw new ConcurrentModificationError(this);
      }
      _DoubleLinkedQueueEntry<E> next = entry._nextLink; // Cannot be null.
      if (identical(removeMatching, matches)) {
        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 the element of the sentinel throws.
    if (identical(_sentinel._nextLink, _sentinel._previousLink)) {
      _DoubleLinkedQueueEntry<E> entry = _sentinel._nextLink;
      return entry._element;
    }
    throw IterableElementError.tooMany();
  }

  /**
   * The entry object of the first element in the queue.
   *
   * Each element of the queue has an associated [DoubleLinkedQueueEntry].
   * Returns the entry object corresponding to the first element of the queue.
   *
   * The entry objects can also be accessed using [lastEntry],
   * and they can be iterated using [DoubleLinkedQueueEntry.nextEntry()] and
   * [DoubleLinkedQueueEntry.previousEntry()].
   */
  DoubleLinkedQueueEntry<E> firstEntry() {
    return _sentinel.nextEntry();
  }

  /**
   * The entry object of the last element in the queue.
   *
   * Each element of the queue has an associated [DoubleLinkedQueueEntry].
   * Returns the entry object corresponding to the last element of the queue.
   *
   * The entry objects can also be accessed using [firstEntry],
   * and they can be iterated using [DoubleLinkedQueueEntry.nextEntry()] and
   * [DoubleLinkedQueueEntry.previousEntry()].
   */
  DoubleLinkedQueueEntry<E> lastEntry() {
    return _sentinel.previousEntry();
  }

  bool get isEmpty {
    return (identical(_sentinel._nextLink, _sentinel));
  }

  void clear() {
    _sentinel._nextLink = _sentinel;
    _sentinel._previousLink = _sentinel;
    _elementCount = 0;
  }

  /**
   * Calls [action] for each entry object of this double-linked queue.
   *
   * Each element of the queue has an associated [DoubleLinkedQueueEntry].
   * This method iterates the entry objects from first to last and calls
   * [action] with each object in turn.
   *
   * The entry objects can also be accessed using [firstEntry] and [lastEntry],
   * and iterated using [DoubleLinkedQueueEntry.nextEntry()] and
   * [DoubleLinkedQueueEntry.previousEntry()].
   *
   * The [action] function can use methods on [DoubleLinkedQueueEntry] to remove
   * the entry or it can insert elements before or after then entry.
   * If the current entry is removed, iteration continues with the entry that
   * was following the current entry when [action] was called. Any elements
   * inserted after the current element before it is removed will not be
   * visited by the iteration.
   */
  void forEachEntry(void action(DoubleLinkedQueueEntry<E> element)) {
    _DoubleLinkedQueueEntry<E> entry = _sentinel._nextLink;
    while (!identical(entry, _sentinel)) {
      _DoubleLinkedQueueElement<E> element = entry;
      _DoubleLinkedQueueEntry<E> next = element._nextLink;
      // Remember both entry and entry._nextLink.
      // If someone calls `element.remove()` we continue from `next`.
      // Otherwise we use the value of entry._nextLink which may have been
      // updated.
      action(element);
      if (identical(this, entry._queue)) {
        next = entry._nextLink;
      } else if (!identical(this, next._queue)) {
        throw new ConcurrentModificationError(this);
      }
      entry = next;
    }
  }

  _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 (!identical(_sentinel._queue, elementEntry._queue)) {
      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 ListIterable<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 the [elements] should be instances of [E].
   * The `elements` iterable itself may have any element type, so this
   * constructor can be used to down-cast a `Queue`, for example as:
   * ```dart
   * Queue<SuperType> superQueue = ...;
   * Queue<SubType> subQueue =
   *     new ListQueue<SubType>.from(superQueue.whereType<SubType>());
   * ```
   */
  factory ListQueue.from(Iterable elements) {
    if (elements is List) {
      int length = elements.length;
      ListQueue<E> queue = new ListQueue<E>(length + 1);
      assert(queue._table.length > length);
      for (int i = 0; i < length; i++) {
        queue._table[i] = elements[i];
      }
      queue._tail = length;
      return queue;
    } else {
      int capacity = _INITIAL_CAPACITY;
      if (elements is EfficientLengthIterable) {
        capacity = elements.length;
      }
      ListQueue<E> result = new ListQueue<E>(capacity);
      for (final element in elements) {
        result.addLast(element);
      }
      return result;
    }
  }

  /**
   * Create a `ListQueue` from [elements].
   *
   * The elements are added to the queue, as by [addLast], in the order given by
   * `elements.iterator`.
   */
  factory ListQueue.of(Iterable<E> elements) =>
      new ListQueue<E>()..addAll(elements);

  // Iterable interface.

  Queue<R> cast<R>() {
    Queue<Object> self = this;
    return self is Queue<R> ? self : this.retype<R>();
  }

  Queue<R> retype<R>() => Queue.castFrom<E, R>(this);

  Iterator<E> get iterator => new _ListQueueIterator<E>(this);

  void forEach(void f(E element)) {
    int modificationCount = _modificationCount;
    for (int i = _head; i != _tail; i = (i + 1) & (_table.length - 1)) {
      f(_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 = <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 linearly 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;
  }
}
