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

Unified Diff: sdk/lib/core/list.dart

Issue 11896013: Add List.reversed to give a reverse fixed-length view of a list. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 7 years, 11 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
Index: sdk/lib/core/list.dart
diff --git a/sdk/lib/core/list.dart b/sdk/lib/core/list.dart
index 062a0d9cfa7e947082ddd57d44ce5daa3ee54887..f5ef21867ffd56890486183934e08ad88821b21c 100644
--- a/sdk/lib/core/list.dart
+++ b/sdk/lib/core/list.dart
@@ -85,6 +85,15 @@ abstract class List<E> implements Collection<E> {
void addAll(Iterable<E> iterable);
/**
+ * Returns a reversed fixed-length view of this [List].
+ *
+ * The reversed list has elements in the opposite order of this list.
+ * It is backed by this list, but will stop working if this list
+ * becomes shorter than its current length.
+ */
+ List<T> get reversed => new ReversedList(this, 0, length);
+
+ /**
* Sorts the list according to the order specified by the [compare] function.
*
* The [compare] function must act as a [Comparator].
@@ -192,11 +201,12 @@ abstract class List<E> implements Collection<E> {
}
/**
- * An unmodifiable [List].
+ * Class implementing the read-operations on [List].
+ *
+ * Implements all operations except [:operator[]:] and [:length:] that does not
+ * modify the list in terms of those two.
*/
-abstract class NonExtensibleListMixin<E>
- extends Iterable<E> implements List<E> {
-
+abstract class BaseListMixin<E> extends Iterable<E> implements List<E> {
floitsch 2013/01/21 14:38:06 These classes are no longer in core.
Lasse Reichstein Nielsen 2013/01/22 10:18:52 Moved to collection-dev.
Iterator<E> get iterator => new ListIterator(this);
void forEach(f(E element)) {
@@ -278,6 +288,98 @@ abstract class NonExtensibleListMixin<E>
}
return result;
}
+}
+
+/**
+ * Abstract class implementing the non-length changing operations of [List].
+ */
+abstract class FixedLengthListMixin<E> extends BaseListMixin<E> {
floitsch 2013/01/21 14:38:06 Can't be a mixin, since it extends (or mixins) Bas
Lasse Reichstein Nielsen 2013/01/22 10:18:52 True, so it needs a better name. Just FixedLengthL
+ void operator[]=(int index, E value);
+
+ List<E> get reversed => new ReversedList<E>(this, 0, length);
+
+ void sort([Comparator<E> compare]) {
+ coreSort(this, compare);
+ }
+
+ void setRange(int start, int length, List<E> from, [int startFrom]) {
+ if (length < 0) throw new ArgumentError("length: $length");
+ if (startFrom == null) startFrom = 0;
+ for (int i = 0; i < length; i++) {
+ this[from + i] = from[startFrom + i];
+ }
+ }
+
+ 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 addLast(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 removeMatching(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");
+ }
+}
+
+/**
+ * An unmodifiable [List].
+ */
+abstract class UnmodifiableListMixin<E> extends BaseListMixin<E> {
void operator []=(int index, E value) {
throw new UnsupportedError(
@@ -385,7 +487,7 @@ class ListIterator<E> implements Iterator<E> {
E get current => _current;
}
-class MappedList<S, T> extends NonExtensibleListMixin<T> {
+class MappedList<S, T> extends UnmodifiableListMixin<T> {
final List<S> _list;
// TODO(ahe): Restore type when feature is implemented in dart2js
// checked mode. http://dartbug.com/7733
@@ -397,10 +499,17 @@ class MappedList<S, T> extends NonExtensibleListMixin<T> {
int get length => _list.length;
}
+/** An empty fixed-length list. */
+class EmptyList<E> extends FixedLengthListMixin<E> {
+ int get length => 0;
+ E operator[](int index) { throw new ArgumentError(index); }
floitsch 2013/01/21 14:38:06 RangeError
Lasse Reichstein Nielsen 2013/01/22 10:18:52 Done.
+ void operator[]=(int index, E value) { throw new ArgumentError(index); }
+}
+
/**
- * An immutable view of a [List].
+ * An unmodifiable view of a [List].
*/
-class ListView<E> extends NonExtensibleListMixin<E> {
+class ListView<E> extends UnmodifiableListMixin<E> {
final List<E> _list;
final int _offset;
final int _length;
@@ -452,4 +561,98 @@ class ListView<E> extends NonExtensibleListMixin<E> {
if (_length != null && takeCount > _length) newLength = _length;
return new ListView(_list, _offset, newLength);
}
+
+ List<E> get reversed => new ReversedList(_list, _offset, _offset + _length);
+
+ String toString() => Collections.collectionToString(this);
+}
+
+/**
+ * Reversed view of a [List], or a slice of a list.
+ *
+ * The view is fixed-length and becomes invalid if the underlying
+ * list changes its length below the slice used by this reversed list.
floitsch 2013/01/21 14:38:06 That's now how iterables work. And ReversedList (l
Lasse Reichstein Nielsen 2013/01/21 14:43:40 So what should it do?
+ */
+class ReversedList<E> extends FixedLengthListMixin<E> {
+ final List<E> _list;
+ final int _start;
+ final int _end;
+ ReversedList(List<E> list, int start, int end)
+ : _list = list, _start = start, _end = end;
+
+ int get length => _end - _start;
+
+ E operator[](int index) {
+ if (_list.length < _end) throw new StateError("Concurrent modification");
+ int length = _end - _start;
+ if (index < 0 || index > length) {
+ throw new RangeError("$index not in range 0..$length");
+ }
+ return _list[_end - index - 1];
+ }
+
+ void operator[]=(int index, E value) {
+ if (_list.length < _end) throw new StateError("Concurrent modification");
+ int length = _end - _start;
+ if (index < 0 || index > length) {
+ throw new RangeError("$index not in range 0..$length");
+ }
+ _list[_end - index - 1] = value;
+ }
+
+ Iterable<E> get iterator => new ReverseListIterator<E>(_list, _start, _end);
+
+ List<E> take(int count) {
+ if (count is! int || count < 0) {
+ throw new ArgumentError(count);
+ }
+ int length = _end - _start;
+ if (count > length) count = length;
+ return new ReversedList(_list, _end - count, _end);
+ }
+
+ List<E> skip(int count) {
+ if (count is! int || count < 0) {
+ throw new ArgumentError(count);
+ }
+ int length = _end - _start;
+ if (count >= length) return new EmptyList();
+ return new ReversedList(_list, _start, _end - count);
+ }
+
+ void sort([int compare(E first, E second)]) {
+ if (compare == null) compare = Comparable.compare;
+ // TODO(lrn): Make a way to sort a slice of a list using core sort.
+ List<E> slice = _list.getRange(_start, _end);
+ slice.sort((E a, E b) => compare(b, a));
+ _list.setRange(_start, slice.length, slice);
+ }
+
+ List<E> get reversed {
+ return new ListView(_list, _start, _end - _start);
+ }
+
+ String toString() => Collections.collectionToString(this);
+}
+
+/**
+ * An [Iterator] over a slice of a list that access elements in reverse order.
+ */
+class ReverseListIterator<E> implements Iterator<E> {
+ final List<E> _list;
+ final int _start;
+ int _index;
+ E _current;
+
+ ReverseListIterator(List<E> list, int start, int end)
+ : _list = list, _start = start, _index = end;
+
+ bool moveNext() {
+ if (_index <= _start) return false;
+ _index -= 1;
+ _current = _list[_index];
+ return true;
+ }
+
+ E get current => _current;
}
« no previous file with comments | « sdk/lib/_internal/compiler/implementation/lib/js_array.dart ('k') | sdk/lib/html/html_common/filtered_element_list.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698