Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(544)

Unified Diff: lib/core/queue.dart

Issue 11339038: Move DoubleLinkedQueue from coreimpl to core. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 8 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « lib/core/core.dart ('k') | lib/coreimpl/coreimpl.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: lib/core/queue.dart
diff --git a/lib/core/queue.dart b/lib/core/queue.dart
index ecdfe3641d6057297258c8e91abbdbdd40b7c3c3..bf1e49c2113bbc97e3066b5a9e98891c697aee05 100644
--- a/lib/core/queue.dart
+++ b/lib/core/queue.dart
@@ -70,3 +70,269 @@ abstract class Queue<E> extends Collection<E> {
*/
void clear();
}
+
+
+/**
+ * An entry in a doubly linked list. It contains a pointer to the next
+ * entry, the previous entry, and the boxed element.
+ *
+ * WARNING: This class is temporary located in dart:core. It'll be removed
+ * at some point in the near future.
+ */
+class DoubleLinkedQueueEntry<E> {
+ DoubleLinkedQueueEntry<E> _previous;
+ DoubleLinkedQueueEntry<E> _next;
+ E _element;
+
+ DoubleLinkedQueueEntry(E e) {
+ _element = e;
+ }
+
+ void _link(DoubleLinkedQueueEntry<E> p,
+ DoubleLinkedQueueEntry<E> n) {
+ _next = n;
+ _previous = p;
+ p._next = this;
+ n._previous = this;
+ }
+
+ void append(E e) {
+ new DoubleLinkedQueueEntry<E>(e)._link(this, _next);
+ }
+
+ void prepend(E e) {
+ new DoubleLinkedQueueEntry<E>(e)._link(_previous, this);
+ }
+
+ E remove() {
+ _previous._next = _next;
+ _next._previous = _previous;
+ _next = null;
+ _previous = null;
+ return _element;
+ }
+
+ DoubleLinkedQueueEntry<E> _asNonSentinelEntry() {
+ return this;
+ }
+
+ DoubleLinkedQueueEntry<E> previousEntry() {
+ return _previous._asNonSentinelEntry();
+ }
+
+ DoubleLinkedQueueEntry<E> nextEntry() {
+ return _next._asNonSentinelEntry();
+ }
+
+ E get element {
+ return _element;
+ }
+
+ void set element(E e) {
+ _element = e;
+ }
+}
+
+/**
+ * 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 _DoubleLinkedQueueEntrySentinel<E> extends DoubleLinkedQueueEntry<E> {
+ _DoubleLinkedQueueEntrySentinel() : super(null) {
+ _link(this, this);
+ }
+
+ E remove() {
+ throw new StateError("Empty queue");
+ }
+
+ DoubleLinkedQueueEntry<E> _asNonSentinelEntry() {
+ return null;
+ }
+
+ void set element(E e) {
+ // This setter is unreachable.
+ assert(false);
+ }
+
+ E get element {
+ throw new StateError("Empty queue");
+ }
+}
+
+/**
+ * Implementation of a double linked list that box list elements into
+ * DoubleLinkedQueueEntry objects.
+ *
+ * WARNING: This class is temporary located in dart:core. It'll be removed
+ * at some point in the near future.
+ */
+class DoubleLinkedQueue<E> implements Queue<E> {
+ _DoubleLinkedQueueEntrySentinel<E> _sentinel;
+
+ DoubleLinkedQueue() {
+ _sentinel = new _DoubleLinkedQueueEntrySentinel<E>();
+ }
+
+ factory DoubleLinkedQueue.from(Iterable<E> other) {
+ Queue<E> list = new DoubleLinkedQueue();
+ for (final e in other) {
+ list.addLast(e);
+ }
+ return list;
+ }
+
+ void addLast(E value) {
+ _sentinel.prepend(value);
+ }
+
+ void addFirst(E value) {
+ _sentinel.append(value);
+ }
+
+ void add(E value) {
+ addLast(value);
+ }
+
+ void addAll(Collection<E> collection) {
+ for (final e in collection) {
+ add(e);
+ }
+ }
+
+ E removeLast() {
+ return _sentinel._previous.remove();
+ }
+
+ E removeFirst() {
+ return _sentinel._next.remove();
+ }
+
+ E get first {
+ return _sentinel._next.element;
+ }
+
+ E get last {
+ return _sentinel._previous.element;
+ }
+
+ DoubleLinkedQueueEntry<E> lastEntry() {
+ return _sentinel.previousEntry();
+ }
+
+ DoubleLinkedQueueEntry<E> firstEntry() {
+ return _sentinel.nextEntry();
+ }
+
+ int get length {
+ int counter = 0;
+ forEach(void _(E element) { counter++; });
+ return counter;
+ }
+
+ bool get isEmpty {
+ return (_sentinel._next === _sentinel);
+ }
+
+ void clear() {
+ _sentinel._next = _sentinel;
+ _sentinel._previous = _sentinel;
+ }
+
+ void forEach(void f(E element)) {
+ DoubleLinkedQueueEntry<E> entry = _sentinel._next;
+ while (entry !== _sentinel) {
+ DoubleLinkedQueueEntry<E> nextEntry = entry._next;
+ f(entry._element);
+ entry = nextEntry;
+ }
+ }
+
+ void forEachEntry(void f(DoubleLinkedQueueEntry<E> element)) {
+ DoubleLinkedQueueEntry<E> entry = _sentinel._next;
+ while (entry !== _sentinel) {
+ DoubleLinkedQueueEntry<E> nextEntry = entry._next;
+ f(entry);
+ entry = nextEntry;
+ }
+ }
+
+ bool every(bool f(E element)) {
+ DoubleLinkedQueueEntry<E> entry = _sentinel._next;
+ while (entry !== _sentinel) {
+ DoubleLinkedQueueEntry<E> nextEntry = entry._next;
+ if (!f(entry._element)) return false;
+ entry = nextEntry;
+ }
+ return true;
+ }
+
+ bool some(bool f(E element)) {
+ DoubleLinkedQueueEntry<E> entry = _sentinel._next;
+ while (entry !== _sentinel) {
+ DoubleLinkedQueueEntry<E> nextEntry = entry._next;
+ if (f(entry._element)) return true;
+ entry = nextEntry;
+ }
+ return false;
+ }
+
+ Queue map(f(E element)) {
+ Queue other = new Queue();
+ DoubleLinkedQueueEntry<E> entry = _sentinel._next;
+ while (entry !== _sentinel) {
+ DoubleLinkedQueueEntry<E> nextEntry = entry._next;
+ other.addLast(f(entry._element));
+ entry = nextEntry;
+ }
+ return other;
+ }
+
+ Dynamic reduce(Dynamic initialValue,
+ Dynamic combine(Dynamic previousValue, E element)) {
+ return Collections.reduce(this, initialValue, combine);
+ }
+
+ Queue<E> filter(bool f(E element)) {
+ Queue<E> other = new Queue<E>();
+ DoubleLinkedQueueEntry<E> entry = _sentinel._next;
+ while (entry !== _sentinel) {
+ DoubleLinkedQueueEntry<E> nextEntry = entry._next;
+ if (f(entry._element)) other.addLast(entry._element);
+ entry = nextEntry;
+ }
+ return other;
+ }
+
+ _DoubleLinkedQueueIterator<E> iterator() {
+ return new _DoubleLinkedQueueIterator<E>(_sentinel);
+ }
+
+ String toString() {
+ return Collections.collectionToString(this);
+ }
+}
+
+class _DoubleLinkedQueueIterator<E> implements Iterator<E> {
+ final _DoubleLinkedQueueEntrySentinel<E> _sentinel;
+ DoubleLinkedQueueEntry<E> _currentEntry;
+
+ _DoubleLinkedQueueIterator(_DoubleLinkedQueueEntrySentinel this._sentinel) {
+ _currentEntry = _sentinel;
+ }
+
+ bool get hasNext {
+ return _currentEntry._next !== _sentinel;
+ }
+
+ E next() {
+ if (!hasNext) {
+ throw new StateError("No more elements");
+ }
+ _currentEntry = _currentEntry._next;
+ return _currentEntry.element;
+ }
+}
« no previous file with comments | « lib/core/core.dart ('k') | lib/coreimpl/coreimpl.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698