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

Side by Side 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: 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
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 * Base class for implementing a [Map].
9 *
10 * This class has a basic implementation of all but five of the members of
11 * [Map].
12 * A basic `Map` class can be implemented by extending this class and
13 * implementing `keys`, `operator[]`, `operator[]=`, `remove` and `clear`.
14 * The remaining operations are implemented in terms of these five.
15 *
16 * The `keys` iterable should have efficient [length] and [contains]
17 * operations, and it should catch concurrent modifications of the keys
18 * while iterating.
19 *
20 * A more efficient implementation is usually possible by also overriding
floitsch 2014/03/25 21:03:18 also ... as well Remove either "also" or "as well"
Lasse Reichstein Nielsen 2014/03/26 10:25:20 Done.
21 * some of the other members as well.
22 */
23 class MapBase<K, V> implements Map<K, V> {
24 Iterable<K> get keys;
25 V operator[](Object key);
26 operator []=(K key, V value);
27 V remove(Object key);
28 // The `clear` operation should not be based on `remove`.
29 // It should clear the map even if some keys are not equal to themselves.
30 void clear();
31
32 void forEach(void action(K key, V value)) {
33 for (K key in keys) {
34 action(key, this[key]);
35 }
36 }
37
38 void addAll(Map<K, V> other) {
39 for (K key in other.keys) {
40 this[key] = other[key];
41 }
42 }
43
44 bool containsValue(V value) {
45 for (K key in keys) {
46 if (this[key] == value) return true;
47 }
48 return false;
49 }
50
51 V putIfAbsent(K key, V ifAbsent()) {
52 if (keys.contains(key)) {
53 return this[key];
54 }
55 return this[key] = ifAbsent();
56 }
57
58 bool containsKey(Object key) => keys.contains(key);
59 int get length => keys.length;
60 bool get isEmpty => keys.isEmpty;
61 bool get isNotEmpty => keys.isNotEmpty;
62 Iterable<V> get values => new MapBaseValueIterable<V>(this);
63 String toString() => Maps.mapToString(this);
64 }
65
66 /**
67 * Basic implementation of an unmodifiable [Map].
68 *
69 * This class has a basic implementation of all but two of the members of
70 * an umodifiable [Map].
71 * A simple unmodifiable `Map` class can be implemented by extending this
72 * class and implementing `keys` and `operator[]`.
73 *
74 * Modifying operations throw when used.
75 * The remaining non-modifying operations are implemented in terms of `keys`
76 * and `operator[]`.
77 *
78 * The `keys` iterable should have efficient [length] and [contains]
79 * operations, and it should catch concurrent modifications of the keys
80 * while iterating.
81 *
82 * A more efficient implementation is usually possible by also overriding
83 * some of the other members as well.
84 */
85 class UnmodifiableMapBase<K, V> = MapBase<K, V> with UnmodifiableMapMixin<K, V>;
86
87 /**
88 * Implementation of [Map.values] based on the map and its [Map.keys] iterable.
89 *
90 * Iterable that iterates over the values of a `Map`.
91 * It accesses the values by iterating over the keys of the map, and using the
92 * map's `operator[]` to lookup the keys.
93 */
94 class MapBaseValueIterable<V> extends IterableBase<V>
floitsch 2014/03/25 21:03:18 Do we need to make this public?
Lasse Reichstein Nielsen 2014/03/26 10:25:20 No. I've made this, the iterator and the mixin pri
95 implements EfficientLength {
96 final Map _map;
97 MapBaseValueIterable(this._map);
98
99 int get length => _map.length;
100 bool get isEmpty => _map.isEmpty;
101 bool get isNotEmpty => _map.isNotEmpty;
102 V get first => _map[_map.keys.first];
103 V get single => _map[_map.keys.single];
104 V get last => _map[_map.keys.last];
105
106 Iterator<V> get iterator => new MapBaseValueIterator<V>(_map);
107 }
108
109 /**
110 * Iterator created by [MapBaseValueIterable].
111 *
112 * Iterates over the values of a map by iterating its keys and lookup up the
113 * values.
114 */
115 class MapBaseValueIterator<V> implements Iterator<V> {
floitsch 2014/03/25 21:03:18 ditto.
Lasse Reichstein Nielsen 2014/03/26 10:25:20 Done.
116 final Iterator _keys;
117 final Map _map;
118 V _current = null;
119
120 MapBaseValueIterator(Map map) : _map = map, _keys = map.keys.iterator;
121
122 bool moveNext() {
123 if (_keys.moveNext()) {
124 _current = _map[_keys.current];
125 return true;
126 }
127 _current = null;
128 return false;
129 }
130
131 V get current => _current;
132 }
133
134 /**
135 * Mixin that overrides mutating map operations with implementations that throw.
136 */
137 class UnmodifiableMapMixin<K, V> implements Map<K, V> {
floitsch 2014/03/25 21:03:18 I know this comes from pkg:collection where I revi
Lasse Reichstein Nielsen 2014/03/26 10:25:20 This is now private, so it's only used internally.
138 void operator[]=(K key, V value) {
139 throw new UnsupportedError("Cannot modify unmodifiable map");
140 }
141 void addAll(Map<K, V> other) {
142 throw new UnsupportedError("Cannot modify unmodifiable map");
143 }
144 void clear() {
145 throw new UnsupportedError("Cannot modify unmodifiable map");
146 }
147 V remove(Object key) {
148 throw new UnsupportedError("Cannot modify unmodifiable map");
149 }
150 V putIfAbsent(K key, V ifAbsent()) {
151 throw new UnsupportedError("Cannot modify unmodifiable map");
152 }
153 }
154
155 /**
156 * Wrapper around a class that implements [Map] that only exposes `Map` members.
157 *
158 * A simple wrapper that delegates all `Map` members to the map provided in the
159 * constructor.
160 *
161 * Base for delegating map implementations like [UnmodifiableMapView].
162 */
163 class MapView<K, V> implements Map<K, V> {
164 final Map<K, V> _map;
165 MapView(Map<K, V> map) : _map = map;
166
167 V operator[](Object key) => _map[key];
168 void operator[]=(K key, V value) { _map[key] = value; }
169 void addAll(Map<K, V> other) { _map.addAll(other); }
170 void clear() { _map.clear(); }
171 V putIfAbsent(K key, V ifAbsent()) => _map.putIfAbsent(key, ifAbsent);
172 bool containsKey(Object key) => _map.containsKey(key);
173 bool containsValue(Object value) => _map.containsValue(value);
174 void forEach(void action(K key, V value)) { _map.forEach(action); }
175 bool get isEmpty => _map.isEmpty;
176 bool get isNotEmpty => _map.isNotEmpty;
177 int get length => _map.length;
178 Iterable<K> get keys => _map.keys;
179 V remove(Object key) => _map.remove(key);
180 String toString() => _map.toString();
181 Iterable<V> get values => _map.values;
182 }
183
184 /**
185 * View of a [Map] that disallow modifying the map.
186 *
187 * A wrapper around a `Map` that forwards all members to the map provided in
188 * the constructor, except for operations that modify the map.
189 * Modifying operations throw instead.
190 */
191 class UnmodifiableMapView<K, V> = MapView<K, V> with UnmodifiableMapMixin<K, V>;
192
193 /**
8 * Helper class which implements complex [Map] operations 194 * Helper class which implements complex [Map] operations
9 * in term of basic ones ([Map.keys], [Map.operator []], 195 * in term of basic ones ([Map.keys], [Map.operator []],
10 * [Map.operator []=] and [Map.remove].) Not all methods are 196 * [Map.operator []=] and [Map.remove].) Not all methods are
11 * necessary to implement each particular operation. 197 * necessary to implement each particular operation.
12 */ 198 */
13 class Maps { 199 class Maps {
14 static bool containsValue(Map map, value) { 200 static bool containsValue(Map map, value) {
15 for (final v in map.values) { 201 for (final v in map.values) {
16 if (value == v) { 202 if (value == v) {
17 return true; 203 return true;
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after
141 map[keyIterator.current] = valueIterator.current; 327 map[keyIterator.current] = valueIterator.current;
142 hasNextKey = keyIterator.moveNext(); 328 hasNextKey = keyIterator.moveNext();
143 hasNextValue = valueIterator.moveNext(); 329 hasNextValue = valueIterator.moveNext();
144 } 330 }
145 331
146 if (hasNextKey || hasNextValue) { 332 if (hasNextKey || hasNextValue) {
147 throw new ArgumentError("Iterables do not have same length."); 333 throw new ArgumentError("Iterables do not have same length.");
148 } 334 }
149 } 335 }
150 } 336 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698