OLD | NEW |
---|---|
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, 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 /** | 5 /** |
6 * Wrappers that prevent List, Set, or Map objects from being modified. | 6 * Wrappers that prevent a List, Set, or Map objects from being modified. |
floitsch
2013/11/18 18:21:29
object-s-
Lasse Reichstein Nielsen
2013/11/19 12:11:44
Done.
| |
7 * | 7 * |
8 * The [Set] and [Map] wrappers allow reading from the wrapped collection, | 8 * The [Set] and [Map] wrappers allow reading from the wrapped collection, |
9 * but prohibit writing. | 9 * but prohibit writing. |
10 * | 10 * |
11 * The [List] wrapper prevents changes to the length of the wrapped list, | 11 * The [List] wrapper prevents changes to the length of the wrapped list, |
12 * but allows changes to the contents. | 12 * but allows changes to the contents. |
13 */ | 13 */ |
14 library unmodifiable_collection; | 14 part of dart.collection_helpers.wrappers; |
15 | |
16 import "dart:math" show Random; | |
17 export "dart:collection" show UnmodifiableListView; | |
18 | 15 |
19 /** | 16 /** |
20 * A fixed-length list. | 17 * A fixed-length list. |
21 * | 18 * |
22 * A NonGrowableListView contains a [List] object and ensures that | 19 * A `NonGrowableListView` contains a [List] object and ensures that |
23 * its length does not change. | 20 * its length does not change. |
24 * Methods that would change the length of the list, | 21 * Methods that would change the length of the list, |
25 * such as [add] and [remove], throw an [UnsupportedError]. | 22 * such as [add] and [remove], throw an [UnsupportedError]. |
23 * All other methods work directly on the underlying list. | |
26 * | 24 * |
27 * This class _does_ allow changes to the contents of the wrapped list. | 25 * This class _does_ allow changes to the contents of the wrapped list. |
28 * You can, for example, [sort] the list. | 26 * You can, for example, [sort] the list. |
29 * Permitted operations defer to the wrapped list. | 27 * Permitted operations defer to the wrapped list. |
30 */ | 28 */ |
31 class NonGrowableListView<E> extends _IterableView<E> | 29 class NonGrowableListView<E> extends DelegatingList<E> |
32 implements List<E> { | 30 with NonGrowableListMixin<E> { |
33 List<E> _source; | 31 NonGrowableListView(List<E> listBase) : super(listBase); |
34 NonGrowableListView(List<E> source) : _source = source; | 32 } |
35 | 33 |
34 /** | |
35 * Mixin class that implements a throwing version of all list operations that | |
36 * change the List's length. | |
37 */ | |
38 abstract class NonGrowableListMixin<E> implements List<E> { | |
36 static void _throw() { | 39 static void _throw() { |
37 throw new UnsupportedError( | 40 throw new UnsupportedError( |
38 "Cannot change the length of a fixed-length list"); | 41 "Cannot change the length of a fixed-length list"); |
39 } | 42 } |
40 | 43 |
41 int get length => _source.length; | |
42 | |
43 E operator [](int index) => _source[index]; | |
44 | |
45 int indexOf(E element, [int start = 0]) => _source.indexOf(element, start); | |
46 | |
47 int lastIndexOf(E element, [int start]) | |
48 => _source.lastIndexOf(element, start); | |
49 | |
50 Iterable<E> getRange(int start, int end) => _source.getRange(start, end); | |
51 | |
52 List<E> sublist(int start, [int end]) => _source.sublist(start, end); | |
53 | |
54 Iterable<E> get reversed => _source.reversed; | |
55 | |
56 Map<int, E> asMap() => _source.asMap(); | |
57 | |
58 void operator []=(int index, E value) { _source[index] = value; } | |
59 | |
60 void sort([int compare(E a, E b)]) { _source.sort(compare); } | |
61 | |
62 void shuffle([Random random]) { _source.shuffle(random); } | |
63 | |
64 void setRange(int start, int end, Iterable<E> iterable, [int skipCount = 0]) { | |
65 _source.setRange(start, end, iterable, skipCount); | |
66 } | |
67 | |
68 void fillRange(int start, int end, [E fillValue]) { | |
69 _source.fillRange(start, end, fillValue); | |
70 } | |
71 | |
72 void setAll(int index, Iterable<E> iterable) { | |
73 _source.setAll(index, iterable); | |
74 } | |
75 | |
76 | |
77 /** | 44 /** |
78 * Throws an [UnsupportedError]; | 45 * Throws an [UnsupportedError]; |
79 * operations that change the length of the list are disallowed. | 46 * operations that change the length of the list are disallowed. |
80 */ | 47 */ |
81 void set length(int newLength) => _throw(); | 48 void set length(int newLength) => _throw(); |
82 | 49 |
83 /** | 50 /** |
84 * Throws an [UnsupportedError]; | 51 * Throws an [UnsupportedError]; |
85 * operations that change the length of the list are disallowed. | 52 * operations that change the length of the list are disallowed. |
86 */ | 53 */ |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
157 | 124 |
158 /** | 125 /** |
159 * An unmodifiable set. | 126 * An unmodifiable set. |
160 * | 127 * |
161 * An UnmodifiableSetView contains a [Set] object and ensures | 128 * An UnmodifiableSetView contains a [Set] object and ensures |
162 * that it does not change. | 129 * that it does not change. |
163 * Methods that would change the set, | 130 * Methods that would change the set, |
164 * such as [add] and [remove], throw an [UnsupportedError]. | 131 * such as [add] and [remove], throw an [UnsupportedError]. |
165 * Permitted operations defer to the wrapped set. | 132 * Permitted operations defer to the wrapped set. |
166 */ | 133 */ |
167 class UnmodifiableSetView<E> extends _IterableView<E> | 134 class UnmodifiableSetView<E> extends DelegatingSet<E> |
168 implements Set<E> { | 135 with UnmodifiableSetMixin<E> { |
169 Set<E> _source; | 136 UnmodifiableSetView(Set<E> setBase) : super(setBase); |
170 UnmodifiableSetView(Set<E> source) : _source = source; | 137 } |
171 | 138 |
139 /** | |
140 * Mixin class that implements a throwing version of all set operations that | |
141 * change the Set. | |
142 */ | |
143 abstract class UnmodifiableSetMixin<E> implements Set<E> { | |
172 void _throw() { | 144 void _throw() { |
173 throw new UnsupportedError("Cannot modify an unmodifiable Set"); | 145 throw new UnsupportedError("Cannot modify an unmodifiable Set"); |
174 } | 146 } |
175 | 147 |
176 bool containsAll(Iterable<E> other) => _source.containsAll(other); | |
177 | |
178 Set<E> intersection(Set<E> other) => _source.intersection(other); | |
179 | |
180 Set<E> union(Set<E> other) => _source.union(other); | |
181 | |
182 Set<E> difference(Set<E> other) => _source.difference(other); | |
183 | |
184 E lookup(Object object) => _source.lookup(object); | |
185 | |
186 /** | 148 /** |
187 * Throws an [UnsupportedError]; | 149 * Throws an [UnsupportedError]; |
188 * operations that change the set are disallowed. | 150 * operations that change the set are disallowed. |
189 */ | 151 */ |
190 bool add(E value) { | 152 bool add(E value) { |
191 _throw(); | 153 _throw(); |
192 } | 154 } |
193 | 155 |
194 /** | 156 /** |
195 * Throws an [UnsupportedError]; | 157 * Throws an [UnsupportedError]; |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
236 | 198 |
237 /** | 199 /** |
238 * An unmodifiable map. | 200 * An unmodifiable map. |
239 * | 201 * |
240 * An UnmodifiableMapView contains a [Map] object and ensures | 202 * An UnmodifiableMapView contains a [Map] object and ensures |
241 * that it does not change. | 203 * that it does not change. |
242 * Methods that would change the map, | 204 * Methods that would change the map, |
243 * such as [addAll] and [remove], throw an [UnsupportedError]. | 205 * such as [addAll] and [remove], throw an [UnsupportedError]. |
244 * Permitted operations defer to the wrapped map. | 206 * Permitted operations defer to the wrapped map. |
245 */ | 207 */ |
246 class UnmodifiableMapView<K, V> implements Map<K, V> { | 208 class UnmodifiableMapView<K, V> extends DelegatingMap<K, V> |
247 Map<K, V> _source; | 209 with UnmodifiableMapMixin<K, V> { |
248 UnmodifiableMapView(Map<K, V> source) : _source = source; | 210 UnmodifiableMapView(Map<K, V> baseMap) : super(baseMap); |
211 } | |
249 | 212 |
213 /** | |
214 * Mixin class that implements a throwing version of all map operations that | |
215 * change the Map. | |
216 */ | |
217 abstract class UnmodifiableMapMixin<K, V> implements Map<K, V> { | |
250 static void _throw() { | 218 static void _throw() { |
251 throw new UnsupportedError("Cannot modify an unmodifiable Map"); | 219 throw new UnsupportedError("Cannot modify an unmodifiable Map"); |
252 } | 220 } |
253 | 221 |
254 int get length => _source.length; | |
255 | |
256 bool get isEmpty => _source.isEmpty; | |
257 | |
258 bool get isNotEmpty => _source.isNotEmpty; | |
259 | |
260 V operator [](K key) => _source[key]; | |
261 | |
262 bool containsKey(K key) => _source.containsKey(key); | |
263 | |
264 bool containsValue(V value) => _source.containsValue(value); | |
265 | |
266 void forEach(void f(K key, V value)) => _source.forEach(f); | |
267 | |
268 Iterable<K> get keys => _source.keys; | |
269 | |
270 Iterable<V> get values => _source.values; | |
271 | |
272 | |
273 /** | 222 /** |
274 * Throws an [UnsupportedError]; | 223 * Throws an [UnsupportedError]; |
275 * operations that change the map are disallowed. | 224 * operations that change the map are disallowed. |
276 */ | 225 */ |
277 void operator []=(K key, V value) => _throw(); | 226 void operator []=(K key, V value) => _throw(); |
278 | 227 |
279 /** | 228 /** |
280 * Throws an [UnsupportedError]; | 229 * Throws an [UnsupportedError]; |
281 * operations that change the map are disallowed. | 230 * operations that change the map are disallowed. |
282 */ | 231 */ |
(...skipping 10 matching lines...) Expand all Loading... | |
293 * operations that change the map are disallowed. | 242 * operations that change the map are disallowed. |
294 */ | 243 */ |
295 V remove(K key) { _throw(); } | 244 V remove(K key) { _throw(); } |
296 | 245 |
297 /** | 246 /** |
298 * Throws an [UnsupportedError]; | 247 * Throws an [UnsupportedError]; |
299 * operations that change the map are disallowed. | 248 * operations that change the map are disallowed. |
300 */ | 249 */ |
301 void clear() => _throw(); | 250 void clear() => _throw(); |
302 } | 251 } |
303 | |
304 abstract class _IterableView<E> { | |
305 Iterable<E> get _source; | |
306 | |
307 bool any(bool test(E element)) => _source.any(test); | |
308 | |
309 bool contains(E element) => _source.contains(element); | |
310 | |
311 E elementAt(int index) => _source.elementAt(index); | |
312 | |
313 bool every(bool test(E element)) => _source.every(test); | |
314 | |
315 Iterable expand(Iterable f(E element)) => _source.expand(f); | |
316 | |
317 E get first => _source.first; | |
318 | |
319 E firstWhere(bool test(E element), { E orElse() }) | |
320 => _source.firstWhere(test, orElse: orElse); | |
321 | |
322 dynamic fold(var initialValue, | |
323 dynamic combine(var previousValue, E element)) | |
324 => _source.fold(initialValue, combine); | |
325 | |
326 void forEach(void f(E element)) => _source.forEach(f); | |
327 | |
328 bool get isEmpty => _source.isEmpty; | |
329 | |
330 bool get isNotEmpty => _source.isNotEmpty; | |
331 | |
332 Iterator<E> get iterator => _source.iterator; | |
333 | |
334 String join([String separator = ""]) => _source.join(separator); | |
335 | |
336 E get last => _source.last; | |
337 | |
338 E lastWhere(bool test(E element), {E orElse()}) | |
339 => _source.lastWhere(test, orElse: orElse); | |
340 | |
341 int get length => _source.length; | |
342 | |
343 Iterable map(f(E element)) => _source.map(f); | |
344 | |
345 E reduce(E combine(E value, E element)) => _source.reduce(combine); | |
346 | |
347 E get single => _source.single; | |
348 | |
349 E singleWhere(bool test(E element)) => _source.singleWhere(test); | |
350 | |
351 Iterable<E> skip(int n) => _source.skip(n); | |
352 | |
353 Iterable<E> skipWhile(bool test(E value)) => _source.skipWhile(test); | |
354 | |
355 Iterable<E> take(int n) => _source.take(n); | |
356 | |
357 Iterable<E> takeWhile(bool test(E value)) => _source.takeWhile(test); | |
358 | |
359 List<E> toList({ bool growable: true }) => _source.toList(growable: growable); | |
360 | |
361 Set<E> toSet() => _source.toSet(); | |
362 | |
363 Iterable<E> where(bool test(E element)) => _source.where(test); | |
364 } | |
OLD | NEW |