Code review changes
diff --git a/lib/src/typed_queue.dart b/lib/src/typed_queue.dart
index 0e36197..93b0a42 100644
--- a/lib/src/typed_queue.dart
+++ b/lib/src/typed_queue.dart
@@ -7,13 +7,14 @@
import "package:collection/collection.dart";
+import '../typed_buffers.dart';
+
/// The shared superclass of all the typed queue subclasses.
-abstract class _TypedQueue<E, L extends List<E>> extends Object
- with ListMixin<E> {
+abstract class _TypedQueue<E, L extends List<E>> with ListMixin<E> {
/// The underlying data buffer.
///
/// This is always both a List<E> and a TypedData, which we don't have a type
- /// for that. For example, for a `Uint8Buffer`, this is a `Uint8List`.
+ /// for that. For example, for a `Uint8Queue`, this is a `Uint8List`.
L _table;
int _head;
@@ -29,7 +30,7 @@
int get length => (_tail - _head) & (_table.length - 1);
List<E> toList({bool growable = true}) {
- var list = growable ? (<E>[]..length = length) : _createList(length);
+ var list = growable ? _createBuffer(length) : _createList(length);
_writeToList(list);
return list;
}
@@ -77,15 +78,21 @@
var delta = value - length;
if (delta >= 0) {
- if (_table.length <= value) _growTo(value);
+ var needsToGrow = _table.length <= value;
+ if (needsToGrow) _growTo(value);
_tail = (_tail + delta) & (_table.length - 1);
+
+ // If we didn't copy into a new table, make sure that we overwrite the
+ // existing data so that users don't accidentally depend on it still
+ // existing.
+ if (!needsToGrow) fillRange(value - delta, value, _defaultValue);
} else {
removeRange(value, length);
}
}
E operator [](int index) {
- RangeError.checkValidIndex(index, this);
+ RangeError.checkValidIndex(index, this, null, this.length);
return _table[(_head + index) & (_table.length - 1)];
}
@@ -222,11 +229,21 @@
}
}
+ void fillRange(int start, int end, [E value]) {
+ var startInTable = (_head + start) & (_table.length - 1);
+ var endInTable = (_head + end) & (_table.length - 1);
+ if (startInTable <= endInTable) {
+ _table.fillRange(startInTable, endInTable, value);
+ } else {
+ _table.fillRange(startInTable, _table.length, value);
+ _table.fillRange(0, endInTable, value);
+ }
+ }
+
L sublist(int start, [int end]) {
var length = this.length;
- RangeError.checkValidRange(start, end, length);
+ end = RangeError.checkValidRange(start, end, length);
- end ??= length;
var list = _createList(end - start);
_writeToList(list, start, end);
return list;
@@ -245,6 +262,7 @@
start ??= 0;
end ??= length;
assert(target.length >= end - start);
+ assert(start <= end);
var elementsToWrite = end - start;
var startInTable = (_head + start) & (_table.length - 1);
@@ -296,15 +314,25 @@
// Create a new typed list.
L _createList(int size);
+
+ // Create a new typed buffer of the given type.
+ List<E> _createBuffer(int size);
+
+ /// The default value used to fill the queue when changing length.
+ E get _defaultValue;
}
abstract class _IntQueue<L extends List<int>> extends _TypedQueue<int, L> {
_IntQueue(List<int> queue) : super(queue);
+
+ int get _defaultValue => 0;
}
abstract class _FloatQueue<L extends List<double>>
extends _TypedQueue<double, L> {
_FloatQueue(List<double> queue) : super(queue);
+
+ double get _defaultValue => 0.0;
}
/// A [QueueList] that efficiently stores 8-bit unsigned integers.
@@ -325,6 +353,7 @@
Uint8Queue(elements.length)..addAll(elements);
Uint8List _createList(int size) => Uint8List(size);
+ Uint8Buffer _createBuffer(int size) => Uint8Buffer(size);
}
/// A [QueueList] that efficiently stores 8-bit signed integers.
@@ -346,6 +375,7 @@
Int8Queue(elements.length)..addAll(elements);
Int8List _createList(int size) => Int8List(size);
+ Int8Buffer _createBuffer(int size) => Int8Buffer(size);
}
/// A [QueueList] that efficiently stores 8-bit unsigned integers.
@@ -369,6 +399,7 @@
Uint8ClampedQueue(elements.length)..addAll(elements);
Uint8ClampedList _createList(int size) => Uint8ClampedList(size);
+ Uint8ClampedBuffer _createBuffer(int size) => Uint8ClampedBuffer(size);
}
/// A [QueueList] that efficiently stores 16-bit unsigned integers.
@@ -389,6 +420,7 @@
Uint16Queue(elements.length)..addAll(elements);
Uint16List _createList(int size) => Uint16List(size);
+ Uint16Buffer _createBuffer(int size) => Uint16Buffer(size);
}
/// A [QueueList] that efficiently stores 16-bit signed integers.
@@ -410,6 +442,7 @@
Int16Queue(elements.length)..addAll(elements);
Int16List _createList(int size) => Int16List(size);
+ Int16Buffer _createBuffer(int size) => Int16Buffer(size);
}
/// A [QueueList] that efficiently stores 32-bit unsigned integers.
@@ -430,6 +463,7 @@
Uint32Queue(elements.length)..addAll(elements);
Uint32List _createList(int size) => Uint32List(size);
+ Uint32Buffer _createBuffer(int size) => Uint32Buffer(size);
}
/// A [QueueList] that efficiently stores 32-bit signed integers.
@@ -451,6 +485,7 @@
Int32Queue(elements.length)..addAll(elements);
Int32List _createList(int size) => Int32List(size);
+ Int32Buffer _createBuffer(int size) => Int32Buffer(size);
}
/// A [QueueList] that efficiently stores 64-bit unsigned integers.
@@ -472,6 +507,7 @@
Uint64Queue(elements.length)..addAll(elements);
Uint64List _createList(int size) => Uint64List(size);
+ Uint64Buffer _createBuffer(int size) => Uint64Buffer(size);
}
/// A [QueueList] that efficiently stores 64-bit signed integers.
@@ -493,6 +529,7 @@
Int64Queue(elements.length)..addAll(elements);
Int64List _createList(int size) => Int64List(size);
+ Int64Buffer _createBuffer(int size) => Int64Buffer(size);
}
/// A [QueueList] that efficiently stores IEEE 754 single-precision binary
@@ -515,6 +552,7 @@
Float32Queue(elements.length)..addAll(elements);
Float32List _createList(int size) => Float32List(size);
+ Float32Buffer _createBuffer(int size) => Float32Buffer(size);
}
/// A [QueueList] that efficiently stores IEEE 754 double-precision binary
@@ -534,6 +572,7 @@
Float64Queue(elements.length)..addAll(elements);
Float64List _createList(int size) => Float64List(size);
+ Float64Buffer _createBuffer(int size) => Float64Buffer(size);
}
/// A [QueueList] that efficiently stores [Int32x4] numbers.
@@ -542,6 +581,8 @@
/// time-efficient than a default [QueueList] implementation.
class Int32x4Queue extends _TypedQueue<Int32x4, Int32x4List>
implements QueueList<Int32x4> {
+ static final Int32x4 _zero = Int32x4(0, 0, 0, 0);
+
/// Creates an empty [Int32x4Queue] with the given initial internal capacity
/// (in elements).
Int32x4Queue([int initialCapacity])
@@ -552,6 +593,8 @@
Int32x4Queue(elements.length)..addAll(elements);
Int32x4List _createList(int size) => Int32x4List(size);
+ Int32x4Buffer _createBuffer(int size) => Int32x4Buffer(size);
+ Int32x4 get _defaultValue => _zero;
}
/// A [QueueList] that efficiently stores [Float32x4] numbers.
@@ -570,6 +613,8 @@
Float32x4Queue(elements.length)..addAll(elements);
Float32x4List _createList(int size) => Float32x4List(size);
+ Float32x4Buffer _createBuffer(int size) => Float32x4Buffer(size);
+ Float32x4 get _defaultValue => Float32x4.zero();
}
/// The initial capacity of queues if the user doesn't specify one.
diff --git a/test/queue_test.dart b/test/queue_test.dart
index a98c157..6b6daf9 100644
--- a/test/queue_test.dart
+++ b/test/queue_test.dart
@@ -162,6 +162,14 @@
});
});
+ group("zeroes out existing data", () {
+ forEachInternalRepresentation((queue) {
+ queue.length = 0;
+ queue.length = 15;
+ expect(queue, equals([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]));
+ });
+ });
+
test("throws a RangeError if length is less than 0", () {
expect(() => Uint8Queue().length = -1, throwsRangeError);
});