@@ -145,46 +145,33 @@ extension _ArrayBufferProtocol {
145
145
elementsOf newValues: __owned C
146
146
) where C: Collection , C. Element == Element {
147
147
_internalInvariant ( startIndex == 0 , " _SliceBuffer should override this function. " )
148
- let oldCount = self . count
149
- let eraseCount = subrange. count
150
-
151
- let growth = newCount - eraseCount
152
- // This check will prevent storing a 0 count to the empty array singleton.
153
- if growth != 0 {
154
- self . count = oldCount + growth
155
- }
156
148
157
149
let elements = self . firstElementAddress
158
150
159
151
// erase all the elements we're replacing to create a hole
160
152
let holeStart = elements + subrange. lowerBound
161
- let holeEnd = holeStart + newCount
162
-
163
- // directly forwards to Builtin.destroyArray
164
- // TODO: should we branch here or does the compiler branch implicitly?
153
+ let eraseCount = subrange. count
165
154
holeStart. deinitialize ( count: eraseCount)
166
155
167
- // resize the hole to make it the correct size
168
- // safe to always call, moveInitialize to the same location is a no-op
169
- let tailStart = elements + subrange. upperBound
170
- let tailCount = oldCount - subrange. upperBound
171
- holeEnd. moveInitialize ( from: tailStart, count: tailCount)
156
+ let growth = newCount - eraseCount
172
157
173
- // place the values into the hole we created
174
- if newCount > 0 {
175
- let done : Void ? = newValues. withContiguousStorageIfAvailable {
176
- holeStart. initialize ( from: $0. baseAddress!, count: newCount)
177
- }
178
- if done == nil {
179
- var place = holeStart
180
- var i = newValues. startIndex
181
- while place < holeEnd {
182
- place. initialize ( to: newValues [ i] )
183
- place += 1
184
- newValues. formIndex ( after: & i)
185
- }
186
- _expectEnd ( of: newValues, is: i)
187
- }
158
+ // This check will prevent storing a 0 count to the empty array singleton.
159
+ if growth != 0 {
160
+ let holeEnd = holeStart + newCount
161
+ let tailStart = elements + subrange. upperBound
162
+ let tailCount = self . count - subrange. upperBound
163
+ holeEnd. moveInitialize ( from: tailStart, count: tailCount)
164
+ self . count += growth
188
165
}
166
+
167
+ // place the values into the hole we created
168
+ let buf = UnsafeMutableBufferPointer ( start: holeStart, count: newCount)
169
+ let res = buf. initialize ( fromContentsOf: newValues)
170
+ // memory safety: if we did not fill the buffer, we now have
171
+ // uninitialized memory in the middle of our array
172
+ precondition (
173
+ res == buf. endIndex,
174
+ " invalid Collection: count differed in successive traversals "
175
+ )
189
176
}
190
177
}
0 commit comments