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