mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
Fix IndexSet.RangeView indexing with subranges
On initialization, IndexSet.RangeView made the erroneous assumption that given an intersection range, a nil _indexOfRange(containing: bound) indicated that the bound was beyond the beginning or end of the index set. Instead, the index could simply not exist. We now calculate the actual intersection of the parent index set with the given intersection range and use that as the index set to view. This also makes the unit tests for testing range views more comprehensive.
This commit is contained in:
@@ -58,42 +58,16 @@ public struct IndexSet : ReferenceConvertible, Equatable, BidirectionalCollectio
|
||||
|
||||
fileprivate var indexSet: IndexSet
|
||||
|
||||
// Range of element values
|
||||
private var intersectingRange : Range<IndexSet.Element>?
|
||||
|
||||
fileprivate init(indexSet : IndexSet, intersecting range : Range<IndexSet.Element>?) {
|
||||
self.indexSet = indexSet
|
||||
self.intersectingRange = range
|
||||
|
||||
if let r = range {
|
||||
if r.lowerBound == r.upperBound {
|
||||
startIndex = 0
|
||||
endIndex = 0
|
||||
} else {
|
||||
let minIndex = indexSet._indexOfRange(containing: r.lowerBound)
|
||||
let maxIndex = indexSet._indexOfRange(containing: r.upperBound)
|
||||
|
||||
switch (minIndex, maxIndex) {
|
||||
case (nil, nil):
|
||||
startIndex = 0
|
||||
endIndex = 0
|
||||
case (nil, .some(let max)):
|
||||
// Start is before our first range
|
||||
startIndex = 0
|
||||
endIndex = max + 1
|
||||
case (.some(let min), nil):
|
||||
// End is after our last range
|
||||
startIndex = min
|
||||
endIndex = indexSet._rangeCount
|
||||
case (.some(let min), .some(let max)):
|
||||
startIndex = min
|
||||
endIndex = max + 1
|
||||
}
|
||||
}
|
||||
let otherIndexes = IndexSet(integersIn: r)
|
||||
self.indexSet = indexSet.intersection(otherIndexes)
|
||||
} else {
|
||||
startIndex = 0
|
||||
endIndex = indexSet._rangeCount
|
||||
self.indexSet = indexSet
|
||||
}
|
||||
|
||||
self.startIndex = 0
|
||||
self.endIndex = self.indexSet._rangeCount
|
||||
}
|
||||
|
||||
public func makeIterator() -> IndexingIterator<RangeView> {
|
||||
@@ -102,11 +76,7 @@ public struct IndexSet : ReferenceConvertible, Equatable, BidirectionalCollectio
|
||||
|
||||
public subscript(index : Index) -> CountableRange<IndexSet.Element> {
|
||||
let indexSetRange = indexSet._range(at: index)
|
||||
if let intersectingRange = intersectingRange {
|
||||
return Swift.max(intersectingRange.lowerBound, indexSetRange.lowerBound)..<Swift.min(intersectingRange.upperBound, indexSetRange.upperBound)
|
||||
} else {
|
||||
return indexSetRange.lowerBound..<indexSetRange.upperBound
|
||||
}
|
||||
return indexSetRange.lowerBound..<indexSetRange.upperBound
|
||||
}
|
||||
|
||||
public subscript(bounds: Range<Index>) -> BidirectionalSlice<RangeView> {
|
||||
|
||||
Reference in New Issue
Block a user