Index: lib/core/sequences.dart |
diff --git a/lib/core/sequences.dart b/lib/core/sequences.dart |
new file mode 100644 |
index 0000000000000000000000000000000000000000..56eff07858455300bed40d291ba962fc7e69b274 |
--- /dev/null |
+++ b/lib/core/sequences.dart |
@@ -0,0 +1,178 @@ |
+// 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 |
+ * sequences can implement. |
floitsch
2012/10/16 14:03:19
sequence (-s)
Lasse Reichstein Nielsen
2012/10/17 11:06:45
Done.
|
+ */ |
+abstract class Sequence<T> { |
+ int get length; |
+ T operator[](int index); |
+} |
+ |
+/** |
+ * A skeleton class for a [Collection] that is also a [Sequence]. |
sra1
2012/10/16 18:52:52
The assumption is that length is efficient, otherw
Lasse Reichstein Nielsen
2012/10/17 11:06:45
True. I'm adding this as comments on the methods o
|
+ */ |
+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(this.length); |
floitsch
2012/10/16 14:03:19
This violates the specification of 'map' which spe
sra1
2012/10/16 18:52:52
Dont make the returned value fixed length, since i
Lasse Reichstein Nielsen
2012/10/17 11:06:45
That specification can't be followed exactly. Ther
floitsch
2012/10/17 13:19:32
That was not my point: from what I can see this cl
|
+ for (int i = 0; i < this.length; i++) { |
+ result[i] = f(this[i]); |
+ } |
+ return result; |
+ } |
+ |
+ bool contains(E value) { |
+ for (int i = 0; i < sequence.length; i++) { |
floitsch
2012/10/16 14:03:19
I would store the length in a variable, but that's
Lasse Reichstein Nielsen
2012/10/17 11:06:45
I try to avoid that when I don't know whether the
|
+ 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>[]; |
floitsch
2012/10/16 14:03:19
Ditto: violates the contract.
Lasse Reichstein Nielsen
2012/10/17 11:06:45
Arguably.
|
+ 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 IllegalAccessException(); |
+ } |
+ |
+ void set length(int newLength) { |
+ throw new IllegalAccessException(); |
+ } |
+ |
+ void add(E value) { |
+ throw new IllegalAccessException(); |
+ } |
+ |
+ void addLast(E value) { |
+ throw new IllegalAccessException(); |
+ } |
+ |
+ void addAll(Collection<E> collection) { |
+ throw new IllegalAccessException(); |
+ } |
+ |
+ void sort(Comparator<E> compare) { |
+ throw new IllegalAccessException(); |
ngeoffray
2012/10/16 15:08:18
Access? Should it be UnsupportedOperationException
Lasse Reichstein Nielsen
2012/10/17 11:06:45
You are right - the VM's implementation mostly use
|
+ } |
+ |
+ void clear() { |
+ throw new IllegalAccessException(); |
+ } |
+ |
+ E removeAt(int index) { |
+ throw new IllegalAccessException(); |
+ } |
+ |
+ E removeLast() { |
+ throw new IllegalAccessException(); |
+ } |
+ |
+ void setRange(int start, int length, List<E> from, [int startFrom]) { |
+ throw new IllegalAccessException(); |
+ } |
+ |
+ void removeRange(int start, int length) { |
+ throw new IllegalAccessException(); |
+ } |
+ |
+ void insertRange(int start, int length, [E initialValue]) { |
+ throw new IllegalAccessException(); |
+ } |
+} |
+ |
+/** |
+ * 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(); |
+ } |
+} |
+ |