Skip to content

Commit 93d4c8c

Browse files
authored
Merge pull request #1469 from philium/consolidate-index-checking-in-NSOrderedSet
2 parents 9d123b7 + a72e793 commit 93d4c8c

File tree

1 file changed

+26
-22
lines changed

1 file changed

+26
-22
lines changed

Foundation/NSOrderedSet.swift

Lines changed: 26 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ open class NSOrderedSet : NSObject, NSCopying, NSMutableCopying, NSSecureCoding,
4141
guard aCoder.allowsKeyedCoding else {
4242
preconditionFailure("Unkeyed coding is unsupported.")
4343
}
44-
for idx in 0..<self.count {
44+
for idx in _indices {
4545
aCoder.encode(__SwiftValue.store(self.object(at: idx)), forKey:"NS.object.\(idx)")
4646
}
4747
}
@@ -67,6 +67,7 @@ open class NSOrderedSet : NSObject, NSCopying, NSMutableCopying, NSSecureCoding,
6767
}
6868

6969
open func object(at idx: Int) -> Any {
70+
_validateSubscript(idx)
7071
return __SwiftValue.fetch(nonOptional: _orderedStorage[idx])
7172
}
7273

@@ -120,11 +121,21 @@ open class NSOrderedSet : NSObject, NSCopying, NSMutableCopying, NSSecureCoding,
120121
if type(of: self) === NSOrderedSet.self || type(of: self) === NSMutableOrderedSet.self {
121122
return _orderedStorage.map { __SwiftValue.fetch(nonOptional: $0) }
122123
} else {
123-
return (0..<count).map { idx in
124+
return _indices.map { idx in
124125
return self[idx]
125126
}
126127
}
127128
}
129+
130+
/// The range of indices that are valid for subscripting the ordered set.
131+
internal var _indices: Range<Int> {
132+
return 0..<count
133+
}
134+
135+
/// Checks that an index is valid for subscripting: 0 ≤ `index` < `count`.
136+
internal func _validateSubscript(_ index: Int, file: StaticString = #file, line: UInt = #line) {
137+
precondition(_indices.contains(index), "\(self): Index out of bounds", file: file, line: line)
138+
}
128139
}
129140

130141
extension NSOrderedSet : Sequence {
@@ -148,9 +159,6 @@ extension NSOrderedSet {
148159
open func objects(at indexes: IndexSet) -> [Any] {
149160
var entries = [Any]()
150161
for idx in indexes {
151-
guard idx < count && idx >= 0 else {
152-
fatalError("\(self): Index out of bounds")
153-
}
154162
entries.append(object(at: idx))
155163
}
156164
return entries
@@ -177,7 +185,7 @@ extension NSOrderedSet {
177185
return false
178186
}
179187

180-
for idx in 0..<count {
188+
for idx in _indices {
181189
if let value1 = object(at: idx) as? AnyHashable,
182190
let value2 = other.object(at: idx) as? AnyHashable {
183191
if value1 != value2 {
@@ -338,9 +346,7 @@ extension NSOrderedSet {
338346
open class NSMutableOrderedSet : NSOrderedSet {
339347

340348
open func insert(_ object: Any, at idx: Int) {
341-
guard idx <= count && idx >= 0 else {
342-
fatalError("\(self): Index out of bounds")
343-
}
349+
precondition(idx <= count && idx >= 0, "\(self): Index out of bounds")
344350

345351
let value = __SwiftValue.store(object)
346352

@@ -353,15 +359,12 @@ open class NSMutableOrderedSet : NSOrderedSet {
353359
}
354360

355361
open func removeObject(at idx: Int) {
362+
_validateSubscript(idx)
356363
_storage.remove(_orderedStorage[idx])
357364
_orderedStorage.remove(at: idx)
358365
}
359366

360367
open func replaceObject(at idx: Int, with obj: Any) {
361-
guard idx < count && idx >= 0 else {
362-
fatalError("\(self): Index out of bounds")
363-
}
364-
365368
let value = __SwiftValue.store(obj)
366369
let objectToReplace = __SwiftValue.store(object(at: idx))
367370
_orderedStorage[idx] = value
@@ -420,10 +423,6 @@ extension NSMutableOrderedSet {
420423
}
421424

422425
open func exchangeObject(at idx1: Int, withObjectAt idx2: Int) {
423-
guard idx1 < count && idx1 >= 0 && idx2 < count && idx2 >= 0 else {
424-
fatalError("\(self): Index out of bounds")
425-
}
426-
427426
let object1 = self.object(at: idx1)
428427
let object2 = self.object(at: idx2)
429428
_orderedStorage[idx1] = __SwiftValue.store(object2)
@@ -450,13 +449,18 @@ extension NSMutableOrderedSet {
450449
}
451450
}
452451

452+
/// Sets the object at the specified index of the mutable ordered set.
453+
///
454+
/// - Parameters:
455+
/// - obj: The object to be set.
456+
/// - idx: The index. If the index is equal to `count`, then it appends
457+
/// the object. Otherwise it replaces the object at the index with the
458+
/// given object.
453459
open func setObject(_ obj: Any, at idx: Int) {
454-
let object = __SwiftValue.store(obj)
455-
_storage.insert(object)
456-
if idx == _orderedStorage.count {
457-
_orderedStorage.append(object)
460+
if idx == count {
461+
insert(obj, at: idx)
458462
} else {
459-
_orderedStorage[idx] = object
463+
replaceObject(at: idx, with: obj)
460464
}
461465
}
462466

0 commit comments

Comments
 (0)