| OLD | NEW |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, 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; | 5 part of dart.collection; |
| 6 | 6 |
| 7 /** | 7 /** |
| 8 * This class provides default implementations for Iterables (including Lists). | 8 * This class provides default implementations for Iterables (including Lists). |
| 9 * | 9 * |
| 10 * Once Dart receives Mixins it will be replaced with mixin classes. | 10 * Once Dart receives Mixins it will be replaced with mixin classes. |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 61 | 61 |
| 62 /** | 62 /** |
| 63 * Implementation of [Collection.removeAll] for lists. | 63 * Implementation of [Collection.removeAll] for lists. |
| 64 * | 64 * |
| 65 * This implementation assumes that [Collection.remove] is not efficient | 65 * This implementation assumes that [Collection.remove] is not efficient |
| 66 * (as it usually isn't on a [List]) and uses [Collection.removeMathcing] | 66 * (as it usually isn't on a [List]) and uses [Collection.removeMathcing] |
| 67 * instead of just repeatedly calling remove. | 67 * instead of just repeatedly calling remove. |
| 68 */ | 68 */ |
| 69 static void removeAllList(Collection collection, Iterable elementsToRemove) { | 69 static void removeAllList(Collection collection, Iterable elementsToRemove) { |
| 70 Set setToRemove; | 70 Set setToRemove; |
| 71 // Assume contains is efficient on a Set. | 71 // Assume [contains] is efficient on a Set. |
| 72 if (elementsToRemove is Set) { | 72 if (elementsToRemove is Set) { |
| 73 setToRemove = elementsToRemove; | 73 setToRemove = elementsToRemove; |
| 74 } else { | 74 } else { |
| 75 setToRemove = elementsToRemove.toSet(); | 75 setToRemove = elementsToRemove.toSet(); |
| 76 } | 76 } |
| 77 collection.removeMatching(setToRemove.contains); | 77 collection.removeMatching(setToRemove.contains); |
| 78 } | 78 } |
| 79 | 79 |
| 80 /** | 80 /** |
| 81 * Simple implemenation for [Collection.retainAll]. | 81 * Simple implemenation for [Collection.retainAll]. |
| 82 * | 82 * |
| 83 * This implementation assumes that [Collecton.retainMatching] on [collection] | 83 * This implementation assumes that [Collecton.retainMatching] on [collection] |
| 84 * is efficient. | 84 * is efficient. |
| 85 */ | 85 */ |
| 86 static void retainAll(Collection collection, Iterable elementsToRetain) { | 86 static void retainAll(Collection collection, Iterable elementsToRetain) { |
| 87 Set lookup; | 87 Set lookup; |
| 88 if (elementsToRetain is Set) { | 88 if (elementsToRetain is Set) { |
| 89 lookup = elementsToRetain; | 89 lookup = elementsToRetain; |
| 90 } else { | 90 } else { |
| 91 lookup = elementsToRetain.toSet(); | 91 lookup = elementsToRetain.toSet(); |
| 92 } | 92 } |
| 93 if (lookup.isEmpty) { |
| 94 collection.clear(); |
| 95 return; |
| 96 } |
| 93 collection.retainMatching(lookup.contains); | 97 collection.retainMatching(lookup.contains); |
| 94 } | 98 } |
| 95 | 99 |
| 96 /** | 100 /** |
| 97 * Simple implemenation for [Collection.removeMatching]. | 101 * Simple implemenation for [Collection.removeMatching]. |
| 98 * | 102 * |
| 99 * This implementation assumes that [Collecton.removeAll] on [collection] is | 103 * This implementation assumes that [Collecton.removeAll] on [collection] is |
| 100 * efficient. | 104 * efficient. |
| 101 */ | 105 */ |
| 102 static void removeMatching(Collection collection, bool test(var element)) { | 106 static void removeMatching(Collection collection, bool test(var element)) { |
| 103 List elementsToRemove = []; | 107 List elementsToRemove = []; |
| 104 for (var element in collection) { | 108 for (var element in collection) { |
| 105 if (test(element)) elementsToRemove.add(element); | 109 if (test(element)) elementsToRemove.add(element); |
| 106 } | 110 } |
| 107 collection.removeAll(elementsToRemove); | 111 collection.removeAll(elementsToRemove); |
| 108 } | 112 } |
| 109 | 113 |
| 110 /** | 114 /** |
| 115 * Removes elements matching [test] from [list]. |
| 116 * |
| 117 * This is performed in two steps, to avoid exposing an inconsistent state |
| 118 * to the [test] function. First the elements to ratain are found, and then |
| 119 * the original list is updated to contain those elements. |
| 120 */ |
| 121 static void removeMatchingList(List list, bool test(var element)) { |
| 122 List retained = []; |
| 123 int length = list.length; |
| 124 for (int i = 0; i < length; i++) { |
| 125 var element = list[i]; |
| 126 if (!test(element)) { |
| 127 retained.add(element); |
| 128 } |
| 129 if (length != list.length) { |
| 130 throw new ConcurrentModificationError(list); |
| 131 } |
| 132 } |
| 133 if (retained.length == length) return; |
| 134 for (int i = 0; i < retained.length; i++) { |
| 135 list[i] = retained[i]; |
| 136 } |
| 137 list.length = retained.length; |
| 138 } |
| 139 |
| 140 /** |
| 111 * Simple implemenation for [Collection.retainMatching]. | 141 * Simple implemenation for [Collection.retainMatching]. |
| 112 * | 142 * |
| 113 * This implementation assumes that [Collecton.removeAll] on [collection] is | 143 * This implementation assumes that [Collecton.removeAll] on [collection] is |
| 114 * efficient. | 144 * efficient. |
| 115 */ | 145 */ |
| 116 static void retainMatching(Collection collection, bool test(var element)) { | 146 static void retainMatching(Collection collection, bool test(var element)) { |
| 117 List elementsToRemove = []; | 147 List elementsToRemove = []; |
| 118 for (var element in collection) { | 148 for (var element in collection) { |
| 119 if (!test(element)) elementsToRemove.add(element); | 149 if (!test(element)) elementsToRemove.add(element); |
| 120 } | 150 } |
| 121 collection.removeAll(elementsToRemove); | 151 collection.removeAll(elementsToRemove); |
| 122 } | 152 } |
| 153 |
| 123 static bool isEmpty(Iterable iterable) { | 154 static bool isEmpty(Iterable iterable) { |
| 124 return !iterable.iterator.moveNext(); | 155 return !iterable.iterator.moveNext(); |
| 125 } | 156 } |
| 126 | 157 |
| 127 static dynamic first(Iterable iterable) { | 158 static dynamic first(Iterable iterable) { |
| 128 Iterator it = iterable.iterator; | 159 Iterator it = iterable.iterator; |
| 129 if (!it.moveNext()) { | 160 if (!it.moveNext()) { |
| 130 throw new StateError("No elements"); | 161 throw new StateError("No elements"); |
| 131 } | 162 } |
| 132 return it.current; | 163 return it.current; |
| (...skipping 383 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 516 * Returns true if the specified collection contains the specified object | 547 * Returns true if the specified collection contains the specified object |
| 517 * reference. | 548 * reference. |
| 518 */ | 549 */ |
| 519 static _containsRef(Collection c, Object ref) { | 550 static _containsRef(Collection c, Object ref) { |
| 520 for (var e in c) { | 551 for (var e in c) { |
| 521 if (identical(e, ref)) return true; | 552 if (identical(e, ref)) return true; |
| 522 } | 553 } |
| 523 return false; | 554 return false; |
| 524 } | 555 } |
| 525 } | 556 } |
| OLD | NEW |