splice method
Managed _array__splice.
The tail move uses overlap-safe setRange, matching native memmove for
both right-shift insertion and left-shift deletion. newValues is copied
before mutation, corresponding to a stable external C input buffer.
Implementation
void splice(int index, int oldCount, int newCount, Iterable<T>? newValues) {
_checkUint32(index, 'index');
_checkUint32(oldCount, 'oldCount');
_checkUint32(newCount, 'newCount');
final oldEnd = index + oldCount;
if (oldEnd > _size) {
throw RangeError.range(oldEnd, 0, _size, 'index + oldCount');
}
final inserted = newValues?.take(newCount).toList(growable: false);
if (inserted != null && inserted.length != newCount) {
throw ArgumentError.value(
newValues,
'newValues',
'must contain at least newCount elements',
);
}
final oldSize = _size;
final newSize = _checkedSize(_size + newCount - oldCount);
final newEnd = index + newCount;
reserve(newSize);
final tailCount = oldSize - oldEnd;
if (tailCount > 0 && newEnd != oldEnd) {
_storage.setRange(newEnd, newEnd + tailCount, _storage, oldEnd);
}
for (var offset = 0; offset < newCount; offset++) {
_storage[index + offset] = inserted?[offset] ?? _zeroValue();
}
_size = newSize;
for (var trailing = newSize; trailing < oldSize; trailing++) {
_storage[trailing] = null;
}
}