Index: sdk/lib/collection/list.dart |
diff --git a/sdk/lib/collection/list.dart b/sdk/lib/collection/list.dart |
index 62bd84c5345e30111104f108799dc79c86936f01..8fe7901e161d048630d5437f028ae7a094882a36 100644 |
--- a/sdk/lib/collection/list.dart |
+++ b/sdk/lib/collection/list.dart |
@@ -13,6 +13,22 @@ part of dart.collection; |
typedef ListBase<E> = Object with ListMixin<E>; |
/** |
+ * Abstract implementation of a fixed-length list. |
floitsch
2013/04/10 15:14:07
I thought we agreed that these classes are not in
Lasse Reichstein Nielsen
2013/04/11 07:54:04
Yes, yet another bad merge. Seems I was working on
|
+ * |
+ * All operations are defined in terms of `length`, `operator[]` and |
+ * `operator[]=`, which need to be implemented. |
+ */ |
+typedef FixedLengthListBase<E> = ListBase<E> with FixedLengthListMixin<E>; |
+ |
+/** |
+ * Abstract implementation of an unmodifiable list. |
+ * |
+ * All operations are defined in terms of `length` and `operator[]`, |
+ * which need to be implemented. |
+ */ |
+typedef UnmodifiableListBase<E> = ListBase<E> with UnmodifiableListMixin<E>; |
+ |
+/** |
* Base implementation of a [List] class. |
* |
* This class can be used as a mixin. |
@@ -141,49 +157,9 @@ abstract class ListMixin<E> implements List<E> { |
throw new StateError("No matching element"); |
} |
- E min([int compare(E a, E b)]) { |
- if (length == 0) return null; |
- if (compare == null) { |
- var defaultCompare = Comparable.compare; |
- compare = defaultCompare; |
- } |
- E min = this[0]; |
+ String join([String separator]) { |
floitsch
2013/04/10 15:14:07
bad merge.
Lasse Reichstein Nielsen
2013/04/11 08:00:23
Done.
|
int length = this.length; |
- for (int i = 1; i < length; i++) { |
- E element = this[i]; |
- if (compare(min, element) > 0) { |
- min = element; |
- } |
- if (length != this.length) { |
- throw new ConcurrentModificationError(this); |
- } |
- } |
- return min; |
- } |
- |
- E max([int compare(E a, E b)]) { |
- if (length == 0) return null; |
- if (compare == null) { |
- var defaultCompare = Comparable.compare; |
- compare = defaultCompare; |
- } |
- E max = this[0]; |
- int length = this.length; |
- for (int i = 1; i < length; i++) { |
- E element = this[i]; |
- if (compare(max, element) < 0) { |
- max = element; |
- } |
- if (length != this.length) { |
- throw new ConcurrentModificationError(this); |
- } |
- } |
- return max; |
- } |
- |
- String join([String separator = ""]) { |
- int length = this.length; |
- if (!separator.isEmpty) { |
+ if (separator != null && !separator.isEmpty) { |
floitsch
2013/04/10 15:14:07
bad merge.
Lasse Reichstein Nielsen
2013/04/11 08:00:23
Done.
|
if (length == 0) return ""; |
String first = "${this[0]}"; |
if (length != this.length) { |
@@ -192,7 +168,7 @@ abstract class ListMixin<E> implements List<E> { |
StringBuffer buffer = new StringBuffer(first); |
for (int i = 1; i < length; i++) { |
buffer.write(separator); |
- buffer.write(this[i]); |
+ buffer.write("${this[i]}"); |
floitsch
2013/04/10 15:14:07
bad merge.
|
if (length != this.length) { |
throw new ConcurrentModificationError(this); |
} |
@@ -201,7 +177,7 @@ abstract class ListMixin<E> implements List<E> { |
} else { |
StringBuffer buffer = new StringBuffer(); |
for (int i = 0; i < length; i++) { |
- buffer.write(this[i]); |
+ buffer.write("${this[i]}"); |
floitsch
2013/04/10 15:14:07
bad merge.
|
if (length != this.length) { |
throw new ConcurrentModificationError(this); |
} |
@@ -214,8 +190,13 @@ abstract class ListMixin<E> implements List<E> { |
Iterable map(f(E element)) => new MappedListIterable(this, f); |
- reduce(var initialValue, combine(var previousValue, E element)) { |
- return fold(initialValue, combine); |
+ E reduce(E combine(E previousValue, E element)) { |
+ if (length == 0) throw new StateError("No elements"); |
+ E value = this[0]; |
+ for (int i = 1; i < length; i++) { |
+ value = combine(value, this[i]); |
+ } |
+ return value; |
} |
fold(var initialValue, combine(var previousValue, E element)) { |
@@ -292,7 +273,7 @@ abstract class ListMixin<E> implements List<E> { |
} |
- void retainAll(Iterable<E> elements) { |
+ void retainAll(Iterable<E> iterable) { |
if (elements is! Set) { |
elements = elements.toSet(); |
} |
@@ -327,19 +308,8 @@ abstract class ListMixin<E> implements List<E> { |
} |
} |
- void clear() { this.length = 0; } |
floitsch
2013/04/10 15:14:07
Didn't you just add them?
bad merge?
|
- |
// List interface. |
- E removeLast() { |
- if (length == 0) { |
- throw new StateError("No elements"); |
- } |
- E result = this[length - 1]; |
- length--; |
- return result; |
- } |
- |
void sort([Comparator<E> compare]) { |
Sort.sort(this, compare); |
} |
@@ -451,8 +421,8 @@ abstract class ListMixin<E> implements List<E> { |
if (startIndex < 0) { |
return -1; |
} |
- if (startIndex >= this.length) { |
- startIndex = this.length - 1; |
+ if (startIndex >= a.length) { |
floitsch
2013/04/10 15:14:07
I guess bad merge.
|
+ startIndex = a.length - 1; |
} |
} |
for (int i = startIndex; i >= 0; i--) { |
@@ -463,5 +433,186 @@ abstract class ListMixin<E> implements List<E> { |
return -1; |
} |
- Iterable<E> get reversed => new ReversedListIterable(this); |
+ Iterable<E> get reversed => new _ReversedListIterable(this); |
floitsch
2013/04/10 15:14:07
bad merge.
|
+} |
+ |
+/** |
+ * Mixin that throws on the length changing operations of [List]. |
+ * |
+ * Intended to mix-in on top of [ListMixin] for fixed-length lists. |
+ */ |
+abstract class FixedLengthListMixin<E> { |
floitsch
2013/04/10 15:14:07
This shouldn't be here either.
|
+ void set length(int newLength) { |
+ throw new UnsupportedError( |
+ "Cannot change the length of a fixed-length list"); |
+ } |
+ |
+ void add(E value) { |
+ throw new UnsupportedError( |
+ "Cannot add to a fixed-length list"); |
+ } |
+ |
+ void insert(int index, E value) { |
+ throw new UnsupportedError( |
+ "Cannot add to a fixed-length list"); |
+ } |
+ |
+ void addAll(Iterable<E> iterable) { |
+ throw new UnsupportedError( |
+ "Cannot add to a fixed-length list"); |
+ } |
+ |
+ void remove(E element) { |
+ throw new UnsupportedError( |
+ "Cannot remove from a fixed-length list"); |
+ } |
+ |
+ void removeAll(Iterable elements) { |
+ throw new UnsupportedError( |
+ "Cannot remove from a fixed-length list"); |
+ } |
+ |
+ void retainAll(Iterable elements) { |
+ throw new UnsupportedError( |
+ "Cannot remove from a fixed-length list"); |
+ } |
+ |
+ void removeWhere(bool test(E element)) { |
+ throw new UnsupportedError( |
+ "Cannot remove from a fixed-length list"); |
+ } |
+ |
+ void retainWhere(bool test(E element)) { |
+ throw new UnsupportedError( |
+ "Cannot remove from a fixed-length list"); |
+ } |
+ |
+ void clear() { |
+ throw new UnsupportedError( |
+ "Cannot clear a fixed-length list"); |
+ } |
+ |
+ E removeAt(int index) { |
+ throw new UnsupportedError( |
+ "Cannot remove from a fixed-length list"); |
+ } |
+ |
+ E removeLast() { |
+ throw new UnsupportedError( |
+ "Cannot remove from a fixed-length list"); |
+ } |
+ |
+ void removeRange(int start, int length) { |
+ throw new UnsupportedError( |
+ "Cannot remove from a fixed-length list"); |
+ } |
+ |
+ void insertRange(int start, int length, [E initialValue]) { |
+ throw new UnsupportedError( |
+ "Cannot insert range in a fixed-length list"); |
+ } |
+} |
+ |
+/** |
+ * Mixin for an unmodifiable [List] class. |
+ * |
+ * This overrides all mutating methods with methods that throw. |
+ * This mixin is intended to be mixed in on top of [ListMixin] on |
+ * unmodifiable lists. |
+ */ |
+abstract class UnmodifiableListMixin<E> { |
floitsch
2013/04/10 15:14:07
ditto.
|
+ |
+ void operator []=(int index, E value) { |
+ throw new UnsupportedError( |
+ "Cannot modify an unmodifiable list"); |
+ } |
+ |
+ void set length(int newLength) { |
+ throw new UnsupportedError( |
+ "Cannot change the length of an unmodifiable list"); |
+ } |
+ |
+ void add(E value) { |
+ throw new UnsupportedError( |
+ "Cannot add to an unmodifiable list"); |
+ } |
+ |
+ E insert(int index, E value) { |
+ throw new UnsupportedError( |
+ "Cannot add to an unmodifiable list"); |
+ } |
+ |
+ void addAll(Iterable<E> iterable) { |
+ throw new UnsupportedError( |
+ "Cannot add to an unmodifiable list"); |
+ } |
+ |
+ void remove(E element) { |
+ throw new UnsupportedError( |
+ "Cannot remove from an unmodifiable list"); |
+ } |
+ |
+ void removeAll(Iterable elements) { |
+ throw new UnsupportedError( |
+ "Cannot remove from an unmodifiable list"); |
+ } |
+ |
+ void retainAll(Iterable elements) { |
+ throw new UnsupportedError( |
+ "Cannot remove from an unmodifiable list"); |
+ } |
+ |
+ void removeWhere(bool test(E element)) { |
+ throw new UnsupportedError( |
+ "Cannot remove from an unmodifiable list"); |
+ } |
+ |
+ void retainWhere(bool test(E element)) { |
+ throw new UnsupportedError( |
+ "Cannot remove from an unmodifiable list"); |
+ } |
+ |
+ void sort([Comparator<E> compare]) { |
+ throw new UnsupportedError( |
+ "Cannot modify an unmodifiable list"); |
+ } |
+ |
+ void clear() { |
+ throw new UnsupportedError( |
+ "Cannot clear an unmodifiable list"); |
+ } |
+ |
+ E removeAt(int index) { |
+ throw new UnsupportedError( |
+ "Cannot remove from an unmodifiable list"); |
+ } |
+ |
+ E removeLast() { |
+ throw new UnsupportedError( |
+ "Cannot remove from an unmodifiable list"); |
+ } |
+ |
+ void setRange(int start, int length, List<E> from, [int startFrom]) { |
+ throw new UnsupportedError( |
+ "Cannot modify an unmodifiable list"); |
+ } |
+ |
+ void removeRange(int start, int length) { |
+ throw new UnsupportedError( |
+ "Cannot remove from an unmodifiable list"); |
+ } |
+ |
+ void insertRange(int start, int length, [E initialValue]) { |
+ throw new UnsupportedError( |
+ "Cannot insert range in an unmodifiable list"); |
+ } |
+} |
+ |
+class _ReversedListIterable<E> extends ListIterable<E> { |
+ Iterable<E> _source; |
+ _ReversedListIterable(this._source); |
+ |
+ int get length => _source.length; |
+ |
+ E elementAt(int index) => _source.elementAt(_source.length - 1 - index); |
} |