| 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 |