| OLD | NEW |
| 1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 part of dart.core; | 5 part of dart.core; |
| 6 | 6 |
| 7 /** | 7 /** |
| 8 * An object that uses an [Iterator] to serve objects one at a time. | 8 * An object that uses an [Iterator] to serve objects one at a time. |
| 9 * | 9 * |
| 10 * You can iterate over all objects served by an Iterable object | 10 * You can iterate over all objects served by an Iterable object |
| (...skipping 23 matching lines...) Expand all Loading... |
| 34 abstract class Iterable<E> { | 34 abstract class Iterable<E> { |
| 35 const Iterable(); | 35 const Iterable(); |
| 36 | 36 |
| 37 /** | 37 /** |
| 38 * Creates an Iterable that generates its elements dynamically. | 38 * Creates an Iterable that generates its elements dynamically. |
| 39 * | 39 * |
| 40 * The Iterators created by the Iterable count from | 40 * The Iterators created by the Iterable count from |
| 41 * zero to [:count - 1:] while iterating, and call [generator] | 41 * zero to [:count - 1:] while iterating, and call [generator] |
| 42 * with that index to create the next value. | 42 * with that index to create the next value. |
| 43 * | 43 * |
| 44 * If [generator] is omitted, it defaults to an identity function |
| 45 * on integers `(int x) => x`, so it should only be omitted if the type |
| 46 * parameter allows integer values. |
| 47 * |
| 44 * As an Iterable, [:new Iterable.generate(n, generator)):] is equivalent to | 48 * As an Iterable, [:new Iterable.generate(n, generator)):] is equivalent to |
| 45 * [:const [0, ..., n - 1].map(generator):] | 49 * [:const [0, ..., n - 1].map(generator):] |
| 46 */ | 50 */ |
| 47 factory Iterable.generate(int count, E generator(int index)) { | 51 factory Iterable.generate(int count, [E generator(int index)]) { |
| 52 if (count <= 0) return new EmptyIterable<E>(); |
| 48 return new _GeneratorIterable<E>(count, generator); | 53 return new _GeneratorIterable<E>(count, generator); |
| 49 } | 54 } |
| 50 | 55 |
| 51 /** | 56 /** |
| 52 * Returns an Iterator that iterates over this Iterable object. | 57 * Returns an Iterator that iterates over this Iterable object. |
| 53 */ | 58 */ |
| 54 Iterator<E> get iterator; | 59 Iterator<E> get iterator; |
| 55 | 60 |
| 56 /** | 61 /** |
| 57 * Returns a lazy [Iterable] where each element [:e:] of `this` is replaced | 62 * Returns a lazy [Iterable] where each element [:e:] of `this` is replaced |
| (...skipping 224 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 282 * function may simply return any element without any iteration if there are | 287 * function may simply return any element without any iteration if there are |
| 283 * at least [index] elements in `this`. | 288 * at least [index] elements in `this`. |
| 284 */ | 289 */ |
| 285 E elementAt(int index); | 290 E elementAt(int index); |
| 286 } | 291 } |
| 287 | 292 |
| 288 typedef E _Generator<E>(int index); | 293 typedef E _Generator<E>(int index); |
| 289 | 294 |
| 290 class _GeneratorIterable<E> extends IterableBase<E> | 295 class _GeneratorIterable<E> extends IterableBase<E> |
| 291 implements EfficientLength { | 296 implements EfficientLength { |
| 292 final int _count; | 297 final int _start; |
| 298 final int _end; |
| 293 final _Generator<E> _generator; | 299 final _Generator<E> _generator; |
| 294 _GeneratorIterable(this._count, this._generator); | 300 _GeneratorIterable(this._end, E generator(int n)) |
| 295 Iterator<E> get iterator => new _GeneratorIterator(_count, _generator); | 301 : _start = 0, |
| 296 int get length => _count; | 302 _generator = (generator != null) ? generator : _id; |
| 303 |
| 304 _GeneratorIterable.slice(this._start, this._end, this._generator); |
| 305 |
| 306 Iterator<E> get iterator => |
| 307 new _GeneratorIterator<E>(_start, _end, _generator); |
| 308 int get length => _end - _start; |
| 309 |
| 310 Iterable<E> skip(int n) { |
| 311 if (n < 0) throw new RangeError.value(n); |
| 312 if (n == 0) return this; |
| 313 int newStart = _start + n; |
| 314 if (newStart >= _end) return new EmptyIterable<E>(); |
| 315 return new _GeneratorIterable<E>.slice(newStart, _end, _generator); |
| 316 } |
| 317 |
| 318 Iterable<E> take(int n) { |
| 319 if (n < 0) throw new RangeError.value(n); |
| 320 if (n == 0) return new EmptyIterable<E>(); |
| 321 int newEnd = _start + n; |
| 322 if (newEnd >= _end) return this; |
| 323 return new _GeneratorIterable<E>.slice(_start, newEnd, _generator); |
| 324 } |
| 325 |
| 326 static int _id(int n) => n; |
| 297 } | 327 } |
| 298 | 328 |
| 299 class _GeneratorIterator<E> implements Iterator<E> { | 329 class _GeneratorIterator<E> implements Iterator<E> { |
| 300 final int _count; | 330 final int _end; |
| 301 final _Generator<E> _generator; | 331 final _Generator<E> _generator; |
| 302 int _index = 0; | 332 int _index; |
| 303 E _current; | 333 E _current; |
| 304 | 334 |
| 305 _GeneratorIterator(this._count, this._generator); | 335 _GeneratorIterator(this._index, this._end, this._generator); |
| 306 | 336 |
| 307 bool moveNext() { | 337 bool moveNext() { |
| 308 if (_index < _count) { | 338 if (_index < _end) { |
| 309 _current = _generator(_index); | 339 _current = _generator(_index); |
| 310 _index++; | 340 _index++; |
| 311 return true; | 341 return true; |
| 312 } else { | 342 } else { |
| 313 _current = null; | 343 _current = null; |
| 314 return false; | 344 return false; |
| 315 } | 345 } |
| 316 } | 346 } |
| 317 | 347 |
| 318 E get current => _current; | 348 E get current => _current; |
| 319 } | 349 } |
| 320 | 350 |
| 321 /** | 351 /** |
| 322 * An Iterator that allows moving backwards as well as forwards. | 352 * An Iterator that allows moving backwards as well as forwards. |
| 323 */ | 353 */ |
| 324 abstract class BidirectionalIterator<E> implements Iterator<E> { | 354 abstract class BidirectionalIterator<E> implements Iterator<E> { |
| 325 /** | 355 /** |
| 326 * Move back to the previous element. | 356 * Move back to the previous element. |
| 327 * | 357 * |
| 328 * Returns true and updates [current] if successful. Returns false | 358 * Returns true and updates [current] if successful. Returns false |
| 329 * and sets [current] to null if there is no previous element. | 359 * and sets [current] to null if there is no previous element. |
| 330 */ | 360 */ |
| 331 bool movePrevious(); | 361 bool movePrevious(); |
| 332 } | 362 } |
| OLD | NEW |