Index: sdk/lib/collection/maps.dart |
diff --git a/sdk/lib/collection/maps.dart b/sdk/lib/collection/maps.dart |
index 2d605e8e13a02b7e45c22188bdad4419796e6a1e..29e71886ae8050f08f97b50bece7b82d51f37ae7 100644 |
--- a/sdk/lib/collection/maps.dart |
+++ b/sdk/lib/collection/maps.dart |
@@ -5,6 +5,196 @@ |
part of dart.collection; |
/** |
+ * Base class for implementing a [Map]. |
+ * |
+ * This class has a basic implementation of all but five of the members of |
+ * [Map]. |
+ * A basic `Map` class can be implemented by extending this class and |
+ * implementing `keys`, `operator[]`, `operator[]=`, `remove` and `clear`. |
+ * The remaining operations are implemented in terms of these five. |
+ * |
+ * The `keys` iterable should have efficient [length] and [contains] |
+ * operations, and it should catch concurrent modifications of the keys |
+ * while iterating. |
+ * |
+ * A more efficient implementation is usually possible by overriding |
+ * some of the other members as well. |
+ */ |
+class MapBase<K, V> implements Map<K, V> { |
+ MapBase(); // Prevents use as mixin. |
+ |
+ Iterable<K> get keys; |
+ V operator[](Object key); |
+ operator []=(K key, V value); |
+ V remove(Object key); |
+ // The `clear` operation should not be based on `remove`. |
+ // It should clear the map even if some keys are not equal to themselves. |
+ void clear(); |
+ |
+ void forEach(void action(K key, V value)) { |
+ for (K key in keys) { |
+ action(key, this[key]); |
+ } |
+ } |
+ |
+ void addAll(Map<K, V> other) { |
+ for (K key in other.keys) { |
+ this[key] = other[key]; |
+ } |
+ } |
+ |
+ bool containsValue(V value) { |
+ for (K key in keys) { |
+ if (this[key] == value) return true; |
+ } |
+ return false; |
+ } |
+ |
+ V putIfAbsent(K key, V ifAbsent()) { |
+ if (keys.contains(key)) { |
+ return this[key]; |
+ } |
+ return this[key] = ifAbsent(); |
+ } |
+ |
+ bool containsKey(Object key) => keys.contains(key); |
+ int get length => keys.length; |
+ bool get isEmpty => keys.isEmpty; |
+ bool get isNotEmpty => keys.isNotEmpty; |
+ Iterable<V> get values => new _MapBaseValueIterable<V>(this); |
+ String toString() => Maps.mapToString(this); |
+} |
+ |
+/** |
+ * Basic implementation of an unmodifiable [Map]. |
+ * |
+ * This class has a basic implementation of all but two of the members of |
+ * an umodifiable [Map]. |
+ * A simple unmodifiable `Map` class can be implemented by extending this |
+ * class and implementing `keys` and `operator[]`. |
+ * |
+ * Modifying operations throw when used. |
+ * The remaining non-modifying operations are implemented in terms of `keys` |
+ * and `operator[]`. |
+ * |
+ * The `keys` iterable should have efficient [length] and [contains] |
+ * operations, and it should catch concurrent modifications of the keys |
+ * while iterating. |
+ * |
+ * A more efficient implementation is usually possible by overriding |
+ * some of the other members as well. |
+ */ |
+class UnmodifiableMapBase<K, V> = |
+ MapBase<K, V> with _UnmodifiableMapMixin<K, V>; |
+ |
+/** |
+ * Implementation of [Map.values] based on the map and its [Map.keys] iterable. |
+ * |
+ * Iterable that iterates over the values of a `Map`. |
+ * It accesses the values by iterating over the keys of the map, and using the |
+ * map's `operator[]` to lookup the keys. |
+ */ |
+class _MapBaseValueIterable<V> extends IterableBase<V> |
+ implements EfficientLength { |
+ final Map _map; |
+ _MapBaseValueIterable(this._map); |
+ |
+ int get length => _map.length; |
+ bool get isEmpty => _map.isEmpty; |
+ bool get isNotEmpty => _map.isNotEmpty; |
+ V get first => _map[_map.keys.first]; |
+ V get single => _map[_map.keys.single]; |
+ V get last => _map[_map.keys.last]; |
+ |
+ Iterator<V> get iterator => new _MapBaseValueIterator<V>(_map); |
+} |
+ |
+/** |
+ * Iterator created by [_MapBaseValueIterable]. |
+ * |
+ * Iterates over the values of a map by iterating its keys and lookup up the |
+ * values. |
+ */ |
+class _MapBaseValueIterator<V> implements Iterator<V> { |
+ final Iterator _keys; |
+ final Map _map; |
+ V _current = null; |
+ |
+ _MapBaseValueIterator(Map map) : _map = map, _keys = map.keys.iterator; |
+ |
+ bool moveNext() { |
+ if (_keys.moveNext()) { |
+ _current = _map[_keys.current]; |
+ return true; |
+ } |
+ _current = null; |
+ return false; |
+ } |
+ |
+ V get current => _current; |
+} |
+ |
+/** |
+ * Mixin that overrides mutating map operations with implementations that throw. |
+ */ |
+class _UnmodifiableMapMixin<K, V> implements Map<K, V> { |
+ void operator[]=(K key, V value) { |
+ throw new UnsupportedError("Cannot modify unmodifiable map"); |
+ } |
+ void addAll(Map<K, V> other) { |
+ throw new UnsupportedError("Cannot modify unmodifiable map"); |
+ } |
+ void clear() { |
+ throw new UnsupportedError("Cannot modify unmodifiable map"); |
+ } |
+ V remove(Object key) { |
+ throw new UnsupportedError("Cannot modify unmodifiable map"); |
+ } |
+ V putIfAbsent(K key, V ifAbsent()) { |
+ throw new UnsupportedError("Cannot modify unmodifiable map"); |
+ } |
+} |
+ |
+/** |
+ * Wrapper around a class that implements [Map] that only exposes `Map` members. |
+ * |
+ * A simple wrapper that delegates all `Map` members to the map provided in the |
+ * constructor. |
+ * |
+ * Base for delegating map implementations like [UnmodifiableMapView]. |
+ */ |
+class MapView<K, V> implements Map<K, V> { |
+ final Map<K, V> _map; |
+ MapView(Map<K, V> map) : _map = map; |
+ |
+ V operator[](Object key) => _map[key]; |
+ void operator[]=(K key, V value) { _map[key] = value; } |
+ void addAll(Map<K, V> other) { _map.addAll(other); } |
+ void clear() { _map.clear(); } |
+ V putIfAbsent(K key, V ifAbsent()) => _map.putIfAbsent(key, ifAbsent); |
+ bool containsKey(Object key) => _map.containsKey(key); |
+ bool containsValue(Object value) => _map.containsValue(value); |
+ void forEach(void action(K key, V value)) { _map.forEach(action); } |
+ bool get isEmpty => _map.isEmpty; |
+ bool get isNotEmpty => _map.isNotEmpty; |
+ int get length => _map.length; |
+ Iterable<K> get keys => _map.keys; |
+ V remove(Object key) => _map.remove(key); |
+ String toString() => _map.toString(); |
+ Iterable<V> get values => _map.values; |
+} |
+ |
+/** |
+ * View of a [Map] that disallow modifying the map. |
+ * |
+ * A wrapper around a `Map` that forwards all members to the map provided in |
+ * the constructor, except for operations that modify the map. |
+ * Modifying operations throw instead. |
+ */ |
+class UnmodifiableMapView<K, V> = |
+ MapView<K, V> with _UnmodifiableMapMixin<K, V>; |
+ |
+/** |
* Helper class which implements complex [Map] operations |
* in term of basic ones ([Map.keys], [Map.operator []], |
* [Map.operator []=] and [Map.remove].) Not all methods are |