| 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._internal; | 5 part of dart._internal; |
| 6 | 6 |
| 7 /** | 7 /** |
| 8 * Marker interface for [Iterable] subclasses that have an efficient | 8 * Marker interface for [Iterable] subclasses that have an efficient |
| 9 * [length] implementation. | 9 * [length] implementation. |
| 10 */ | 10 */ |
| (...skipping 339 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 350 final Iterable<S> _iterable; | 350 final Iterable<S> _iterable; |
| 351 final _Transformation<S, T> _f; | 351 final _Transformation<S, T> _f; |
| 352 | 352 |
| 353 factory MappedIterable(Iterable<S> iterable, T function(S value)) { | 353 factory MappedIterable(Iterable<S> iterable, T function(S value)) { |
| 354 if (iterable is EfficientLengthIterable) { | 354 if (iterable is EfficientLengthIterable) { |
| 355 return new EfficientLengthMappedIterable<S, T>(iterable, function); | 355 return new EfficientLengthMappedIterable<S, T>(iterable, function); |
| 356 } | 356 } |
| 357 return new MappedIterable<S, T>._(iterable, function); | 357 return new MappedIterable<S, T>._(iterable, function); |
| 358 } | 358 } |
| 359 | 359 |
| 360 MappedIterable._(this._iterable, T this._f(S element)); | 360 MappedIterable._(this._iterable, this._f); |
| 361 | 361 |
| 362 Iterator<T> get iterator => new MappedIterator<S, T>(_iterable.iterator, _f); | 362 Iterator<T> get iterator => new MappedIterator<S, T>(_iterable.iterator, _f); |
| 363 | 363 |
| 364 // Length related functions are independent of the mapping. | 364 // Length related functions are independent of the mapping. |
| 365 int get length => _iterable.length; | 365 int get length => _iterable.length; |
| 366 bool get isEmpty => _iterable.isEmpty; | 366 bool get isEmpty => _iterable.isEmpty; |
| 367 | 367 |
| 368 // Index based lookup can be done before transforming. | 368 // Index based lookup can be done before transforming. |
| 369 T get first => _f(_iterable.first); | 369 T get first => _f(_iterable.first); |
| 370 T get last => _f(_iterable.last); | 370 T get last => _f(_iterable.last); |
| 371 T get single => _f(_iterable.single); | 371 T get single => _f(_iterable.single); |
| 372 T elementAt(int index) => _f(_iterable.elementAt(index)); | 372 T elementAt(int index) => _f(_iterable.elementAt(index)); |
| 373 } | 373 } |
| 374 | 374 |
| 375 class EfficientLengthMappedIterable<S, T> extends MappedIterable<S, T> | 375 class EfficientLengthMappedIterable<S, T> extends MappedIterable<S, T> |
| 376 implements EfficientLengthIterable<T> { | 376 implements EfficientLengthIterable<T> { |
| 377 EfficientLengthMappedIterable(Iterable<S> iterable, T function(S value)) | 377 EfficientLengthMappedIterable(Iterable<S> iterable, T function(S value)) |
| 378 : super._(iterable, function); | 378 : super._(iterable, function); |
| 379 } | 379 } |
| 380 | 380 |
| 381 class MappedIterator<S, T> extends Iterator<T> { | 381 class MappedIterator<S, T> extends Iterator<T> { |
| 382 T _current; | 382 T _current; |
| 383 final Iterator<S> _iterator; | 383 final Iterator<S> _iterator; |
| 384 final _Transformation<S, T> _f; | 384 final _Transformation<S, T> _f; |
| 385 | 385 |
| 386 MappedIterator(this._iterator, T this._f(S element)); | 386 MappedIterator(this._iterator, this._f); |
| 387 | 387 |
| 388 bool moveNext() { | 388 bool moveNext() { |
| 389 if (_iterator.moveNext()) { | 389 if (_iterator.moveNext()) { |
| 390 _current = _f(_iterator.current); | 390 _current = _f(_iterator.current); |
| 391 return true; | 391 return true; |
| 392 } | 392 } |
| 393 _current = null; | 393 _current = null; |
| 394 return false; | 394 return false; |
| 395 } | 395 } |
| 396 | 396 |
| 397 T get current => _current; | 397 T get current => _current; |
| 398 } | 398 } |
| 399 | 399 |
| 400 /** | 400 /** |
| 401 * Specialized alternative to [MappedIterable] for mapped [List]s. | 401 * Specialized alternative to [MappedIterable] for mapped [List]s. |
| 402 * | 402 * |
| 403 * Expects efficient `length` and `elementAt` on the source iterable. | 403 * Expects efficient `length` and `elementAt` on the source iterable. |
| 404 */ | 404 */ |
| 405 class MappedListIterable<S, T> extends ListIterable<T> { | 405 class MappedListIterable<S, T> extends ListIterable<T> { |
| 406 final Iterable<S> _source; | 406 final Iterable<S> _source; |
| 407 final _Transformation<S, T> _f; | 407 final _Transformation<S, T> _f; |
| 408 | 408 |
| 409 MappedListIterable(this._source, T this._f(S value)); | 409 MappedListIterable(this._source, this._f); |
| 410 | 410 |
| 411 int get length => _source.length; | 411 int get length => _source.length; |
| 412 T elementAt(int index) => _f(_source.elementAt(index)); | 412 T elementAt(int index) => _f(_source.elementAt(index)); |
| 413 } | 413 } |
| 414 | 414 |
| 415 | 415 |
| 416 typedef bool _ElementPredicate<E>(E element); | 416 typedef bool _ElementPredicate<E>(E element); |
| 417 | 417 |
| 418 class WhereIterable<E> extends Iterable<E> { | 418 class WhereIterable<E> extends Iterable<E> { |
| 419 final Iterable<E> _iterable; | 419 final Iterable<E> _iterable; |
| 420 final _ElementPredicate<E> _f; | 420 final _ElementPredicate<E> _f; |
| 421 | 421 |
| 422 WhereIterable(this._iterable, bool this._f(E element)); | 422 WhereIterable(this._iterable, this._f); |
| 423 | 423 |
| 424 Iterator<E> get iterator => new WhereIterator<E>(_iterable.iterator, _f); | 424 Iterator<E> get iterator => new WhereIterator<E>(_iterable.iterator, _f); |
| 425 | 425 |
| 426 // Specialization of [Iterable.map] to non-EfficientLengthIterable. | 426 // Specialization of [Iterable.map] to non-EfficientLengthIterable. |
| 427 Iterable<T> map<T>(T f(E element)) => new MappedIterable<E, T>._(this, f); | 427 Iterable<T> map<T>(T f(E element)) => new MappedIterable<E, T>._(this, f); |
| 428 } | 428 } |
| 429 | 429 |
| 430 class WhereIterator<E> extends Iterator<E> { | 430 class WhereIterator<E> extends Iterator<E> { |
| 431 final Iterator<E> _iterator; | 431 final Iterator<E> _iterator; |
| 432 final _ElementPredicate _f; | 432 final _ElementPredicate _f; |
| 433 | 433 |
| 434 WhereIterator(this._iterator, bool this._f(E element)); | 434 WhereIterator(this._iterator, this._f); |
| 435 | 435 |
| 436 bool moveNext() { | 436 bool moveNext() { |
| 437 while (_iterator.moveNext()) { | 437 while (_iterator.moveNext()) { |
| 438 if (_f(_iterator.current)) { | 438 if (_f(_iterator.current)) { |
| 439 return true; | 439 return true; |
| 440 } | 440 } |
| 441 } | 441 } |
| 442 return false; | 442 return false; |
| 443 } | 443 } |
| 444 | 444 |
| 445 E get current => _iterator.current; | 445 E get current => _iterator.current; |
| 446 } | 446 } |
| 447 | 447 |
| 448 typedef Iterable<T> _ExpandFunction<S, T>(S sourceElement); | 448 typedef Iterable<T> _ExpandFunction<S, T>(S sourceElement); |
| 449 | 449 |
| 450 class ExpandIterable<S, T> extends Iterable<T> { | 450 class ExpandIterable<S, T> extends Iterable<T> { |
| 451 final Iterable<S> _iterable; | 451 final Iterable<S> _iterable; |
| 452 final _ExpandFunction<S, T> _f; | 452 final _ExpandFunction<S, T> _f; |
| 453 | 453 |
| 454 ExpandIterable(this._iterable, Iterable<T> this._f(S element)); | 454 ExpandIterable(this._iterable, this._f); |
| 455 | 455 |
| 456 Iterator<T> get iterator => new ExpandIterator<S, T>(_iterable.iterator, _f); | 456 Iterator<T> get iterator => new ExpandIterator<S, T>(_iterable.iterator, _f); |
| 457 } | 457 } |
| 458 | 458 |
| 459 class ExpandIterator<S, T> implements Iterator<T> { | 459 class ExpandIterator<S, T> implements Iterator<T> { |
| 460 final Iterator<S> _iterator; | 460 final Iterator<S> _iterator; |
| 461 final _ExpandFunction<S, T> _f; | 461 final _ExpandFunction<S, T> _f; |
| 462 // Initialize _currentExpansion to an empty iterable. A null value | 462 // Initialize _currentExpansion to an empty iterable. A null value |
| 463 // marks the end of iteration, and we don't want to call _f before | 463 // marks the end of iteration, and we don't want to call _f before |
| 464 // the first moveNext call. | 464 // the first moveNext call. |
| 465 Iterator<T> _currentExpansion = const EmptyIterator(); | 465 Iterator<T> _currentExpansion = const EmptyIterator(); |
| 466 T _current; | 466 T _current; |
| 467 | 467 |
| 468 ExpandIterator(this._iterator, Iterable<T> this._f(S element)); | 468 ExpandIterator(this._iterator, this._f); |
| 469 | 469 |
| 470 T get current => _current; | 470 T get current => _current; |
| 471 | 471 |
| 472 bool moveNext() { | 472 bool moveNext() { |
| 473 if (_currentExpansion == null) return false; | 473 if (_currentExpansion == null) return false; |
| 474 while (!_currentExpansion.moveNext()) { | 474 while (!_currentExpansion.moveNext()) { |
| 475 _current = null; | 475 _current = null; |
| 476 if (_iterator.moveNext()) { | 476 if (_iterator.moveNext()) { |
| 477 // If _f throws, this ends iteration. Otherwise _currentExpansion and | 477 // If _f throws, this ends iteration. Otherwise _currentExpansion and |
| 478 // _current will be set again below. | 478 // _current will be set again below. |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 541 E get current { | 541 E get current { |
| 542 if (_remaining < 0) return null; | 542 if (_remaining < 0) return null; |
| 543 return _iterator.current; | 543 return _iterator.current; |
| 544 } | 544 } |
| 545 } | 545 } |
| 546 | 546 |
| 547 class TakeWhileIterable<E> extends Iterable<E> { | 547 class TakeWhileIterable<E> extends Iterable<E> { |
| 548 final Iterable<E> _iterable; | 548 final Iterable<E> _iterable; |
| 549 final _ElementPredicate<E> _f; | 549 final _ElementPredicate<E> _f; |
| 550 | 550 |
| 551 TakeWhileIterable(this._iterable, bool this._f(E element)); | 551 TakeWhileIterable(this._iterable, this._f); |
| 552 | 552 |
| 553 Iterator<E> get iterator { | 553 Iterator<E> get iterator { |
| 554 return new TakeWhileIterator<E>(_iterable.iterator, _f); | 554 return new TakeWhileIterator<E>(_iterable.iterator, _f); |
| 555 } | 555 } |
| 556 } | 556 } |
| 557 | 557 |
| 558 class TakeWhileIterator<E> extends Iterator<E> { | 558 class TakeWhileIterator<E> extends Iterator<E> { |
| 559 final Iterator<E> _iterator; | 559 final Iterator<E> _iterator; |
| 560 final _ElementPredicate<E> _f; | 560 final _ElementPredicate<E> _f; |
| 561 bool _isFinished = false; | 561 bool _isFinished = false; |
| 562 | 562 |
| 563 TakeWhileIterator(this._iterator, bool this._f(E element)); | 563 TakeWhileIterator(this._iterator, this._f); |
| 564 | 564 |
| 565 bool moveNext() { | 565 bool moveNext() { |
| 566 if (_isFinished) return false; | 566 if (_isFinished) return false; |
| 567 if (!_iterator.moveNext() || !_f(_iterator.current)) { | 567 if (!_iterator.moveNext() || !_f(_iterator.current)) { |
| 568 _isFinished = true; | 568 _isFinished = true; |
| 569 return false; | 569 return false; |
| 570 } | 570 } |
| 571 return true; | 571 return true; |
| 572 } | 572 } |
| 573 | 573 |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 634 return _iterator.moveNext(); | 634 return _iterator.moveNext(); |
| 635 } | 635 } |
| 636 | 636 |
| 637 E get current => _iterator.current; | 637 E get current => _iterator.current; |
| 638 } | 638 } |
| 639 | 639 |
| 640 class SkipWhileIterable<E> extends Iterable<E> { | 640 class SkipWhileIterable<E> extends Iterable<E> { |
| 641 final Iterable<E> _iterable; | 641 final Iterable<E> _iterable; |
| 642 final _ElementPredicate<E> _f; | 642 final _ElementPredicate<E> _f; |
| 643 | 643 |
| 644 SkipWhileIterable(this._iterable, bool this._f(E element)); | 644 SkipWhileIterable(this._iterable, this._f); |
| 645 | 645 |
| 646 Iterator<E> get iterator { | 646 Iterator<E> get iterator { |
| 647 return new SkipWhileIterator<E>(_iterable.iterator, _f); | 647 return new SkipWhileIterator<E>(_iterable.iterator, _f); |
| 648 } | 648 } |
| 649 } | 649 } |
| 650 | 650 |
| 651 class SkipWhileIterator<E> extends Iterator<E> { | 651 class SkipWhileIterator<E> extends Iterator<E> { |
| 652 final Iterator<E> _iterator; | 652 final Iterator<E> _iterator; |
| 653 final _ElementPredicate<E> _f; | 653 final _ElementPredicate<E> _f; |
| 654 bool _hasSkipped = false; | 654 bool _hasSkipped = false; |
| 655 | 655 |
| 656 SkipWhileIterator(this._iterator, bool this._f(E element)); | 656 SkipWhileIterator(this._iterator, this._f); |
| 657 | 657 |
| 658 bool moveNext() { | 658 bool moveNext() { |
| 659 if (!_hasSkipped) { | 659 if (!_hasSkipped) { |
| 660 _hasSkipped = true; | 660 _hasSkipped = true; |
| 661 while (_iterator.moveNext()) { | 661 while (_iterator.moveNext()) { |
| 662 if (!_f(_iterator.current)) return true; | 662 if (!_f(_iterator.current)) return true; |
| 663 } | 663 } |
| 664 } | 664 } |
| 665 return _iterator.moveNext(); | 665 return _iterator.moveNext(); |
| 666 } | 666 } |
| (...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 755 * Creates errors throw by [Iterable] when the element count is wrong. | 755 * Creates errors throw by [Iterable] when the element count is wrong. |
| 756 */ | 756 */ |
| 757 abstract class IterableElementError { | 757 abstract class IterableElementError { |
| 758 /** Error thrown thrown by, e.g., [Iterable.first] when there is no result. */ | 758 /** Error thrown thrown by, e.g., [Iterable.first] when there is no result. */ |
| 759 static StateError noElement() => new StateError("No element"); | 759 static StateError noElement() => new StateError("No element"); |
| 760 /** Error thrown by, e.g., [Iterable.single] if there are too many results. */ | 760 /** Error thrown by, e.g., [Iterable.single] if there are too many results. */ |
| 761 static StateError tooMany() => new StateError("Too many elements"); | 761 static StateError tooMany() => new StateError("Too many elements"); |
| 762 /** Error thrown by, e.g., [List.setRange] if there are too few elements. */ | 762 /** Error thrown by, e.g., [List.setRange] if there are too few elements. */ |
| 763 static StateError tooFew() => new StateError("Too few elements"); | 763 static StateError tooFew() => new StateError("Too few elements"); |
| 764 } | 764 } |
| OLD | NEW |