Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(545)

Unified Diff: sdk/lib/collection/maps.dart

Issue 211223002: Add MapBase and UnmodifiableMapView classes to dart:collection. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Make stuff private. Created 6 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « sdk/lib/_internal/lib/js_mirrors.dart ('k') | tests/corelib/integer_to_string_test.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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
« no previous file with comments | « sdk/lib/_internal/lib/js_mirrors.dart ('k') | tests/corelib/integer_to_string_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698