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

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

Issue 1992713002: Make Iterable.generate use ListIterable as base implementation. (Closed) Base URL: https://github.com/dart-lang/sdk.git@master
Patch Set: Reword skip docs Created 4 years, 7 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
« no previous file with comments | « sdk/lib/async/future.dart ('k') | tests/corelib/iterable_generate_test.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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.
*/
« no previous file with comments | « sdk/lib/async/future.dart ('k') | tests/corelib/iterable_generate_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698