Skip to content

Commit cb3dec1

Browse files
committed
[stdlib] remove most branches from Array.replaceSubrange
1 parent 77a6690 commit cb3dec1

File tree

1 file changed

+15
-59
lines changed

1 file changed

+15
-59
lines changed

stdlib/public/core/ArrayBufferProtocol.swift

Lines changed: 15 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -154,67 +154,23 @@ extension _ArrayBufferProtocol {
154154
self.count = oldCount + growth
155155
}
156156

157-
let elements = self.subscriptBaseAddress
158-
let oldTailIndex = subrange.upperBound
159-
let oldTailStart = elements + oldTailIndex
160-
let newTailIndex = oldTailIndex + growth
161-
let newTailStart = oldTailStart + growth
157+
let elements = self.firstElementAddress
158+
159+
// erase all the elements we're replacing to create a hole
160+
let holeStart = elements + subrange.lowerBound
161+
let holeEnd = holeStart + newCount
162+
holeStart.deinitialize(count: eraseCount)
163+
164+
// resize the hole to make it the correct size
165+
let tailStart = elements + subrange.upperBound
162166
let tailCount = oldCount - subrange.upperBound
167+
holeEnd.moveInitialize(from: tailStart, count: tailCount)
163168

164-
if growth > 0 {
165-
// Slide the tail part of the buffer forwards, in reverse order
166-
// so as not to self-clobber.
167-
newTailStart.moveInitialize(from: oldTailStart, count: tailCount)
168-
169-
// Update the original subrange
170-
var i = newValues.startIndex
171-
for j in subrange {
172-
elements[j] = newValues[i]
173-
newValues.formIndex(after: &i)
174-
}
175-
// Initialize the hole left by sliding the tail forward
176-
for j in oldTailIndex..<newTailIndex {
177-
(elements + j).initialize(to: newValues[i])
178-
newValues.formIndex(after: &i)
179-
}
180-
_expectEnd(of: newValues, is: i)
181-
}
182-
else { // We're not growing the buffer
183-
// Assign all the new elements into the start of the subrange
184-
var i = subrange.lowerBound
185-
var j = newValues.startIndex
186-
for _ in 0..<newCount {
187-
elements[i] = newValues[j]
188-
i += 1
189-
newValues.formIndex(after: &j)
190-
}
191-
_expectEnd(of: newValues, is: j)
192-
193-
// If the size didn't change, we're done.
194-
if growth == 0 {
195-
return
196-
}
197-
198-
// Move the tail backward to cover the shrinkage.
199-
let shrinkage = -growth
200-
if tailCount > shrinkage { // If the tail length exceeds the shrinkage
201-
202-
// Update the rest of the replaced range with the first
203-
// part of the tail.
204-
newTailStart.moveUpdate(from: oldTailStart, count: shrinkage)
205-
206-
// Slide the rest of the tail back
207-
oldTailStart.moveInitialize(
208-
from: oldTailStart + shrinkage, count: tailCount - shrinkage)
209-
}
210-
else { // Tail fits within erased elements
211-
// Update the start of the replaced range with the tail
212-
newTailStart.moveUpdate(from: oldTailStart, count: tailCount)
213-
214-
// Destroy elements remaining after the tail in subrange
215-
(newTailStart + tailCount).deinitialize(
216-
count: shrinkage - tailCount)
217-
}
169+
// place the values into the hole we created
170+
var place = holeStart
171+
for element in newValues {
172+
place.initialize(to: element)
173+
place += 1
218174
}
219175
}
220176
}

0 commit comments

Comments
 (0)