splice method

void splice(
  1. int index,
  2. int oldCount,
  3. int newCount,
  4. Iterable<T>? newValues,
)

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;
  }
}