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

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

Issue 1104063002: Make EfficientLength public, as EfficientLengthIterable. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Address comment. Created 5 years, 7 months 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 | Annotate | Revision Log
« 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
9 * [length] implementation.
10 */
11 abstract class EfficientLength {
12 /**
13 * Returns the number of elements in the iterable.
14 *
15 * This is an efficient operation that doesn't require iterating through
16 * the elements.
17 */
18 int get length;
19 }
20
21 /**
22 * An [Iterable] for classes that have efficient [length] and [elementAt]. 8 * An [Iterable] for classes that have efficient [length] and [elementAt].
23 * 9 *
24 * All other methods are implemented in terms of [length] and [elementAt], 10 * All other methods are implemented in terms of [length] and [elementAt],
25 * including [iterator]. 11 * including [iterator].
26 */ 12 */
27 abstract class ListIterable<E> extends Iterable<E> 13 abstract class ListIterable<E> extends Iterable<E>
28 implements EfficientLength { 14 implements EfficientLengthIterable<E> {
29 int get length; 15 int get length;
30 E elementAt(int i); 16 E elementAt(int i);
31 17
32 const ListIterable(); 18 const ListIterable();
33 19
34 Iterator<E> get iterator => new ListIterator<E>(this); 20 Iterator<E> get iterator => new ListIterator<E>(this);
35 21
36 void forEach(void action(E element)) { 22 void forEach(void action(E element)) {
37 int length = this.length; 23 int length = this.length;
38 for (int i = 0; i < length; i++) { 24 for (int i = 0; i < length; i++) {
(...skipping 305 matching lines...) Expand 10 before | Expand all | Expand 10 after
344 } 330 }
345 } 331 }
346 332
347 typedef T _Transformation<S, T>(S value); 333 typedef T _Transformation<S, T>(S value);
348 334
349 class MappedIterable<S, T> extends Iterable<T> { 335 class MappedIterable<S, T> extends Iterable<T> {
350 final Iterable<S> _iterable; 336 final Iterable<S> _iterable;
351 final _Transformation<S, T> _f; 337 final _Transformation<S, T> _f;
352 338
353 factory MappedIterable(Iterable iterable, T function(S value)) { 339 factory MappedIterable(Iterable iterable, T function(S value)) {
354 if (iterable is EfficientLength) { 340 if (iterable is EfficientLengthIterable) {
355 return new EfficientLengthMappedIterable<S, T>(iterable, function); 341 return new EfficientLengthMappedIterable<S, T>(iterable, function);
356 } 342 }
357 return new MappedIterable<S, T>._(iterable, function); 343 return new MappedIterable<S, T>._(iterable, function);
358 } 344 }
359 345
360 MappedIterable._(this._iterable, T this._f(S element)); 346 MappedIterable._(this._iterable, T this._f(S element));
361 347
362 Iterator<T> get iterator => new MappedIterator<S, T>(_iterable.iterator, _f); 348 Iterator<T> get iterator => new MappedIterator<S, T>(_iterable.iterator, _f);
363 349
364 // Length related functions are independent of the mapping. 350 // Length related functions are independent of the mapping.
365 int get length => _iterable.length; 351 int get length => _iterable.length;
366 bool get isEmpty => _iterable.isEmpty; 352 bool get isEmpty => _iterable.isEmpty;
367 353
368 // Index based lookup can be done before transforming. 354 // Index based lookup can be done before transforming.
369 T get first => _f(_iterable.first); 355 T get first => _f(_iterable.first);
370 T get last => _f(_iterable.last); 356 T get last => _f(_iterable.last);
371 T get single => _f(_iterable.single); 357 T get single => _f(_iterable.single);
372 T elementAt(int index) => _f(_iterable.elementAt(index)); 358 T elementAt(int index) => _f(_iterable.elementAt(index));
373 } 359 }
374 360
375 class EfficientLengthMappedIterable<S, T> extends MappedIterable<S, T> 361 class EfficientLengthMappedIterable<S, T> extends MappedIterable<S, T>
376 implements EfficientLength { 362 implements EfficientLengthIterable<T> {
377 EfficientLengthMappedIterable(Iterable iterable, T function(S value)) 363 EfficientLengthMappedIterable(Iterable iterable, T function(S value))
378 : super._(iterable, function); 364 : super._(iterable, function);
379 } 365 }
380 366
381 class MappedIterator<S, T> extends Iterator<T> { 367 class MappedIterator<S, T> extends Iterator<T> {
382 T _current; 368 T _current;
383 final Iterator<S> _iterator; 369 final Iterator<S> _iterator;
384 final _Transformation<S, T> _f; 370 final _Transformation<S, T> _f;
385 371
386 MappedIterator(this._iterator, T this._f(S element)); 372 MappedIterator(this._iterator, T this._f(S element));
387 373
388 bool moveNext() { 374 bool moveNext() {
389 if (_iterator.moveNext()) { 375 if (_iterator.moveNext()) {
390 _current = _f(_iterator.current); 376 _current = _f(_iterator.current);
391 return true; 377 return true;
392 } 378 }
393 _current = null; 379 _current = null;
394 return false; 380 return false;
395 } 381 }
396 382
397 T get current => _current; 383 T get current => _current;
398 } 384 }
399 385
400 /** 386 /**
401 * Specialized alternative to [MappedIterable] for mapped [List]s. 387 * Specialized alternative to [MappedIterable] for mapped [List]s.
402 * 388 *
403 * Expects efficient `length` and `elementAt` on the source iterable. 389 * Expects efficient `length` and `elementAt` on the source iterable.
404 */ 390 */
405 class MappedListIterable<S, T> extends ListIterable<T> 391 class MappedListIterable<S, T> extends ListIterable<T> {
406 implements EfficientLength {
407 final Iterable<S> _source; 392 final Iterable<S> _source;
408 final _Transformation<S, T> _f; 393 final _Transformation<S, T> _f;
409 394
410 MappedListIterable(this._source, T this._f(S value)); 395 MappedListIterable(this._source, T this._f(S value));
411 396
412 int get length => _source.length; 397 int get length => _source.length;
413 T elementAt(int index) => _f(_source.elementAt(index)); 398 T elementAt(int index) => _f(_source.elementAt(index));
414 } 399 }
415 400
416 401
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
489 } 474 }
490 475
491 class TakeIterable<E> extends Iterable<E> { 476 class TakeIterable<E> extends Iterable<E> {
492 final Iterable<E> _iterable; 477 final Iterable<E> _iterable;
493 final int _takeCount; 478 final int _takeCount;
494 479
495 factory TakeIterable(Iterable<E> iterable, int takeCount) { 480 factory TakeIterable(Iterable<E> iterable, int takeCount) {
496 if (takeCount is! int || takeCount < 0) { 481 if (takeCount is! int || takeCount < 0) {
497 throw new ArgumentError(takeCount); 482 throw new ArgumentError(takeCount);
498 } 483 }
499 if (iterable is EfficientLength) { 484 if (iterable is EfficientLengthIterable) {
500 return new EfficientLengthTakeIterable<E>(iterable, takeCount); 485 return new EfficientLengthTakeIterable<E>(iterable, takeCount);
501 } 486 }
502 return new TakeIterable<E>._(iterable, takeCount); 487 return new TakeIterable<E>._(iterable, takeCount);
503 } 488 }
504 489
505 TakeIterable._(this._iterable, this._takeCount); 490 TakeIterable._(this._iterable, this._takeCount);
506 491
507 Iterator<E> get iterator { 492 Iterator<E> get iterator {
508 return new TakeIterator<E>(_iterable.iterator, _takeCount); 493 return new TakeIterator<E>(_iterable.iterator, _takeCount);
509 } 494 }
510 } 495 }
511 496
512 class EfficientLengthTakeIterable<E> extends TakeIterable<E> 497 class EfficientLengthTakeIterable<E> extends TakeIterable<E>
513 implements EfficientLength { 498 implements EfficientLengthIterable<E> {
514 EfficientLengthTakeIterable(Iterable<E> iterable, int takeCount) 499 EfficientLengthTakeIterable(Iterable<E> iterable, int takeCount)
515 : super._(iterable, takeCount); 500 : super._(iterable, takeCount);
516 501
517 int get length { 502 int get length {
518 int iterableLength = _iterable.length; 503 int iterableLength = _iterable.length;
519 if (iterableLength > _takeCount) return _takeCount; 504 if (iterableLength > _takeCount) return _takeCount;
520 return iterableLength; 505 return iterableLength;
521 } 506 }
522 } 507 }
523 508
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
576 if (_isFinished) return null; 561 if (_isFinished) return null;
577 return _iterator.current; 562 return _iterator.current;
578 } 563 }
579 } 564 }
580 565
581 class SkipIterable<E> extends Iterable<E> { 566 class SkipIterable<E> extends Iterable<E> {
582 final Iterable<E> _iterable; 567 final Iterable<E> _iterable;
583 final int _skipCount; 568 final int _skipCount;
584 569
585 factory SkipIterable(Iterable<E> iterable, int count) { 570 factory SkipIterable(Iterable<E> iterable, int count) {
586 if (iterable is EfficientLength) { 571 if (iterable is EfficientLengthIterable) {
587 return new EfficientLengthSkipIterable<E>(iterable, count); 572 return new EfficientLengthSkipIterable<E>(iterable, count);
588 } 573 }
589 return new SkipIterable<E>._(iterable, count); 574 return new SkipIterable<E>._(iterable, count);
590 } 575 }
591 576
592 SkipIterable._(this._iterable, this._skipCount) { 577 SkipIterable._(this._iterable, this._skipCount) {
593 if (_skipCount is! int) { 578 if (_skipCount is! int) {
594 throw new ArgumentError.value(_skipCount, "count is not an integer"); 579 throw new ArgumentError.value(_skipCount, "count is not an integer");
595 } 580 }
596 RangeError.checkNotNegative(_skipCount, "count"); 581 RangeError.checkNotNegative(_skipCount, "count");
597 } 582 }
598 583
599 Iterable<E> skip(int count) { 584 Iterable<E> skip(int count) {
600 if (_skipCount is! int) { 585 if (_skipCount is! int) {
601 throw new ArgumentError.value(_skipCount, "count is not an integer"); 586 throw new ArgumentError.value(_skipCount, "count is not an integer");
602 } 587 }
603 RangeError.checkNotNegative(_skipCount, "count"); 588 RangeError.checkNotNegative(_skipCount, "count");
604 return new SkipIterable<E>._(_iterable, _skipCount + count); 589 return new SkipIterable<E>._(_iterable, _skipCount + count);
605 } 590 }
606 591
607 Iterator<E> get iterator { 592 Iterator<E> get iterator {
608 return new SkipIterator<E>(_iterable.iterator, _skipCount); 593 return new SkipIterator<E>(_iterable.iterator, _skipCount);
609 } 594 }
610 } 595 }
611 596
612 class EfficientLengthSkipIterable<E> extends SkipIterable<E> 597 class EfficientLengthSkipIterable<E> extends SkipIterable<E>
613 implements EfficientLength { 598 implements EfficientLengthIterable<E> {
614 EfficientLengthSkipIterable(Iterable<E> iterable, int skipCount) 599 EfficientLengthSkipIterable(Iterable<E> iterable, int skipCount)
615 : super._(iterable, skipCount); 600 : super._(iterable, skipCount);
616 601
617 int get length { 602 int get length {
618 int length = _iterable.length - _skipCount; 603 int length = _iterable.length - _skipCount;
619 if (length >= 0) return length; 604 if (length >= 0) return length;
620 return 0; 605 return 0;
621 } 606 }
622 } 607 }
623 608
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
665 } 650 }
666 return _iterator.moveNext(); 651 return _iterator.moveNext();
667 } 652 }
668 653
669 E get current => _iterator.current; 654 E get current => _iterator.current;
670 } 655 }
671 656
672 /** 657 /**
673 * The always empty [Iterable]. 658 * The always empty [Iterable].
674 */ 659 */
675 class EmptyIterable<E> extends Iterable<E> implements EfficientLength { 660 class EmptyIterable<E> extends Iterable<E>
661 implements EfficientLengthIterable<E> {
Søren Gjesse 2015/05/05 16:33:30 Indentation :-)
676 const EmptyIterable(); 662 const EmptyIterable();
677 663
678 Iterator<E> get iterator => const EmptyIterator(); 664 Iterator<E> get iterator => const EmptyIterator();
679 665
680 void forEach(void action(E element)) {} 666 void forEach(void action(E element)) {}
681 667
682 bool get isEmpty => true; 668 bool get isEmpty => true;
683 669
684 int get length => 0; 670 int get length => 0;
685 671
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
762 * Creates errors throw by [Iterable] when the element count is wrong. 748 * Creates errors throw by [Iterable] when the element count is wrong.
763 */ 749 */
764 abstract class IterableElementError { 750 abstract class IterableElementError {
765 /** Error thrown thrown by, e.g., [Iterable.first] when there is no result. */ 751 /** Error thrown thrown by, e.g., [Iterable.first] when there is no result. */
766 static StateError noElement() => new StateError("No element"); 752 static StateError noElement() => new StateError("No element");
767 /** Error thrown by, e.g., [Iterable.single] if there are too many results. */ 753 /** Error thrown by, e.g., [Iterable.single] if there are too many results. */
768 static StateError tooMany() => new StateError("Too many elements"); 754 static StateError tooMany() => new StateError("Too many elements");
769 /** Error thrown by, e.g., [List.setRange] if there are too few elements. */ 755 /** Error thrown by, e.g., [List.setRange] if there are too few elements. */
770 static StateError tooFew() => new StateError("Too few elements"); 756 static StateError tooFew() => new StateError("Too few elements");
771 } 757 }
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