@@ -204,12 +204,14 @@ extension String.UTF16View: BidirectionalCollection {
204
204
return _foreignIndex ( i, offsetBy: n)
205
205
}
206
206
207
- let threshold = (
208
- i == startIndex ? _breadcrumbStride / 2 : _breadcrumbStride)
209
- if n. magnitude < threshold, !_guts. isASCII {
210
- // Do not use breadcrumbs if directly computing the result is expected to
211
- // be cheaper.
212
- return _index ( i, offsetBy: n) . _knownUTF8
207
+ if !_guts. isASCII { // We have ASCII fast paths below
208
+ let threshold = (
209
+ i == startIndex ? _breadcrumbStride / 2 : _breadcrumbStride)
210
+ if n. magnitude < threshold {
211
+ // Do not use breadcrumbs if directly computing the result is expected to
212
+ // be cheaper.
213
+ return _index ( i, offsetBy: n) . _knownUTF8
214
+ }
213
215
}
214
216
215
217
let lowerOffset = _nativeGetOffset ( for: i)
@@ -230,12 +232,14 @@ extension String.UTF16View: BidirectionalCollection {
230
232
return _foreignIndex ( i, offsetBy: n, limitedBy: limit)
231
233
}
232
234
233
- let threshold = (
234
- _breadcrumbStride + ( i == startIndex ? 0 : _breadcrumbStride / 2 ) )
235
- if n. magnitude < threshold, !_guts. isASCII {
236
- // Do not use breadcrumbs if directly computing the result is expected to
237
- // be cheaper.
238
- return _index ( i, offsetBy: n, limitedBy: limit) ? . _knownUTF8
235
+ if !_guts. isASCII { // We have ASCII fast paths below
236
+ let threshold = (
237
+ _breadcrumbStride + ( i == startIndex ? 0 : _breadcrumbStride / 2 ) )
238
+ if n. magnitude < threshold {
239
+ // Do not use breadcrumbs if directly computing the result is expected to
240
+ // be cheaper.
241
+ return _index ( i, offsetBy: n, limitedBy: limit) ? . _knownUTF8
242
+ }
239
243
}
240
244
241
245
let iOffset = _nativeGetOffset ( for: i)
@@ -275,17 +279,23 @@ extension String.UTF16View: BidirectionalCollection {
275
279
}
276
280
277
281
let utf8Distance = end. _encodedOffset - start. _encodedOffset
282
+
283
+ if _guts. isASCII {
284
+ return utf8Distance
285
+ }
286
+
278
287
let threshold = ( start == startIndex || end == startIndex
279
288
? _breadcrumbStride / 2
280
289
: _breadcrumbStride)
281
- if utf8Distance. magnitude < threshold, !_guts . isASCII {
290
+ if utf8Distance. magnitude < threshold {
282
291
// Do not use breadcrumbs if directly computing the result is expected to
283
292
// be cheaper. The conservative threshold above assumes that each UTF-16
284
293
// code unit will map to a single UTF-8 code unit, i.e., the worst
285
294
// possible (a.k.a. most compact) case with all ASCII scalars.
286
295
// FIXME: Figure out if a more optimistic threshold would work better.
287
296
return _utf16Distance ( from: start, to: end)
288
297
}
298
+
289
299
let lower = _nativeGetOffset ( for: start)
290
300
let upper = _nativeGetOffset ( for: end)
291
301
return upper &- lower
@@ -309,7 +319,14 @@ extension String.UTF16View: BidirectionalCollection {
309
319
let upper = _foreignIndex ( lower, offsetBy: offsets. count)
310
320
return Range ( uncheckedBounds: ( lower, upper) )
311
321
}
312
- if offsets. count < _breadcrumbStride / 2 , !_guts. isASCII {
322
+
323
+ if _guts. isASCII {
324
+ let lower = self . index ( start, offsetBy: offsets. lowerBound)
325
+ let upper = self . index ( lower, offsetBy: offsets. count)
326
+ return Range ( uncheckedBounds: ( lower, upper) )
327
+ }
328
+
329
+ if offsets. count < _breadcrumbStride / 2 {
313
330
let lower = self . index ( start, offsetBy: offsets. lowerBound)
314
331
let upper = _index ( lower, offsetBy: offsets. count) . _knownUTF8
315
332
return Range ( uncheckedBounds: ( lower, upper) )
@@ -348,11 +365,18 @@ extension String.UTF16View: BidirectionalCollection {
348
365
}
349
366
350
367
let utf8Distance = upper. _encodedOffset - lower. _encodedOffset
351
- if utf8Distance. magnitude <= _breadcrumbStride / 2 , !_guts. isASCII {
368
+
369
+ if _guts. isASCII {
370
+ let lowerOffset = lower. _encodedOffset - start. _encodedOffset
371
+ return Range ( uncheckedBounds: ( lowerOffset, lowerOffset + utf8Distance) )
372
+ }
373
+
374
+ if utf8Distance. magnitude <= _breadcrumbStride / 2 {
352
375
let lowerOffset = distance ( from: start, to: lower)
353
376
let distance = _utf16Distance ( from: lower, to: upper)
354
377
return Range ( uncheckedBounds: ( lowerOffset, lowerOffset + distance) )
355
378
}
379
+
356
380
let bias = _nativeGetOffset ( for: start)
357
381
let utf8StartOffset = lower. _encodedOffset - start. _encodedOffset
358
382
let lowerOffset = (
@@ -798,13 +822,12 @@ extension String.UTF16View {
798
822
@_effects ( releasenone)
799
823
internal func _nativeGetOffset( for idx: Index ) -> Int {
800
824
_internalInvariant ( idx. _encodedOffset <= _guts. count)
801
- // Trivial and common: start
802
- if idx == startIndex { return 0 }
803
-
804
825
if _guts. isASCII {
805
826
_internalInvariant ( idx. transcodedOffset == 0 )
806
827
return idx. _encodedOffset
807
828
}
829
+ // Trivial and common: start
830
+ if idx == startIndex { return 0 }
808
831
809
832
let idx = _utf16AlignNativeIndex ( idx)
810
833
0 commit comments