| Index: lib/src/linked_list.dart
|
| diff --git a/lib/src/linked_list.dart b/lib/src/linked_list.dart
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..e95cfd48409aa62b07a65de93fd20f10bb2ea28e
|
| --- /dev/null
|
| +++ b/lib/src/linked_list.dart
|
| @@ -0,0 +1,82 @@
|
| +// Copyright (c) 2012, 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.
|
| +
|
| +/**
|
| + * A doubly-linked list, adapted from DoubleLinkedQueueEntry in
|
| + * sdk/lib/collection/queue.dart.
|
| + */
|
| +// TODO(jmesserly): this should be in a shared pkg somewhere. Surely I am not
|
| +// the only person who will want to use a linked list :)
|
| +library linked_list;
|
| +
|
| +/**
|
| + * An entry in a doubly linked list. It contains a pointer to the next
|
| + * entry, the previous entry, and the boxed value.
|
| + */
|
| +class LinkedListNode<E> {
|
| + LinkedListNode<E> _previous;
|
| + LinkedListNode<E> _next;
|
| + E _value;
|
| +
|
| + LinkedListNode._(E e) {
|
| + _value = e;
|
| + }
|
| +
|
| + void _link(LinkedListNode<E> p, LinkedListNode<E> n) {
|
| + _next = n;
|
| + _previous = p;
|
| + p._next = this;
|
| + n._previous = this;
|
| + }
|
| +
|
| + LinkedListNode<E> append(E e) =>
|
| + new LinkedListNode<E>._(e).._link(this, _next);
|
| +
|
| + LinkedListNode<E> prepend(E e) =>
|
| + new LinkedListNode<E>._(e).._link(_previous, this);
|
| +
|
| + void remove() {
|
| + _previous._next = _next;
|
| + _next._previous = _previous;
|
| + _next = null;
|
| + _previous = null;
|
| + }
|
| +
|
| + LinkedListNode<E> get _nonSentinel => this;
|
| +
|
| + LinkedListNode<E> get previous => _previous._nonSentinel;
|
| +
|
| + LinkedListNode<E> get next => _next._nonSentinel;
|
| +
|
| + E get value => _value;
|
| +
|
| + set value(E e) => _value = 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 value.
|
| + */
|
| +class LinkedListSentinel<E> extends LinkedListNode<E> {
|
| + LinkedListSentinel() : super._(null) {
|
| + _link(this, this);
|
| + }
|
| +
|
| + void remove() {
|
| + throw new StateError("Empty list");
|
| + }
|
| +
|
| + LinkedListNode<E> get _nonSentinel => null;
|
| +
|
| + void set value(E e) {
|
| + throw new StateError("Empty list");
|
| + }
|
| +
|
| + E get value {
|
| + throw new StateError("Empty list");
|
| + }
|
| +}
|
|
|