| OLD | NEW |
| (Empty) |
| 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 | |
| 3 // BSD-style license that can be found in the LICENSE file. | |
| 4 | |
| 5 #library('util'); | |
| 6 | |
| 7 /** | |
| 8 * An abstract map implementation. This class can be used as a superclass for | |
| 9 * implementing maps, requiring only the further implementation of the | |
| 10 * [:operator []:], [:forEach:] and [:length:] methods to provide a fully | |
| 11 * implemented immutable map. | |
| 12 */ | |
| 13 abstract class AbstractMap<K,V> implements Map<K,V> { | |
| 14 AbstractMap(); | |
| 15 AbstractMap.from(Map<K,V> other) { | |
| 16 other.forEach((k,v) => this[k] = v); | |
| 17 } | |
| 18 void operator []=(K key, value) { | |
| 19 throw new UnsupportedOperationException('[]= is not supported'); | |
| 20 } | |
| 21 void clear() { | |
| 22 throw new UnsupportedOperationException('clear() is not supported'); | |
| 23 } | |
| 24 bool containsKey(K key) { | |
| 25 var found = false; | |
| 26 forEach((k,_) { | |
| 27 if (k == key) { | |
| 28 found = true; | |
| 29 } | |
| 30 }); | |
| 31 return found; | |
| 32 } | |
| 33 bool containsValue(V value) { | |
| 34 var found = false; | |
| 35 forEach((_,v) { | |
| 36 if (v == value) { | |
| 37 found = true; | |
| 38 } | |
| 39 }); | |
| 40 return found; | |
| 41 } | |
| 42 Collection<K> getKeys() { | |
| 43 var keys = <K>[]; | |
| 44 forEach((k,_) => keys.add(k)); | |
| 45 return keys; | |
| 46 } | |
| 47 Collection<V> getValues() { | |
| 48 var values = <V>[]; | |
| 49 forEach((_,v) => values.add(v)); | |
| 50 return values; | |
| 51 } | |
| 52 bool isEmpty() => length == 0; | |
| 53 V putIfAbsent(K key, V ifAbsent()) { | |
| 54 if (!containsKey(key)) { | |
| 55 V value = this[key]; | |
| 56 this[key] = ifAbsent(); | |
| 57 return value; | |
| 58 } | |
| 59 return null; | |
| 60 } | |
| 61 V remove(K key) { | |
| 62 throw new UnsupportedOperationException('V remove(K key) is not supported'); | |
| 63 } | |
| 64 } | |
| 65 | |
| 66 /** | |
| 67 * [ImmutableMapWrapper] wraps a (mutable) map as an immutable map where all | |
| 68 * mutating operations throw [UnsupportedOperationException] upon invocation. | |
| 69 */ | |
| 70 class ImmutableMapWrapper<K,V> extends AbstractMap<K,V> { | |
| 71 final Map<K,V> _map; | |
| 72 | |
| 73 ImmutableMapWrapper(this._map); | |
| 74 | |
| 75 int get length => _map.length; | |
| 76 | |
| 77 V operator [](K key) { | |
| 78 if (key is K) { | |
| 79 return _map[key]; | |
| 80 } | |
| 81 return null; | |
| 82 } | |
| 83 | |
| 84 void forEach(void f(K key, V value)) { | |
| 85 _map.forEach(f); | |
| 86 } | |
| 87 } | |
| 88 | |
| 89 /** | |
| 90 * A [Filter] function returns [:true:] iff [value] should be included. | |
| 91 */ | |
| 92 typedef bool Filter<V>(V value); | |
| 93 | |
| 94 /** | |
| 95 * An immutable map wrapper capable of filtering the input map. | |
| 96 */ | |
| 97 class FilteredImmutableMap<K,V> extends ImmutableMapWrapper<K,V> { | |
| 98 final Filter<V> _filter; | |
| 99 | |
| 100 FilteredImmutableMap(Map<K,V> map, this._filter) : super(map); | |
| 101 | |
| 102 int get length { | |
| 103 var count = 0; | |
| 104 forEach((k,v) { | |
| 105 count++; | |
| 106 }); | |
| 107 return count; | |
| 108 } | |
| 109 | |
| 110 void forEach(void f(K key, V value)) { | |
| 111 _map.forEach((K k, V v) { | |
| 112 if (_filter(v)) { | |
| 113 f(k, v); | |
| 114 } | |
| 115 }); | |
| 116 } | |
| 117 } | |
| 118 | |
| 119 /** | |
| 120 * An [AsFilter] takes a [value] of type [V1] and returns [value] iff it is of | |
| 121 * type [V2] or [:null:] otherwise. An [AsFilter] therefore behaves like the | |
| 122 * [:as:] expression. | |
| 123 */ | |
| 124 typedef V2 AsFilter<V1, V2>(V1 value); | |
| 125 | |
| 126 /** | |
| 127 * An immutable map wrapper capable of filtering the input map based on types. | |
| 128 * It takes an [AsFilter] function which converts the original values of type | |
| 129 * [Vin] into values of type [Vout], or returns [:null:] if the value should | |
| 130 * not be included in the filtered map. | |
| 131 */ | |
| 132 class AsFilteredImmutableMap<K, Vin, Vout> extends AbstractMap<K, Vout> { | |
| 133 final Map<K, Vin> _map; | |
| 134 final AsFilter<Vin, Vout> _filter; | |
| 135 | |
| 136 AsFilteredImmutableMap(this._map, this._filter); | |
| 137 | |
| 138 int get length { | |
| 139 var count = 0; | |
| 140 forEach((k,v) { | |
| 141 count++; | |
| 142 }); | |
| 143 return count; | |
| 144 } | |
| 145 | |
| 146 Vout operator [](K key) { | |
| 147 if (key is K) { | |
| 148 return _filter(_map[key]); | |
| 149 } | |
| 150 return null; | |
| 151 } | |
| 152 | |
| 153 void forEach(void f(K key, Vout value)) { | |
| 154 _map.forEach((K k, Vin v) { | |
| 155 var value = _filter(v); | |
| 156 if (value !== null) { | |
| 157 f(k, value); | |
| 158 } | |
| 159 }); | |
| 160 } | |
| 161 } | |
| OLD | NEW |