| OLD | NEW |
| (Empty) |
| 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 | |
| 3 // BSD-style license that can be found in the LICENSE file. | |
| 4 | |
| 5 class GrowableObjectArray<T> implements Array<T> { | |
| 6 ObjectArray<T> backingArray; | |
| 7 | |
| 8 void copyFrom(List<Object> src, int srcStart, int dstStart, int count) { | |
| 9 Arrays.copy(src, srcStart, this, dstStart, count); | |
| 10 } | |
| 11 | |
| 12 void setRange(int start, int length, List<T> from, [int startFrom = 0]) { | |
| 13 if (length < 0) { | |
| 14 throw new IllegalArgumentException("negative length $length"); | |
| 15 } | |
| 16 Arrays.copy(from, startFrom, this, start, length); | |
| 17 } | |
| 18 | |
| 19 void removeRange(int start, int length) { | |
| 20 if (length == 0) { | |
| 21 return; | |
| 22 } | |
| 23 if (length < 0) { | |
| 24 throw new IllegalArgumentException("negative length $length"); | |
| 25 } | |
| 26 if (start < 0 || start >= this.length) { | |
| 27 throw new IndexOutOfRangeException(start); | |
| 28 } | |
| 29 if (start + length > this.length) { | |
| 30 throw new IndexOutOfRangeException(start + length); | |
| 31 } | |
| 32 Arrays.copy(backingArray, | |
| 33 start + length, | |
| 34 backingArray, | |
| 35 start, | |
| 36 this.length - length - start); | |
| 37 this.length = this.length - length; | |
| 38 } | |
| 39 | |
| 40 void insertRange(int start, int length, [T initialValue = null]) { | |
| 41 if (length == 0) { | |
| 42 return; | |
| 43 } | |
| 44 if (length < 0) { | |
| 45 throw new IllegalArgumentException("negative length $length"); | |
| 46 } | |
| 47 if (start < 0 || start > this.length) { | |
| 48 throw new IndexOutOfRangeException(start); | |
| 49 } | |
| 50 if (this.length + length >= backingArray.length) { | |
| 51 grow(backingArray.length + length); | |
| 52 } | |
| 53 Arrays.copy(backingArray, | |
| 54 start, | |
| 55 backingArray, | |
| 56 start + length, | |
| 57 this.length - start); | |
| 58 if (initialValue !== null) { | |
| 59 for (int i = start; i < start + length; i++) { | |
| 60 backingArray[i] = initialValue; | |
| 61 } | |
| 62 } | |
| 63 this.length = this.length + length; | |
| 64 } | |
| 65 | |
| 66 List<T> getRange(int start, int length) { | |
| 67 if (length == 0) return []; | |
| 68 Arrays.rangeCheck(this, start, length); | |
| 69 return new List<T>.fromList(this, start, start + length); | |
| 70 } | |
| 71 | |
| 72 // The length of this growable array. It is always less than the | |
| 73 // length of the backing array. | |
| 74 int _length; | |
| 75 // Constant used by indexOf and lastIndexOf when the element given | |
| 76 // is not in the array. | |
| 77 static final int ABSENT = -1; | |
| 78 | |
| 79 GrowableObjectArray() | |
| 80 : _length = 0, backingArray = new ObjectArray<T>(4) {} | |
| 81 | |
| 82 GrowableObjectArray.withCapacity(int capacity) { | |
| 83 _length = 0; | |
| 84 if (capacity <= 0) { | |
| 85 capacity = 4; | |
| 86 } | |
| 87 backingArray = new ObjectArray<T>(capacity); | |
| 88 } | |
| 89 | |
| 90 GrowableObjectArray._usingArray(Array<T> array) { | |
| 91 backingArray = array; | |
| 92 _length = array.length; | |
| 93 if (_length == 0) { | |
| 94 grow(4); | |
| 95 } | |
| 96 } | |
| 97 | |
| 98 factory GrowableObjectArray.from(Collection<T> other) { | |
| 99 Array result = new GrowableObjectArray(); | |
| 100 result.addAll(other); | |
| 101 return result; | |
| 102 } | |
| 103 | |
| 104 int get length() { | |
| 105 return _length; | |
| 106 } | |
| 107 | |
| 108 void set length(int new_length) { | |
| 109 if (new_length >= backingArray.length) { | |
| 110 grow(new_length); | |
| 111 } else { | |
| 112 for (int i = new_length; i < _length; i++) { | |
| 113 backingArray[i] = null; | |
| 114 } | |
| 115 } | |
| 116 _length = new_length; | |
| 117 } | |
| 118 | |
| 119 T operator [](int index) { | |
| 120 if (index >= _length) { | |
| 121 throw new IndexOutOfRangeException(index); | |
| 122 } | |
| 123 return backingArray[index]; | |
| 124 } | |
| 125 | |
| 126 void operator []=(int index, T value) { | |
| 127 if (index >= _length) { | |
| 128 throw new IndexOutOfRangeException(index); | |
| 129 } | |
| 130 backingArray[index] = value; | |
| 131 } | |
| 132 | |
| 133 void grow(int capacity) { | |
| 134 ObjectArray<T> newArray = new ObjectArray<T>(capacity); | |
| 135 int length = backingArray.length; | |
| 136 for (int i = 0; i < length; i++) { | |
| 137 newArray[i] = backingArray[i]; | |
| 138 } | |
| 139 backingArray = newArray; | |
| 140 } | |
| 141 | |
| 142 int add(T value) { | |
| 143 if (_length == backingArray.length) { | |
| 144 grow(_length * 2); | |
| 145 } | |
| 146 backingArray[_length] = value; | |
| 147 return ++_length; | |
| 148 } | |
| 149 | |
| 150 void addLast(T element) { | |
| 151 add(element); | |
| 152 } | |
| 153 | |
| 154 void addAll(Collection<T> collection) { | |
| 155 for (T elem in collection) { | |
| 156 add(elem); | |
| 157 } | |
| 158 } | |
| 159 | |
| 160 T removeLast() { | |
| 161 _length--; | |
| 162 return backingArray[_length]; | |
| 163 } | |
| 164 | |
| 165 T last() { | |
| 166 if (_length === 0) { | |
| 167 throw new IndexOutOfRangeException(-1); | |
| 168 } | |
| 169 return backingArray[_length - 1]; | |
| 170 } | |
| 171 | |
| 172 int indexOf(T element, int startIndex) { | |
| 173 return Arrays.indexOf(backingArray, element, startIndex, _length); | |
| 174 } | |
| 175 | |
| 176 int lastIndexOf(T element, int startIndex) { | |
| 177 return Arrays.lastIndexOf(backingArray, element, startIndex); | |
| 178 } | |
| 179 | |
| 180 /** | |
| 181 * Collection interface. | |
| 182 */ | |
| 183 | |
| 184 void forEach(f(T element)) { | |
| 185 // TODO(srdjan): Use Collections.forEach(this, f); | |
| 186 // Using backingArray directly improves DeltaBlue performance by 25%. | |
| 187 for (int i = 0; i < _length; i++) { | |
| 188 f(backingArray[i]); | |
| 189 } | |
| 190 } | |
| 191 | |
| 192 Collection<T> filter(bool f(T element)) { | |
| 193 return Collections.filter(this, new GrowableObjectArray<T>(), f); | |
| 194 } | |
| 195 | |
| 196 bool every(bool f(T element)) { | |
| 197 return Collections.every(this, f); | |
| 198 } | |
| 199 | |
| 200 bool some(bool f(T element)) { | |
| 201 return Collections.some(this, f); | |
| 202 } | |
| 203 | |
| 204 bool isEmpty() { | |
| 205 return this.length === 0; | |
| 206 } | |
| 207 | |
| 208 void clear() { | |
| 209 this.length = 0; | |
| 210 } | |
| 211 | |
| 212 void sort(int compare(T a, T b)) { | |
| 213 DualPivotQuicksort.sort(this, compare); | |
| 214 } | |
| 215 | |
| 216 Iterator<T> iterator() { | |
| 217 return new VariableSizeArrayIterator<T>(this); | |
| 218 } | |
| 219 } | |
| 220 | |
| 221 | |
| 222 // Iterator for arrays with variable size. | |
| 223 class VariableSizeArrayIterator<T> implements Iterator<T> { | |
| 224 VariableSizeArrayIterator(GrowableObjectArray<T> array) | |
| 225 : _array = array, _pos = 0 { | |
| 226 } | |
| 227 | |
| 228 bool hasNext() { | |
| 229 return _array._length > _pos; | |
| 230 } | |
| 231 | |
| 232 T next() { | |
| 233 if (!hasNext()) { | |
| 234 throw const NoMoreElementsException(); | |
| 235 } | |
| 236 return _array[_pos++]; | |
| 237 } | |
| 238 | |
| 239 final GrowableObjectArray<T> _array; | |
| 240 int _pos; | |
| 241 } | |
| 242 | |
| OLD | NEW |