Index: sdk/lib/core/iterable.dart |
diff --git a/sdk/lib/core/iterable.dart b/sdk/lib/core/iterable.dart |
index cf05cdec4a55bdef6ece8554b8dfa90b4ebe6822..300b2efcc4cf6a77b23136738fdb9ac988f96427 100644 |
--- a/sdk/lib/core/iterable.dart |
+++ b/sdk/lib/core/iterable.dart |
@@ -14,7 +14,7 @@ part of dart.core; |
* the iterator has now moved to the next element, |
* which is then available as [Iterator.current]. |
* If the call returns `false`, there are no more elements, |
- * and `iterator.currrent` returns `null`. |
+ * and `iterator.current` returns `null`. |
* |
* You can create more than one iterator from the same `Iterable`. |
* Each time `iterator` is read, it returns a new iterator, |
@@ -83,15 +83,16 @@ abstract class Iterable<E> { |
const Iterable(); |
/** |
- * Creates an `Iterable` that generates its elements dynamically. |
+ * Creates an `Iterable` which generates its elements dynamically. |
* |
- * An `Iterator` created by [iterator] will count from |
- * zero to [:count - 1:], and call [generator] |
- * with each index in turn to create the next value. |
+ * The generated iterable has [count] elements, |
+ * and the element at index `n` is computed by calling `generator(n)`. |
+ * Values are not cached, so each iteration computes the values again. |
* |
* If [generator] is omitted, it defaults to an identity function |
- * on integers `(int x) => x`, so it should only be omitted if the type |
- * parameter allows integer values. |
+ * on integers `(int x) => x`, so it may only be omitted if the type |
+ * parameter allows integer values. That is, if [E] is one of |
+ * `int`, `num`, `Object` or `dynamic`. |
* |
* As an `Iterable`, `new Iterable.generate(n, generator))` is equivalent to |
* `const [0, ..., n - 1].map(generator)`. |
@@ -163,14 +164,14 @@ abstract class Iterable<E> { |
* The matching elements have the same order in the returned iterable |
* as they have in [iterator]. |
* |
- * This method returns a view of the mapped elements. As long as the |
- * returned [Iterable] is not iterated over, the supplied function [test] will |
- * not be invoked. Iterating will not cache results, and thus iterating |
- * multiple times over the returned [Iterable] will invoke the supplied |
+ * This method returns a view of the mapped elements. |
+ * As long as the returned [Iterable] is not iterated over, |
+ * the supplied function [test] will not be invoked. |
+ * Iterating will not cache results, and thus iterating multiple times over |
+ * the returned [Iterable] may invoke the supplied |
* function [test] multiple times on the same element. |
*/ |
- Iterable<E> where(bool test(E element)) => |
- new WhereIterable<E>(this, test); |
+ Iterable<E> where(bool test(E element)) => new WhereIterable<E>(this, test); |
/** |
* Expands each element of this [Iterable] into zero or more elements. |
@@ -410,7 +411,7 @@ abstract class Iterable<E> { |
} |
/** |
- * Returns an Iterable that provides all but the first [count] elements. |
+ * Returns an [Iterable] that provides all but the first [count] elements. |
* |
* When the returned iterable is iterated, it starts iterating over `this`, |
* first skipping past the initial [count] elements. |
@@ -419,23 +420,27 @@ abstract class Iterable<E> { |
* After that, the remaining elements are iterated in the same order as |
* in this iterable. |
* |
- * The `count` must not be negative. |
+ * Some iterables may be able to find later elements without first iterating |
+ * through earlier elements, for example when iterating a [List]. |
+ * Such iterables are allowed to ignore the initial skipped elements. |
+ * |
+ * The [count] must not be negative. |
*/ |
Iterable<E> skip(int count) { |
return new SkipIterable<E>(this, count); |
} |
/** |
- * Returns an Iterable that skips leading elements while [test] is satisfied. |
+ * Returns an `Iterable` that skips leading elements while [test] is satisfied. |
* |
- * The filtering happens lazily. Every new Iterator of the returned |
- * Iterable iterates over all elements of `this`. |
+ * The filtering happens lazily. Every new [Iterator] of the returned |
+ * iterable iterates over all elements of `this`. |
* |
* The returned iterable provides elements by iterating this iterable, |
* but skipping over all initial elements where `test(element)` returns |
* true. If all elements satisfy `test` the resulting iterable is empty, |
* otherwise it iterates the remaining elements in their original order, |
- * starting with the first element for which `test(element)` returns false. |
+ * starting with the first element for which `test(element)` returns `false`. |
*/ |
Iterable<E> skipWhile(bool test(E value)) { |
return new SkipWhileIterable<E>(this, test); |
@@ -494,7 +499,7 @@ abstract class Iterable<E> { |
/** |
* Returns the first element that satisfies the given predicate [test]. |
* |
- * Iterates through elements and returns the first to satsify [test]. |
+ * Iterates through elements and returns the first to satisfy [test]. |
* |
* If no element satisfies [test], the result of invoking the [orElse] |
* function is returned. |
@@ -518,7 +523,7 @@ abstract class Iterable<E> { |
* checks `test(element)` for each, |
* and finally returns that last one that matched. |
* |
- * If no element satsfies [test], the result of invoking the [orElse] |
+ * If no element satisfies [test], the result of invoking the [orElse] |
* function is returned. |
* If [orElse] is omitted, it defaults to throwing a [StateError]. |
*/ |
@@ -603,72 +608,30 @@ abstract class Iterable<E> { |
typedef E _Generator<E>(int index); |
-class _GeneratorIterable<E> extends Iterable<E> |
- implements EfficientLength { |
- final int _start; |
- final int _end; |
+class _GeneratorIterable<E> extends ListIterable<E> { |
+ /// The length of the generated iterable. |
+ final int length; |
+ |
+ /// The function mapping indices to values. |
final _Generator<E> _generator; |
- /// Creates an iterable that builds the elements from a generator function. |
+ /// Creates the generated iterable. |
/// |
- /// The [generator] may be null, in which case the default generator |
- /// enumerating the integer positions is used. This means that [int] must |
- /// be assignable to [E] when no generator is provided. In practice this means |
- /// that the generator can only be emitted when [E] is equal to `dynamic`, |
- /// `int`, or `num`. The constructor will check that the types match. |
- _GeneratorIterable(this._end, E generator(int n)) |
- : _start = 0, |
- // The `as` below is used as check to make sure that `int` is assignable |
+ /// If [generator] is `null`, it is checked that `int` is assignable to [E]. |
+ _GeneratorIterable(this.length, E generator(int index)) |
+ : // The `as` below is used as check to make sure that `int` is assignable |
// to [E]. |
_generator = (generator != null) ? generator : _id as _Generator<E>; |
- _GeneratorIterable.slice(this._start, this._end, this._generator); |
- |
- Iterator<E> get iterator => |
- new _GeneratorIterator<E>(_start, _end, _generator); |
- int get length => _end - _start; |
- |
- Iterable<E> skip(int count) { |
- RangeError.checkNotNegative(count, "count"); |
- if (count == 0) return this; |
- int newStart = _start + count; |
- if (newStart >= _end) return new EmptyIterable<E>(); |
- return new _GeneratorIterable<E>.slice(newStart, _end, _generator); |
- } |
- |
- Iterable<E> take(int count) { |
- RangeError.checkNotNegative(count, "count"); |
- if (count == 0) return new EmptyIterable<E>(); |
- int newEnd = _start + count; |
- if (newEnd >= _end) return this; |
- return new _GeneratorIterable<E>.slice(_start, newEnd, _generator); |
+ E elementAt(int index) { |
+ RangeError.checkValidIndex(index, this); |
+ return _generator(index); |
} |
+ /// Helper function used as default _generator function. |
static int _id(int n) => n; |
} |
-class _GeneratorIterator<E> implements Iterator<E> { |
- final int _end; |
- final _Generator<E> _generator; |
- int _index; |
- E _current; |
- |
- _GeneratorIterator(this._index, this._end, this._generator); |
- |
- bool moveNext() { |
- if (_index < _end) { |
- _current = _generator(_index); |
- _index++; |
- return true; |
- } else { |
- _current = null; |
- return false; |
- } |
- } |
- |
- E get current => _current; |
-} |
- |
/** |
* An Iterator that allows moving backwards as well as forwards. |
*/ |