| OLD | NEW |
| 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.core; | 5 part of dart.core; |
| 6 | 6 |
| 7 /** | 7 /** |
| 8 * A [List] is an indexable collection with a length. It can be of | 8 * A [List] is an indexable collection with a length. It can be of |
| 9 * fixed size or extendable. | 9 * fixed size or extendable. |
| 10 */ | 10 */ |
| (...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 183 * not extendable. | 183 * not extendable. |
| 184 * If [length] is 0, this method does not do anything. | 184 * If [length] is 0, this method does not do anything. |
| 185 * If [start] is the length of the list, this method inserts the | 185 * If [start] is the length of the list, this method inserts the |
| 186 * range at the end of the list. | 186 * range at the end of the list. |
| 187 * Throws an [ArgumentError] if [length] is negative. | 187 * Throws an [ArgumentError] if [length] is negative. |
| 188 * Throws an [RangeError] if [start] is negative or if | 188 * Throws an [RangeError] if [start] is negative or if |
| 189 * [start] is greater than the length of the list. | 189 * [start] is greater than the length of the list. |
| 190 */ | 190 */ |
| 191 void insertRange(int start, int length, [E fill]); | 191 void insertRange(int start, int length, [E fill]); |
| 192 } | 192 } |
| 193 | |
| 194 /** | |
| 195 * An unmodifiable [List]. | |
| 196 */ | |
| 197 abstract class NonExtensibleListMixin<E> | |
| 198 extends Iterable<E> implements List<E> { | |
| 199 | |
| 200 Iterator<E> get iterator => new ListIterator(this); | |
| 201 | |
| 202 void forEach(f(E element)) { | |
| 203 for (int i = 0; i < this.length; i++) f(this[i]); | |
| 204 } | |
| 205 | |
| 206 bool contains(E value) { | |
| 207 for (int i = 0; i < length; i++) { | |
| 208 if (this[i] == value) return true; | |
| 209 } | |
| 210 return false; | |
| 211 } | |
| 212 | |
| 213 reduce(initialValue, combine(previousValue, E element)) { | |
| 214 var value = initialValue; | |
| 215 for (int i = 0; i < this.length; i++) { | |
| 216 value = combine(value, this[i]); | |
| 217 } | |
| 218 return value; | |
| 219 } | |
| 220 | |
| 221 bool every(bool f(E element)) { | |
| 222 for (int i = 0; i < this.length; i++) { | |
| 223 if (!f(this[i])) return false; | |
| 224 } | |
| 225 return true; | |
| 226 } | |
| 227 | |
| 228 bool any(bool f(E element)) { | |
| 229 for (int i = 0; i < this.length; i++) { | |
| 230 if (f(this[i])) return true; | |
| 231 } | |
| 232 return false; | |
| 233 } | |
| 234 | |
| 235 bool get isEmpty { | |
| 236 return this.length == 0; | |
| 237 } | |
| 238 | |
| 239 E elementAt(int index) { | |
| 240 return this[index]; | |
| 241 } | |
| 242 | |
| 243 int indexOf(E value, [int start = 0]) { | |
| 244 for (int i = start; i < length; i++) { | |
| 245 if (this[i] == value) return i; | |
| 246 } | |
| 247 return -1; | |
| 248 } | |
| 249 | |
| 250 int lastIndexOf(E value, [int start]) { | |
| 251 if (start == null) start = length - 1; | |
| 252 for (int i = start; i >= 0; i--) { | |
| 253 if (this[i] == value) return i; | |
| 254 } | |
| 255 return -1; | |
| 256 } | |
| 257 | |
| 258 E get first { | |
| 259 if (length > 0) return this[0]; | |
| 260 throw new StateError("No elements"); | |
| 261 } | |
| 262 | |
| 263 E get last { | |
| 264 if (length > 0) return this[length - 1]; | |
| 265 throw new StateError("No elements"); | |
| 266 } | |
| 267 | |
| 268 E get single { | |
| 269 if (length == 1) return this[0]; | |
| 270 if (length == 0) throw new StateError("No elements"); | |
| 271 throw new StateError("More than one element"); | |
| 272 } | |
| 273 | |
| 274 List<E> getRange(int start, int length) { | |
| 275 List<E> result = <E>[]; | |
| 276 for (int i = 0; i < length; i++) { | |
| 277 result.add(this[start + i]); | |
| 278 } | |
| 279 return result; | |
| 280 } | |
| 281 | |
| 282 void operator []=(int index, E value) { | |
| 283 throw new UnsupportedError( | |
| 284 "Cannot modify an unmodifiable list"); | |
| 285 } | |
| 286 | |
| 287 void set length(int newLength) { | |
| 288 throw new UnsupportedError( | |
| 289 "Cannot change the length of an unmodifiable list"); | |
| 290 } | |
| 291 | |
| 292 void add(E value) { | |
| 293 throw new UnsupportedError( | |
| 294 "Cannot add to an unmodifiable list"); | |
| 295 } | |
| 296 | |
| 297 void addLast(E value) { | |
| 298 throw new UnsupportedError( | |
| 299 "Cannot add to an unmodifiable list"); | |
| 300 } | |
| 301 | |
| 302 void addAll(Iterable<E> iterable) { | |
| 303 throw new UnsupportedError( | |
| 304 "Cannot add to an unmodifiable list"); | |
| 305 } | |
| 306 | |
| 307 void sort([Comparator<E> compare]) { | |
| 308 throw new UnsupportedError( | |
| 309 "Cannot modify an unmodifiable list"); | |
| 310 } | |
| 311 | |
| 312 void clear() { | |
| 313 throw new UnsupportedError( | |
| 314 "Cannot clear an unmodifiable list"); | |
| 315 } | |
| 316 | |
| 317 E removeAt(int index) { | |
| 318 throw new UnsupportedError( | |
| 319 "Cannot remove in an unmodifiable list"); | |
| 320 } | |
| 321 | |
| 322 E removeLast() { | |
| 323 throw new UnsupportedError( | |
| 324 "Cannot remove in an unmodifiable list"); | |
| 325 } | |
| 326 | |
| 327 void setRange(int start, int length, List<E> from, [int startFrom]) { | |
| 328 throw new UnsupportedError( | |
| 329 "Cannot modify an unmodifiable list"); | |
| 330 } | |
| 331 | |
| 332 void removeRange(int start, int length) { | |
| 333 throw new UnsupportedError( | |
| 334 "Cannot remove in an unmodifiable list"); | |
| 335 } | |
| 336 | |
| 337 void insertRange(int start, int length, [E initialValue]) { | |
| 338 throw new UnsupportedError( | |
| 339 "Cannot insert range in an unmodifiable list"); | |
| 340 } | |
| 341 } | |
| 342 | |
| 343 /** | |
| 344 * Iterates over a [Sequence] in growing index order. | |
| 345 */ | |
| 346 class ListIterator<E> implements Iterator<E> { | |
| 347 final List<E> _list; | |
| 348 int _position; | |
| 349 E _current; | |
| 350 | |
| 351 ListIterator(this._list) : _position = -1; | |
| 352 | |
| 353 bool moveNext() { | |
| 354 int nextPosition = _position + 1; | |
| 355 if (nextPosition < _list.length) { | |
| 356 _current = _list[nextPosition]; | |
| 357 _position = nextPosition; | |
| 358 return true; | |
| 359 } | |
| 360 _position = _list.length; | |
| 361 _current = null; | |
| 362 return false; | |
| 363 } | |
| 364 | |
| 365 E get current => _current; | |
| 366 } | |
| 367 | |
| 368 class MappedList<S, T> extends NonExtensibleListMixin<T> { | |
| 369 final List<S> _list; | |
| 370 // TODO(ahe): Restore type when feature is implemented in dart2js | |
| 371 // checked mode. http://dartbug.com/7733 | |
| 372 final /* _Transformation<S, T> */ _f; | |
| 373 | |
| 374 MappedList(this._list, T this._f(S element)); | |
| 375 | |
| 376 T operator[](int index) => _f(_list[index]); | |
| 377 int get length => _list.length; | |
| 378 } | |
| 379 | |
| 380 /** | |
| 381 * An immutable view of a [List]. | |
| 382 */ | |
| 383 class ListView<E> extends NonExtensibleListMixin<E> { | |
| 384 final List<E> _list; | |
| 385 final int _offset; | |
| 386 final int _length; | |
| 387 | |
| 388 /** | |
| 389 * If the given length is `null` then the ListView's length is bound by | |
| 390 * the backed [list]. | |
| 391 */ | |
| 392 ListView(List<E> list, this._offset, this._length) : _list = list { | |
| 393 if (_offset is! int || _offset < 0) { | |
| 394 throw new ArgumentError(_offset); | |
| 395 } | |
| 396 if (_length != null && | |
| 397 (_length is! int || _length < 0)) { | |
| 398 throw new ArgumentError(_length); | |
| 399 } | |
| 400 } | |
| 401 | |
| 402 int get length { | |
| 403 int originalLength = _list.length; | |
| 404 int skipLength = originalLength - _offset; | |
| 405 if (skipLength < 0) return 0; | |
| 406 if (_length == null || _length > skipLength) return skipLength; | |
| 407 return _length; | |
| 408 } | |
| 409 | |
| 410 E operator[](int index) { | |
| 411 int skipIndex = index + _offset; | |
| 412 if (index < 0 || | |
| 413 (_length != null && index >= _length) || | |
| 414 index + _offset >= _list.length) { | |
| 415 throw new RangeError.value(index); | |
| 416 } | |
| 417 return _list[index + _offset]; | |
| 418 } | |
| 419 | |
| 420 ListView<E> skip(int skipCount) { | |
| 421 if (skipCount is! int || skipCount < 0) { | |
| 422 throw new ArgumentError(skipCount); | |
| 423 } | |
| 424 return new ListView(_list, _offset + skipCount, _length); | |
| 425 } | |
| 426 | |
| 427 ListView<E> take(int takeCount) { | |
| 428 if (takeCount is! int || takeCount < 0) { | |
| 429 throw new ArgumentError(takeCount); | |
| 430 } | |
| 431 int newLength = takeCount; | |
| 432 if (_length != null && takeCount > _length) newLength = _length; | |
| 433 return new ListView(_list, _offset, newLength); | |
| 434 } | |
| 435 } | |
| OLD | NEW |