Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 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 | |
| 3 // BSD-style license that can be found in the LICENSE file. | |
| 4 | |
| 5 part of dart.collection.dev; | |
| 6 | |
| 7 /** | |
| 8 * Skeleton class for an unmodifiable [List]. | |
|
floitsch
2013/01/17 18:31:47
Changed this comment. Otherwise identical to old c
| |
| 9 */ | |
| 10 abstract class NonExtensibleListMixin<E> | |
| 11 extends Iterable<E> implements List<E> { | |
| 12 | |
| 13 Iterator<E> get iterator => new ListIterator(this); | |
| 14 | |
| 15 void forEach(f(E element)) { | |
| 16 for (int i = 0; i < this.length; i++) f(this[i]); | |
| 17 } | |
| 18 | |
| 19 bool contains(E value) { | |
| 20 for (int i = 0; i < length; i++) { | |
| 21 if (this[i] == value) return true; | |
| 22 } | |
| 23 return false; | |
| 24 } | |
| 25 | |
| 26 reduce(initialValue, combine(previousValue, E element)) { | |
| 27 var value = initialValue; | |
| 28 for (int i = 0; i < this.length; i++) { | |
| 29 value = combine(value, this[i]); | |
| 30 } | |
| 31 return value; | |
| 32 } | |
| 33 | |
| 34 bool every(bool f(E element)) { | |
| 35 for (int i = 0; i < this.length; i++) { | |
| 36 if (!f(this[i])) return false; | |
| 37 } | |
| 38 return true; | |
| 39 } | |
| 40 | |
| 41 bool any(bool f(E element)) { | |
| 42 for (int i = 0; i < this.length; i++) { | |
| 43 if (f(this[i])) return true; | |
| 44 } | |
| 45 return false; | |
| 46 } | |
| 47 | |
| 48 bool get isEmpty { | |
| 49 return this.length == 0; | |
| 50 } | |
| 51 | |
| 52 E elementAt(int index) { | |
| 53 return this[index]; | |
| 54 } | |
| 55 | |
| 56 int indexOf(E value, [int start = 0]) { | |
| 57 for (int i = start; i < length; i++) { | |
| 58 if (this[i] == value) return i; | |
| 59 } | |
| 60 return -1; | |
| 61 } | |
| 62 | |
| 63 int lastIndexOf(E value, [int start]) { | |
| 64 if (start == null) start = length - 1; | |
| 65 for (int i = start; i >= 0; i--) { | |
| 66 if (this[i] == value) return i; | |
| 67 } | |
| 68 return -1; | |
| 69 } | |
| 70 | |
| 71 E get first { | |
| 72 if (length > 0) return this[0]; | |
| 73 throw new StateError("No elements"); | |
| 74 } | |
| 75 | |
| 76 E get last { | |
| 77 if (length > 0) return this[length - 1]; | |
| 78 throw new StateError("No elements"); | |
| 79 } | |
| 80 | |
| 81 E get single { | |
| 82 if (length == 1) return this[0]; | |
| 83 if (length == 0) throw new StateError("No elements"); | |
| 84 throw new StateError("More than one element"); | |
| 85 } | |
| 86 | |
| 87 List<E> getRange(int start, int length) { | |
| 88 List<E> result = <E>[]; | |
| 89 for (int i = 0; i < length; i++) { | |
| 90 result.add(this[start + i]); | |
| 91 } | |
| 92 return result; | |
| 93 } | |
| 94 | |
| 95 void operator []=(int index, E value) { | |
| 96 throw new UnsupportedError( | |
| 97 "Cannot modify an unmodifiable list"); | |
| 98 } | |
| 99 | |
| 100 void set length(int newLength) { | |
| 101 throw new UnsupportedError( | |
| 102 "Cannot change the length of an unmodifiable list"); | |
| 103 } | |
| 104 | |
| 105 void add(E value) { | |
| 106 throw new UnsupportedError( | |
| 107 "Cannot add to an unmodifiable list"); | |
| 108 } | |
| 109 | |
| 110 void addLast(E value) { | |
| 111 throw new UnsupportedError( | |
| 112 "Cannot add to an unmodifiable list"); | |
| 113 } | |
| 114 | |
| 115 void addAll(Iterable<E> iterable) { | |
| 116 throw new UnsupportedError( | |
| 117 "Cannot add to an unmodifiable list"); | |
| 118 } | |
| 119 | |
| 120 void sort([Comparator<E> compare]) { | |
| 121 throw new UnsupportedError( | |
| 122 "Cannot modify an unmodifiable list"); | |
| 123 } | |
| 124 | |
| 125 void clear() { | |
| 126 throw new UnsupportedError( | |
| 127 "Cannot clear an unmodifiable list"); | |
| 128 } | |
| 129 | |
| 130 E removeAt(int index) { | |
| 131 throw new UnsupportedError( | |
| 132 "Cannot remove in an unmodifiable list"); | |
| 133 } | |
| 134 | |
| 135 E removeLast() { | |
| 136 throw new UnsupportedError( | |
| 137 "Cannot remove in an unmodifiable list"); | |
| 138 } | |
| 139 | |
| 140 void setRange(int start, int length, List<E> from, [int startFrom]) { | |
| 141 throw new UnsupportedError( | |
| 142 "Cannot modify an unmodifiable list"); | |
| 143 } | |
| 144 | |
| 145 void removeRange(int start, int length) { | |
| 146 throw new UnsupportedError( | |
| 147 "Cannot remove in an unmodifiable list"); | |
| 148 } | |
| 149 | |
| 150 void insertRange(int start, int length, [E initialValue]) { | |
| 151 throw new UnsupportedError( | |
| 152 "Cannot insert range in an unmodifiable list"); | |
| 153 } | |
| 154 } | |
| 155 | |
| 156 /** | |
| 157 * Iterates over a [Sequence] in growing index order. | |
|
Lasse Reichstein Nielsen
2013/01/18 11:34:25
Sequence -> List.
floitsch
2013/01/18 17:02:29
Done.
| |
| 158 */ | |
| 159 class ListIterator<E> implements Iterator<E> { | |
| 160 final List<E> _list; | |
| 161 int _position; | |
| 162 E _current; | |
| 163 | |
| 164 ListIterator(this._list) : _position = -1; | |
| 165 | |
| 166 bool moveNext() { | |
| 167 int nextPosition = _position + 1; | |
| 168 if (nextPosition < _list.length) { | |
| 169 _current = _list[nextPosition]; | |
| 170 _position = nextPosition; | |
| 171 return true; | |
| 172 } | |
| 173 _position = _list.length; | |
| 174 _current = null; | |
| 175 return false; | |
| 176 } | |
| 177 | |
| 178 E get current => _current; | |
| 179 } | |
| 180 | |
| 181 class MappedList<S, T> extends NonExtensibleListMixin<T> { | |
| 182 final List<S> _list; | |
| 183 // TODO(ahe): Restore type when feature is implemented in dart2js | |
| 184 // checked mode. http://dartbug.com/7733 | |
| 185 final /* _Transformation<S, T> */ _f; | |
| 186 | |
| 187 MappedList(this._list, T this._f(S element)); | |
| 188 | |
| 189 T operator[](int index) => _f(_list[index]); | |
| 190 int get length => _list.length; | |
| 191 } | |
| 192 | |
| 193 /** | |
| 194 * An immutable view of a [List]. | |
| 195 */ | |
| 196 class ListView<E> extends NonExtensibleListMixin<E> { | |
| 197 final List<E> _list; | |
| 198 final int _offset; | |
| 199 final int _length; | |
| 200 | |
| 201 /** | |
| 202 * If the given length is `null` then the ListView's length is bound by | |
| 203 * the backed [list]. | |
| 204 */ | |
| 205 ListView(List<E> list, this._offset, this._length) : _list = list { | |
| 206 if (_offset is! int || _offset < 0) { | |
| 207 throw new ArgumentError(_offset); | |
| 208 } | |
| 209 if (_length != null && | |
| 210 (_length is! int || _length < 0)) { | |
| 211 throw new ArgumentError(_length); | |
| 212 } | |
| 213 } | |
| 214 | |
| 215 int get length { | |
| 216 int originalLength = _list.length; | |
| 217 int skipLength = originalLength - _offset; | |
| 218 if (skipLength < 0) return 0; | |
| 219 if (_length == null || _length > skipLength) return skipLength; | |
| 220 return _length; | |
| 221 } | |
| 222 | |
| 223 E operator[](int index) { | |
| 224 int skipIndex = index + _offset; | |
| 225 if (index < 0 || | |
| 226 (_length != null && index >= _length) || | |
| 227 index + _offset >= _list.length) { | |
| 228 throw new RangeError.value(index); | |
| 229 } | |
| 230 return _list[index + _offset]; | |
| 231 } | |
| 232 | |
| 233 ListView<E> skip(int skipCount) { | |
| 234 if (skipCount is! int || skipCount < 0) { | |
| 235 throw new ArgumentError(skipCount); | |
| 236 } | |
| 237 return new ListView(_list, _offset + skipCount, _length); | |
| 238 } | |
| 239 | |
| 240 ListView<E> take(int takeCount) { | |
| 241 if (takeCount is! int || takeCount < 0) { | |
| 242 throw new ArgumentError(takeCount); | |
| 243 } | |
| 244 int newLength = takeCount; | |
| 245 if (_length != null && takeCount > _length) newLength = _length; | |
| 246 return new ListView(_list, _offset, newLength); | |
| 247 } | |
| 248 } | |
| OLD | NEW |