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 import "dart:collection"; | 5 import "dart:collection"; |
6 import "dart:math" as math; | 6 import "dart:math" as math; |
7 | 7 |
| 8 import "typed_wrappers.dart"; |
8 import "unmodifiable_wrappers.dart"; | 9 import "unmodifiable_wrappers.dart"; |
9 | 10 |
10 typedef K _KeyForValue<K, V>(V value); | 11 typedef K _KeyForValue<K, V>(V value); |
11 | 12 |
12 /// A base class for delegating iterables. | 13 /// A base class for delegating iterables. |
13 /// | 14 /// |
14 /// Subclasses can provide a [_base] that should be delegated to. Unlike | 15 /// Subclasses can provide a [_base] that should be delegated to. Unlike |
15 /// [DelegatingIterable], this allows the base to be created on demand. | 16 /// [DelegatingIterable], this allows the base to be created on demand. |
16 abstract class _DelegatingIterableBase<E> implements Iterable<E> { | 17 abstract class _DelegatingIterableBase<E> implements Iterable<E> { |
17 Iterable<E> get _base; | 18 Iterable<E> get _base; |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
74 | 75 |
75 List<E> toList({bool growable: true}) => _base.toList(growable: growable); | 76 List<E> toList({bool growable: true}) => _base.toList(growable: growable); |
76 | 77 |
77 Set<E> toSet() => _base.toSet(); | 78 Set<E> toSet() => _base.toSet(); |
78 | 79 |
79 Iterable<E> where(bool test(E element)) => _base.where(test); | 80 Iterable<E> where(bool test(E element)) => _base.where(test); |
80 | 81 |
81 String toString() => _base.toString(); | 82 String toString() => _base.toString(); |
82 } | 83 } |
83 | 84 |
84 /// Creates an [Iterable] that delegates all operations to a base iterable. | 85 /// An [Iterable] that delegates all operations to a base iterable. |
85 /// | 86 /// |
86 /// This class can be used hide non-`Iterable` methods of an iterable object, | 87 /// This class can be used to hide non-`Iterable` methods of an iterable object, |
87 /// or it can be extended to add extra functionality on top of an existing | 88 /// or it can be extended to add extra functionality on top of an existing |
88 /// iterable object. | 89 /// iterable object. |
89 class DelegatingIterable<E> extends _DelegatingIterableBase<E> { | 90 class DelegatingIterable<E> extends _DelegatingIterableBase<E> { |
90 final Iterable<E> _base; | 91 final Iterable<E> _base; |
91 | 92 |
92 /// Create a wrapper that forwards operations to [base]. | 93 /// Creates a wrapper that forwards operations to [base]. |
93 const DelegatingIterable(Iterable<E> base) : _base = base; | 94 const DelegatingIterable(Iterable<E> base) : _base = base; |
| 95 |
| 96 /// Creates a wrapper that asserts the types of values in [base]. |
| 97 /// |
| 98 /// This soundly converts an [Iterable] without a generic type to an |
| 99 /// `Iterable<E>` by asserting that its elements are instances of `E` whenever |
| 100 /// they're accessed. If they're not, it throws a [CastError]. |
| 101 /// |
| 102 /// This forwards all operations to [base], so any changes in [base] will be |
| 103 /// reflected in [this]. If [base] is already an `Iterable<E>`, it's returned |
| 104 /// unmodified. |
| 105 static Iterable/*<E>*/ typed/*<E>*/(Iterable base) => |
| 106 base is Iterable/*<E>*/ ? base : new TypedIterable/*<E>*/(base); |
94 } | 107 } |
95 | 108 |
96 | 109 |
97 /// Creates a [List] that delegates all operations to a base list. | 110 /// A [List] that delegates all operations to a base list. |
98 /// | 111 /// |
99 /// This class can be used hide non-`List` methods of a list object, | 112 /// This class can be used to hide non-`List` methods of a list object, or it |
100 /// or it can be extended to add extra functionality on top of an existing | 113 /// can be extended to add extra functionality on top of an existing list |
101 /// list object. | 114 /// object. |
102 class DelegatingList<E> extends DelegatingIterable<E> implements List<E> { | 115 class DelegatingList<E> extends DelegatingIterable<E> implements List<E> { |
103 const DelegatingList(List<E> base) : super(base); | 116 const DelegatingList(List<E> base) : super(base); |
104 | 117 |
| 118 /// Creates a wrapper that asserts the types of values in [base]. |
| 119 /// |
| 120 /// This soundly converts a [List] without a generic type to a `List<E>` by |
| 121 /// asserting that its elements are instances of `E` whenever they're |
| 122 /// accessed. If they're not, it throws a [CastError]. Note that even if an |
| 123 /// operation throws a [CastError], it may still mutate the underlying |
| 124 /// collection. |
| 125 /// |
| 126 /// This forwards all operations to [base], so any changes in [base] will be |
| 127 /// reflected in [this]. If [base] is already a `List<E>`, it's returned |
| 128 /// unmodified. |
| 129 static List/*<E>*/ typed/*<E>*/(List base) => |
| 130 base is List/*<E>*/ ? base : new TypedList/*<E>*/(base); |
| 131 |
105 List<E> get _listBase => _base; | 132 List<E> get _listBase => _base; |
106 | 133 |
107 E operator [](int index) => _listBase[index]; | 134 E operator [](int index) => _listBase[index]; |
108 | 135 |
109 void operator []=(int index, E value) { | 136 void operator []=(int index, E value) { |
110 _listBase[index] = value; | 137 _listBase[index] = value; |
111 } | 138 } |
112 | 139 |
113 void add(E value) { | 140 void add(E value) { |
114 _listBase.add(value); | 141 _listBase.add(value); |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
184 } | 211 } |
185 | 212 |
186 void sort([int compare(E a, E b)]) { | 213 void sort([int compare(E a, E b)]) { |
187 _listBase.sort(compare); | 214 _listBase.sort(compare); |
188 } | 215 } |
189 | 216 |
190 List<E> sublist(int start, [int end]) => _listBase.sublist(start, end); | 217 List<E> sublist(int start, [int end]) => _listBase.sublist(start, end); |
191 } | 218 } |
192 | 219 |
193 | 220 |
194 /// Creates a [Set] that delegates all operations to a base set. | 221 /// A [Set] that delegates all operations to a base set. |
195 /// | 222 /// |
196 /// This class can be used hide non-`Set` methods of a set object, | 223 /// This class can be used to hide non-`Set` methods of a set object, or it can |
197 /// or it can be extended to add extra functionality on top of an existing | 224 /// be extended to add extra functionality on top of an existing set object. |
198 /// set object. | |
199 class DelegatingSet<E> extends DelegatingIterable<E> implements Set<E> { | 225 class DelegatingSet<E> extends DelegatingIterable<E> implements Set<E> { |
200 const DelegatingSet(Set<E> base) : super(base); | 226 const DelegatingSet(Set<E> base) : super(base); |
201 | 227 |
| 228 /// Creates a wrapper that asserts the types of values in [base]. |
| 229 /// |
| 230 /// This soundly converts a [Set] without a generic type to a `Set<E>` by |
| 231 /// asserting that its elements are instances of `E` whenever they're |
| 232 /// accessed. If they're not, it throws a [CastError]. Note that even if an |
| 233 /// operation throws a [CastError], it may still mutate the underlying |
| 234 /// collection. |
| 235 /// |
| 236 /// This forwards all operations to [base], so any changes in [base] will be |
| 237 /// reflected in [this]. If [base] is already a `Set<E>`, it's returned |
| 238 /// unmodified. |
| 239 static Set/*<E>*/ typed/*<E>*/(Set base) => |
| 240 base is Set/*<E>*/ ? base : new TypedSet/*<E>*/(base); |
| 241 |
202 Set<E> get _setBase => _base; | 242 Set<E> get _setBase => _base; |
203 | 243 |
204 bool add(E value) => _setBase.add(value); | 244 bool add(E value) => _setBase.add(value); |
205 | 245 |
206 void addAll(Iterable<E> elements) { | 246 void addAll(Iterable<E> elements) { |
207 _setBase.addAll(elements); | 247 _setBase.addAll(elements); |
208 } | 248 } |
209 | 249 |
210 void clear() { | 250 void clear() { |
211 _setBase.clear(); | 251 _setBase.clear(); |
(...skipping 23 matching lines...) Expand all Loading... |
235 | 275 |
236 void retainWhere(bool test(E element)) { | 276 void retainWhere(bool test(E element)) { |
237 _setBase.retainWhere(test); | 277 _setBase.retainWhere(test); |
238 } | 278 } |
239 | 279 |
240 Set<E> union(Set<E> other) => _setBase.union(other); | 280 Set<E> union(Set<E> other) => _setBase.union(other); |
241 | 281 |
242 Set<E> toSet() => new DelegatingSet<E>(_setBase.toSet()); | 282 Set<E> toSet() => new DelegatingSet<E>(_setBase.toSet()); |
243 } | 283 } |
244 | 284 |
245 /// Creates a [Queue] that delegates all operations to a base queue. | 285 /// A [Queue] that delegates all operations to a base queue. |
246 /// | 286 /// |
247 /// This class can be used hide non-`Queue` methods of a queue object, | 287 /// This class can be used to hide non-`Queue` methods of a queue object, or it |
248 /// or it can be extended to add extra functionality on top of an existing | 288 /// can be extended to add extra functionality on top of an existing queue |
249 /// queue object. | 289 /// object. |
250 class DelegatingQueue<E> extends DelegatingIterable<E> implements Queue<E> { | 290 class DelegatingQueue<E> extends DelegatingIterable<E> implements Queue<E> { |
251 const DelegatingQueue(Queue<E> queue) : super(queue); | 291 const DelegatingQueue(Queue<E> queue) : super(queue); |
252 | 292 |
| 293 /// Creates a wrapper that asserts the types of values in [base]. |
| 294 /// |
| 295 /// This soundly converts a [Queue] without a generic type to a `Queue<E>` by |
| 296 /// asserting that its elements are instances of `E` whenever they're |
| 297 /// accessed. If they're not, it throws a [CastError]. Note that even if an |
| 298 /// operation throws a [CastError], it may still mutate the underlying |
| 299 /// collection. |
| 300 /// |
| 301 /// This forwards all operations to [base], so any changes in [base] will be |
| 302 /// reflected in [this]. If [base] is already a `Queue<E>`, it's returned |
| 303 /// unmodified. |
| 304 static Queue/*<E>*/ typed/*<E>*/(Queue base) => |
| 305 base is Queue/*<E>*/ ? base : new TypedQueue/*<E>*/(base); |
| 306 |
253 Queue<E> get _baseQueue => _base; | 307 Queue<E> get _baseQueue => _base; |
254 | 308 |
255 void add(E value) { | 309 void add(E value) { |
256 _baseQueue.add(value); | 310 _baseQueue.add(value); |
257 } | 311 } |
258 | 312 |
259 void addAll(Iterable<E> iterable) { | 313 void addAll(Iterable<E> iterable) { |
260 _baseQueue.addAll(iterable); | 314 _baseQueue.addAll(iterable); |
261 } | 315 } |
262 | 316 |
(...skipping 13 matching lines...) Expand all Loading... |
276 | 330 |
277 void removeWhere(bool test(E element)) { _baseQueue.removeWhere(test); } | 331 void removeWhere(bool test(E element)) { _baseQueue.removeWhere(test); } |
278 | 332 |
279 void retainWhere(bool test(E element)) { _baseQueue.retainWhere(test); } | 333 void retainWhere(bool test(E element)) { _baseQueue.retainWhere(test); } |
280 | 334 |
281 E removeFirst() => _baseQueue.removeFirst(); | 335 E removeFirst() => _baseQueue.removeFirst(); |
282 | 336 |
283 E removeLast() => _baseQueue.removeLast(); | 337 E removeLast() => _baseQueue.removeLast(); |
284 } | 338 } |
285 | 339 |
286 /// Creates a [Map] that delegates all operations to a base map. | 340 /// A [Map] that delegates all operations to a base map. |
287 /// | 341 /// |
288 /// This class can be used hide non-`Map` methods of an object that extends | 342 /// This class can be used to hide non-`Map` methods of an object that extends |
289 /// `Map`, or it can be extended to add extra functionality on top of an | 343 /// `Map`, or it can be extended to add extra functionality on top of an |
290 /// existing map object. | 344 /// existing map object. |
291 class DelegatingMap<K, V> implements Map<K, V> { | 345 class DelegatingMap<K, V> implements Map<K, V> { |
292 final Map<K, V> _base; | 346 final Map<K, V> _base; |
293 | 347 |
294 const DelegatingMap(Map<K, V> base) : _base = base; | 348 const DelegatingMap(Map<K, V> base) : _base = base; |
295 | 349 |
| 350 /// Creates a wrapper that asserts the types of keys and values in [base]. |
| 351 /// |
| 352 /// This soundly converts a [Map] without generic types to a `Map<K, V>` by |
| 353 /// asserting that its keys are instances of `E` and its values are instances |
| 354 /// of `V` whenever they're accessed. If they're not, it throws a [CastError]. |
| 355 /// Note that even if an operation throws a [CastError], it may still mutate |
| 356 /// the underlying collection. |
| 357 /// |
| 358 /// This forwards all operations to [base], so any changes in [base] will be |
| 359 /// reflected in [this]. If [base] is already a `Map<K, V>`, it's returned |
| 360 /// unmodified. |
| 361 static Map/*<K, V>*/ typed/*<K, V>*/(Map base) => |
| 362 base is Map<K, V> ? base : new TypedMap<K, V>(base); |
| 363 |
296 V operator [](Object key) => _base[key]; | 364 V operator [](Object key) => _base[key]; |
297 | 365 |
298 void operator []=(K key, V value) { | 366 void operator []=(K key, V value) { |
299 _base[key] = value; | 367 _base[key] = value; |
300 } | 368 } |
301 | 369 |
302 void addAll(Map<K, V> other) { | 370 void addAll(Map<K, V> other) { |
303 _base.addAll(other); | 371 _base.addAll(other); |
304 } | 372 } |
305 | 373 |
(...skipping 223 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
529 | 597 |
530 /// Returns a new set which contains all the elements of [this] and [other]. | 598 /// Returns a new set which contains all the elements of [this] and [other]. |
531 /// | 599 /// |
532 /// That is, the returned set contains all the elements of this [Set] and all | 600 /// That is, the returned set contains all the elements of this [Set] and all |
533 /// the elements of [other]. | 601 /// the elements of [other]. |
534 /// | 602 /// |
535 /// Note that the returned set will use the default equality operation, which | 603 /// Note that the returned set will use the default equality operation, which |
536 /// may be different than the equality operation [this] uses. | 604 /// may be different than the equality operation [this] uses. |
537 Set<V> union(Set<V> other) => toSet()..addAll(other); | 605 Set<V> union(Set<V> other) => toSet()..addAll(other); |
538 } | 606 } |
OLD | NEW |