@@ -305,33 +305,42 @@ extension FlattenCollection: Collection {
305
305
}
306
306
307
307
// The following path combines the distances of three regions.
308
- let range = minus ? end ..< start : start ..< end
309
- var outer = range. lowerBound. _outer
310
-
311
308
var distance : Int = 0
312
- let step : Int = minus ? - 1 : 1
309
+ let step : Int
310
+ let lowerBound : Index
311
+ let upperBound : Index
313
312
314
- // This unwrap always succeeds.
315
- if let inner = range. lowerBound. _inner {
316
- let collection = _base [ outer]
317
- _base. formIndex ( after: & outer)
313
+ if minus {
314
+ lowerBound = end
315
+ upperBound = start
316
+ step = - 1
317
+ } else {
318
+ lowerBound = start
319
+ upperBound = end
320
+ step = 01
321
+ }
322
+
323
+ // This always unwraps because start._outer != end._outer.
324
+ if let inner = lowerBound. _inner {
325
+ let collection = _base [ lowerBound. _outer]
318
326
distance += minus
319
327
? collection. distance ( from: collection. endIndex, to: inner)
320
328
: collection. distance ( from: inner, to: collection. endIndex)
321
329
}
322
330
323
- // Using count is fine because the distance is nonzero here.
324
- // In other words, the most negative nontrapping value is -Int.max.
325
- _internalInvariant ( distance != 0 , " distance should not be zero " )
326
- while outer < range. upperBound. _outer {
327
- // 0...Int.max can always be negated.
328
- let collection = _base [ outer]
331
+ // We can use each collection's count in the middle region since the
332
+ // fast path ensures that the other regions cover a nonzero distance,
333
+ // which means that an extra Int.min distance should trap regardless.
334
+ var outer = _base. index ( after: lowerBound. _outer)
335
+ while outer < upperBound. _outer {
336
+ // 0 ... Int.max can always be negated.
337
+ distance += _base [ outer] . count &* step
329
338
_base. formIndex ( after: & outer)
330
- distance += collection. count &* step
331
339
}
332
340
333
- if let inner = range. upperBound. _inner {
334
- let collection = _base [ outer]
341
+ /// This unwraps if start != endIndex and end != endIndex.
342
+ if let inner = upperBound. _inner {
343
+ let collection = _base [ upperBound. _outer]
335
344
distance += minus
336
345
? collection. distance ( from: inner, to: collection. startIndex)
337
346
: collection. distance ( from: collection. startIndex, to: inner)
0 commit comments