@@ -299,6 +299,70 @@ extension String.UTF16View: BidirectionalCollection {
299
299
return _nativeGetOffset ( for: endIndex)
300
300
}
301
301
302
+ internal func _indexRange(
303
+ for offsets: Range < Int > ,
304
+ from start: Index
305
+ ) -> Range < Index > {
306
+ _internalInvariant ( _guts. hasMatchingEncoding ( start) )
307
+ if _slowPath ( _guts. isForeign) {
308
+ let lower = self . index ( start, offsetBy: offsets. lowerBound)
309
+ let upper = _foreignIndex ( lower, offsetBy: offsets. count)
310
+ return Range ( uncheckedBounds: ( lower, upper) )
311
+ }
312
+ if offsets. count < _breadcrumbStride / 2 , !_guts. isASCII {
313
+ let lower = self . index ( start, offsetBy: offsets. lowerBound)
314
+ let upper = _index ( lower, offsetBy: offsets. count) . _knownUTF8
315
+ return Range ( uncheckedBounds: ( lower, upper) )
316
+ }
317
+
318
+ let bias = _nativeGetOffset ( for: start)
319
+ let lower = (
320
+ offsets. lowerBound - bias <= _breadcrumbStride / 2
321
+ ? _index ( start, offsetBy: offsets. lowerBound)
322
+ : _nativeGetIndex ( for: bias + offsets. lowerBound) )
323
+ let upper = _nativeGetIndex ( for: bias + offsets. upperBound)
324
+ return Range ( uncheckedBounds: ( lower, upper) )
325
+ }
326
+
327
+ internal func _offsetRange(
328
+ for range: Range < Index > ,
329
+ from start: Index
330
+ ) -> Range < Int > {
331
+ let lower = _guts. ensureMatchingEncoding ( range. lowerBound)
332
+ let upper = _guts. ensureMatchingEncoding ( range. upperBound)
333
+ _internalInvariant ( _guts. hasMatchingEncoding ( start) )
334
+
335
+ _precondition (
336
+ ifLinkedOnOrAfter: . v5_7_0,
337
+ lower. _encodedOffset <= _guts. count,
338
+ " String index is out of bounds " )
339
+ _precondition (
340
+ ifLinkedOnOrAfter: . v5_7_0,
341
+ upper. _encodedOffset <= _guts. count,
342
+ " String index is out of bounds " )
343
+
344
+ if _slowPath ( _guts. isForeign) {
345
+ let lowerOffset = _foreignDistance ( from: start, to: lower)
346
+ let distance = _foreignDistance ( from: lower, to: upper)
347
+ return Range ( uncheckedBounds: ( lowerOffset, lowerOffset + distance) )
348
+ }
349
+
350
+ let utf8Distance = upper. _encodedOffset - lower. _encodedOffset
351
+ if utf8Distance. magnitude <= _breadcrumbStride / 2 , !_guts. isASCII {
352
+ let lowerOffset = distance ( from: start, to: lower)
353
+ let distance = _utf16Distance ( from: lower, to: upper)
354
+ return Range ( uncheckedBounds: ( lowerOffset, lowerOffset + distance) )
355
+ }
356
+ let bias = _nativeGetOffset ( for: start)
357
+ let utf8StartOffset = lower. _encodedOffset - start. _encodedOffset
358
+ let lowerOffset = (
359
+ utf8StartOffset <= _breadcrumbStride / 2
360
+ ? _utf16Distance ( from: start, to: lower)
361
+ : _nativeGetOffset ( for: lower) - bias)
362
+ let upperOffset = _nativeGetOffset ( for: upper) - bias
363
+ return Range ( uncheckedBounds: ( lowerOffset, upperOffset) )
364
+ }
365
+
302
366
/// Accesses the code unit at the given position.
303
367
///
304
368
/// The following example uses the subscript to print the value of a
0 commit comments