1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88
|
//===----------------------------------------------------------------------===//
//
// This source file is part of the Swift Collections open source project
//
// Copyright (c) 2023 - 2024 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
//
//===----------------------------------------------------------------------===//
#if swift(>=5.8)
@available(macOS 13.3, iOS 16.4, watchOS 9.4, tvOS 16.4, *)
extension BigString {
mutating func _replaceSubrange(
_ range: Range<Index>,
with newElements: some StringProtocol
) {
precondition(range.upperBound <= endIndex, "Index out of bounds")
if range.isEmpty {
insert(contentsOf: newElements, at: range.lowerBound)
return
}
var builder = _split(removing: range)
var ingester = _Ingester(Substring(newElements), startState: builder.prefixEndState)
builder.append(from: &ingester)
self = builder.finalize()
}
mutating func _replaceSubrange(
_ range: Range<Index>,
with newElements: BigString
) {
precondition(range.upperBound <= endIndex, "Index out of bounds")
if range.isEmpty {
insert(contentsOf: newElements, at: range.lowerBound)
return
}
var builder = _split(removing: range)
builder.append(newElements)
self = builder.finalize()
}
mutating func _replaceSubrange(
_ targetRange: Range<Index>,
with newElements: BigSubstring
) {
_replaceSubrange(targetRange, with: newElements._base, in: newElements._bounds)
}
mutating func _replaceSubrange(
_ targetRange: Range<Index>,
with newElements: BigString,
in sourceRange: Range<Index>
) {
if sourceRange._isEmptyUTF8 {
removeSubrange(targetRange)
return
}
if targetRange._isEmptyUTF8 {
_insert(
contentsOf: newElements,
in: sourceRange,
at: targetRange.lowerBound)
return
}
precondition(targetRange.upperBound <= endIndex, "Index out of bounds")
var builder = _split(removing: targetRange)
builder.append(newElements, in: sourceRange)
self = builder.finalize()
}
mutating func _split(removing range: Range<Index>) -> Builder {
let lower = range.lowerBound.utf8Offset
let upper = range.upperBound.utf8Offset
// FIXME: Don't split the indices twice -- they are currently split once here and once in the
// builder initializer below.
let startState = _breakState(upTo: range.lowerBound)
let endState = _breakState(upTo: range.upperBound)
let b = _rope.builder(removing: lower ..< upper, in: _UTF8Metric())
return Builder(base: b, prefixEndState: startState, suffixStartState: endState)
}
}
#endif
|