| 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 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 87 int length = this.length; | 87 int length = this.length; |
| 88 for (int i = 0; i < length; i++) { | 88 for (int i = 0; i < length; i++) { |
| 89 if (test(elementAt(i))) return true; | 89 if (test(elementAt(i))) return true; |
| 90 if (length != this.length) { | 90 if (length != this.length) { |
| 91 throw new ConcurrentModificationError(this); | 91 throw new ConcurrentModificationError(this); |
| 92 } | 92 } |
| 93 } | 93 } |
| 94 return false; | 94 return false; |
| 95 } | 95 } |
| 96 | 96 |
| 97 E firstWhere(bool test(E element), { E orElse() }) { | 97 E firstWhere(bool test(E element), {E orElse()}) { |
| 98 int length = this.length; | 98 int length = this.length; |
| 99 for (int i = 0; i < length; i++) { | 99 for (int i = 0; i < length; i++) { |
| 100 E element = elementAt(i); | 100 E element = elementAt(i); |
| 101 if (test(element)) return element; | 101 if (test(element)) return element; |
| 102 if (length != this.length) { | 102 if (length != this.length) { |
| 103 throw new ConcurrentModificationError(this); | 103 throw new ConcurrentModificationError(this); |
| 104 } | 104 } |
| 105 } | 105 } |
| 106 if (orElse != null) return orElse(); | 106 if (orElse != null) return orElse(); |
| 107 throw IterableElementError.noElement(); | 107 throw IterableElementError.noElement(); |
| 108 } | 108 } |
| 109 | 109 |
| 110 E lastWhere(bool test(E element), { E orElse() }) { | 110 E lastWhere(bool test(E element), {E orElse()}) { |
| 111 int length = this.length; | 111 int length = this.length; |
| 112 for (int i = length - 1; i >= 0; i--) { | 112 for (int i = length - 1; i >= 0; i--) { |
| 113 E element = elementAt(i); | 113 E element = elementAt(i); |
| 114 if (test(element)) return element; | 114 if (test(element)) return element; |
| 115 if (length != this.length) { | 115 if (length != this.length) { |
| 116 throw new ConcurrentModificationError(this); | 116 throw new ConcurrentModificationError(this); |
| 117 } | 117 } |
| 118 } | 118 } |
| 119 if (orElse != null) return orElse(); | 119 if (orElse != null) return orElse(); |
| 120 throw IterableElementError.noElement(); | 120 throw IterableElementError.noElement(); |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 176 | 176 |
| 177 E reduce(E combine(var value, E element)) { | 177 E reduce(E combine(var value, E element)) { |
| 178 int length = this.length; | 178 int length = this.length; |
| 179 if (length == 0) throw IterableElementError.noElement(); | 179 if (length == 0) throw IterableElementError.noElement(); |
| 180 E value = elementAt(0); | 180 E value = elementAt(0); |
| 181 for (int i = 1; i < length; i++) { | 181 for (int i = 1; i < length; i++) { |
| 182 value = combine(value, elementAt(i)); | 182 value = combine(value, elementAt(i)); |
| 183 if (length != this.length) { | 183 if (length != this.length) { |
| 184 throw new ConcurrentModificationError(this); | 184 throw new ConcurrentModificationError(this); |
| 185 } | 185 } |
| 186 | |
| 187 } | 186 } |
| 188 return value; | 187 return value; |
| 189 } | 188 } |
| 190 | 189 |
| 191 T fold<T>(T initialValue, T combine(T previousValue, E element)) { | 190 T fold<T>(T initialValue, T combine(T previousValue, E element)) { |
| 192 var value = initialValue; | 191 var value = initialValue; |
| 193 int length = this.length; | 192 int length = this.length; |
| 194 for (int i = 0; i < length; i++) { | 193 for (int i = 0; i < length; i++) { |
| 195 value = combine(value, elementAt(i)); | 194 value = combine(value, elementAt(i)); |
| 196 if (length != this.length) { | 195 if (length != this.length) { |
| 197 throw new ConcurrentModificationError(this); | 196 throw new ConcurrentModificationError(this); |
| 198 } | 197 } |
| 199 } | 198 } |
| 200 return value; | 199 return value; |
| 201 } | 200 } |
| 202 | 201 |
| 203 Iterable<E> skip(int count) => new SubListIterable<E>(this, count, null); | 202 Iterable<E> skip(int count) => new SubListIterable<E>(this, count, null); |
| 204 | 203 |
| 205 Iterable<E> skipWhile(bool test(E element)) => super.skipWhile(test); | 204 Iterable<E> skipWhile(bool test(E element)) => super.skipWhile(test); |
| 206 | 205 |
| 207 Iterable<E> take(int count) => new SubListIterable<E>(this, 0, count); | 206 Iterable<E> take(int count) => new SubListIterable<E>(this, 0, count); |
| 208 | 207 |
| 209 Iterable<E> takeWhile(bool test(E element)) => super.takeWhile(test); | 208 Iterable<E> takeWhile(bool test(E element)) => super.takeWhile(test); |
| 210 | 209 |
| 211 List<E> toList({ bool growable: true }) { | 210 List<E> toList({bool growable: true}) { |
| 212 List<E> result; | 211 List<E> result; |
| 213 if (growable) { | 212 if (growable) { |
| 214 result = new List<E>()..length = length; | 213 result = new List<E>()..length = length; |
| 215 } else { | 214 } else { |
| 216 result = new List<E>(length); | 215 result = new List<E>(length); |
| 217 } | 216 } |
| 218 for (int i = 0; i < length; i++) { | 217 for (int i = 0; i < length; i++) { |
| 219 result[i] = elementAt(i); | 218 result[i] = elementAt(i); |
| 220 } | 219 } |
| 221 return result; | 220 return result; |
| 222 } | 221 } |
| 223 | 222 |
| 224 Set<E> toSet() { | 223 Set<E> toSet() { |
| 225 Set<E> result = new Set<E>(); | 224 Set<E> result = new Set<E>(); |
| 226 for (int i = 0; i < length; i++) { | 225 for (int i = 0; i < length; i++) { |
| 227 result.add(elementAt(i)); | 226 result.add(elementAt(i)); |
| 228 } | 227 } |
| 229 return result; | 228 return result; |
| 230 } | 229 } |
| 231 } | 230 } |
| 232 | 231 |
| 233 class SubListIterable<E> extends ListIterable<E> { | 232 class SubListIterable<E> extends ListIterable<E> { |
| 234 final Iterable<E> _iterable; // Has efficient length and elementAt. | 233 final Iterable<E> _iterable; // Has efficient length and elementAt. |
| 235 final int _start; | 234 final int _start; |
| 236 /** If null, represents the length of the iterable. */ | 235 /** If null, represents the length of the iterable. */ |
| 237 final int _endOrLength; | 236 final int _endOrLength; |
| 238 | 237 |
| 239 SubListIterable(this._iterable, this._start, this._endOrLength) { | 238 SubListIterable(this._iterable, this._start, this._endOrLength) { |
| 240 RangeError.checkNotNegative(_start, "start"); | 239 RangeError.checkNotNegative(_start, "start"); |
| 241 if (_endOrLength != null) { | 240 if (_endOrLength != null) { |
| 242 RangeError.checkNotNegative(_endOrLength, "end"); | 241 RangeError.checkNotNegative(_endOrLength, "end"); |
| 243 if (_start > _endOrLength) { | 242 if (_start > _endOrLength) { |
| 244 throw new RangeError.range(_start, 0, _endOrLength, "start"); | 243 throw new RangeError.range(_start, 0, _endOrLength, "start"); |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 294 return new SubListIterable<E>(_iterable, _start, newEnd); | 293 return new SubListIterable<E>(_iterable, _start, newEnd); |
| 295 } | 294 } |
| 296 } | 295 } |
| 297 | 296 |
| 298 List<E> toList({bool growable: true}) { | 297 List<E> toList({bool growable: true}) { |
| 299 int start = _start; | 298 int start = _start; |
| 300 int end = _iterable.length; | 299 int end = _iterable.length; |
| 301 if (_endOrLength != null && _endOrLength < end) end = _endOrLength; | 300 if (_endOrLength != null && _endOrLength < end) end = _endOrLength; |
| 302 int length = end - start; | 301 int length = end - start; |
| 303 if (length < 0) length = 0; | 302 if (length < 0) length = 0; |
| 304 List<E> result = growable ? (new List<E>()..length = length) | 303 List<E> result = |
| 305 : new List<E>(length); | 304 growable ? (new List<E>()..length = length) : new List<E>(length); |
| 306 for (int i = 0; i < length; i++) { | 305 for (int i = 0; i < length; i++) { |
| 307 result[i] = _iterable.elementAt(start + i); | 306 result[i] = _iterable.elementAt(start + i); |
| 308 if (_iterable.length < end) throw new ConcurrentModificationError(this); | 307 if (_iterable.length < end) throw new ConcurrentModificationError(this); |
| 309 } | 308 } |
| 310 return result; | 309 return result; |
| 311 } | 310 } |
| 312 } | 311 } |
| 313 | 312 |
| 314 /** | 313 /** |
| 315 * An [Iterator] that iterates a list-like [Iterable]. | 314 * An [Iterator] that iterates a list-like [Iterable]. |
| 316 * | 315 * |
| 317 * All iterations is done in terms of [Iterable.length] and | 316 * All iterations is done in terms of [Iterable.length] and |
| 318 * [Iterable.elementAt]. These operations are fast for list-like | 317 * [Iterable.elementAt]. These operations are fast for list-like |
| 319 * iterables. | 318 * iterables. |
| 320 */ | 319 */ |
| 321 class ListIterator<E> implements Iterator<E> { | 320 class ListIterator<E> implements Iterator<E> { |
| 322 final Iterable<E> _iterable; | 321 final Iterable<E> _iterable; |
| 323 final int _length; | 322 final int _length; |
| 324 int _index; | 323 int _index; |
| 325 E _current; | 324 E _current; |
| 326 | 325 |
| 327 ListIterator(Iterable<E> iterable) | 326 ListIterator(Iterable<E> iterable) |
| 328 : _iterable = iterable, _length = iterable.length, _index = 0; | 327 : _iterable = iterable, |
| 328 _length = iterable.length, |
| 329 _index = 0; |
| 329 | 330 |
| 330 E get current => _current; | 331 E get current => _current; |
| 331 | 332 |
| 332 bool moveNext() { | 333 bool moveNext() { |
| 333 int length = _iterable.length; | 334 int length = _iterable.length; |
| 334 if (_length != length) { | 335 if (_length != length) { |
| 335 throw new ConcurrentModificationError(_iterable); | 336 throw new ConcurrentModificationError(_iterable); |
| 336 } | 337 } |
| 337 if (_index >= length) { | 338 if (_index >= length) { |
| 338 _current = null; | 339 _current = null; |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 405 class MappedListIterable<S, T> extends ListIterable<T> { | 406 class MappedListIterable<S, T> extends ListIterable<T> { |
| 406 final Iterable<S> _source; | 407 final Iterable<S> _source; |
| 407 final _Transformation<S, T> _f; | 408 final _Transformation<S, T> _f; |
| 408 | 409 |
| 409 MappedListIterable(this._source, this._f); | 410 MappedListIterable(this._source, this._f); |
| 410 | 411 |
| 411 int get length => _source.length; | 412 int get length => _source.length; |
| 412 T elementAt(int index) => _f(_source.elementAt(index)); | 413 T elementAt(int index) => _f(_source.elementAt(index)); |
| 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, this._f); | 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 |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 502 } | 502 } |
| 503 | 503 |
| 504 TakeIterable._(this._iterable, this._takeCount); | 504 TakeIterable._(this._iterable, this._takeCount); |
| 505 | 505 |
| 506 Iterator<E> get iterator { | 506 Iterator<E> get iterator { |
| 507 return new TakeIterator<E>(_iterable.iterator, _takeCount); | 507 return new TakeIterator<E>(_iterable.iterator, _takeCount); |
| 508 } | 508 } |
| 509 } | 509 } |
| 510 | 510 |
| 511 class EfficientLengthTakeIterable<E> extends TakeIterable<E> | 511 class EfficientLengthTakeIterable<E> extends TakeIterable<E> |
| 512 implements EfficientLengthIterable<E> { | 512 implements EfficientLengthIterable<E> { |
| 513 EfficientLengthTakeIterable(Iterable<E> iterable, int takeCount) | 513 EfficientLengthTakeIterable(Iterable<E> iterable, int takeCount) |
| 514 : super._(iterable, takeCount); | 514 : super._(iterable, takeCount); |
| 515 | 515 |
| 516 int get length { | 516 int get length { |
| 517 int iterableLength = _iterable.length; | 517 int iterableLength = _iterable.length; |
| 518 if (iterableLength > _takeCount) return _takeCount; | 518 if (iterableLength > _takeCount) return _takeCount; |
| 519 return iterableLength; | 519 return iterableLength; |
| 520 } | 520 } |
| 521 } | 521 } |
| 522 | 522 |
| 523 | |
| 524 class TakeIterator<E> extends Iterator<E> { | 523 class TakeIterator<E> extends Iterator<E> { |
| 525 final Iterator<E> _iterator; | 524 final Iterator<E> _iterator; |
| 526 int _remaining; | 525 int _remaining; |
| 527 | 526 |
| 528 TakeIterator(this._iterator, this._remaining) { | 527 TakeIterator(this._iterator, this._remaining) { |
| 529 assert(_remaining is int && _remaining >= 0); | 528 assert(_remaining is int && _remaining >= 0); |
| 530 } | 529 } |
| 531 | 530 |
| 532 bool moveNext() { | 531 bool moveNext() { |
| 533 _remaining--; | 532 _remaining--; |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 602 RangeError.checkNotNegative(_skipCount, "count"); | 601 RangeError.checkNotNegative(_skipCount, "count"); |
| 603 return new SkipIterable<E>._(_iterable, _skipCount + count); | 602 return new SkipIterable<E>._(_iterable, _skipCount + count); |
| 604 } | 603 } |
| 605 | 604 |
| 606 Iterator<E> get iterator { | 605 Iterator<E> get iterator { |
| 607 return new SkipIterator<E>(_iterable.iterator, _skipCount); | 606 return new SkipIterator<E>(_iterable.iterator, _skipCount); |
| 608 } | 607 } |
| 609 } | 608 } |
| 610 | 609 |
| 611 class EfficientLengthSkipIterable<E> extends SkipIterable<E> | 610 class EfficientLengthSkipIterable<E> extends SkipIterable<E> |
| 612 implements EfficientLengthIterable<E> { | 611 implements EfficientLengthIterable<E> { |
| 613 EfficientLengthSkipIterable(Iterable<E> iterable, int skipCount) | 612 EfficientLengthSkipIterable(Iterable<E> iterable, int skipCount) |
| 614 : super._(iterable, skipCount); | 613 : super._(iterable, skipCount); |
| 615 | 614 |
| 616 int get length { | 615 int get length { |
| 617 int length = _iterable.length - _skipCount; | 616 int length = _iterable.length - _skipCount; |
| 618 if (length >= 0) return length; | 617 if (length >= 0) return length; |
| 619 return 0; | 618 return 0; |
| 620 } | 619 } |
| 621 } | 620 } |
| 622 | 621 |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 675 const EmptyIterable(); | 674 const EmptyIterable(); |
| 676 | 675 |
| 677 Iterator<E> get iterator => const EmptyIterator(); | 676 Iterator<E> get iterator => const EmptyIterator(); |
| 678 | 677 |
| 679 void forEach(void action(E element)) {} | 678 void forEach(void action(E element)) {} |
| 680 | 679 |
| 681 bool get isEmpty => true; | 680 bool get isEmpty => true; |
| 682 | 681 |
| 683 int get length => 0; | 682 int get length => 0; |
| 684 | 683 |
| 685 E get first { throw IterableElementError.noElement(); } | 684 E get first { |
| 685 throw IterableElementError.noElement(); |
| 686 } |
| 686 | 687 |
| 687 E get last { throw IterableElementError.noElement(); } | 688 E get last { |
| 689 throw IterableElementError.noElement(); |
| 690 } |
| 688 | 691 |
| 689 E get single { throw IterableElementError.noElement(); } | 692 E get single { |
| 693 throw IterableElementError.noElement(); |
| 694 } |
| 690 | 695 |
| 691 E elementAt(int index) { throw new RangeError.range(index, 0, 0, "index"); } | 696 E elementAt(int index) { |
| 697 throw new RangeError.range(index, 0, 0, "index"); |
| 698 } |
| 692 | 699 |
| 693 bool contains(Object element) => false; | 700 bool contains(Object element) => false; |
| 694 | 701 |
| 695 bool every(bool test(E element)) => true; | 702 bool every(bool test(E element)) => true; |
| 696 | 703 |
| 697 bool any(bool test(E element)) => false; | 704 bool any(bool test(E element)) => false; |
| 698 | 705 |
| 699 E firstWhere(bool test(E element), { E orElse() }) { | 706 E firstWhere(bool test(E element), {E orElse()}) { |
| 700 if (orElse != null) return orElse(); | 707 if (orElse != null) return orElse(); |
| 701 throw IterableElementError.noElement(); | 708 throw IterableElementError.noElement(); |
| 702 } | 709 } |
| 703 | 710 |
| 704 E lastWhere(bool test(E element), { E orElse() }) { | 711 E lastWhere(bool test(E element), {E orElse()}) { |
| 705 if (orElse != null) return orElse(); | 712 if (orElse != null) return orElse(); |
| 706 throw IterableElementError.noElement(); | 713 throw IterableElementError.noElement(); |
| 707 } | 714 } |
| 708 | 715 |
| 709 E singleWhere(bool test(E element), { E orElse() }) { | 716 E singleWhere(bool test(E element), {E orElse()}) { |
| 710 if (orElse != null) return orElse(); | 717 if (orElse != null) return orElse(); |
| 711 throw IterableElementError.noElement(); | 718 throw IterableElementError.noElement(); |
| 712 } | 719 } |
| 713 | 720 |
| 714 String join([String separator = ""]) => ""; | 721 String join([String separator = ""]) => ""; |
| 715 | 722 |
| 716 Iterable<E> where(bool test(E element)) => this; | 723 Iterable<E> where(bool test(E element)) => this; |
| 717 | 724 |
| 718 Iterable<T> map<T>(T f(E element)) => const EmptyIterable(); | 725 Iterable<T> map<T>(T f(E element)) => const EmptyIterable(); |
| 719 | 726 |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 755 * Creates errors throw by [Iterable] when the element count is wrong. | 762 * Creates errors throw by [Iterable] when the element count is wrong. |
| 756 */ | 763 */ |
| 757 abstract class IterableElementError { | 764 abstract class IterableElementError { |
| 758 /** 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. */ |
| 759 static StateError noElement() => new StateError("No element"); | 766 static StateError noElement() => new StateError("No element"); |
| 760 /** 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. */ |
| 761 static StateError tooMany() => new StateError("Too many elements"); | 768 static StateError tooMany() => new StateError("Too many elements"); |
| 762 /** 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. */ |
| 763 static StateError tooFew() => new StateError("Too few elements"); | 770 static StateError tooFew() => new StateError("Too few elements"); |
| 764 } | 771 } |
| OLD | NEW |