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

Side by Side Diff: sdk/lib/internal/iterable.dart

Issue 2467113003: Make EfficientLength extend Iterable. (Closed)
Patch Set: Reverted, prepare to reland. Make new test not break web-testing framework. Created 4 years, 1 month 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 unified diff | Download patch
« no previous file with comments | « sdk/lib/core/set.dart ('k') | tests/corelib/growable_list_test.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 */
11 abstract class EfficientLength { 11 abstract class EfficientLengthIterable<T> extends Iterable<T> {
12 const EfficientLengthIterable();
12 /** 13 /**
13 * Returns the number of elements in the iterable. 14 * Returns the number of elements in the iterable.
14 * 15 *
15 * This is an efficient operation that doesn't require iterating through 16 * This is an efficient operation that doesn't require iterating through
16 * the elements. 17 * the elements.
17 */ 18 */
18 int get length; 19 int get length;
19 } 20 }
20 21
21 /** 22 /**
22 * An [Iterable] for classes that have efficient [length] and [elementAt]. 23 * An [Iterable] for classes that have efficient [length] and [elementAt].
23 * 24 *
24 * All other methods are implemented in terms of [length] and [elementAt], 25 * All other methods are implemented in terms of [length] and [elementAt],
25 * including [iterator]. 26 * including [iterator].
26 */ 27 */
27 abstract class ListIterable<E> extends Iterable<E> 28 abstract class ListIterable<E> extends EfficientLengthIterable<E> {
28 implements EfficientLength {
29 int get length; 29 int get length;
30 E elementAt(int i); 30 E elementAt(int i);
31 31
32 const ListIterable(); 32 const ListIterable();
33 33
34 Iterator<E> get iterator => new ListIterator<E>(this); 34 Iterator<E> get iterator => new ListIterator<E>(this);
35 35
36 void forEach(void action(E element)) { 36 void forEach(void action(E element)) {
37 int length = this.length; 37 int length = this.length;
38 for (int i = 0; i < length; i++) { 38 for (int i = 0; i < length; i++) {
(...skipping 308 matching lines...) Expand 10 before | Expand all | Expand 10 after
347 } 347 }
348 } 348 }
349 349
350 typedef T _Transformation<S, T>(S value); 350 typedef T _Transformation<S, T>(S value);
351 351
352 class MappedIterable<S, T> extends Iterable<T> { 352 class MappedIterable<S, T> extends Iterable<T> {
353 final Iterable<S> _iterable; 353 final Iterable<S> _iterable;
354 final _Transformation<S, T> _f; 354 final _Transformation<S, T> _f;
355 355
356 factory MappedIterable(Iterable<S> iterable, T function(S value)) { 356 factory MappedIterable(Iterable<S> iterable, T function(S value)) {
357 if (iterable is EfficientLength) { 357 if (iterable is EfficientLengthIterable) {
358 return new EfficientLengthMappedIterable<S, T>(iterable, function); 358 return new EfficientLengthMappedIterable<S, T>(iterable, function);
359 } 359 }
360 return new MappedIterable<S, T>._(iterable, function); 360 return new MappedIterable<S, T>._(iterable, function);
361 } 361 }
362 362
363 MappedIterable._(this._iterable, T this._f(S element)); 363 MappedIterable._(this._iterable, T this._f(S element));
364 364
365 Iterator<T> get iterator => new MappedIterator<S, T>(_iterable.iterator, _f); 365 Iterator<T> get iterator => new MappedIterator<S, T>(_iterable.iterator, _f);
366 366
367 // Length related functions are independent of the mapping. 367 // Length related functions are independent of the mapping.
368 int get length => _iterable.length; 368 int get length => _iterable.length;
369 bool get isEmpty => _iterable.isEmpty; 369 bool get isEmpty => _iterable.isEmpty;
370 370
371 // Index based lookup can be done before transforming. 371 // Index based lookup can be done before transforming.
372 T get first => _f(_iterable.first); 372 T get first => _f(_iterable.first);
373 T get last => _f(_iterable.last); 373 T get last => _f(_iterable.last);
374 T get single => _f(_iterable.single); 374 T get single => _f(_iterable.single);
375 T elementAt(int index) => _f(_iterable.elementAt(index)); 375 T elementAt(int index) => _f(_iterable.elementAt(index));
376 } 376 }
377 377
378 class EfficientLengthMappedIterable<S, T> extends MappedIterable<S, T> 378 class EfficientLengthMappedIterable<S, T> extends MappedIterable<S, T>
379 implements EfficientLength { 379 implements EfficientLengthIterable<T> {
380 EfficientLengthMappedIterable(Iterable<S> iterable, T function(S value)) 380 EfficientLengthMappedIterable(Iterable<S> iterable, T function(S value))
381 : super._(iterable, function); 381 : super._(iterable, function);
382 } 382 }
383 383
384 class MappedIterator<S, T> extends Iterator<T> { 384 class MappedIterator<S, T> extends Iterator<T> {
385 T _current; 385 T _current;
386 final Iterator<S> _iterator; 386 final Iterator<S> _iterator;
387 final _Transformation<S, T> _f; 387 final _Transformation<S, T> _f;
388 388
389 MappedIterator(this._iterator, T this._f(S element)); 389 MappedIterator(this._iterator, T this._f(S element));
390 390
391 bool moveNext() { 391 bool moveNext() {
392 if (_iterator.moveNext()) { 392 if (_iterator.moveNext()) {
393 _current = _f(_iterator.current); 393 _current = _f(_iterator.current);
394 return true; 394 return true;
395 } 395 }
396 _current = null; 396 _current = null;
397 return false; 397 return false;
398 } 398 }
399 399
400 T get current => _current; 400 T get current => _current;
401 } 401 }
402 402
403 /** 403 /**
404 * Specialized alternative to [MappedIterable] for mapped [List]s. 404 * Specialized alternative to [MappedIterable] for mapped [List]s.
405 * 405 *
406 * Expects efficient `length` and `elementAt` on the source iterable. 406 * Expects efficient `length` and `elementAt` on the source iterable.
407 */ 407 */
408 class MappedListIterable<S, T> extends ListIterable<T> 408 class MappedListIterable<S, T> extends ListIterable<T>
409 implements EfficientLength { 409 implements EfficientLengthIterable<T> {
410 final Iterable<S> _source; 410 final Iterable<S> _source;
411 final _Transformation<S, T> _f; 411 final _Transformation<S, T> _f;
412 412
413 MappedListIterable(this._source, T this._f(S value)); 413 MappedListIterable(this._source, T this._f(S value));
414 414
415 int get length => _source.length; 415 int get length => _source.length;
416 T elementAt(int index) => _f(_source.elementAt(index)); 416 T elementAt(int index) => _f(_source.elementAt(index));
417 } 417 }
418 418
419 419
420 typedef bool _ElementPredicate<E>(E element); 420 typedef bool _ElementPredicate<E>(E element);
421 421
422 class WhereIterable<E> extends Iterable<E> { 422 class WhereIterable<E> extends Iterable<E> {
423 final Iterable<E> _iterable; 423 final Iterable<E> _iterable;
424 final _ElementPredicate<E> _f; 424 final _ElementPredicate<E> _f;
425 425
426 WhereIterable(this._iterable, bool this._f(E element)); 426 WhereIterable(this._iterable, bool this._f(E element));
427 427
428 Iterator<E> get iterator => new WhereIterator<E>(_iterable.iterator, _f); 428 Iterator<E> get iterator => new WhereIterator<E>(_iterable.iterator, _f);
429 429
430 // Specialization of [Iterable.map] to non-EfficientLength. 430 // Specialization of [Iterable.map] to non-EfficientLengthIterable.
431 Iterable/*<T>*/ map/*<T>*/(/*=T*/ f(E element)) => 431 Iterable/*<T>*/ map/*<T>*/(/*=T*/ f(E element)) =>
432 new MappedIterable<E, dynamic/*=T*/>._(this, f); 432 new MappedIterable<E, dynamic/*=T*/>._(this, f);
433 } 433 }
434 434
435 class WhereIterator<E> extends Iterator<E> { 435 class WhereIterator<E> extends Iterator<E> {
436 final Iterator<E> _iterator; 436 final Iterator<E> _iterator;
437 final _ElementPredicate _f; 437 final _ElementPredicate _f;
438 438
439 WhereIterator(this._iterator, bool this._f(E element)); 439 WhereIterator(this._iterator, bool this._f(E element));
440 440
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
493 } 493 }
494 494
495 class TakeIterable<E> extends Iterable<E> { 495 class TakeIterable<E> extends Iterable<E> {
496 final Iterable<E> _iterable; 496 final Iterable<E> _iterable;
497 final int _takeCount; 497 final int _takeCount;
498 498
499 factory TakeIterable(Iterable<E> iterable, int takeCount) { 499 factory TakeIterable(Iterable<E> iterable, int takeCount) {
500 if (takeCount is! int || takeCount < 0) { 500 if (takeCount is! int || takeCount < 0) {
501 throw new ArgumentError(takeCount); 501 throw new ArgumentError(takeCount);
502 } 502 }
503 if (iterable is EfficientLength) { 503 if (iterable is EfficientLengthIterable) {
504 return new EfficientLengthTakeIterable<E>(iterable, takeCount); 504 return new EfficientLengthTakeIterable<E>(iterable, takeCount);
505 } 505 }
506 return new TakeIterable<E>._(iterable, takeCount); 506 return new TakeIterable<E>._(iterable, takeCount);
507 } 507 }
508 508
509 TakeIterable._(this._iterable, this._takeCount); 509 TakeIterable._(this._iterable, this._takeCount);
510 510
511 Iterator<E> get iterator { 511 Iterator<E> get iterator {
512 return new TakeIterator<E>(_iterable.iterator, _takeCount); 512 return new TakeIterator<E>(_iterable.iterator, _takeCount);
513 } 513 }
514 } 514 }
515 515
516 class EfficientLengthTakeIterable<E> extends TakeIterable<E> 516 class EfficientLengthTakeIterable<E> extends TakeIterable<E>
517 implements EfficientLength { 517 implements EfficientLengthIterable<E> {
518 EfficientLengthTakeIterable(Iterable<E> iterable, int takeCount) 518 EfficientLengthTakeIterable(Iterable<E> iterable, int takeCount)
519 : super._(iterable, takeCount); 519 : super._(iterable, takeCount);
520 520
521 int get length { 521 int get length {
522 int iterableLength = _iterable.length; 522 int iterableLength = _iterable.length;
523 if (iterableLength > _takeCount) return _takeCount; 523 if (iterableLength > _takeCount) return _takeCount;
524 return iterableLength; 524 return iterableLength;
525 } 525 }
526 } 526 }
527 527
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
580 if (_isFinished) return null; 580 if (_isFinished) return null;
581 return _iterator.current; 581 return _iterator.current;
582 } 582 }
583 } 583 }
584 584
585 class SkipIterable<E> extends Iterable<E> { 585 class SkipIterable<E> extends Iterable<E> {
586 final Iterable<E> _iterable; 586 final Iterable<E> _iterable;
587 final int _skipCount; 587 final int _skipCount;
588 588
589 factory SkipIterable(Iterable<E> iterable, int count) { 589 factory SkipIterable(Iterable<E> iterable, int count) {
590 if (iterable is EfficientLength) { 590 if (iterable is EfficientLengthIterable) {
591 return new EfficientLengthSkipIterable<E>(iterable, count); 591 return new EfficientLengthSkipIterable<E>(iterable, count);
592 } 592 }
593 return new SkipIterable<E>._(iterable, count); 593 return new SkipIterable<E>._(iterable, count);
594 } 594 }
595 595
596 SkipIterable._(this._iterable, this._skipCount) { 596 SkipIterable._(this._iterable, this._skipCount) {
597 if (_skipCount is! int) { 597 if (_skipCount is! int) {
598 throw new ArgumentError.value(_skipCount, "count is not an integer"); 598 throw new ArgumentError.value(_skipCount, "count is not an integer");
599 } 599 }
600 RangeError.checkNotNegative(_skipCount, "count"); 600 RangeError.checkNotNegative(_skipCount, "count");
601 } 601 }
602 602
603 Iterable<E> skip(int count) { 603 Iterable<E> skip(int count) {
604 if (_skipCount is! int) { 604 if (_skipCount is! int) {
605 throw new ArgumentError.value(_skipCount, "count is not an integer"); 605 throw new ArgumentError.value(_skipCount, "count is not an integer");
606 } 606 }
607 RangeError.checkNotNegative(_skipCount, "count"); 607 RangeError.checkNotNegative(_skipCount, "count");
608 return new SkipIterable<E>._(_iterable, _skipCount + count); 608 return new SkipIterable<E>._(_iterable, _skipCount + count);
609 } 609 }
610 610
611 Iterator<E> get iterator { 611 Iterator<E> get iterator {
612 return new SkipIterator<E>(_iterable.iterator, _skipCount); 612 return new SkipIterator<E>(_iterable.iterator, _skipCount);
613 } 613 }
614 } 614 }
615 615
616 class EfficientLengthSkipIterable<E> extends SkipIterable<E> 616 class EfficientLengthSkipIterable<E> extends SkipIterable<E>
617 implements EfficientLength { 617 implements EfficientLengthIterable<E> {
618 EfficientLengthSkipIterable(Iterable<E> iterable, int skipCount) 618 EfficientLengthSkipIterable(Iterable<E> iterable, int skipCount)
619 : super._(iterable, skipCount); 619 : super._(iterable, skipCount);
620 620
621 int get length { 621 int get length {
622 int length = _iterable.length - _skipCount; 622 int length = _iterable.length - _skipCount;
623 if (length >= 0) return length; 623 if (length >= 0) return length;
624 return 0; 624 return 0;
625 } 625 }
626 } 626 }
627 627
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
669 } 669 }
670 return _iterator.moveNext(); 670 return _iterator.moveNext();
671 } 671 }
672 672
673 E get current => _iterator.current; 673 E get current => _iterator.current;
674 } 674 }
675 675
676 /** 676 /**
677 * The always empty [Iterable]. 677 * The always empty [Iterable].
678 */ 678 */
679 class EmptyIterable<E> extends Iterable<E> implements EfficientLength { 679 class EmptyIterable<E> extends EfficientLengthIterable<E> {
680 const EmptyIterable(); 680 const EmptyIterable();
681 681
682 Iterator<E> get iterator => const EmptyIterator(); 682 Iterator<E> get iterator => const EmptyIterator();
683 683
684 void forEach(void action(E element)) {} 684 void forEach(void action(E element)) {}
685 685
686 bool get isEmpty => true; 686 bool get isEmpty => true;
687 687
688 int get length => 0; 688 int get length => 0;
689 689
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
762 * Creates errors throw by [Iterable] when the element count is wrong. 762 * Creates errors throw by [Iterable] when the element count is wrong.
763 */ 763 */
764 abstract class IterableElementError { 764 abstract class IterableElementError {
765 /** Error thrown thrown by, e.g., [Iterable.first] when there is no result. */ 765 /** Error thrown thrown by, e.g., [Iterable.first] when there is no result. */
766 static StateError noElement() => new StateError("No element"); 766 static StateError noElement() => new StateError("No element");
767 /** Error thrown by, e.g., [Iterable.single] if there are too many results. */ 767 /** Error thrown by, e.g., [Iterable.single] if there are too many results. */
768 static StateError tooMany() => new StateError("Too many elements"); 768 static StateError tooMany() => new StateError("Too many elements");
769 /** Error thrown by, e.g., [List.setRange] if there are too few elements. */ 769 /** Error thrown by, e.g., [List.setRange] if there are too few elements. */
770 static StateError tooFew() => new StateError("Too few elements"); 770 static StateError tooFew() => new StateError("Too few elements");
771 } 771 }
OLDNEW
« no previous file with comments | « sdk/lib/core/set.dart ('k') | tests/corelib/growable_list_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698