| 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.
|
| */
|
|
|