Skip to content

Commit 70be266

Browse files
Merge pull request swiftlang#23293 from PatrickPijnappel/range-overlaps-performance-impl
[stdlib] Refactor Range Overlaps for Performance
2 parents b2542a3 + 87f02b1 commit 70be266

File tree

2 files changed

+22
-5
lines changed

2 files changed

+22
-5
lines changed

stdlib/public/core/ClosedRange.swift

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -444,7 +444,12 @@ extension ClosedRange where Bound: Strideable, Bound.Stride : SignedInteger {
444444
extension ClosedRange {
445445
@inlinable
446446
public func overlaps(_ other: ClosedRange<Bound>) -> Bool {
447-
return self.contains(other.lowerBound) || other.contains(lowerBound)
447+
// Disjoint iff the other range is completely before or after our range.
448+
// Unlike a `Range`, a `ClosedRange` can *not* be empty, so no check for
449+
// that case is needed here.
450+
let isDisjoint = other.upperBound < self.lowerBound
451+
|| self.upperBound < other.lowerBound
452+
return !isDisjoint
448453
}
449454

450455
@inlinable

stdlib/public/core/Range.swift

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -943,14 +943,26 @@ extension Range {
943943
/// common; otherwise, `false`.
944944
@inlinable
945945
public func overlaps(_ other: Range<Bound>) -> Bool {
946-
return (!other.isEmpty && self.contains(other.lowerBound))
947-
|| (!self.isEmpty && other.contains(self.lowerBound))
946+
// Disjoint iff the other range is completely before or after our range.
947+
// Additionally either `Range` (unlike a `ClosedRange`) could be empty, in
948+
// which case it is disjoint with everything as overlap is defined as having
949+
// an element in common.
950+
let isDisjoint = other.upperBound <= self.lowerBound
951+
|| self.upperBound <= other.lowerBound
952+
|| self.isEmpty || other.isEmpty
953+
return !isDisjoint
948954
}
949955

950956
@inlinable
951957
public func overlaps(_ other: ClosedRange<Bound>) -> Bool {
952-
return self.contains(other.lowerBound)
953-
|| (!self.isEmpty && other.contains(self.lowerBound))
958+
// Disjoint iff the other range is completely before or after our range.
959+
// Additionally the `Range` (unlike the `ClosedRange`) could be empty, in
960+
// which case it is disjoint with everything as overlap is defined as having
961+
// an element in common.
962+
let isDisjoint = other.upperBound < self.lowerBound
963+
|| self.upperBound <= other.lowerBound
964+
|| self.isEmpty
965+
return !isDisjoint
954966
}
955967
}
956968

0 commit comments

Comments
 (0)