@@ -358,6 +358,13 @@ fileprivate enum Match<Index: Comparable> {
358358 case notFound( insertAt: Index )
359359}
360360
361+ extension Range where Bound == Int {
362+ var middle : Int ? {
363+ guard !isEmpty else { return nil }
364+ return lowerBound + count / 2
365+ }
366+ }
367+
361368extension SortedArray {
362369 /// Searches the array for `element` using binary search.
363370 ///
@@ -375,26 +382,15 @@ extension SortedArray {
375382 }
376383
377384 fileprivate func search( for element: Element , in range: Range < Index > ) -> Match < Index > {
378- guard !range. isEmpty else { return . notFound( insertAt: range. upperBound) }
379- var left = range. lowerBound
380- var right = index ( before: range. upperBound)
381-
382- while left <= right {
383- let dist = distance ( from: left, to: right)
384- let mid = index ( left, offsetBy: dist/ 2 )
385- let candidate = self [ mid]
386-
387- switch compare ( candidate, element) {
388- case . orderedAscending:
389- left = index ( after: mid)
390- case . orderedDescending:
391- right = index ( before: mid)
392- case . orderedSame:
393- return . found( at: mid)
394- }
385+ guard let middle = range. middle else { return . notFound( insertAt: range. upperBound) }
386+ switch compare ( element, self [ middle] ) {
387+ case . orderedDescending:
388+ return search ( for: element, in: index ( after: middle) ..< range. upperBound)
389+ case . orderedAscending:
390+ return search ( for: element, in: range. lowerBound..< middle)
391+ case . orderedSame:
392+ return . found( at: middle)
395393 }
396- // Not found. left is the index where this element should be placed if it were inserted.
397- return . notFound( insertAt: left)
398394 }
399395}
400396
0 commit comments