| Index: lib/core/sequences.dart
|
| diff --git a/lib/core/sequences.dart b/lib/core/sequences.dart
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..5ed4366aa2e91f58330897c94e713d0d814d0c27
|
| --- /dev/null
|
| +++ b/lib/core/sequences.dart
|
| @@ -0,0 +1,204 @@
|
| +// 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.
|
| +
|
| +/**
|
| + * An indexed sequence of elements of the same type.
|
| + *
|
| + * This is a primitive interface that any finite integer-indexable
|
| + * sequence can implement.
|
| + * It is intended for data structures where access by index is
|
| + * the most efficient way to access the data.
|
| + */
|
| +abstract class Sequence<T> {
|
| + /**
|
| + * The limit of valid indices of the sequence.
|
| + *
|
| + * The length getter should be efficient.
|
| + */
|
| + int get length;
|
| +
|
| + /**
|
| + * Returns the value at the given [index].
|
| + *
|
| + * Valid indices must be in the range [:0..length - 1:].
|
| + * The lookup operator should be efficient.
|
| + */
|
| + T operator[](int index);
|
| +}
|
| +
|
| +/**
|
| + * A skeleton class for a [Collection] that is also a [Sequence].
|
| + */
|
| +abstract class SequenceCollection<E> implements Collection<E>, Sequence<E> {
|
| + // The class is intended for use as a mixin as well.
|
| +
|
| + Iterator<E> iterator() => new SequenceIterator(sequence);
|
| +
|
| + void forEach(f(E element)) {
|
| + for (int i = 0; i < this.length; i++) f(this[i]);
|
| + }
|
| +
|
| + Collection map(f(E element)) {
|
| + List result = new List();
|
| + for (int i = 0; i < this.length; i++) {
|
| + result.add(f(this[i]));
|
| + }
|
| + return result;
|
| + }
|
| +
|
| + bool contains(E value) {
|
| + for (int i = 0; i < sequence.length; i++) {
|
| + if (sequence[i] == value) return true;
|
| + }
|
| + return false;
|
| + }
|
| +
|
| + reduce(initialValue, combine(previousValue, E element)) {
|
| + var value = initialValue;
|
| + for (int i = 0; i < this.length; i++) {
|
| + value = combine(value, this[i]);
|
| + }
|
| + return value;
|
| + }
|
| +
|
| + Collection<E> filter(bool f(E element)) {
|
| + List<E> result = <E>[];
|
| + for (int i = 0; i < this.length; i++) {
|
| + E element = this[i];
|
| + if (f(element)) result.add(element);
|
| + }
|
| + return result;
|
| + }
|
| +
|
| + bool every(bool f(E element)) {
|
| + for (int i = 0; i < this.length; i++) {
|
| + if (!f(this[i])) return false;
|
| + }
|
| + return true;
|
| + }
|
| +
|
| + bool some(bool f(E element)) {
|
| + for (int i = 0; i < this.length; i++) {
|
| + if (f(this[i])) return true;
|
| + }
|
| + return false;
|
| + }
|
| +
|
| + bool isEmpty() {
|
| + return this.length == 0;
|
| + }
|
| +}
|
| +
|
| +
|
| +/**
|
| + * An unmodifiable [List] backed by a [Sequence].
|
| + */
|
| +class SequenceList<E> extends SequenceCollection<E> implements List<E> {
|
| + Sequence<E> sequence;
|
| + SequenceList(this.sequence);
|
| +
|
| + int get length => sequence.length;
|
| +
|
| + T operator[](int index) => sequence[index];
|
| +
|
| + int indexOf(E value, [int start = 0]) {
|
| + for (int i = start; i < sequence.length; i++) {
|
| + if (sequence[i] == value) return i;
|
| + }
|
| + return -1;
|
| + }
|
| +
|
| + int lastIndexOf(E value, [int start]) {
|
| + if (start == null) start = sequence.length - 1;
|
| + for (int i = start; i >= 0; i--) {
|
| + if (sequence[i] == value) return i;
|
| + }
|
| + return -1;
|
| + }
|
| +
|
| + E last() => sequence[sequence.length - 1];
|
| +
|
| + List<E> getRange(int start, int length) {
|
| + List<E> result = <E>[];
|
| + for (int i = 0; i < length; i++) {
|
| + result.add(sequence[start + i]);
|
| + }
|
| + return result;
|
| + }
|
| +
|
| + void operator []=(int index, E value) {
|
| + throw new UnsupportedOperationException(
|
| + "Cannot modify an unmodifiable list");
|
| + }
|
| +
|
| + void set length(int newLength) {
|
| + throw new UnsupportedOperationException(
|
| + "Cannot change the length of an unmodifiable list");
|
| + }
|
| +
|
| + void add(E value) {
|
| + throw new UnsupportedOperationException(
|
| + "Cannot add to an unmodifiable list");
|
| + }
|
| +
|
| + void addLast(E value) {
|
| + throw new UnsupportedOperationException(
|
| + "Cannot add to an unmodifiable list");
|
| + }
|
| +
|
| + void addAll(Collection<E> collection) {
|
| + throw new UnsupportedOperationException(
|
| + "Cannot add to an unmodifiable list");
|
| + }
|
| +
|
| + void sort([Comparator<E> compare]) {
|
| + throw new UnsupportedOperationException(
|
| + "Cannot modify an unmodifiable list");
|
| + }
|
| +
|
| + void clear() {
|
| + throw new UnsupportedOperationException(
|
| + "Cannot clear an unmodifiable list");
|
| + }
|
| +
|
| + E removeAt(int index) {
|
| + throw new UnsupportedOperationException(
|
| + "Cannot remove in an unmodifiable list");
|
| + }
|
| +
|
| + E removeLast() {
|
| + throw new UnsupportedOperationException(
|
| + "Cannot remove in an unmodifiable list");
|
| + }
|
| +
|
| + void setRange(int start, int length, List<E> from, [int startFrom]) {
|
| + throw new UnsupportedOperationException(
|
| + "Cannot modify an unmodifiable list");
|
| + }
|
| +
|
| + void removeRange(int start, int length) {
|
| + throw new UnsupportedOperationException(
|
| + "Cannot remove in an unmodifiable list");
|
| + }
|
| +
|
| + void insertRange(int start, int length, [E initialValue]) {
|
| + throw new UnsupportedOperationException(
|
| + "Cannot insert range in an unmodifiable list");
|
| + }
|
| +}
|
| +
|
| +/**
|
| + * Iterates over a [Sequence] in growing index order.
|
| + */
|
| +class SequenceIterator<E> implements Iterator<E> {
|
| + Sequence<E> _sequence;
|
| + int _position;
|
| + SequenceIterator(this._sequence) : _position = 0;
|
| + bool hasNext() => _position < _sequence.length;
|
| + E next() {
|
| + if (hasNext()) return _sequence[_position++];
|
| + throw new NoMoreElementsException();
|
| + }
|
| +}
|
| +
|
|
|