OLD | NEW |
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, 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._collection.dev; | 5 part of dart.collection; |
| 6 |
| 7 /** |
| 8 * Abstract implementation of a list. |
| 9 * |
| 10 * All operations are defined in terms of `length`, `operator[]`, |
| 11 * `operator[]=` and `length=`, which need to be implemented. |
| 12 */ |
| 13 typedef ListBase<E> = Object with ListMixin<E>; |
6 | 14 |
7 /** | 15 /** |
8 * Base implementation of a [List] class. | 16 * Base implementation of a [List] class. |
9 * | 17 * |
10 * This class can be used as a mixin. | 18 * This class can be used as a mixin. |
11 * | 19 * |
12 * This implements all read operations using only the `length` and | 20 * This implements all read operations using only the `length` and |
13 * `operator[]` members. It implements write operations using those and | 21 * `operator[]` members. It implements write operations using those and |
14 * `length=` and `operator[]=` | 22 * `length=` and `operator[]=` |
15 * | 23 * |
(...skipping 423 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
439 for (int i = startIndex; i >= 0; i--) { | 447 for (int i = startIndex; i >= 0; i--) { |
440 if (this[i] == element) { | 448 if (this[i] == element) { |
441 return i; | 449 return i; |
442 } | 450 } |
443 } | 451 } |
444 return -1; | 452 return -1; |
445 } | 453 } |
446 | 454 |
447 Iterable<E> get reversed => new ReversedListIterable(this); | 455 Iterable<E> get reversed => new ReversedListIterable(this); |
448 } | 456 } |
449 | |
450 /** | |
451 * Mixin that throws on the length changing operations of [List]. | |
452 * | |
453 * Intended to mix-in on top of [ListMixin] for fixed-length lists. | |
454 */ | |
455 abstract class FixedLengthListMixin<E> { | |
456 void set length(int newLength) { | |
457 throw new UnsupportedError( | |
458 "Cannot change the length of a fixed-length list"); | |
459 } | |
460 | |
461 void add(E value) { | |
462 throw new UnsupportedError( | |
463 "Cannot add to a fixed-length list"); | |
464 } | |
465 | |
466 void insert(int index, E value) { | |
467 throw new UnsupportedError( | |
468 "Cannot add to a fixed-length list"); | |
469 } | |
470 | |
471 void addAll(Iterable<E> iterable) { | |
472 throw new UnsupportedError( | |
473 "Cannot add to a fixed-length list"); | |
474 } | |
475 | |
476 void remove(E element) { | |
477 throw new UnsupportedError( | |
478 "Cannot remove from a fixed-length list"); | |
479 } | |
480 | |
481 void removeAll(Iterable elements) { | |
482 throw new UnsupportedError( | |
483 "Cannot remove from a fixed-length list"); | |
484 } | |
485 | |
486 void retainAll(Iterable elements) { | |
487 throw new UnsupportedError( | |
488 "Cannot remove from a fixed-length list"); | |
489 } | |
490 | |
491 void removeWhere(bool test(E element)) { | |
492 throw new UnsupportedError( | |
493 "Cannot remove from a fixed-length list"); | |
494 } | |
495 | |
496 void retainWhere(bool test(E element)) { | |
497 throw new UnsupportedError( | |
498 "Cannot remove from a fixed-length list"); | |
499 } | |
500 | |
501 void clear() { | |
502 throw new UnsupportedError( | |
503 "Cannot clear a fixed-length list"); | |
504 } | |
505 | |
506 E removeAt(int index) { | |
507 throw new UnsupportedError( | |
508 "Cannot remove from a fixed-length list"); | |
509 } | |
510 | |
511 E removeLast() { | |
512 throw new UnsupportedError( | |
513 "Cannot remove from a fixed-length list"); | |
514 } | |
515 | |
516 void removeRange(int start, int length) { | |
517 throw new UnsupportedError( | |
518 "Cannot remove from a fixed-length list"); | |
519 } | |
520 | |
521 void insertRange(int start, int length, [E initialValue]) { | |
522 throw new UnsupportedError( | |
523 "Cannot insert range in a fixed-length list"); | |
524 } | |
525 } | |
526 | |
527 /** | |
528 * Mixin for an unmodifiable [List] class. | |
529 * | |
530 * This overrides all mutating methods with methods that throw. | |
531 * This mixin is intended to be mixed in on top of [ListMixin] on | |
532 * unmodifiable lists. | |
533 */ | |
534 abstract class UnmodifiableListMixin<E> { | |
535 | |
536 void operator []=(int index, E value) { | |
537 throw new UnsupportedError( | |
538 "Cannot modify an unmodifiable list"); | |
539 } | |
540 | |
541 void set length(int newLength) { | |
542 throw new UnsupportedError( | |
543 "Cannot change the length of an unmodifiable list"); | |
544 } | |
545 | |
546 void add(E value) { | |
547 throw new UnsupportedError( | |
548 "Cannot add to an unmodifiable list"); | |
549 } | |
550 | |
551 E insert(int index, E value) { | |
552 throw new UnsupportedError( | |
553 "Cannot add to an unmodifiable list"); | |
554 } | |
555 | |
556 void addAll(Iterable<E> iterable) { | |
557 throw new UnsupportedError( | |
558 "Cannot add to an unmodifiable list"); | |
559 } | |
560 | |
561 void remove(E element) { | |
562 throw new UnsupportedError( | |
563 "Cannot remove from an unmodifiable list"); | |
564 } | |
565 | |
566 void removeAll(Iterable elements) { | |
567 throw new UnsupportedError( | |
568 "Cannot remove from an unmodifiable list"); | |
569 } | |
570 | |
571 void retainAll(Iterable elements) { | |
572 throw new UnsupportedError( | |
573 "Cannot remove from an unmodifiable list"); | |
574 } | |
575 | |
576 void removeWhere(bool test(E element)) { | |
577 throw new UnsupportedError( | |
578 "Cannot remove from an unmodifiable list"); | |
579 } | |
580 | |
581 void retainWhere(bool test(E element)) { | |
582 throw new UnsupportedError( | |
583 "Cannot remove from an unmodifiable list"); | |
584 } | |
585 | |
586 void sort([Comparator<E> compare]) { | |
587 throw new UnsupportedError( | |
588 "Cannot modify an unmodifiable list"); | |
589 } | |
590 | |
591 void clear() { | |
592 throw new UnsupportedError( | |
593 "Cannot clear an unmodifiable list"); | |
594 } | |
595 | |
596 E removeAt(int index) { | |
597 throw new UnsupportedError( | |
598 "Cannot remove from an unmodifiable list"); | |
599 } | |
600 | |
601 E removeLast() { | |
602 throw new UnsupportedError( | |
603 "Cannot remove from an unmodifiable list"); | |
604 } | |
605 | |
606 void setRange(int start, int length, List<E> from, [int startFrom]) { | |
607 throw new UnsupportedError( | |
608 "Cannot modify an unmodifiable list"); | |
609 } | |
610 | |
611 void removeRange(int start, int length) { | |
612 throw new UnsupportedError( | |
613 "Cannot remove from an unmodifiable list"); | |
614 } | |
615 | |
616 void insertRange(int start, int length, [E initialValue]) { | |
617 throw new UnsupportedError( | |
618 "Cannot insert range in an unmodifiable list"); | |
619 } | |
620 } | |
621 | |
622 | |
623 /** | |
624 * Abstract implementation of a list. | |
625 * | |
626 * All operations are defined in terms of `length`, `operator[]`, | |
627 * `operator[]=` and `length=`, which need to be implemented. | |
628 */ | |
629 abstract class ListBase<E> extends ListMixin<E> implements List<E> {} | |
630 | |
631 /** | |
632 * Abstract implementation of a fixed-length list. | |
633 * | |
634 * All operations are defined in terms of `length`, `operator[]` and | |
635 * `operator[]=`, which need to be implemented. | |
636 */ | |
637 abstract class FixedLengthListBase<E> extends ListBase<E> | |
638 with FixedLengthListMixin<E> {} | |
639 | |
640 /** | |
641 * Abstract implementation of an unmodifiable list. | |
642 * | |
643 * All operations are defined in terms of `length` and `operator[]`, | |
644 * which need to be implemented. | |
645 */ | |
646 abstract class UnmodifiableListBase<E> extends ListBase<E> | |
647 with UnmodifiableListMixin<E> {} | |
648 | |
649 /** An empty fixed-length (and therefore unmodifiable) list. */ | |
650 class EmptyList<E> extends FixedLengthListBase<E> { | |
651 int get length => 0; | |
652 E operator[](int index) { throw new RangeError.value(index); } | |
653 void operator []=(int index, E value) { throw new RangeError.value(index); } | |
654 Iterable<E> skip(int count) => const EmptyIterable(); | |
655 Iterable<E> take(int count) => const EmptyIterable(); | |
656 Iterable<E> get reversed => const EmptyIterable(); | |
657 void sort([int compare(E a, E b)]) {} | |
658 } | |
659 | |
660 class ReversedListIterable<E> extends ListIterable<E> { | |
661 Iterable<E> _source; | |
662 ReversedListIterable(this._source); | |
663 | |
664 int get length => _source.length; | |
665 | |
666 E elementAt(int index) => _source.elementAt(_source.length - 1 - index); | |
667 } | |
668 | |
669 /** | |
670 * An [Iterable] of the UTF-16 code units of a [String] in index order. | |
671 */ | |
672 class CodeUnits extends UnmodifiableListBase<int> { | |
673 /** The string that this is the code units of. */ | |
674 String _string; | |
675 | |
676 CodeUnits(this._string); | |
677 | |
678 int get length => _string.length; | |
679 int operator[](int i) => _string.codeUnitAt(i); | |
680 } | |
681 | |
682 class _ListIndicesIterable extends ListIterable<int> { | |
683 List _backedList; | |
684 | |
685 _ListIndicesIterable(this._backedList); | |
686 | |
687 int get length => _backedList.length; | |
688 int elementAt(int index) { | |
689 if (index < 0 || index >= length) { | |
690 throw new RangeError.range(index, 0, length); | |
691 } | |
692 return index; | |
693 } | |
694 } | |
695 | |
696 class ListMapView<E> implements Map<int, E> { | |
697 List<E> _values; | |
698 | |
699 ListMapView(this._values); | |
700 | |
701 E operator[] (int key) => containsKey(key) ? _values[key] : null; | |
702 int get length => _values.length; | |
703 | |
704 Iterable<E> get values => new SubListIterable<E>(_values, 0, null); | |
705 Iterable<int> get keys => new _ListIndicesIterable(_values); | |
706 | |
707 bool get isEmpty => _values.isEmpty; | |
708 bool containsValue(E value) => _values.contains(value); | |
709 bool containsKey(int key) => key is int && key >= 0 && key < length; | |
710 | |
711 void forEach(void f(int key, E value)) { | |
712 int length = _values.length; | |
713 for (int i = 0; i < length; i++) { | |
714 f(i, _values[i]); | |
715 if (length != _values.length) { | |
716 throw new ConcurrentModificationError(_values); | |
717 } | |
718 } | |
719 } | |
720 | |
721 void operator[]= (int key, E value) { | |
722 throw new UnsupportedError("Cannot modify an unmodifiable map"); | |
723 } | |
724 | |
725 E putIfAbsent(int key, E ifAbsent()) { | |
726 throw new UnsupportedError("Cannot modify an unmodifiable map"); | |
727 } | |
728 | |
729 E remove(int key) { | |
730 throw new UnsupportedError("Cannot modify an unmodifiable map"); | |
731 } | |
732 | |
733 void clear() { | |
734 throw new UnsupportedError("Cannot modify an unmodifiable map"); | |
735 } | |
736 } | |
OLD | NEW |