@@ -235,10 +235,31 @@ extension Substring {
235
235
///
236
236
/// Complexity: O(n) if non-contiguous, O(1) if already contiguous
237
237
///
238
- @_alwaysEmitIntoClient
238
+ @_alwaysEmitIntoClient @ inline ( __always )
239
239
public mutating func makeContiguousUTF8( ) {
240
- if _fastPath ( isContiguousUTF8) { return }
241
- self = String . _copying ( self ) [ ... ]
240
+ if isContiguousUTF8 { return }
241
+ return _slowMakeContiguousUTF8 ( )
242
+ }
243
+
244
+ @_alwaysEmitIntoClient // Swift 5.7
245
+ @inline ( never)
246
+ internal mutating func _slowMakeContiguousUTF8( ) {
247
+ _internalInvariant ( !isContiguousUTF8)
248
+
249
+ let scalarOffset = base. unicodeScalars. distance (
250
+ from: base. startIndex, to: startIndex)
251
+ let scalarCount = base. unicodeScalars. distance (
252
+ from: startIndex, to: endIndex)
253
+
254
+ let scalars = String . _copying ( base) . unicodeScalars
255
+
256
+ var newStart = scalars. index ( scalars. startIndex, offsetBy: scalarOffset)
257
+ var newEnd = scalars. index ( newStart, offsetBy: scalarCount)
258
+
259
+ if startIndex. _isCharacterAligned { newStart = newStart. _characterAligned }
260
+ if endIndex. _isCharacterAligned { newEnd = newEnd. _characterAligned }
261
+
262
+ self = Substring ( _unchecked: scalars. _guts, bounds: newStart ..< newEnd)
242
263
}
243
264
244
265
/// Runs `body` over the content of this substring in contiguous memory. If
@@ -258,13 +279,7 @@ extension Substring {
258
279
public mutating func withUTF8< R> (
259
280
_ body: ( UnsafeBufferPointer < UInt8 > ) throws -> R
260
281
) rethrows -> R {
261
- if _fastPath ( isContiguousUTF8) {
262
- return try _wholeGuts. withFastUTF8 ( range: self . _offsetRange) {
263
- return try body ( $0)
264
- }
265
- }
266
-
267
282
makeContiguousUTF8 ( )
268
- return try _wholeGuts. withFastUTF8 ( body)
283
+ return try _wholeGuts. withFastUTF8 ( range : _offsetRange , body)
269
284
}
270
285
}
0 commit comments