| OLD | NEW |
| 1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2011, 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 class ListFactory<T> { | 5 class ListFactory<E> { |
| 6 | 6 |
| 7 factory List.from(Iterable<T> other) { | 7 factory List.from(Iterable<E> other) { |
| 8 GrowableObjectArray<T> list = new GrowableObjectArray<T>(); | 8 GrowableObjectArray<E> list = new GrowableObjectArray<E>(); |
| 9 for (final e in other) { | 9 for (final e in other) { |
| 10 list.add(e); | 10 list.add(e); |
| 11 } | 11 } |
| 12 return list; | 12 return list; |
| 13 } | 13 } |
| 14 | 14 |
| 15 factory List([int length = null]) { | 15 factory List([int length = null]) { |
| 16 if (length === null) { | 16 if (length === null) { |
| 17 return new GrowableObjectArray<T>(); | 17 return new GrowableObjectArray<E>(); |
| 18 } else { | 18 } else { |
| 19 return new ObjectArray<T>(length); | 19 return new ObjectArray<E>(length); |
| 20 } | 20 } |
| 21 } | 21 } |
| 22 } | 22 } |
| 23 | 23 |
| 24 // TODO(srdjan): Use shared array implementation. | 24 // TODO(srdjan): Use shared array implementation. |
| 25 class ObjectArray<T> implements List<T> { | 25 class ObjectArray<E> implements List<E> { |
| 26 | 26 |
| 27 factory ObjectArray(int length) native "ObjectArray_allocate"; | 27 factory ObjectArray(int length) native "ObjectArray_allocate"; |
| 28 | 28 |
| 29 T operator [](int index) native "ObjectArray_getIndexed"; | 29 E operator [](int index) native "ObjectArray_getIndexed"; |
| 30 | 30 |
| 31 void operator []=(int index, T value) native "ObjectArray_setIndexed"; | 31 void operator []=(int index, E value) native "ObjectArray_setIndexed"; |
| 32 | 32 |
| 33 String toString() { | 33 String toString() { |
| 34 return Arrays.asString(this); | 34 return Arrays.asString(this); |
| 35 } | 35 } |
| 36 | 36 |
| 37 int get length() native "ObjectArray_getLength"; | 37 int get length() native "ObjectArray_getLength"; |
| 38 | 38 |
| 39 void copyFrom(List src, int srcStart, int dstStart, int count) { | 39 void copyFrom(List src, int srcStart, int dstStart, int count) { |
| 40 if (src is ObjectArray) { | 40 if (src is ObjectArray) { |
| 41 _copyFromObjectArray(src, srcStart, dstStart, count); | 41 _copyFromObjectArray(src, srcStart, dstStart, count); |
| 42 } else { | 42 } else { |
| 43 Arrays.copy(src, srcStart, this, dstStart, count); | 43 Arrays.copy(src, srcStart, this, dstStart, count); |
| 44 } | 44 } |
| 45 } | 45 } |
| 46 | 46 |
| 47 void _copyFromObjectArray(ObjectArray src, | 47 void _copyFromObjectArray(ObjectArray src, |
| 48 int srcStart, | 48 int srcStart, |
| 49 int dstStart, | 49 int dstStart, |
| 50 int count) | 50 int count) |
| 51 native "ObjectArray_copyFromObjectArray"; | 51 native "ObjectArray_copyFromObjectArray"; |
| 52 | 52 |
| 53 void setRange(int start, int length, List<T> from, [int startFrom = 0]) { | 53 void setRange(int start, int length, List<E> from, [int startFrom = 0]) { |
| 54 if (length < 0) { | 54 if (length < 0) { |
| 55 throw new IllegalArgumentException("negative length $length"); | 55 throw new IllegalArgumentException("negative length $length"); |
| 56 } | 56 } |
| 57 copyFrom(from, startFrom, start, length); | 57 copyFrom(from, startFrom, start, length); |
| 58 } | 58 } |
| 59 | 59 |
| 60 void removeRange(int start, int length) { | 60 void removeRange(int start, int length) { |
| 61 throw const UnsupportedOperationException( | 61 throw const UnsupportedOperationException( |
| 62 "Cannot remove range of a non-extendable array"); | 62 "Cannot remove range of a non-extendable array"); |
| 63 } | 63 } |
| 64 | 64 |
| 65 void insertRange(int start, int length, [T initialValue = null]) { | 65 void insertRange(int start, int length, [E initialValue = null]) { |
| 66 throw const UnsupportedOperationException( | 66 throw const UnsupportedOperationException( |
| 67 "Cannot insert range in a non-extendable array"); | 67 "Cannot insert range in a non-extendable array"); |
| 68 } | 68 } |
| 69 | 69 |
| 70 List<T> getRange(int start, int length) { | 70 List<E> getRange(int start, int length) { |
| 71 if (length == 0) return []; | 71 if (length == 0) return []; |
| 72 Arrays.rangeCheck(this, start, length); | 72 Arrays.rangeCheck(this, start, length); |
| 73 List list = new List<T>(); | 73 List list = new List<E>(); |
| 74 list.length = length; | 74 list.length = length; |
| 75 Arrays.copy(this, start, list, 0, length); | 75 Arrays.copy(this, start, list, 0, length); |
| 76 return list; | 76 return list; |
| 77 } | 77 } |
| 78 | 78 |
| 79 /** | 79 /** |
| 80 * Collection interface. | 80 * Collection interface. |
| 81 */ | 81 */ |
| 82 | 82 |
| 83 void forEach(f(T element)) { | 83 void forEach(f(E element)) { |
| 84 Collections.forEach(this, f); | 84 Collections.forEach(this, f); |
| 85 } | 85 } |
| 86 | 86 |
| 87 Collection<T> filter(bool f(T element)) { | 87 Collection<E> filter(bool f(E element)) { |
| 88 return Collections.filter(this, new GrowableObjectArray<T>(), f); | 88 return Collections.filter(this, new GrowableObjectArray<E>(), f); |
| 89 } | 89 } |
| 90 | 90 |
| 91 bool every(bool f(T element)) { | 91 bool every(bool f(E element)) { |
| 92 return Collections.every(this, f); | 92 return Collections.every(this, f); |
| 93 } | 93 } |
| 94 | 94 |
| 95 bool some(bool f(T element)) { | 95 bool some(bool f(E element)) { |
| 96 return Collections.some(this, f); | 96 return Collections.some(this, f); |
| 97 } | 97 } |
| 98 | 98 |
| 99 bool isEmpty() { | 99 bool isEmpty() { |
| 100 return this.length === 0; | 100 return this.length === 0; |
| 101 } | 101 } |
| 102 | 102 |
| 103 void sort(int compare(T a, T b)) { | 103 void sort(int compare(E a, E b)) { |
| 104 DualPivotQuicksort.sort(this, compare); | 104 DualPivotQuicksort.sort(this, compare); |
| 105 } | 105 } |
| 106 | 106 |
| 107 int indexOf(T element, [int start = 0]) { | 107 int indexOf(E element, [int start = 0]) { |
| 108 return Arrays.indexOf(this, element, start, this.length); | 108 return Arrays.indexOf(this, element, start, this.length); |
| 109 } | 109 } |
| 110 | 110 |
| 111 int lastIndexOf(T element, [int start = null]) { | 111 int lastIndexOf(E element, [int start = null]) { |
| 112 if (start === null) start = length - 1; | 112 if (start === null) start = length - 1; |
| 113 return Arrays.lastIndexOf(this, element, start); | 113 return Arrays.lastIndexOf(this, element, start); |
| 114 } | 114 } |
| 115 | 115 |
| 116 Iterator<T> iterator() { | 116 Iterator<E> iterator() { |
| 117 return new FixedSizeArrayIterator<T>(this); | 117 return new FixedSizeArrayIterator<E>(this); |
| 118 } | 118 } |
| 119 | 119 |
| 120 void add(T element) { | 120 void add(E element) { |
| 121 throw const UnsupportedOperationException( | 121 throw const UnsupportedOperationException( |
| 122 "Cannot add to a non-extendable array"); | 122 "Cannot add to a non-extendable array"); |
| 123 } | 123 } |
| 124 | 124 |
| 125 void addLast(T element) { | 125 void addLast(E element) { |
| 126 add(element); | 126 add(element); |
| 127 } | 127 } |
| 128 | 128 |
| 129 void addAll(Collection<T> elements) { | 129 void addAll(Collection<E> elements) { |
| 130 throw const UnsupportedOperationException( | 130 throw const UnsupportedOperationException( |
| 131 "Cannot add to a non-extendable array"); | 131 "Cannot add to a non-extendable array"); |
| 132 } | 132 } |
| 133 | 133 |
| 134 void clear() { | 134 void clear() { |
| 135 throw const UnsupportedOperationException( | 135 throw const UnsupportedOperationException( |
| 136 "Cannot clear a non-extendable array"); | 136 "Cannot clear a non-extendable array"); |
| 137 } | 137 } |
| 138 | 138 |
| 139 void set length(int length) { | 139 void set length(int length) { |
| 140 throw const UnsupportedOperationException( | 140 throw const UnsupportedOperationException( |
| 141 "Cannot change the length of a non-extendable array"); | 141 "Cannot change the length of a non-extendable array"); |
| 142 } | 142 } |
| 143 | 143 |
| 144 T removeLast() { | 144 E removeLast() { |
| 145 throw const UnsupportedOperationException( | 145 throw const UnsupportedOperationException( |
| 146 "Cannot remove in a non-extendable array"); | 146 "Cannot remove in a non-extendable array"); |
| 147 } | 147 } |
| 148 | 148 |
| 149 T last() { | 149 E last() { |
| 150 return this[length - 1]; | 150 return this[length - 1]; |
| 151 } | 151 } |
| 152 } | 152 } |
| 153 | 153 |
| 154 | 154 |
| 155 // This is essentially the same class as ObjectArray, but it does not | 155 // This is essentially the same class as ObjectArray, but it does not |
| 156 // permit any modification of array elements from Dart code. We use | 156 // permit any modification of array elements from Dart code. We use |
| 157 // this class for arrays constructed from Dart array literals. | 157 // this class for arrays constructed from Dart array literals. |
| 158 // TODO(hausner): We should consider the trade-offs between two | 158 // TODO(hausner): We should consider the trade-offs between two |
| 159 // classes (and inline cache misses) versus a field in the native | 159 // classes (and inline cache misses) versus a field in the native |
| 160 // implementation (checks when modifying). We should keep watching | 160 // implementation (checks when modifying). We should keep watching |
| 161 // the inline cache misses. | 161 // the inline cache misses. |
| 162 class ImmutableArray<T> implements List<T> { | 162 class ImmutableArray<E> implements List<E> { |
| 163 | 163 |
| 164 factory ImmutableArray._uninstantiable() { | 164 factory ImmutableArray._uninstantiable() { |
| 165 throw const UnsupportedOperationException( | 165 throw const UnsupportedOperationException( |
| 166 "ImmutableArray can only be allocated by the VM"); | 166 "ImmutableArray can only be allocated by the VM"); |
| 167 } | 167 } |
| 168 | 168 |
| 169 T operator [](int index) native "ObjectArray_getIndexed"; | 169 E operator [](int index) native "ObjectArray_getIndexed"; |
| 170 | 170 |
| 171 void operator []=(int index, T value) { | 171 void operator []=(int index, E value) { |
| 172 throw const UnsupportedOperationException( | 172 throw const UnsupportedOperationException( |
| 173 "Cannot modify an immutable array"); | 173 "Cannot modify an immutable array"); |
| 174 } | 174 } |
| 175 | 175 |
| 176 int get length() native "ObjectArray_getLength"; | 176 int get length() native "ObjectArray_getLength"; |
| 177 | 177 |
| 178 void copyFrom(List src, int srcStart, int dstStart, int count) { | 178 void copyFrom(List src, int srcStart, int dstStart, int count) { |
| 179 throw const UnsupportedOperationException( | 179 throw const UnsupportedOperationException( |
| 180 "Cannot modify an immutable array"); | 180 "Cannot modify an immutable array"); |
| 181 } | 181 } |
| 182 | 182 |
| 183 void setRange(int start, int length, List<T> from, [int startFrom = 0]) { | 183 void setRange(int start, int length, List<E> from, [int startFrom = 0]) { |
| 184 throw const UnsupportedOperationException( | 184 throw const UnsupportedOperationException( |
| 185 "Cannot modify an immutable array"); | 185 "Cannot modify an immutable array"); |
| 186 } | 186 } |
| 187 | 187 |
| 188 void removeRange(int start, int length) { | 188 void removeRange(int start, int length) { |
| 189 throw const UnsupportedOperationException( | 189 throw const UnsupportedOperationException( |
| 190 "Cannot remove range of an immutable array"); | 190 "Cannot remove range of an immutable array"); |
| 191 } | 191 } |
| 192 | 192 |
| 193 void insertRange(int start, int length, [T initialValue = null]) { | 193 void insertRange(int start, int length, [E initialValue = null]) { |
| 194 throw const UnsupportedOperationException( | 194 throw const UnsupportedOperationException( |
| 195 "Cannot insert range in an immutable array"); | 195 "Cannot insert range in an immutable array"); |
| 196 } | 196 } |
| 197 | 197 |
| 198 List<T> getRange(int start, int length) { | 198 List<E> getRange(int start, int length) { |
| 199 if (length == 0) return []; | 199 if (length == 0) return []; |
| 200 Arrays.rangeCheck(this, start, length); | 200 Arrays.rangeCheck(this, start, length); |
| 201 List list = new List<T>(); | 201 List list = new List<E>(); |
| 202 list.length = length; | 202 list.length = length; |
| 203 Arrays.copy(this, start, list, 0, length); | 203 Arrays.copy(this, start, list, 0, length); |
| 204 return list; | 204 return list; |
| 205 } | 205 } |
| 206 | 206 |
| 207 /** | 207 /** |
| 208 * Collection interface. | 208 * Collection interface. |
| 209 */ | 209 */ |
| 210 | 210 |
| 211 void forEach(f(T element)) { | 211 void forEach(f(E element)) { |
| 212 Collections.forEach(this, f); | 212 Collections.forEach(this, f); |
| 213 } | 213 } |
| 214 | 214 |
| 215 Collection<T> filter(bool f(T element)) { | 215 Collection<E> filter(bool f(E element)) { |
| 216 return Collections.filter(this, new GrowableObjectArray<T>(), f); | 216 return Collections.filter(this, new GrowableObjectArray<E>(), f); |
| 217 } | 217 } |
| 218 | 218 |
| 219 bool every(bool f(T element)) { | 219 bool every(bool f(E element)) { |
| 220 return Collections.every(this, f); | 220 return Collections.every(this, f); |
| 221 } | 221 } |
| 222 | 222 |
| 223 bool some(bool f(T element)) { | 223 bool some(bool f(E element)) { |
| 224 return Collections.some(this, f); | 224 return Collections.some(this, f); |
| 225 } | 225 } |
| 226 | 226 |
| 227 bool isEmpty() { | 227 bool isEmpty() { |
| 228 return this.length === 0; | 228 return this.length === 0; |
| 229 } | 229 } |
| 230 | 230 |
| 231 void sort(int compare(T a, T b)) { | 231 void sort(int compare(E a, E b)) { |
| 232 throw const UnsupportedOperationException( | 232 throw const UnsupportedOperationException( |
| 233 "Cannot modify an immutable array"); | 233 "Cannot modify an immutable array"); |
| 234 } | 234 } |
| 235 | 235 |
| 236 String toString() { | 236 String toString() { |
| 237 return "ImmutableArray"; | 237 return "ImmutableArray"; |
| 238 } | 238 } |
| 239 | 239 |
| 240 int indexOf(T element, [int start = 0]) { | 240 int indexOf(E element, [int start = 0]) { |
| 241 return Arrays.indexOf(this, element, start, this.length); | 241 return Arrays.indexOf(this, element, start, this.length); |
| 242 } | 242 } |
| 243 | 243 |
| 244 int lastIndexOf(T element, [int start = null]) { | 244 int lastIndexOf(E element, [int start = null]) { |
| 245 if (start === null) start = length - 1; | 245 if (start === null) start = length - 1; |
| 246 return Arrays.lastIndexOf(this, element, start); | 246 return Arrays.lastIndexOf(this, element, start); |
| 247 } | 247 } |
| 248 | 248 |
| 249 Iterator<T> iterator() { | 249 Iterator<E> iterator() { |
| 250 return new FixedSizeArrayIterator<T>(this); | 250 return new FixedSizeArrayIterator<E>(this); |
| 251 } | 251 } |
| 252 | 252 |
| 253 void add(T element) { | 253 void add(E element) { |
| 254 throw const UnsupportedOperationException( | 254 throw const UnsupportedOperationException( |
| 255 "Cannot add to an immutable array"); | 255 "Cannot add to an immutable array"); |
| 256 } | 256 } |
| 257 | 257 |
| 258 void addLast(T element) { | 258 void addLast(E element) { |
| 259 add(element); | 259 add(element); |
| 260 } | 260 } |
| 261 | 261 |
| 262 void addAll(Collection<T> elements) { | 262 void addAll(Collection<E> elements) { |
| 263 throw const UnsupportedOperationException( | 263 throw const UnsupportedOperationException( |
| 264 "Cannot add to an immutable array"); | 264 "Cannot add to an immutable array"); |
| 265 } | 265 } |
| 266 | 266 |
| 267 void clear() { | 267 void clear() { |
| 268 throw const UnsupportedOperationException( | 268 throw const UnsupportedOperationException( |
| 269 "Cannot clear an immutable array"); | 269 "Cannot clear an immutable array"); |
| 270 } | 270 } |
| 271 | 271 |
| 272 void set length(int length) { | 272 void set length(int length) { |
| 273 throw const UnsupportedOperationException( | 273 throw const UnsupportedOperationException( |
| 274 "Cannot change the length of an immutable array"); | 274 "Cannot change the length of an immutable array"); |
| 275 } | 275 } |
| 276 | 276 |
| 277 T removeLast() { | 277 E removeLast() { |
| 278 throw const UnsupportedOperationException( | 278 throw const UnsupportedOperationException( |
| 279 "Cannot remove in a non-extendable array"); | 279 "Cannot remove in a non-extendable array"); |
| 280 } | 280 } |
| 281 | 281 |
| 282 T last() { | 282 E last() { |
| 283 return this[length - 1]; | 283 return this[length - 1]; |
| 284 } | 284 } |
| 285 } | 285 } |
| 286 | 286 |
| 287 | 287 |
| 288 // Iterator for arrays with fixed size. | 288 // Iterator for arrays with fixed size. |
| 289 class FixedSizeArrayIterator<T> implements Iterator<T> { | 289 class FixedSizeArrayIterator<E> implements Iterator<E> { |
| 290 FixedSizeArrayIterator(List array) | 290 FixedSizeArrayIterator(List array) |
| 291 : _array = array, _length = array.length, _pos = 0 { | 291 : _array = array, _length = array.length, _pos = 0 { |
| 292 assert(array is ObjectArray || array is ImmutableArray); | 292 assert(array is ObjectArray || array is ImmutableArray); |
| 293 } | 293 } |
| 294 | 294 |
| 295 bool hasNext() { | 295 bool hasNext() { |
| 296 return _length > _pos; | 296 return _length > _pos; |
| 297 } | 297 } |
| 298 | 298 |
| 299 T next() { | 299 E next() { |
| 300 if (!hasNext()) { | 300 if (!hasNext()) { |
| 301 throw const NoMoreElementsException(); | 301 throw const NoMoreElementsException(); |
| 302 } | 302 } |
| 303 return _array[_pos++]; | 303 return _array[_pos++]; |
| 304 } | 304 } |
| 305 | 305 |
| 306 final List<T> _array; | 306 final List<E> _array; |
| 307 final int _length; // Cache array length for faster access. | 307 final int _length; // Cache array length for faster access. |
| 308 int _pos; | 308 int _pos; |
| 309 } | 309 } |
| OLD | NEW |