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 219 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
230 } | 230 } |
231 } | 231 } |
232 | 232 |
233 class SubListIterable<E> extends ListIterable<E> { | 233 class SubListIterable<E> extends ListIterable<E> { |
234 final Iterable<E> _iterable; // Has efficient length and elementAt. | 234 final Iterable<E> _iterable; // Has efficient length and elementAt. |
235 final int _start; | 235 final int _start; |
236 /** If null, represents the length of the iterable. */ | 236 /** If null, represents the length of the iterable. */ |
237 final int _endOrLength; | 237 final int _endOrLength; |
238 | 238 |
239 SubListIterable(this._iterable, this._start, this._endOrLength) { | 239 SubListIterable(this._iterable, this._start, this._endOrLength) { |
240 if (_start < 0) { | 240 RangeError.checkNotNegative(_start, "start"); |
241 throw new RangeError.value(_start); | |
242 } | |
243 if (_endOrLength != null) { | 241 if (_endOrLength != null) { |
244 if (_endOrLength < 0) { | 242 RangeError.checkNotNegative(_endOrLength, "end"); |
245 throw new RangeError.value(_endOrLength); | |
246 } | |
247 if (_start > _endOrLength) { | 243 if (_start > _endOrLength) { |
248 throw new RangeError.range(_start, 0, _endOrLength); | 244 throw new RangeError.range(_start, 0, _endOrLength, "start"); |
249 } | 245 } |
250 } | 246 } |
251 } | 247 } |
252 | 248 |
253 int get _endIndex { | 249 int get _endIndex { |
254 int length = _iterable.length; | 250 int length = _iterable.length; |
255 if (_endOrLength == null || _endOrLength > length) return length; | 251 if (_endOrLength == null || _endOrLength > length) return length; |
256 return _endOrLength; | 252 return _endOrLength; |
257 } | 253 } |
258 | 254 |
259 int get _startIndex { | 255 int get _startIndex { |
260 int length = _iterable.length; | 256 int length = _iterable.length; |
261 if (_start > length) return length; | 257 if (_start > length) return length; |
262 return _start; | 258 return _start; |
263 } | 259 } |
264 | 260 |
265 int get length { | 261 int get length { |
266 int length = _iterable.length; | 262 int length = _iterable.length; |
267 if (_start >= length) return 0; | 263 if (_start >= length) return 0; |
268 if (_endOrLength == null || _endOrLength >= length) { | 264 if (_endOrLength == null || _endOrLength >= length) { |
269 return length - _start; | 265 return length - _start; |
270 } | 266 } |
271 return _endOrLength - _start; | 267 return _endOrLength - _start; |
272 } | 268 } |
273 | 269 |
274 E elementAt(int index) { | 270 E elementAt(int index) { |
275 int realIndex = _startIndex + index; | 271 int realIndex = _startIndex + index; |
276 if (index < 0 || realIndex >= _endIndex) { | 272 if (index < 0 || realIndex >= _endIndex) { |
277 throw new RangeError.range(index, 0, length); | 273 throw new RangeError.index(index, this, "index"); |
278 } | 274 } |
279 return _iterable.elementAt(realIndex); | 275 return _iterable.elementAt(realIndex); |
280 } | 276 } |
281 | 277 |
282 Iterable<E> skip(int count) { | 278 Iterable<E> skip(int count) { |
283 if (count < 0) throw new RangeError.value(count); | 279 RangeError.checkNotNegative(count, "count"); |
284 int newStart = _start + count; | 280 int newStart = _start + count; |
285 if (_endOrLength != null && newStart >= _endOrLength) { | 281 if (_endOrLength != null && newStart >= _endOrLength) { |
286 return new EmptyIterable<E>(); | 282 return new EmptyIterable<E>(); |
287 } | 283 } |
288 return new SubListIterable<E>(_iterable, newStart, _endOrLength); | 284 return new SubListIterable<E>(_iterable, newStart, _endOrLength); |
289 } | 285 } |
290 | 286 |
291 Iterable<E> take(int count) { | 287 Iterable<E> take(int count) { |
292 if (count < 0) throw new RangeError.value(count); | 288 RangeError.checkNotNegative(count, "count"); |
293 if (_endOrLength == null) { | 289 if (_endOrLength == null) { |
294 return new SubListIterable<E>(_iterable, _start, _start + count); | 290 return new SubListIterable<E>(_iterable, _start, _start + count); |
295 } else { | 291 } else { |
296 int newEnd = _start + count; | 292 int newEnd = _start + count; |
297 if (_endOrLength < newEnd) return this; | 293 if (_endOrLength < newEnd) return this; |
298 return new SubListIterable<E>(_iterable, _start, newEnd); | 294 return new SubListIterable<E>(_iterable, _start, newEnd); |
299 } | 295 } |
300 } | 296 } |
301 | 297 |
302 List<E> toList({bool growable: true}) { | 298 List<E> toList({bool growable: true}) { |
(...skipping 276 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
579 E get current { | 575 E get current { |
580 if (_isFinished) return null; | 576 if (_isFinished) return null; |
581 return _iterator.current; | 577 return _iterator.current; |
582 } | 578 } |
583 } | 579 } |
584 | 580 |
585 class SkipIterable<E> extends IterableBase<E> { | 581 class SkipIterable<E> extends IterableBase<E> { |
586 final Iterable<E> _iterable; | 582 final Iterable<E> _iterable; |
587 final int _skipCount; | 583 final int _skipCount; |
588 | 584 |
589 factory SkipIterable(Iterable<E> iterable, int skipCount) { | 585 factory SkipIterable(Iterable<E> iterable, int count) { |
590 if (iterable is EfficientLength) { | 586 if (iterable is EfficientLength) { |
591 return new EfficientLengthSkipIterable<E>(iterable, skipCount); | 587 return new EfficientLengthSkipIterable<E>(iterable, count); |
592 } | 588 } |
593 return new SkipIterable<E>._(iterable, skipCount); | 589 return new SkipIterable<E>._(iterable, count); |
594 } | 590 } |
595 | 591 |
596 SkipIterable._(this._iterable, this._skipCount) { | 592 SkipIterable._(this._iterable, this._skipCount) { |
597 if (_skipCount is! int || _skipCount < 0) { | 593 if (_skipCount is! int) { |
598 throw new RangeError(_skipCount); | 594 throw new ArgumentError.value(_skipCount, "count is not an integer"); |
599 } | 595 } |
| 596 RangeError.checkNotNegative(_skipCount, "count"); |
600 } | 597 } |
601 | 598 |
602 Iterable<E> skip(int n) { | 599 Iterable<E> skip(int count) { |
603 if (n is! int || n < 0) { | 600 if (_skipCount is! int) { |
604 throw new RangeError.value(n); | 601 throw new ArgumentError.value(_skipCount, "count is not an integer"); |
605 } | 602 } |
606 return new SkipIterable<E>(_iterable, _skipCount + n); | 603 RangeError.checkNotNegative(_skipCount, "count"); |
| 604 return new SkipIterable<E>._(_iterable, _skipCount + count); |
607 } | 605 } |
608 | 606 |
609 Iterator<E> get iterator { | 607 Iterator<E> get iterator { |
610 return new SkipIterator<E>(_iterable.iterator, _skipCount); | 608 return new SkipIterator<E>(_iterable.iterator, _skipCount); |
611 } | 609 } |
612 } | 610 } |
613 | 611 |
614 class EfficientLengthSkipIterable<E> extends SkipIterable<E> | 612 class EfficientLengthSkipIterable<E> extends SkipIterable<E> |
615 implements EfficientLength { | 613 implements EfficientLength { |
616 EfficientLengthSkipIterable(Iterable<E> iterable, int skipCount) | 614 EfficientLengthSkipIterable(Iterable<E> iterable, int skipCount) |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
684 bool get isEmpty => true; | 682 bool get isEmpty => true; |
685 | 683 |
686 int get length => 0; | 684 int get length => 0; |
687 | 685 |
688 E get first { throw IterableElementError.noElement(); } | 686 E get first { throw IterableElementError.noElement(); } |
689 | 687 |
690 E get last { throw IterableElementError.noElement(); } | 688 E get last { throw IterableElementError.noElement(); } |
691 | 689 |
692 E get single { throw IterableElementError.noElement(); } | 690 E get single { throw IterableElementError.noElement(); } |
693 | 691 |
694 E elementAt(int index) { throw new RangeError.value(index); } | 692 E elementAt(int index) { throw new RangeError.range(index, 0, 0, "index"); } |
695 | 693 |
696 bool contains(Object element) => false; | 694 bool contains(Object element) => false; |
697 | 695 |
698 bool every(bool test(E element)) => true; | 696 bool every(bool test(E element)) => true; |
699 | 697 |
700 bool any(bool test(E element)) => false; | 698 bool any(bool test(E element)) => false; |
701 | 699 |
702 E firstWhere(bool test(E element), { E orElse() }) { | 700 E firstWhere(bool test(E element), { E orElse() }) { |
703 if (orElse != null) return orElse(); | 701 if (orElse != null) return orElse(); |
704 throw IterableElementError.noElement(); | 702 throw IterableElementError.noElement(); |
(...skipping 17 matching lines...) Expand all Loading... |
722 | 720 |
723 E reduce(E combine(E value, E element)) { | 721 E reduce(E combine(E value, E element)) { |
724 throw IterableElementError.noElement(); | 722 throw IterableElementError.noElement(); |
725 } | 723 } |
726 | 724 |
727 fold(var initialValue, combine(var previousValue, E element)) { | 725 fold(var initialValue, combine(var previousValue, E element)) { |
728 return initialValue; | 726 return initialValue; |
729 } | 727 } |
730 | 728 |
731 Iterable<E> skip(int count) { | 729 Iterable<E> skip(int count) { |
732 if (count < 0) throw new RangeError.value(count); | 730 RangeError.checkNotNegative(count, "count"); |
733 return this; | 731 return this; |
734 } | 732 } |
735 | 733 |
736 Iterable<E> skipWhile(bool test(E element)) => this; | 734 Iterable<E> skipWhile(bool test(E element)) => this; |
737 | 735 |
738 Iterable<E> take(int count) { | 736 Iterable<E> take(int count) { |
739 if (count < 0) throw new RangeError.value(count); | 737 RangeError.checkNotNegative(count, "count"); |
740 return this; | 738 return this; |
741 } | 739 } |
742 | 740 |
743 Iterable<E> takeWhile(bool test(E element)) => this; | 741 Iterable<E> takeWhile(bool test(E element)) => this; |
744 | 742 |
745 List toList({ bool growable: true }) => growable ? <E>[] : new List<E>(0); | 743 List toList({ bool growable: true }) => growable ? <E>[] : new List<E>(0); |
746 | 744 |
747 Set toSet() => new Set<E>(); | 745 Set toSet() => new Set<E>(); |
748 } | 746 } |
749 | 747 |
(...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
917 throw IterableElementError.tooMany(); | 915 throw IterableElementError.tooMany(); |
918 } | 916 } |
919 result = element; | 917 result = element; |
920 foundMatching = true; | 918 foundMatching = true; |
921 } | 919 } |
922 } | 920 } |
923 if (foundMatching) return result; | 921 if (foundMatching) return result; |
924 throw IterableElementError.noElement(); | 922 throw IterableElementError.noElement(); |
925 } | 923 } |
926 | 924 |
927 static dynamic elementAt(Iterable iterable, int index) { | 925 static elementAt(Iterable iterable, int index) { |
928 if (index is! int || index < 0) throw new RangeError.value(index); | 926 if (index is! int) throw new ArgumentError.notNull("index"); |
929 int remaining = index; | 927 RangeError.checkNotNegative(index, "index"); |
930 for (dynamic element in iterable) { | 928 int elementIndex = 0; |
931 if (remaining == 0) return element; | 929 for (E element in iterable) { |
932 remaining--; | 930 if (index == elementIndex) return element; |
| 931 elementIndex++; |
933 } | 932 } |
934 throw new RangeError.value(index); | 933 throw new RangeError.index(index, iterable, "index", null, elementIndex); |
935 } | 934 } |
936 | 935 |
937 static String join(Iterable iterable, [String separator]) { | 936 static String join(Iterable iterable, [String separator]) { |
938 StringBuffer buffer = new StringBuffer(); | 937 StringBuffer buffer = new StringBuffer(); |
939 buffer.writeAll(iterable, separator); | 938 buffer.writeAll(iterable, separator); |
940 return buffer.toString(); | 939 return buffer.toString(); |
941 } | 940 } |
942 | 941 |
943 static String joinList(List list, [String separator]) { | 942 static String joinList(List list, [String separator]) { |
944 if (list.isEmpty) return ""; | 943 if (list.isEmpty) return ""; |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1018 static int indexOfList(List list, var element, int start) { | 1017 static int indexOfList(List list, var element, int start) { |
1019 return Lists.indexOf(list, element, start, list.length); | 1018 return Lists.indexOf(list, element, start, list.length); |
1020 } | 1019 } |
1021 | 1020 |
1022 static int lastIndexOfList(List list, var element, int start) { | 1021 static int lastIndexOfList(List list, var element, int start) { |
1023 if (start == null) start = list.length - 1; | 1022 if (start == null) start = list.length - 1; |
1024 return Lists.lastIndexOf(list, element, start); | 1023 return Lists.lastIndexOf(list, element, start); |
1025 } | 1024 } |
1026 | 1025 |
1027 static void _rangeCheck(List list, int start, int end) { | 1026 static void _rangeCheck(List list, int start, int end) { |
1028 if (start < 0 || start > list.length) { | 1027 RangeError.checkValidRange(start, end, list.length); |
1029 throw new RangeError.range(start, 0, list.length); | |
1030 } | |
1031 if (end < start || end > list.length) { | |
1032 throw new RangeError.range(end, start, list.length); | |
1033 } | |
1034 } | 1028 } |
1035 | 1029 |
1036 Iterable<T> getRangeList(List list, int start, int end) { | 1030 Iterable<T> getRangeList(List list, int start, int end) { |
1037 _rangeCheck(list, start, end); | 1031 _rangeCheck(list, start, end); |
1038 // The generic type is currently lost. It will be fixed with mixins. | 1032 // The generic type is currently lost. It will be fixed with mixins. |
1039 return new SubListIterable<T>(list, start, end); | 1033 return new SubListIterable<T>(list, start, end); |
1040 } | 1034 } |
1041 | 1035 |
1042 static void setRangeList(List list, int start, int end, | 1036 static void setRangeList(List list, int start, int end, |
1043 Iterable from, int skipCount) { | 1037 Iterable from, int skipCount) { |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1091 } | 1085 } |
1092 | 1086 |
1093 static void fillRangeList(List list, int start, int end, fillValue) { | 1087 static void fillRangeList(List list, int start, int end, fillValue) { |
1094 _rangeCheck(list, start, end); | 1088 _rangeCheck(list, start, end); |
1095 for (int i = start; i < end; i++) { | 1089 for (int i = start; i < end; i++) { |
1096 list[i] = fillValue; | 1090 list[i] = fillValue; |
1097 } | 1091 } |
1098 } | 1092 } |
1099 | 1093 |
1100 static void insertAllList(List list, int index, Iterable iterable) { | 1094 static void insertAllList(List list, int index, Iterable iterable) { |
1101 if (index < 0 || index > list.length) { | 1095 RangeError.checkValidIndex(index, list); |
1102 throw new RangeError.range(index, 0, list.length); | |
1103 } | |
1104 if (iterable is! EfficientLength) { | 1096 if (iterable is! EfficientLength) { |
1105 iterable = iterable.toList(growable: false); | 1097 iterable = iterable.toList(growable: false); |
1106 } | 1098 } |
1107 int insertionLength = iterable.length; | 1099 int insertionLength = iterable.length; |
1108 list.length += insertionLength; | 1100 list.length += insertionLength; |
1109 list.setRange(index + insertionLength, list.length, list, index); | 1101 list.setRange(index + insertionLength, list.length, list, index); |
1110 for (var element in iterable) { | 1102 for (var element in iterable) { |
1111 list[index++] = element; | 1103 list[index++] = element; |
1112 } | 1104 } |
1113 } | 1105 } |
1114 | 1106 |
1115 static void setAllList(List list, int index, Iterable iterable) { | 1107 static void setAllList(List list, int index, Iterable iterable) { |
1116 if (index < 0 || index > list.length) { | 1108 RangeError.checkValueInInterval(index, 0, list.length, "index"); |
1117 throw new RangeError.range(index, 0, list.length); | |
1118 } | |
1119 for (var element in iterable) { | 1109 for (var element in iterable) { |
1120 list[index++] = element; | 1110 list[index++] = element; |
1121 } | 1111 } |
1122 } | 1112 } |
1123 | 1113 |
1124 Map<int, T> asMapList(List l) { | 1114 Map<int, T> asMapList(List l) { |
1125 return new ListMapView<T>(l); | 1115 return new ListMapView<T>(l); |
1126 } | 1116 } |
1127 | 1117 |
1128 static bool setContainsAll(Set set, Iterable other) { | 1118 static bool setContainsAll(Set set, Iterable other) { |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1170 * Creates errors throw by [Iterable] when the element count is wrong. | 1160 * Creates errors throw by [Iterable] when the element count is wrong. |
1171 */ | 1161 */ |
1172 abstract class IterableElementError { | 1162 abstract class IterableElementError { |
1173 /** Error thrown thrown by, e.g., [Iterable.first] when there is no result. */ | 1163 /** Error thrown thrown by, e.g., [Iterable.first] when there is no result. */ |
1174 static StateError noElement() => new StateError("No element"); | 1164 static StateError noElement() => new StateError("No element"); |
1175 /** Error thrown by, e.g., [Iterable.single] if there are too many results. */ | 1165 /** Error thrown by, e.g., [Iterable.single] if there are too many results. */ |
1176 static StateError tooMany() => new StateError("Too many elements"); | 1166 static StateError tooMany() => new StateError("Too many elements"); |
1177 /** Error thrown by, e.g., [List.setRange] if there are too few elements. */ | 1167 /** Error thrown by, e.g., [List.setRange] if there are too few elements. */ |
1178 static StateError tooFew() => new StateError("Too few elements"); | 1168 static StateError tooFew() => new StateError("Too few elements"); |
1179 } | 1169 } |
OLD | NEW |