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

Side by Side Diff: pkg/dev_compiler/tool/input_sdk/lib/internal/iterable.dart

Issue 2698353003: unfork DDC's copy of most SDK libraries (Closed)
Patch Set: revert core_patch Created 3 years, 9 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
OLDNEW
(Empty)
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
3 // BSD-style license that can be found in the LICENSE file.
4
5 part of dart._internal;
6
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].
23 *
24 * All other methods are implemented in terms of [length] and [elementAt],
25 * including [iterator].
26 */
27 abstract class ListIterable<E> extends Iterable<E>
28 implements EfficientLength {
29 int get length;
30 E elementAt(int i);
31
32 const ListIterable();
33
34 Iterator<E> get iterator => new ListIterator<E>(this);
35
36 void forEach(void action(E element)) {
37 int length = this.length;
38 for (int i = 0; i < length; i++) {
39 action(elementAt(i));
40 if (length != this.length) {
41 throw new ConcurrentModificationError(this);
42 }
43 }
44 }
45
46 bool get isEmpty => length == 0;
47
48 E get first {
49 if (length == 0) throw IterableElementError.noElement();
50 return elementAt(0);
51 }
52
53 E get last {
54 if (length == 0) throw IterableElementError.noElement();
55 return elementAt(length - 1);
56 }
57
58 E get single {
59 if (length == 0) throw IterableElementError.noElement();
60 if (length > 1) throw IterableElementError.tooMany();
61 return elementAt(0);
62 }
63
64 bool contains(Object element) {
65 int length = this.length;
66 for (int i = 0; i < length; i++) {
67 if (elementAt(i) == element) return true;
68 if (length != this.length) {
69 throw new ConcurrentModificationError(this);
70 }
71 }
72 return false;
73 }
74
75 bool every(bool test(E element)) {
76 int length = this.length;
77 for (int i = 0; i < length; i++) {
78 if (!test(elementAt(i))) return false;
79 if (length != this.length) {
80 throw new ConcurrentModificationError(this);
81 }
82 }
83 return true;
84 }
85
86 bool any(bool test(E element)) {
87 int length = this.length;
88 for (int i = 0; i < length; i++) {
89 if (test(elementAt(i))) return true;
90 if (length != this.length) {
91 throw new ConcurrentModificationError(this);
92 }
93 }
94 return false;
95 }
96
97 E firstWhere(bool test(E element), { E orElse() }) {
98 int length = this.length;
99 for (int i = 0; i < length; i++) {
100 E element = elementAt(i);
101 if (test(element)) return element;
102 if (length != this.length) {
103 throw new ConcurrentModificationError(this);
104 }
105 }
106 if (orElse != null) return orElse();
107 throw IterableElementError.noElement();
108 }
109
110 E lastWhere(bool test(E element), { E orElse() }) {
111 int length = this.length;
112 for (int i = length - 1; i >= 0; i--) {
113 E element = elementAt(i);
114 if (test(element)) return element;
115 if (length != this.length) {
116 throw new ConcurrentModificationError(this);
117 }
118 }
119 if (orElse != null) return orElse();
120 throw IterableElementError.noElement();
121 }
122
123 E singleWhere(bool test(E element)) {
124 int length = this.length;
125 E match = null;
126 bool matchFound = false;
127 for (int i = 0; i < length; i++) {
128 E element = elementAt(i);
129 if (test(element)) {
130 if (matchFound) {
131 throw IterableElementError.tooMany();
132 }
133 matchFound = true;
134 match = element;
135 }
136 if (length != this.length) {
137 throw new ConcurrentModificationError(this);
138 }
139 }
140 if (matchFound) return match;
141 throw IterableElementError.noElement();
142 }
143
144 String join([String separator = ""]) {
145 int length = this.length;
146 if (!separator.isEmpty) {
147 if (length == 0) return "";
148 String first = "${elementAt(0)}";
149 if (length != this.length) {
150 throw new ConcurrentModificationError(this);
151 }
152 StringBuffer buffer = new StringBuffer(first);
153 for (int i = 1; i < length; i++) {
154 buffer.write(separator);
155 buffer.write(elementAt(i));
156 if (length != this.length) {
157 throw new ConcurrentModificationError(this);
158 }
159 }
160 return buffer.toString();
161 } else {
162 StringBuffer buffer = new StringBuffer();
163 for (int i = 0; i < length; i++) {
164 buffer.write(elementAt(i));
165 if (length != this.length) {
166 throw new ConcurrentModificationError(this);
167 }
168 }
169 return buffer.toString();
170 }
171 }
172
173 Iterable<E> where(bool test(E element)) => super.where(test);
174
175 Iterable/*<T>*/ map/*<T>*/(/*=T*/ f(E element)) =>
176 new MappedListIterable<E, dynamic/*=T*/ >(this, f);
177
178 E reduce(E combine(var value, E element)) {
179 int length = this.length;
180 if (length == 0) throw IterableElementError.noElement();
181 E value = elementAt(0);
182 for (int i = 1; i < length; i++) {
183 value = combine(value, elementAt(i));
184 if (length != this.length) {
185 throw new ConcurrentModificationError(this);
186 }
187 }
188 return value;
189 }
190
191 /*=T*/ fold/*<T>*/(
192 var/*=T*/ initialValue, /*=T*/ combine(
193 var/*=T*/ previousValue, E element)) {
194 var value = initialValue;
195 int length = this.length;
196 for (int i = 0; i < length; i++) {
197 value = combine(value, elementAt(i));
198 if (length != this.length) {
199 throw new ConcurrentModificationError(this);
200 }
201 }
202 return value;
203 }
204
205 Iterable<E> skip(int count) => new SubListIterable<E>(this, count, null);
206
207 Iterable<E> skipWhile(bool test(E element)) => super.skipWhile(test);
208
209 Iterable<E> take(int count) => new SubListIterable<E>(this, 0, count);
210
211 Iterable<E> takeWhile(bool test(E element)) => super.takeWhile(test);
212
213 List<E> toList({bool growable: true}) {
214 List<E> result;
215 if (growable) {
216 result = new List<E>()..length = length;
217 } else {
218 result = new List<E>(length);
219 }
220 for (int i = 0; i < length; i++) {
221 result[i] = elementAt(i);
222 }
223 return result;
224 }
225
226 Set<E> toSet() {
227 Set<E> result = new Set<E>();
228 for (int i = 0; i < length; i++) {
229 result.add(elementAt(i));
230 }
231 return result;
232 }
233 }
234
235 class SubListIterable<E> extends ListIterable<E> {
236 final Iterable<E> _iterable; // Has efficient length and elementAt.
237 final int _start;
238 /** If null, represents the length of the iterable. */
239 final int _endOrLength;
240
241 SubListIterable(this._iterable, this._start, this._endOrLength) {
242 RangeError.checkNotNegative(_start, "start");
243 if (_endOrLength != null) {
244 RangeError.checkNotNegative(_endOrLength, "end");
245 if (_start > _endOrLength) {
246 throw new RangeError.range(_start, 0, _endOrLength, "start");
247 }
248 }
249 }
250
251 int get _endIndex {
252 int length = _iterable.length;
253 if (_endOrLength == null || _endOrLength > length) return length;
254 return _endOrLength;
255 }
256
257 int get _startIndex {
258 int length = _iterable.length;
259 if (_start > length) return length;
260 return _start;
261 }
262
263 int get length {
264 int length = _iterable.length;
265 if (_start >= length) return 0;
266 if (_endOrLength == null || _endOrLength >= length) {
267 return length - _start;
268 }
269 return _endOrLength - _start;
270 }
271
272 E elementAt(int index) {
273 int realIndex = _startIndex + index;
274 if (index < 0 || realIndex >= _endIndex) {
275 throw new RangeError.index(index, this, "index");
276 }
277 return _iterable.elementAt(realIndex);
278 }
279
280 Iterable<E> skip(int count) {
281 RangeError.checkNotNegative(count, "count");
282 int newStart = _start + count;
283 if (_endOrLength != null && newStart >= _endOrLength) {
284 return new EmptyIterable<E>();
285 }
286 return new SubListIterable<E>(_iterable, newStart, _endOrLength);
287 }
288
289 Iterable<E> take(int count) {
290 RangeError.checkNotNegative(count, "count");
291 if (_endOrLength == null) {
292 return new SubListIterable<E>(_iterable, _start, _start + count);
293 } else {
294 int newEnd = _start + count;
295 if (_endOrLength < newEnd) return this;
296 return new SubListIterable<E>(_iterable, _start, newEnd);
297 }
298 }
299
300 List<E> toList({bool growable: true}) {
301 int start = _start;
302 int end = _iterable.length;
303 if (_endOrLength != null && _endOrLength < end) end = _endOrLength;
304 int length = end - start;
305 if (length < 0) length = 0;
306 List<E> result = growable ? (new List<E>()..length = length)
307 : new List<E>(length);
308 for (int i = 0; i < length; i++) {
309 result[i] = _iterable.elementAt(start + i);
310 if (_iterable.length < end) throw new ConcurrentModificationError(this);
311 }
312 return result;
313 }
314 }
315
316 /**
317 * An [Iterator] that iterates a list-like [Iterable].
318 *
319 * All iterations is done in terms of [Iterable.length] and
320 * [Iterable.elementAt]. These operations are fast for list-like
321 * iterables.
322 */
323 class ListIterator<E> implements Iterator<E> {
324 final Iterable<E> _iterable;
325 final int _length;
326 int _index;
327 E _current;
328
329 ListIterator(Iterable<E> iterable)
330 : _iterable = iterable, _length = iterable.length, _index = 0;
331
332 E get current => _current;
333
334 bool moveNext() {
335 int length = _iterable.length;
336 if (_length != length) {
337 throw new ConcurrentModificationError(_iterable);
338 }
339 if (_index >= length) {
340 _current = null;
341 return false;
342 }
343 _current = _iterable.elementAt(_index);
344 _index++;
345 return true;
346 }
347 }
348
349 typedef T _Transformation<S, T>(S value);
350
351 class MappedIterable<S, T> extends Iterable<T> {
352 final Iterable<S> _iterable;
353 final _Transformation<S, T> _f;
354
355 factory MappedIterable(Iterable<S> iterable, T function(S value)) {
356 if (iterable is EfficientLength) {
357 return new EfficientLengthMappedIterable<S, T>(iterable, function);
358 }
359 return new MappedIterable<S, T>._(iterable, function);
360 }
361
362 MappedIterable._(this._iterable, T this._f(S element));
363
364 Iterator<T> get iterator => new MappedIterator<S, T>(_iterable.iterator, _f);
365
366 // Length related functions are independent of the mapping.
367 int get length => _iterable.length;
368 bool get isEmpty => _iterable.isEmpty;
369
370 // Index based lookup can be done before transforming.
371 T get first => _f(_iterable.first);
372 T get last => _f(_iterable.last);
373 T get single => _f(_iterable.single);
374 T elementAt(int index) => _f(_iterable.elementAt(index));
375 }
376
377 class EfficientLengthMappedIterable<S, T> extends MappedIterable<S, T>
378 implements EfficientLength {
379 EfficientLengthMappedIterable(Iterable<S> iterable, T function(S value))
380 : super._(iterable, function);
381 }
382
383 class MappedIterator<S, T> extends Iterator<T> {
384 T _current;
385 final Iterator<S> _iterator;
386 final _Transformation<S, T> _f;
387
388 MappedIterator(this._iterator, T this._f(S element));
389
390 bool moveNext() {
391 if (_iterator.moveNext()) {
392 _current = _f(_iterator.current);
393 return true;
394 }
395 _current = null;
396 return false;
397 }
398
399 T get current => _current;
400 }
401
402 /**
403 * Specialized alternative to [MappedIterable] for mapped [List]s.
404 *
405 * Expects efficient `length` and `elementAt` on the source iterable.
406 */
407 class MappedListIterable<S, T> extends ListIterable<T>
408 implements EfficientLength {
409 final Iterable<S> _source;
410 final _Transformation<S, T> _f;
411
412 MappedListIterable(this._source, T this._f(S value));
413
414 int get length => _source.length;
415 T elementAt(int index) => _f(_source.elementAt(index));
416 }
417
418
419 typedef bool _ElementPredicate<E>(E element);
420
421 class WhereIterable<E> extends Iterable<E> {
422 final Iterable<E> _iterable;
423 final _ElementPredicate<E> _f;
424
425 WhereIterable(this._iterable, bool this._f(E element));
426
427 Iterator<E> get iterator => new WhereIterator<E>(_iterable.iterator, _f);
428 }
429
430 class WhereIterator<E> extends Iterator<E> {
431 final Iterator<E> _iterator;
432 final _ElementPredicate<E> _f;
433
434 WhereIterator(this._iterator, bool this._f(E element));
435
436 bool moveNext() {
437 while (_iterator.moveNext()) {
438 if (_f(_iterator.current)) {
439 return true;
440 }
441 }
442 return false;
443 }
444
445 E get current => _iterator.current;
446 }
447
448 typedef Iterable<T> _ExpandFunction<S, T>(S sourceElement);
449
450 class ExpandIterable<S, T> extends Iterable<T> {
451 final Iterable<S> _iterable;
452 final _ExpandFunction<S, T> _f;
453
454 ExpandIterable(this._iterable, Iterable<T> this._f(S element));
455
456 Iterator<T> get iterator => new ExpandIterator<S, T>(_iterable.iterator, _f);
457 }
458
459 class ExpandIterator<S, T> implements Iterator<T> {
460 final Iterator<S> _iterator;
461 final _ExpandFunction<S, T> _f;
462 // Initialize _currentExpansion to an empty iterable. A null value
463 // marks the end of iteration, and we don't want to call _f before
464 // the first moveNext call.
465 Iterator<T> _currentExpansion = const EmptyIterator();
466 T _current;
467
468 ExpandIterator(this._iterator, Iterable<T> this._f(S element));
469
470 T get current => _current;
471
472 bool moveNext() {
473 if (_currentExpansion == null) return false;
474 while (!_currentExpansion.moveNext()) {
475 _current = null;
476 if (_iterator.moveNext()) {
477 // If _f throws, this ends iteration. Otherwise _currentExpansion and
478 // _current will be set again below.
479 _currentExpansion = null;
480 _currentExpansion = _f(_iterator.current).iterator;
481 } else {
482 return false;
483 }
484 }
485 _current = _currentExpansion.current;
486 return true;
487 }
488 }
489
490 class TakeIterable<E> extends Iterable<E> {
491 final Iterable<E> _iterable;
492 final int _takeCount;
493
494 factory TakeIterable(Iterable<E> iterable, int takeCount) {
495 if (takeCount is! int || takeCount < 0) {
496 throw new ArgumentError(takeCount);
497 }
498 if (iterable is EfficientLength) {
499 return new EfficientLengthTakeIterable<E>(iterable, takeCount);
500 }
501 return new TakeIterable<E>._(iterable, takeCount);
502 }
503
504 TakeIterable._(this._iterable, this._takeCount);
505
506 Iterator<E> get iterator {
507 return new TakeIterator<E>(_iterable.iterator, _takeCount);
508 }
509 }
510
511 class EfficientLengthTakeIterable<E> extends TakeIterable<E>
512 implements EfficientLength {
513 EfficientLengthTakeIterable(Iterable<E> iterable, int takeCount)
514 : super._(iterable, takeCount);
515
516 int get length {
517 int iterableLength = _iterable.length;
518 if (iterableLength > _takeCount) return _takeCount;
519 return iterableLength;
520 }
521 }
522
523
524 class TakeIterator<E> extends Iterator<E> {
525 final Iterator<E> _iterator;
526 int _remaining;
527
528 TakeIterator(this._iterator, this._remaining) {
529 assert(_remaining is int && _remaining >= 0);
530 }
531
532 bool moveNext() {
533 _remaining--;
534 if (_remaining >= 0) {
535 return _iterator.moveNext();
536 }
537 _remaining = -1;
538 return false;
539 }
540
541 E get current {
542 if (_remaining < 0) return null;
543 return _iterator.current;
544 }
545 }
546
547 class TakeWhileIterable<E> extends Iterable<E> {
548 final Iterable<E> _iterable;
549 final _ElementPredicate<E> _f;
550
551 TakeWhileIterable(this._iterable, bool this._f(E element));
552
553 Iterator<E> get iterator {
554 return new TakeWhileIterator<E>(_iterable.iterator, _f);
555 }
556 }
557
558 class TakeWhileIterator<E> extends Iterator<E> {
559 final Iterator<E> _iterator;
560 final _ElementPredicate<E> _f;
561 bool _isFinished = false;
562
563 TakeWhileIterator(this._iterator, bool this._f(E element));
564
565 bool moveNext() {
566 if (_isFinished) return false;
567 if (!_iterator.moveNext() || !_f(_iterator.current)) {
568 _isFinished = true;
569 return false;
570 }
571 return true;
572 }
573
574 E get current {
575 if (_isFinished) return null;
576 return _iterator.current;
577 }
578 }
579
580 class SkipIterable<E> extends Iterable<E> {
581 final Iterable<E> _iterable;
582 final int _skipCount;
583
584 factory SkipIterable(Iterable<E> iterable, int count) {
585 if (iterable is EfficientLength) {
586 return new EfficientLengthSkipIterable<E>(iterable, count);
587 }
588 return new SkipIterable<E>._(iterable, count);
589 }
590
591 SkipIterable._(this._iterable, this._skipCount) {
592 if (_skipCount is! int) {
593 throw new ArgumentError.value(_skipCount, "count is not an integer");
594 }
595 RangeError.checkNotNegative(_skipCount, "count");
596 }
597
598 Iterable<E> skip(int count) {
599 if (_skipCount is! int) {
600 throw new ArgumentError.value(_skipCount, "count is not an integer");
601 }
602 RangeError.checkNotNegative(_skipCount, "count");
603 return new SkipIterable<E>._(_iterable, _skipCount + count);
604 }
605
606 Iterator<E> get iterator {
607 return new SkipIterator<E>(_iterable.iterator, _skipCount);
608 }
609 }
610
611 class EfficientLengthSkipIterable<E> extends SkipIterable<E>
612 implements EfficientLength {
613 EfficientLengthSkipIterable(Iterable<E> iterable, int skipCount)
614 : super._(iterable, skipCount);
615
616 int get length {
617 int length = _iterable.length - _skipCount;
618 if (length >= 0) return length;
619 return 0;
620 }
621 }
622
623 class SkipIterator<E> extends Iterator<E> {
624 final Iterator<E> _iterator;
625 int _skipCount;
626
627 SkipIterator(this._iterator, this._skipCount) {
628 assert(_skipCount is int && _skipCount >= 0);
629 }
630
631 bool moveNext() {
632 for (int i = 0; i < _skipCount; i++) _iterator.moveNext();
633 _skipCount = 0;
634 return _iterator.moveNext();
635 }
636
637 E get current => _iterator.current;
638 }
639
640 class SkipWhileIterable<E> extends Iterable<E> {
641 final Iterable<E> _iterable;
642 final _ElementPredicate<E> _f;
643
644 SkipWhileIterable(this._iterable, bool this._f(E element));
645
646 Iterator<E> get iterator {
647 return new SkipWhileIterator<E>(_iterable.iterator, _f);
648 }
649 }
650
651 class SkipWhileIterator<E> extends Iterator<E> {
652 final Iterator<E> _iterator;
653 final _ElementPredicate<E> _f;
654 bool _hasSkipped = false;
655
656 SkipWhileIterator(this._iterator, bool this._f(E element));
657
658 bool moveNext() {
659 if (!_hasSkipped) {
660 _hasSkipped = true;
661 while (_iterator.moveNext()) {
662 if (!_f(_iterator.current)) return true;
663 }
664 }
665 return _iterator.moveNext();
666 }
667
668 E get current => _iterator.current;
669 }
670
671 /**
672 * The always empty [Iterable].
673 */
674 class EmptyIterable<E> extends Iterable<E> implements EfficientLength {
675 const EmptyIterable();
676
677 Iterator<E> get iterator => const EmptyIterator();
678
679 void forEach(void action(E element)) {}
680
681 bool get isEmpty => true;
682
683 int get length => 0;
684
685 E get first { throw IterableElementError.noElement(); }
686
687 E get last { throw IterableElementError.noElement(); }
688
689 E get single { throw IterableElementError.noElement(); }
690
691 E elementAt(int index) { throw new RangeError.range(index, 0, 0, "index"); }
692
693 bool contains(Object element) => false;
694
695 bool every(bool test(E element)) => true;
696
697 bool any(bool test(E element)) => false;
698
699 E firstWhere(bool test(E element), {E orElse()}) {
700 if (orElse != null) return orElse();
701 throw IterableElementError.noElement();
702 }
703
704 E lastWhere(bool test(E element), {E orElse()}) {
705 if (orElse != null) return orElse();
706 throw IterableElementError.noElement();
707 }
708
709 E singleWhere(bool test(E element), {E orElse()}) {
710 if (orElse != null) return orElse();
711 throw IterableElementError.noElement();
712 }
713
714 String join([String separator = ""]) => "";
715
716 Iterable<E> where(bool test(E element)) => this;
717
718 Iterable/*<T>*/ map/*<T>*/(/*=T*/ f(E element)) => const EmptyIterable();
719
720 E reduce(E combine(E value, E element)) {
721 throw IterableElementError.noElement();
722 }
723
724 /*=T*/ fold/*<T>*/(
725 var/*=T*/ initialValue, /*=T*/ combine(
726 var/*=T*/ previousValue, E element)) {
727 return initialValue;
728 }
729
730 Iterable<E> skip(int count) {
731 RangeError.checkNotNegative(count, "count");
732 return this;
733 }
734
735 Iterable<E> skipWhile(bool test(E element)) => this;
736
737 Iterable<E> take(int count) {
738 RangeError.checkNotNegative(count, "count");
739 return this;
740 }
741
742 Iterable<E> takeWhile(bool test(E element)) => this;
743
744 List<E> toList({bool growable: true}) => growable ? <E>[] : new List<E>(0);
745
746 Set<E> toSet() => new Set<E>();
747 }
748
749 /** The always empty iterator. */
750 class EmptyIterator<E> implements Iterator<E> {
751 const EmptyIterator();
752 bool moveNext() => false;
753 E get current => null;
754 }
755
756 /**
757 * Creates errors throw by [Iterable] when the element count is wrong.
758 */
759 abstract class IterableElementError {
760 /** Error thrown thrown by, e.g., [Iterable.first] when there is no result. */
761 static StateError noElement() => new StateError("No element");
762 /** Error thrown by, e.g., [Iterable.single] if there are too many results. */
763 static StateError tooMany() => new StateError("Too many elements");
764 /** Error thrown by, e.g., [List.setRange] if there are too few elements. */
765 static StateError tooFew() => new StateError("Too few elements");
766 }
OLDNEW
« no previous file with comments | « pkg/dev_compiler/tool/input_sdk/lib/internal/internal.dart ('k') | pkg/dev_compiler/tool/input_sdk/lib/internal/list.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698