Skip to content

Commit d072016

Browse files
authored
Merge pull request #3769 from parkera/indexset_optional_find
IndexSet's find family of methods should have optional returns
2 parents 178d194 + 57e184a commit d072016

File tree

2 files changed

+56
-16
lines changed

2 files changed

+56
-16
lines changed

stdlib/public/SDK/Foundation/IndexSet.swift

Lines changed: 21 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -327,29 +327,29 @@ public struct IndexSet : ReferenceConvertible, Equatable, BidirectionalCollectio
327327
return _handle.map { _toOptional($0.lastIndex) }
328328
}
329329

330-
/// Returns an integer contained in `self` which is greater than `integer`.
331-
public func integerGreaterThan(_ integer: Element) -> Element {
332-
return _handle.map { $0.indexGreaterThanIndex(integer) }
330+
/// Returns an integer contained in `self` which is greater than `integer`, or `nil` if a result could not be found.
331+
public func integerGreaterThan(_ integer: Element) -> Element? {
332+
return _handle.map { _toOptional($0.indexGreaterThanIndex(integer)) }
333333
}
334334

335-
/// Returns an integer contained in `self` which is less than `integer`.
336-
public func integerLessThan(_ integer: Element) -> Element {
337-
return _handle.map { $0.indexLessThanIndex(integer) }
335+
/// Returns an integer contained in `self` which is less than `integer`, or `nil` if a result could not be found.
336+
public func integerLessThan(_ integer: Element) -> Element? {
337+
return _handle.map { _toOptional($0.indexLessThanIndex(integer)) }
338338
}
339339

340-
/// Returns an integer contained in `self` which is greater than or equal to `integer`.
341-
public func integerGreaterThanOrEqualTo(_ integer: Element) -> Element {
342-
return _handle.map { $0.indexGreaterThanOrEqual(to: integer) }
340+
/// Returns an integer contained in `self` which is greater than or equal to `integer`, or `nil` if a result could not be found.
341+
public func integerGreaterThanOrEqualTo(_ integer: Element) -> Element? {
342+
return _handle.map { _toOptional($0.indexGreaterThanOrEqual(to: integer)) }
343343
}
344344

345-
/// Returns an integer contained in `self` which is less than or equal to `integer`.
346-
public func integerLessThanOrEqualTo(_ integer: Element) -> Element {
347-
return _handle.map { $0.indexLessThanOrEqual(to: integer) }
345+
/// Returns an integer contained in `self` which is less than or equal to `integer`, or `nil` if a result could not be found.
346+
public func integerLessThanOrEqualTo(_ integer: Element) -> Element? {
347+
return _handle.map { _toOptional($0.indexLessThanOrEqual(to: integer)) }
348348
}
349349

350350
/// Return a `Range<IndexSet.Index>` which can be used to subscript the index set.
351351
///
352-
/// The resulting range is the range of the intersection of the integers in `range` with the index set.
352+
/// The resulting range is the range of the intersection of the integers in `range` with the index set. The resulting range will be `isEmpty` if the intersection is empty.
353353
///
354354
/// - parameter range: The range of integers to include.
355355
public func indexRange(in range: Range<Element>) -> Range<Index> {
@@ -363,9 +363,14 @@ public struct IndexSet : ReferenceConvertible, Equatable, BidirectionalCollectio
363363
return i..<i
364364
}
365365

366-
let resultFirst = _index(ofInteger: integerGreaterThanOrEqualTo(range.lowerBound))
367-
let resultLast = _index(ofInteger: integerLessThanOrEqualTo(range.upperBound - 1))
368-
return resultFirst..<index(after: resultLast)
366+
if let start = integerGreaterThanOrEqualTo(range.lowerBound), let end = integerLessThanOrEqualTo(range.upperBound - 1) {
367+
let resultFirst = _index(ofInteger: start)
368+
let resultLast = _index(ofInteger: end)
369+
return resultFirst..<index(after: resultLast)
370+
} else {
371+
let i = _index(ofInteger: 0)
372+
return i..<i
373+
}
369374
}
370375

371376
/// Return a `Range<IndexSet.Index>` which can be used to subscript the index set.

test/1_stdlib/TestIndexSet.swift

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ class TestIndexSet : TestIndexSetSuper {
7979

8080
r = someIndexes.indexRange(in: 100..<201)
8181
expectEqual(r.lowerBound, r.upperBound)
82+
expectTrue(r.isEmpty)
8283

8384
r = someIndexes.indexRange(in: 0..<100)
8485
expectEqual(r.lowerBound, someIndexes.startIndex)
@@ -87,6 +88,9 @@ class TestIndexSet : TestIndexSetSuper {
8788
r = someIndexes.indexRange(in: 1..<11)
8889
expectEqual(1, someIndexes[r.lowerBound])
8990
expectEqual(11, someIndexes[r.upperBound])
91+
92+
let empty = IndexSet()
93+
expectTrue(empty.indexRange(in: 1..<3).isEmpty)
9094
}
9195

9296
func testMutation() {
@@ -728,6 +732,36 @@ class TestIndexSet : TestIndexSetSuper {
728732
}
729733
}
730734

735+
func test_findIndex() {
736+
var i = IndexSet()
737+
738+
// Verify nil result for empty sets
739+
expectEqual(nil, i.first)
740+
expectEqual(nil, i.last)
741+
expectEqual(nil, i.integerGreaterThan(5))
742+
expectEqual(nil, i.integerLessThan(5))
743+
expectEqual(nil, i.integerGreaterThanOrEqualTo(5))
744+
expectEqual(nil, i.integerLessThanOrEqualTo(5))
745+
746+
i.insert(integersIn: 5..<10)
747+
i.insert(integersIn: 15..<20)
748+
749+
// Verify non-nil result
750+
expectEqual(5, i.first)
751+
expectEqual(19, i.last)
752+
753+
expectEqual(nil, i.integerGreaterThan(19))
754+
expectEqual(5, i.integerGreaterThan(3))
755+
756+
expectEqual(nil, i.integerLessThan(5))
757+
expectEqual(5, i.integerLessThan(6))
758+
759+
expectEqual(nil, i.integerGreaterThanOrEqualTo(20))
760+
expectEqual(19, i.integerGreaterThanOrEqualTo(19))
761+
762+
expectEqual(nil, i.integerLessThanOrEqualTo(4))
763+
expectEqual(5, i.integerLessThanOrEqualTo(5))
764+
}
731765

732766
// MARK: -
733767
// MARK: Performance Testing
@@ -806,6 +840,7 @@ IndexSetTests.test("testSubsequences") { TestIndexSet().testSubsequences() }
806840
IndexSetTests.test("testFiltering") { TestIndexSet().testFiltering() }
807841
IndexSetTests.test("testFilteringRanges") { TestIndexSet().testFilteringRanges() }
808842
IndexSetTests.test("testShift") { TestIndexSet().testShift() }
843+
IndexSetTests.test("test_findIndex") { TestIndexSet().test_findIndex() }
809844
// IndexSetTests.test("testIndexingPerformance") { TestIndexSet().testIndexingPerformance() }
810845
IndexSetTests.test("test_AnyHashableContainingIndexSet") { TestIndexSet().test_AnyHashableContainingIndexSet() }
811846
IndexSetTests.test("test_AnyHashableCreatedFromNSIndexSet") { TestIndexSet().test_AnyHashableCreatedFromNSIndexSet() }

0 commit comments

Comments
 (0)