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 * A collection of values, or "elements", that can be accessed sequentially. | 8 * A collection of values, or "elements", that can be accessed sequentially. |
9 * | 9 * |
10 * The elements of the iterable are accessed by getting an [Iterator] | 10 * The elements of the iterable are accessed by getting an [Iterator] |
(...skipping 433 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
444 } | 444 } |
445 | 445 |
446 /** | 446 /** |
447 * Returns the first element. | 447 * Returns the first element. |
448 * | 448 * |
449 * Throws a [StateError] if `this` is empty. | 449 * Throws a [StateError] if `this` is empty. |
450 * Otherwise returs the first element in the iteration order, | 450 * Otherwise returs the first element in the iteration order, |
451 * equivalent to `(iterator..moveNext())..current`. | 451 * equivalent to `(iterator..moveNext())..current`. |
452 */ | 452 */ |
453 E get first { | 453 E get first { |
454 Iterator it = iterator; | 454 Iterator<E> it = iterator; |
455 if (!it.moveNext()) { | 455 if (!it.moveNext()) { |
456 throw IterableElementError.noElement(); | 456 throw IterableElementError.noElement(); |
457 } | 457 } |
458 return it.current; | 458 return it.current; |
459 } | 459 } |
460 | 460 |
461 /** | 461 /** |
462 * Returns the last element. | 462 * Returns the last element. |
463 * | 463 * |
464 * Throws a [StateError] if `this` is empty. | 464 * Throws a [StateError] if `this` is empty. |
465 * Otherwise may iterate through the elements and returns the last one | 465 * Otherwise may iterate through the elements and returns the last one |
466 * seen. | 466 * seen. |
467 * Some iterables may have more efficient ways to find the last element | 467 * Some iterables may have more efficient ways to find the last element |
468 * (for example a list can directly access the last element, | 468 * (for example a list can directly access the last element, |
469 * without iterating through the previous ones). | 469 * without iterating through the previous ones). |
470 */ | 470 */ |
471 E get last { | 471 E get last { |
472 Iterator it = iterator; | 472 Iterator<E> it = iterator; |
473 if (!it.moveNext()) { | 473 if (!it.moveNext()) { |
474 throw IterableElementError.noElement(); | 474 throw IterableElementError.noElement(); |
475 } | 475 } |
476 E result; | 476 E result; |
477 do { | 477 do { |
478 result = it.current; | 478 result = it.current; |
479 } while(it.moveNext()); | 479 } while(it.moveNext()); |
480 return result; | 480 return result; |
481 } | 481 } |
482 | 482 |
483 /** | 483 /** |
484 * Checks that this iterable has only one element, and returns that element. | 484 * Checks that this iterable has only one element, and returns that element. |
485 * | 485 * |
486 * Throws a [StateError] if `this` is empty or has more than one element. | 486 * Throws a [StateError] if `this` is empty or has more than one element. |
487 */ | 487 */ |
488 E get single { | 488 E get single { |
489 Iterator it = iterator; | 489 Iterator<E> it = iterator; |
490 if (!it.moveNext()) throw IterableElementError.noElement(); | 490 if (!it.moveNext()) throw IterableElementError.noElement(); |
491 E result = it.current; | 491 E result = it.current; |
492 if (it.moveNext()) throw IterableElementError.tooMany(); | 492 if (it.moveNext()) throw IterableElementError.tooMany(); |
493 return result; | 493 return result; |
494 } | 494 } |
495 | 495 |
496 /** | 496 /** |
497 * Returns the first element that satisfies the given predicate [test]. | 497 * Returns the first element that satisfies the given predicate [test]. |
498 * | 498 * |
499 * Iterates through elements and returns the first to satsify [test]. | 499 * Iterates through elements and returns the first to satsify [test]. |
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
603 String toString() => IterableBase.iterableToShortString(this, '(', ')'); | 603 String toString() => IterableBase.iterableToShortString(this, '(', ')'); |
604 } | 604 } |
605 | 605 |
606 typedef E _Generator<E>(int index); | 606 typedef E _Generator<E>(int index); |
607 | 607 |
608 class _GeneratorIterable<E> extends Iterable<E> | 608 class _GeneratorIterable<E> extends Iterable<E> |
609 implements EfficientLength { | 609 implements EfficientLength { |
610 final int _start; | 610 final int _start; |
611 final int _end; | 611 final int _end; |
612 final _Generator<E> _generator; | 612 final _Generator<E> _generator; |
| 613 |
| 614 /// Creates an iterable that builds the elements from a generator function. |
| 615 /// |
| 616 /// The [generator] may be null, in which case the default generator |
| 617 /// enumerating the integer positions is used. This means that [int] must |
| 618 /// be assignable to [E] when no generator is provided. In practice this means |
| 619 /// that the generator can only be emitted when [E] is equal to `dynamic`, |
| 620 /// `int`, or `num`. The constructor will check that the types match. |
613 _GeneratorIterable(this._end, E generator(int n)) | 621 _GeneratorIterable(this._end, E generator(int n)) |
614 : _start = 0, | 622 : _start = 0, |
615 _generator = (generator != null) ? generator : _id; | 623 // The `as` below is used as check to make sure that `int` is assignable |
| 624 // to [E]. |
| 625 _generator = (generator != null) ? generator : _id as _Generator<E>; |
616 | 626 |
617 _GeneratorIterable.slice(this._start, this._end, this._generator); | 627 _GeneratorIterable.slice(this._start, this._end, this._generator); |
618 | 628 |
619 Iterator<E> get iterator => | 629 Iterator<E> get iterator => |
620 new _GeneratorIterator<E>(_start, _end, _generator); | 630 new _GeneratorIterator<E>(_start, _end, _generator); |
621 int get length => _end - _start; | 631 int get length => _end - _start; |
622 | 632 |
623 Iterable<E> skip(int count) { | 633 Iterable<E> skip(int count) { |
624 RangeError.checkNotNegative(count, "count"); | 634 RangeError.checkNotNegative(count, "count"); |
625 if (count == 0) return this; | 635 if (count == 0) return this; |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
666 */ | 676 */ |
667 abstract class BidirectionalIterator<E> implements Iterator<E> { | 677 abstract class BidirectionalIterator<E> implements Iterator<E> { |
668 /** | 678 /** |
669 * Move back to the previous element. | 679 * Move back to the previous element. |
670 * | 680 * |
671 * Returns true and updates [current] if successful. Returns false | 681 * Returns true and updates [current] if successful. Returns false |
672 * and sets [current] to null if there is no previous element. | 682 * and sets [current] to null if there is no previous element. |
673 */ | 683 */ |
674 bool movePrevious(); | 684 bool movePrevious(); |
675 } | 685 } |
OLD | NEW |