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

Side by Side Diff: sdk/lib/_collection_dev/list.dart

Issue 12295009: Recommit changing List.skip/take/revert returns Iterable and remove mappedBy. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Make Future.wait simpler. Created 7 years, 10 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) 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 part of dart._collection.dev; 5 part of dart._collection.dev;
6 6
7 /** 7 /**
8 * Class implementing the read-operations on [List]. 8 * Class implementing the read-operations on [List].
9 * 9 *
10 * Implements all read-only operations, except [:operator[]:] and [:length:], 10 * Implements all read-only operations, except [:operator[]:] and [:length:],
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
90 for (int i = 0; i < length; i++) { 90 for (int i = 0; i < length; i++) {
91 result.add(this[start + i]); 91 result.add(this[start + i]);
92 } 92 }
93 return result; 93 return result;
94 } 94 }
95 95
96 Iterable map(f(E element)) { 96 Iterable map(f(E element)) {
97 return new MappedIterable(this, f); 97 return new MappedIterable(this, f);
98 } 98 }
99 99
100 List mappedBy(f(E element)) { 100 Iterable<E> take(int n) {
101 return new MappedList(this, f); 101 return new SubListIterable(this, 0, n);
102 } 102 }
103 103
104 List<E> take(int n) { 104 Iterable<E> skip(int n) {
105 return new ListView(this, 0, n); 105 return new SubListIterable(this, n, null);
106 } 106 }
107 107
108 List<E> skip(int n) { 108 Iterable<E> get reversed => new ReversedListIterable(this);
109 return new ListView(this, n, null);
110 }
111 109
112 String toString() => ToString.collectionToString(this); 110 String toString() => ToString.collectionToString(this);
113
114 List<E> get reversed {
115 return new ReversedListView(this, 0, null);
116 }
117 } 111 }
118 112
119 /** 113 /**
120 * Abstract class implementing the non-length changing operations of [List]. 114 * Abstract class implementing the non-length changing operations of [List].
115 *
116 * All modifications are performed using [[]=].
121 */ 117 */
122 abstract class FixedLengthListBase<E> extends ListBase<E> { 118 abstract class FixedLengthListBase<E> extends ListBase<E> {
123 void operator[]=(int index, E value); 119 void operator[]=(int index, E value);
124 120
125 void sort([Comparator<E> compare]) { 121 void sort([Comparator<E> compare]) {
126 Sort.sort(this, compare); 122 Sort.sort(this, compare);
127 } 123 }
128 124
129 void setRange(int start, int length, List<E> from, [int startFrom]) { 125 void setRange(int start, int length, List<E> from, [int startFrom]) {
130 if (length < 0) throw new ArgumentError("length: $length"); 126 if (length < 0) throw new ArgumentError("length: $length");
(...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after
279 throw new UnsupportedError( 275 throw new UnsupportedError(
280 "Cannot remove from an unmodifiable list"); 276 "Cannot remove from an unmodifiable list");
281 } 277 }
282 278
283 void insertRange(int start, int length, [E initialValue]) { 279 void insertRange(int start, int length, [E initialValue]) {
284 throw new UnsupportedError( 280 throw new UnsupportedError(
285 "Cannot insert range in an unmodifiable list"); 281 "Cannot insert range in an unmodifiable list");
286 } 282 }
287 } 283 }
288 284
289 /**
290 * Iterates over a [List] in growing index order.
291 */
292 class ListIterator<E> implements Iterator<E> {
293 final List<E> _list;
294 final int _length;
295 int _position;
296 E _current;
297
298 ListIterator(List<E> list)
299 : _list = list, _position = -1, _length = list.length;
300
301 bool moveNext() {
302 if (_list.length != _length) {
303 throw new ConcurrentModificationError(_list);
304 }
305 int nextPosition = _position + 1;
306 if (nextPosition < _length) {
307 _position = nextPosition;
308 _current = _list[nextPosition];
309 return true;
310 }
311 _current = null;
312 return false;
313 }
314
315 E get current => _current;
316 }
317
318 class MappedList<S, T> extends UnmodifiableListBase<T> {
319 final List<S> _list;
320 // TODO(ahe): Restore type when feature is implemented in dart2js
321 // checked mode. http://dartbug.com/7733
322 final /* _Transformation<S, T> */ _f;
323
324 MappedList(this._list, T this._f(S element));
325
326 T operator[](int index) => _f(_list[index]);
327 int get length => _list.length;
328 }
329
330 /** An empty fixed-length list. */ 285 /** An empty fixed-length list. */
331 class EmptyList<E> extends FixedLengthListBase<E> { 286 class EmptyList<E> extends FixedLengthListBase<E> {
332 int get length => 0; 287 int get length => 0;
333 E operator[](int index) { throw new RangeError.value(index); } 288 E operator[](int index) { throw new RangeError.value(index); }
334 void operator []=(int index, E value) { throw new RangeError.value(index); } 289 void operator []=(int index, E value) { throw new RangeError.value(index); }
335 List<E> skip(int count) => this; 290 Iterable<E> skip(int count) => const EmptyIterable();
336 List<E> take(int count) => this; 291 Iterable<E> take(int count) => const EmptyIterable();
337 List<E> get reversed => this; 292 Iterable<E> get reversed => const EmptyIterable();
338 void sort([int compare(E a, E b)]) {} 293 void sort([int compare(E a, E b)]) {}
339 } 294 }
340 295
341 /** 296 class ReversedListIterable<E> extends ListIterable<E> {
342 * A fixed-length view of a sub-range of another [List]. 297 Iterable<E> _source;
343 * 298 ReversedListIterable(this._source);
344 * The range is described by start and end points relative
345 * to the other List's start or end.
346 *
347 * The range changes dynamically as the underlying list changes
348 * its length.
349 */
350 abstract class SubListView<E> extends UnmodifiableListBase<E> {
351 final List<E> _list;
352 final int _start;
353 final int _end;
354 299
355 /** 300 int get length => _source.length;
356 * Create a sub-list view.
357 *
358 * Both [_start] and [_end] can be given as positions
359 * relative to the start of [_list] (a non-negative integer)
360 * or relative to the end of [_list] (a negative integer or
361 * null, with null being at the end of the list).
362 */
363 SubListView(this._list, this._start, this._end);
364 301
365 int _absoluteIndex(int relativeIndex) { 302 E elementAt(int index) => _source.elementAt(_source.length - 1 - index);
366 if (relativeIndex == null) return _list.length;
367 if (relativeIndex < 0) {
368 int result = _list.length + relativeIndex;
369 if (result < 0) return 0;
370 return result;
371 }
372 if (relativeIndex > _list.length) {
373 return _list.length;
374 }
375 return relativeIndex;
376 }
377
378 int get length {
379 int result = _absoluteIndex(_end) - _absoluteIndex(_start);
380 if (result >= 0) return result;
381 return 0;
382 }
383
384 _createListView(int start, int end) {
385 if (start == null) return new EmptyList<E>();
386 if (end != null) {
387 if (start < 0) {
388 if (end <= start) return new EmptyList<E>();
389 } else {
390 if (end >= 0 && end <= start) return new EmptyList<E>();
391 }
392 }
393 return new ListView(_list, start, end);
394 }
395
396 _createReversedListView(int start, int end) {
397 if (start == null) return new EmptyList<E>();
398 if (end != null) {
399 if (start < 0) {
400 if (end <= start) return new EmptyList<E>();
401 } else {
402 if (end >= 0 && end <= start) return new EmptyList<E>();
403 }
404 }
405 return new ReversedListView(_list, start, end);
406 }
407 } 303 }
408
409
410 /**
411 * A fixed-length view of a sub-range of a [List].
412 */
413 class ListView<E> extends SubListView<E> {
414
415 ListView(List<E> list, int start, int end) : super(list, start, end);
416
417 E operator[](int index) {
418 int start = _absoluteIndex(_start);
419 int end = _absoluteIndex(_end);
420 int length = end - start;
421 if (index < 0 || index >= length) {
422 throw new RangeError.range(index, 0, length);
423 }
424 return _list[start + index];
425 }
426
427 List<E> skip(int count) {
428 if (count is! int || count < 0) {
429 throw new ArgumentError(count);
430 }
431 if (_start == null) {
432 return new EmptyList<E>();
433 }
434 int newStart = _start + count;
435 if (_start < 0 && newStart >= 0) {
436 return new EmptyList<E>();
437 }
438 return _createListView(newStart, _end);
439 }
440
441 List<E> take(int count) {
442 if (count is! int || count < 0) {
443 throw new ArgumentError(count);
444 }
445 if (_start == null) {
446 return new EmptyList<E>();
447 }
448 int newEnd = _start + count;
449 if (_start < 0 && newEnd >= 0) {
450 newEnd = null;
451 }
452 return _createListView(_start, newEnd);
453 }
454
455 List<E> get reversed => new ReversedListView(_list, _start, _end);
456 }
457
458 /**
459 * Reversed view of a [List], or a slice of a list.
460 *
461 * The view is fixed-length and becomes invalid if the underlying
462 * list changes its length below the slice used by this reversed list.
463 *
464 * Start index and end index can be either positive, negative or null.
465 * Positive means an index relative to the start of the list,
466 * negative means an index relative to the end of the list, and null
467 * means at the end of the list (since there is no -0 integer).
468 */
469 class ReversedListView<E> extends SubListView<E> {
470
471 ReversedListView(List<E> list, int start, int end)
472 : super(list, start, end);
473
474 E operator[](int index) {
475 int start = _absoluteIndex(_start);
476 int end = _absoluteIndex(_end);
477 int length = end - start;
478 if (index < 0 || index >= length) {
479 throw new RangeError.range(index, 0, length);
480 }
481 return _list[end - index - 1];
482 }
483
484 List<E> skip(int count) {
485 if (count is! int || count < 0) {
486 throw new ArgumentError(count);
487 }
488 if (_end == null) {
489 return _createReversedListView(_start, -count);
490 }
491 int newEnd = _end - count;
492 if (_end >= 0 && newEnd < 0) {
493 return new EmptyList<E>();
494 }
495 return _createReversedListView(_start, newEnd);
496 }
497
498 List<E> take(int count) {
499 if (count is! int || count < 0) {
500 throw new ArgumentError(count);
501 }
502 int newStart;
503 if (_end == null) {
504 newStart = -count;
505 } else {
506 newStart = _end - count;
507 if (_end >= 0 && newStart < 0) {
508 return new EmptyList<E>();
509 }
510 }
511 return _createReversedListView(newStart, _end);
512 }
513
514 Iterator<E> get iterator => new ReverseListIterator<E>(
515 _list, _absoluteIndex(_start), _absoluteIndex(_end));
516
517 List<E> get reversed {
518 return new ListView(_list, _start, _end);
519 }
520 }
521
522 /**
523 * An [Iterator] over a slice of a list that access elements in reverse order.
524 */
525 class ReverseListIterator<E> implements Iterator<E> {
526 final List<E> _list;
527 final int _start;
528 final int _originalLength;
529 int _index;
530 E _current;
531
532 ReverseListIterator(List<E> list, int start, int end)
533 : _list = list,
534 _start = start,
535 _index = end,
536 _originalLength = list.length;
537
538 bool moveNext() {
539 if (_list.length != _originalLength) {
540 throw new ConcurrentModificationError(_list);
541 }
542 if (_index <= _start) return false;
543 _index -= 1;
544 _current = _list[_index];
545 return true;
546 }
547
548 E get current => _current;
549 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698