Skip to content

Commit 6ce7922

Browse files
authored
Fix RandomAccessCollection + lowerBound API (#579)
1 parent c9dd35a commit 6ce7922

File tree

2 files changed

+36
-11
lines changed

2 files changed

+36
-11
lines changed

Sources/OpenSwiftUICore/Util/StandardLibraryAdditions.swift

Lines changed: 18 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -593,28 +593,35 @@ extension BidirectionalCollection where Self: MutableCollection, Element: Compar
593593
}
594594
}
595595

596-
// MARK: - RandomAccessCollection Extensions [Copilot]
596+
// MARK: - RandomAccessCollection Extensions [6.5.4]
597597

598598
extension RandomAccessCollection {
599599
package func lowerBound(_ predicate: (Element) -> Bool) -> Index {
600-
var left = startIndex
601-
var right = endIndex
602-
603-
while left < right {
604-
let mid = index(left, offsetBy: distance(from: left, to: right) / 2)
600+
var result = startIndex
601+
var remaining = count
602+
guard remaining >= 1 else {
603+
return result
604+
}
605+
repeat {
606+
let half = remaining / 2
607+
var mid = result
608+
formIndex(&mid, offsetBy: half)
609+
605610
if predicate(self[mid]) {
606-
right = mid
611+
result = mid
612+
formIndex(after: &result)
613+
remaining &+= -(half + 1)
607614
} else {
608-
left = index(after: mid)
615+
remaining = half
609616
}
610-
}
611-
return left
617+
} while remaining > 0
618+
return result
612619
}
613620
}
614621

615622
extension RandomAccessCollection where Element: Comparable {
616623
package func lowerBound(of value: Element) -> Index {
617-
lowerBound { $0 >= value }
624+
lowerBound { $0 < value }
618625
}
619626
}
620627

Tests/OpenSwiftUICoreTests/Util/StandardLibraryAdditionsTests.swift

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -310,6 +310,24 @@ struct Cache3Tests {
310310
}
311311
}
312312

313+
// MARK: - RandomAccessCollection + lowerBound
314+
315+
struct RandomAccessCollectionLowerBoundTests {
316+
@Test
317+
func customPredicate() {
318+
let array = [1, 3, 5, 7, 9, 11, 13, 15]
319+
let index = array.lowerBound { $0 <= 9 }
320+
#expect(index == 5)
321+
}
322+
323+
@Test
324+
func defaultPredicate() {
325+
let array = [1, 3, 5, 7, 9, 11, 13, 15]
326+
let index = array.lowerBound(of: 7)
327+
#expect(index == 3)
328+
}
329+
}
330+
313331
// MARK: - CollectionOfTwoTests
314332

315333
struct CollectionOfTwoTests {

0 commit comments

Comments
 (0)