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