Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 // patch classes for Int8List ..... Float64List and ByteData implementations. | 5 // patch classes for Int8List ..... Float64List and ByteData implementations. |
| 6 | 6 |
| 7 import "dart:_internal"; | 7 import "dart:_internal"; |
| 8 import 'dart:math' show Random; | 8 import 'dart:math' show Random; |
| 9 | 9 |
| 10 patch class Int8List { | 10 patch class Int8List { |
| (...skipping 223 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 234 | 234 |
| 235 // Called directly from C code. | 235 // Called directly from C code. |
| 236 factory ByteData._view(TypedData typedData, int offsetInBytes, int length) { | 236 factory ByteData._view(TypedData typedData, int offsetInBytes, int length) { |
| 237 return new _ByteDataView(typedData, offsetInBytes, length); | 237 return new _ByteDataView(typedData, offsetInBytes, length); |
| 238 } | 238 } |
| 239 } | 239 } |
| 240 | 240 |
| 241 | 241 |
| 242 // Based class for _TypedList that provides common methods for implementing | 242 // Based class for _TypedList that provides common methods for implementing |
| 243 // the collection and list interfaces. | 243 // the collection and list interfaces. |
| 244 // TODO(13647): Make this extends ListBase<T> | 244 // This class does not extend ListBase<T> since that would add type arguments |
| 245 // to instances of _TypeListBase. Instead the subclasses use number-type specifi c | |
|
Ivan Posva
2015/01/29 15:03:18
Long line.
Florian Schneider
2015/02/03 08:18:19
Done.
| |
| 246 // mixins (like _IntListMixin, _DoubleListMixin) to implement ListBase<T>. | |
| 245 abstract class _TypedListBase { | 247 abstract class _TypedListBase { |
| 246 | 248 |
| 247 // Method(s) implementing the Collection interface. | 249 // Method(s) implementing the Collection interface. |
| 248 bool contains(element) => IterableMixinWorkaround.contains(this, element); | 250 bool contains(element) { |
| 251 int len = this.length; | |
| 252 for (int i = 0; i < len; ++i) { | |
| 253 if (this[i] == element) return true; | |
| 254 } | |
| 255 return false; | |
| 256 } | |
| 249 | 257 |
| 250 void forEach(void f(element)) { | 258 void forEach(void f(element)) { |
| 251 var len = this.length; | 259 int len = this.length; |
| 252 for (var i = 0; i < len; i++) { | 260 for (int i = 0; i < len; i++) { |
|
Ivan Posva
2015/01/29 15:03:18
Any reason for this change? Generally we tend to u
Florian Schneider
2015/02/03 08:18:19
Done.
| |
| 253 f(this[i]); | 261 f(this[i]); |
| 254 } | 262 } |
| 255 } | 263 } |
| 256 | 264 |
| 257 String join([String separator = ""]) { | 265 String join([String separator = ""]) { |
| 258 return IterableMixinWorkaround.join(this, separator); | 266 StringBuffer buffer = new StringBuffer(); |
| 267 buffer.writeAll(this, separator); | |
| 268 return buffer.toString(); | |
| 259 } | 269 } |
| 260 | 270 |
| 261 dynamic reduce(dynamic combine(value, element)) { | 271 dynamic reduce(dynamic combine(value, element)) { |
| 262 return IterableMixinWorkaround.reduce(this, combine); | 272 int len = this.length; |
| 273 if (len == 0) throw IterableElementError.noElement(); | |
| 274 int i = 0; | |
|
srdjan
2015/01/29 17:29:40
Remove int i = 0;
Florian Schneider
2015/02/03 08:18:19
Done.
| |
| 275 var value = this[0]; | |
| 276 for (var i = 1; i < len; ++i) { | |
| 277 value = combine(value, this[i]); | |
| 278 } | |
| 279 return value; | |
| 263 } | 280 } |
| 264 | 281 |
| 265 dynamic fold(dynamic initialValue, | 282 dynamic fold(dynamic initialValue, |
| 266 dynamic combine(dynamic initialValue, element)) { | 283 dynamic combine(dynamic initialValue, element)) { |
| 267 return IterableMixinWorkaround.fold(this, initialValue, combine); | 284 int len = this.length; |
| 285 for (int i = 0; i < len; ++i) { | |
| 286 initialValue = combine(initialValue, this[i]); | |
| 287 } | |
| 288 return initialValue; | |
| 268 } | 289 } |
| 269 | 290 |
| 270 Iterable map(f(element)) { | 291 Iterable map(f(element)) => new MappedIterable(this, f); |
| 271 return IterableMixinWorkaround.mapList(this, f); | |
| 272 } | |
| 273 | 292 |
| 274 Iterable expand(Iterable f(element)) { | 293 Iterable expand(Iterable f(element)) => new ExpandIterable(this, f); |
| 275 return IterableMixinWorkaround.expand(this, f); | |
| 276 } | |
| 277 | 294 |
| 278 bool every(bool f(element)) { | 295 bool every(bool f(element)) { |
| 279 return IterableMixinWorkaround.every(this, f); | 296 int len = this.length; |
| 297 for (int i = 0; i < len; ++i) { | |
| 298 if (!f(this[i])) return false; | |
| 299 } | |
| 300 return true; | |
| 280 } | 301 } |
| 281 | 302 |
| 282 bool any(bool f(element)) { | 303 bool any(bool f(element)) { |
| 283 return IterableMixinWorkaround.any(this, f); | 304 int len = this.length; |
| 305 for (int i = 0; i < len; ++i) { | |
| 306 if (f(this[i])) return true; | |
| 307 } | |
| 308 return false; | |
| 284 } | 309 } |
| 285 | 310 |
| 286 dynamic firstWhere(bool test(element), {orElse()}) { | 311 dynamic firstWhere(bool test(element), {orElse()}) { |
| 287 return IterableMixinWorkaround.firstWhere(this, test, orElse); | 312 int len = this.length; |
| 313 for (int i = 0; i < len; ++i) { | |
| 314 var element = this[i]; | |
| 315 if (test(element)) return element; | |
| 316 } | |
| 317 if (orElse != null) return orElse(); | |
| 318 throw IterableElementError.noElement(); | |
| 288 } | 319 } |
| 289 | 320 |
| 290 dynamic lastWhere(bool test(element), {orElse()}) { | 321 dynamic lastWhere(bool test(element), {orElse()}) { |
| 291 return IterableMixinWorkaround.lastWhereList(this, test, orElse); | 322 dynamic result = null; |
|
srdjan
2015/01/29 17:29:39
var result = null;
Florian Schneider
2015/02/03 08:18:19
Done.
| |
| 323 bool foundMatching = false; | |
| 324 int len = this.length; | |
| 325 for (int i = 0; i < len; ++i) { | |
|
srdjan
2015/01/29 17:29:39
Why not going backward len - 1 ... 0 and return fi
Florian Schneider
2015/02/03 08:18:19
Done.
| |
| 326 dynamic element = this[i]; | |
|
srdjan
2015/01/29 17:29:40
var element =
Florian Schneider
2015/02/03 08:18:19
Done.
| |
| 327 if (test(element)) { | |
| 328 result = element; | |
| 329 foundMatching = true; | |
| 330 } | |
| 331 } | |
| 332 if (foundMatching) return result; | |
| 333 if (orElse != null) return orElse(); | |
| 334 throw IterableElementError.noElement(); | |
| 292 } | 335 } |
| 293 | 336 |
| 294 dynamic singleWhere(bool test(element)) { | 337 dynamic singleWhere(bool test(element)) { |
| 295 return IterableMixinWorkaround.singleWhere(this, test); | 338 dynamic result = null; |
|
srdjan
2015/01/29 17:29:40
var result =
Florian Schneider
2015/02/03 08:18:19
Done.
| |
| 339 bool foundMatching = false; | |
| 340 int len = this.length; | |
| 341 for (int i = 0; i < len; ++i) { | |
| 342 dynamic element = this[i]; | |
| 343 if (test(element)) { | |
| 344 if (foundMatching) { | |
| 345 throw IterableElementError.tooMany(); | |
| 346 } | |
| 347 result = element; | |
| 348 foundMatching = true; | |
| 349 } | |
| 350 } | |
| 351 if (foundMatching) return result; | |
| 352 throw IterableElementError.noElement(); | |
| 296 } | 353 } |
| 297 | 354 |
| 298 dynamic elementAt(int index) { | 355 dynamic elementAt(int index) { |
| 299 return this[index]; | 356 return this[index]; |
| 300 } | 357 } |
| 301 | 358 |
| 302 bool get isEmpty { | 359 bool get isEmpty { |
| 303 return this.length == 0; | 360 return this.length == 0; |
| 304 } | 361 } |
| 305 | 362 |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 326 throw new UnsupportedError( | 383 throw new UnsupportedError( |
| 327 "Cannot insert into a fixed-length list"); | 384 "Cannot insert into a fixed-length list"); |
| 328 } | 385 } |
| 329 | 386 |
| 330 void insertAll(int index, Iterable values) { | 387 void insertAll(int index, Iterable values) { |
| 331 throw new UnsupportedError( | 388 throw new UnsupportedError( |
| 332 "Cannot insert into a fixed-length list"); | 389 "Cannot insert into a fixed-length list"); |
| 333 } | 390 } |
| 334 | 391 |
| 335 void sort([int compare(a, b)]) { | 392 void sort([int compare(a, b)]) { |
| 336 IterableMixinWorkaround.sortList(this, compare); | 393 if (compare == null) compare = Comparable.compare; |
| 394 Sort.sort(this, compare); | |
| 337 } | 395 } |
| 338 | 396 |
| 339 void shuffle([Random random]) { | 397 void shuffle([Random random]) { |
| 340 IterableMixinWorkaround.shuffleList(this, random); | 398 if (random == null) random = new Random(); |
| 399 int i = this.length; | |
| 400 while (i > 1) { | |
| 401 int pos = random.nextInt(i); | |
| 402 i -= 1; | |
| 403 var tmp = this[i]; | |
| 404 this[i] = this[pos]; | |
| 405 this[pos] = tmp; | |
| 406 } | |
| 341 } | 407 } |
| 342 | 408 |
| 343 int indexOf(element, [int start = 0]) { | 409 int indexOf(element, [int start = 0]) { |
| 344 return IterableMixinWorkaround.indexOfList(this, element, start); | 410 return Lists.indexOf(this, element, start, this.length); |
| 345 } | 411 } |
| 346 | 412 |
| 347 int lastIndexOf(element, [int start = null]) { | 413 int lastIndexOf(element, [int start = null]) { |
| 348 return IterableMixinWorkaround.lastIndexOfList(this, element, start); | 414 if (start == null) start = this.length - 1; |
| 415 return Lists.lastIndexOf(this, element, start); | |
| 349 } | 416 } |
| 350 | 417 |
| 351 void clear() { | 418 void clear() { |
| 352 throw new UnsupportedError( | 419 throw new UnsupportedError( |
| 353 "Cannot remove from a fixed-length list"); | 420 "Cannot remove from a fixed-length list"); |
| 354 } | 421 } |
| 355 | 422 |
| 356 int removeLast() { | 423 int removeLast() { |
| 357 throw new UnsupportedError( | 424 throw new UnsupportedError( |
| 358 "Cannot remove from a fixed-length list"); | 425 "Cannot remove from a fixed-length list"); |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 373 "Cannot remove from a fixed-length list"); | 440 "Cannot remove from a fixed-length list"); |
| 374 } | 441 } |
| 375 | 442 |
| 376 void retainWhere(bool test(element)) { | 443 void retainWhere(bool test(element)) { |
| 377 throw new UnsupportedError( | 444 throw new UnsupportedError( |
| 378 "Cannot remove from a fixed-length list"); | 445 "Cannot remove from a fixed-length list"); |
| 379 } | 446 } |
| 380 | 447 |
| 381 dynamic get first { | 448 dynamic get first { |
| 382 if (length > 0) return this[0]; | 449 if (length > 0) return this[0]; |
| 383 throw new StateError("No elements"); | 450 throw IterableElementError.noElement(); |
| 384 } | 451 } |
| 385 | 452 |
| 386 dynamic get last { | 453 dynamic get last { |
| 387 if (length > 0) return this[length - 1]; | 454 if (length > 0) return this[length - 1]; |
| 388 throw new StateError("No elements"); | 455 throw IterableElementError.noElement(); |
| 389 } | 456 } |
| 390 | 457 |
| 391 dynamic get single { | 458 dynamic get single { |
| 392 if (length == 1) return this[0]; | 459 if (length == 1) return this[0]; |
| 393 if (length == 0) throw new StateError("No elements"); | 460 if (length == 0) throw IterableElementError.noElement(); |
| 394 throw new StateError("More than one element"); | 461 throw IterableElementError.tooMany(); |
| 395 } | 462 } |
| 396 | 463 |
| 397 void removeRange(int start, int end) { | 464 void removeRange(int start, int end) { |
| 398 throw new UnsupportedError( | 465 throw new UnsupportedError( |
| 399 "Cannot remove from a fixed-length list"); | 466 "Cannot remove from a fixed-length list"); |
| 400 } | 467 } |
| 401 | 468 |
| 402 void replaceRange(int start, int end, Iterable iterable) { | 469 void replaceRange(int start, int end, Iterable iterable) { |
| 403 throw new UnsupportedError( | 470 throw new UnsupportedError( |
| 404 "Cannot remove from a fixed-length list"); | 471 "Cannot remove from a fixed-length list"); |
| (...skipping 26 matching lines...) Expand all Loading... | |
| 431 } | 498 } |
| 432 if (start > end) { | 499 if (start > end) { |
| 433 throw _newRangeError(start, end + 1); | 500 throw _newRangeError(start, end + 1); |
| 434 } | 501 } |
| 435 if (skipCount < 0) { | 502 if (skipCount < 0) { |
| 436 throw new ArgumentError(skipCount); | 503 throw new ArgumentError(skipCount); |
| 437 } | 504 } |
| 438 | 505 |
| 439 final count = end - start; | 506 final count = end - start; |
| 440 if ((from.length - skipCount) < count) { | 507 if ((from.length - skipCount) < count) { |
| 441 throw new StateError("Not enough elements"); | 508 throw IterableElementError.tooFew(); |
| 442 } | 509 } |
| 443 | 510 |
| 444 if (from is _TypedListBase) { | 511 if (from is _TypedListBase) { |
| 445 if (this.elementSizeInBytes == from.elementSizeInBytes) { | 512 if (this.elementSizeInBytes == from.elementSizeInBytes) { |
| 446 if ((count < 10) && (from.buffer != this.buffer)) { | 513 if ((count < 10) && (from.buffer != this.buffer)) { |
| 447 Lists.copy(from, skipCount, this, start, count); | 514 Lists.copy(from, skipCount, this, start, count); |
| 448 return; | 515 return; |
| 449 } else if (this.buffer._data._setRange( | 516 } else if (this.buffer._data._setRange( |
| 450 start * elementSizeInBytes + this.offsetInBytes, | 517 start * elementSizeInBytes + this.offsetInBytes, |
| 451 count * elementSizeInBytes, | 518 count * elementSizeInBytes, |
| 452 from.buffer._data, | 519 from.buffer._data, |
| 453 skipCount * elementSizeInBytes + from.offsetInBytes, | 520 skipCount * elementSizeInBytes + from.offsetInBytes, |
| 454 ClassID.getID(this), ClassID.getID(from))) { | 521 ClassID.getID(this), ClassID.getID(from))) { |
| 455 return; | 522 return; |
| 456 } | 523 } |
| 457 } else if (from.buffer == this.buffer) { | 524 } else if (from.buffer == this.buffer) { |
| 458 // Different element sizes, but same buffer means that we need | 525 // Different element sizes, but same buffer means that we need |
| 459 // an intermediate structure. | 526 // an intermediate structure. |
| 460 // TODO(srdjan): Optimize to skip copying if the range does not overlap. | 527 // TODO(srdjan): Optimize to skip copying if the range does not overlap. |
| 461 final temp_buffer = new List(count); | 528 final temp_buffer = new List(count); |
| 462 for (int i = 0; i < count; i++) { | 529 for (int i = 0; i < count; i++) { |
| 463 temp_buffer[i] = from[skipCount + i]; | 530 temp_buffer[i] = from[skipCount + i]; |
| 464 } | 531 } |
| 465 for (int i = start; i < end; i++) { | 532 for (int i = start; i < end; i++) { |
| 466 this[i] = temp_buffer[i - start]; | 533 this[i] = temp_buffer[i - start]; |
| 467 } | 534 } |
| 468 return; | 535 return; |
| 469 } | 536 } |
| 470 } | 537 } |
| 471 IterableMixinWorkaround.setRangeList(this, start, | 538 |
| 472 end, from, skipCount); | 539 if (count == 0) return; |
| 540 List otherList; | |
| 541 int otherStart; | |
| 542 if (from is List) { | |
| 543 otherList = from; | |
| 544 otherStart = skipCount; | |
| 545 } else { | |
| 546 otherList = from.skip(skipCount).toList(growable: false); | |
| 547 otherStart = 0; | |
| 548 } | |
| 549 if (otherStart + count > otherList.length) { | |
| 550 throw IterableElementError.tooFew(); | |
| 551 } | |
| 552 Lists.copy(otherList, otherStart, this, start, count); | |
| 473 } | 553 } |
| 474 | 554 |
| 475 void setAll(int index, Iterable iterable) { | 555 void setAll(int index, Iterable iterable) { |
| 476 final end = iterable.length + index; | 556 final end = iterable.length + index; |
| 477 setRange(index, end, iterable); | 557 setRange(index, end, iterable); |
| 478 } | 558 } |
| 479 | 559 |
| 480 void fillRange(int start, int end, [fillValue]) { | 560 void fillRange(int start, int end, [fillValue]) { |
| 481 IterableMixinWorkaround.fillRangeList(this, start, end, fillValue); | 561 RangeError.checkValidRange(start, end, this.length); |
| 562 for (int i = start; i < end; ++i) { | |
| 563 this[i] = fillValue; | |
| 564 } | |
| 482 } | 565 } |
| 483 | 566 |
| 484 | 567 |
| 485 // Method(s) implementing Object interface. | 568 // Method(s) implementing Object interface. |
| 486 | 569 |
| 487 String toString() => ListBase.listToString(this); | 570 String toString() => ListBase.listToString(this); |
| 488 | 571 |
| 489 | 572 |
| 490 // Internal utility methods. | 573 // Internal utility methods. |
| 491 | 574 |
| (...skipping 2994 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3486 return value; | 3569 return value; |
| 3487 } | 3570 } |
| 3488 return object; | 3571 return object; |
| 3489 } | 3572 } |
| 3490 | 3573 |
| 3491 | 3574 |
| 3492 _newRangeError(int index, int length) { | 3575 _newRangeError(int index, int length) { |
| 3493 String message = "$index must be in the range [0..$length)"; | 3576 String message = "$index must be in the range [0..$length)"; |
| 3494 return new RangeError(message); | 3577 return new RangeError(message); |
| 3495 } | 3578 } |
| OLD | NEW |