Index: sdk/lib/core/iterable.dart |
diff --git a/sdk/lib/core/iterable.dart b/sdk/lib/core/iterable.dart |
index 8ea9c99f825f1a6bb03048fa0d7f0fb54acc7464..7d0ff160c9f3647831f773ca9058c11d14aee955 100644 |
--- a/sdk/lib/core/iterable.dart |
+++ b/sdk/lib/core/iterable.dart |
@@ -41,10 +41,15 @@ abstract class Iterable<E> { |
* zero to [:count - 1:] while iterating, and call [generator] |
* with that index to create the next value. |
* |
+ * 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. |
+ * |
* As an Iterable, [:new Iterable.generate(n, generator)):] is equivalent to |
* [:const [0, ..., n - 1].map(generator):] |
*/ |
- factory Iterable.generate(int count, E generator(int index)) { |
+ factory Iterable.generate(int count, [E generator(int index)]) { |
+ if (count <= 0) return new EmptyIterable<E>(); |
return new _GeneratorIterable<E>(count, generator); |
} |
@@ -289,23 +294,48 @@ typedef E _Generator<E>(int index); |
class _GeneratorIterable<E> extends IterableBase<E> |
implements EfficientLength { |
- final int _count; |
+ final int _start; |
+ final int _end; |
final _Generator<E> _generator; |
- _GeneratorIterable(this._count, this._generator); |
- Iterator<E> get iterator => new _GeneratorIterator(_count, _generator); |
- int get length => _count; |
+ _GeneratorIterable(this._end, E generator(int n)) |
+ : _start = 0, |
+ _generator = (generator != null) ? generator : _id; |
+ |
+ _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 n) { |
+ if (n < 0) throw new RangeError.value(n); |
+ if (n == 0) return this; |
+ int newStart = _start + n; |
+ if (newStart >= _end) return new EmptyIterable<E>(); |
+ return new _GeneratorIterable<E>.slice(newStart, _end, _generator); |
+ } |
+ |
+ Iterable<E> take(int n) { |
+ if (n < 0) throw new RangeError.value(n); |
+ if (n == 0) return new EmptyIterable<E>(); |
+ int newEnd = _start + n; |
+ if (newEnd >= _end) return this; |
+ return new _GeneratorIterable<E>.slice(_start, newEnd, _generator); |
+ } |
+ |
+ static int _id(int n) => n; |
} |
class _GeneratorIterator<E> implements Iterator<E> { |
- final int _count; |
+ final int _end; |
final _Generator<E> _generator; |
- int _index = 0; |
+ int _index; |
E _current; |
- _GeneratorIterator(this._count, this._generator); |
+ _GeneratorIterator(this._index, this._end, this._generator); |
bool moveNext() { |
- if (_index < _count) { |
+ if (_index < _end) { |
_current = _generator(_index); |
_index++; |
return true; |