Skip to content

Commit 321e40e

Browse files
authored
Merge pull request #71648 from oscbyspro/better-joined-distance-from-to
FlattenSequence/distance(from:to:) enhancements.
2 parents d3a0bf4 + 9abed8c commit 321e40e

File tree

1 file changed

+29
-19
lines changed

1 file changed

+29
-19
lines changed

stdlib/public/core/Flatten.swift

Lines changed: 29 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -289,31 +289,41 @@ extension FlattenCollection: Collection {
289289

290290
@inlinable // lazy-performance
291291
public func distance(from start: Index, to end: Index) -> Int {
292-
// The following check makes sure that distance(from:to:) is invoked on the
293-
// _base at least once, to trigger a _precondition in forward only
292+
// The following check ensures that distance(from:to:) is invoked on
293+
// the _base at least once, to trigger a _precondition in forward only
294294
// collections.
295-
if end < start {
295+
if start > end {
296296
_ = _base.distance(from: _base.endIndex, to: _base.startIndex)
297297
}
298-
var _start: Index
299-
let _end: Index
300-
let step: Int
301-
if start > end {
302-
_start = end
303-
_end = start
304-
step = -1
298+
299+
// This handles indices belonging to the same collection.
300+
if start._outer == end._outer {
301+
guard let i = start._inner, let j = end._inner else { return 0 }
302+
return _base[start._outer].distance(from: i, to: j)
305303
}
306-
else {
307-
_start = start
308-
_end = end
309-
step = 1
304+
305+
// The following combines the distance of three sections.
306+
let range = start <= end ? start ..< end : end ..< start
307+
var outer = range.lowerBound._outer
308+
var count = 0 as Int // 0...Int.max
309+
310+
if let inner = range.lowerBound._inner {
311+
let collection = _base[outer]
312+
count += collection.distance(from: inner, to: collection.endIndex)
313+
_base.formIndex(after: &outer)
314+
}
315+
316+
while outer < range.upperBound._outer {
317+
count += _base[outer].count
318+
_base.formIndex(after: &outer)
310319
}
311-
var count = 0
312-
while _start != _end {
313-
count += step
314-
formIndex(after: &_start)
320+
321+
if let inner = range.upperBound._inner {
322+
let collection = _base[outer]
323+
count += collection.distance(from: collection.startIndex, to: inner)
315324
}
316-
return count
325+
326+
return start <= end ? count : -count
317327
}
318328

319329
@inline(__always)

0 commit comments

Comments
 (0)