Skip to content

Commit 273fa4f

Browse files
committed
NSOrderedSet: Implement more functionality
- Add copy() and mutableCopy(). - Add .set and .array to return immumtable views of the current contents. - Implement index(of:inSortedRange:options:usingComparator cmp:) by calling NSArray()'s version on ._orderedStorage. - Implement description(withLocale:), description(withLocale:indent:), .description and .customMirror. - NSCoding still needs to be implemented.
1 parent 2ab5621 commit 273fa4f

File tree

2 files changed

+113
-37
lines changed

2 files changed

+113
-37
lines changed

Foundation/NSOrderedSet.swift

Lines changed: 112 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -8,24 +8,46 @@
88
//
99

1010
/**************** Immutable Ordered Set ****************/
11-
open class NSOrderedSet : NSObject, NSCopying, NSMutableCopying, NSSecureCoding, ExpressibleByArrayLiteral {
12-
internal var _storage: NSSet
13-
internal var _orderedStorage: NSArray
11+
open class NSOrderedSet: NSObject, NSCopying, NSMutableCopying, NSSecureCoding, ExpressibleByArrayLiteral {
12+
13+
fileprivate var _storage: NSSet
14+
fileprivate var _orderedStorage: NSArray
1415

1516
open override func copy() -> Any {
1617
return copy(with: nil)
1718
}
1819

1920
open func copy(with zone: NSZone? = nil) -> Any {
20-
NSUnimplemented()
21+
if type(of: self) === NSOrderedSet.self {
22+
return self
23+
} else {
24+
return NSOrderedSet(storage: self.set as NSSet, orderedStorage: self.array as NSArray)
25+
}
2126
}
2227

2328
open override func mutableCopy() -> Any {
2429
return mutableCopy(with: nil)
2530
}
2631

2732
open func mutableCopy(with zone: NSZone? = nil) -> Any {
28-
NSUnimplemented()
33+
if type(of: self) === NSOrderedSet.self || type(of: self) === NSMutableOrderedSet.self {
34+
let mutableOrderedSet = NSMutableOrderedSet()
35+
mutableOrderedSet._mutableStorage._storage = self._storage._storage
36+
mutableOrderedSet._storage = mutableOrderedSet._mutableStorage
37+
mutableOrderedSet._mutableOrderedStorage._storage = self._orderedStorage._storage
38+
mutableOrderedSet._orderedStorage = mutableOrderedSet._mutableOrderedStorage
39+
return mutableOrderedSet
40+
} else {
41+
let count = self.count
42+
let mutableSet = NSMutableSet(capacity: count)
43+
let mutableArray = NSMutableArray(capacity: count)
44+
45+
for obj in self {
46+
mutableSet.add(obj)
47+
mutableArray.add(obj)
48+
}
49+
return NSMutableOrderedSet(mutableStorage: mutableSet, mutableOrderedStorage: mutableArray)
50+
}
2951
}
3052

3153
public static var supportsSecureCoding: Bool {
@@ -124,21 +146,6 @@ open class NSOrderedSet : NSObject, NSCopying, NSMutableCopying, NSSecureCoding,
124146
internal func _validateSubscript(_ index: Int, file: StaticString = #file, line: UInt = #line) {
125147
precondition(_indices.contains(index), "\(self): Index out of bounds", file: file, line: line)
126148
}
127-
}
128-
129-
extension NSOrderedSet : Sequence {
130-
131-
public typealias Iterator = NSEnumerator.Iterator
132-
133-
/// Return a *generator* over the elements of this *sequence*.
134-
///
135-
/// - Complexity: O(1).
136-
public func makeIterator() -> Iterator {
137-
return self.objectEnumerator().makeIterator()
138-
}
139-
}
140-
141-
extension NSOrderedSet {
142149

143150
/// Returns an array with the objects at the specified indexes in the
144151
/// ordered set.
@@ -246,8 +253,31 @@ extension NSOrderedSet {
246253
// to the original ordered set will "show through" the facade and it will
247254
// appear to change spontaneously, since a copy of the ordered set is not
248255
// being made.
249-
public var array: [Any] { NSUnimplemented() }
250-
public var set: Set<AnyHashable> { NSUnimplemented() }
256+
public var array: [Any] {
257+
if type(of: self) === NSOrderedSet.self || type(of: self) === NSMutableOrderedSet.self {
258+
return _orderedStorage._storage
259+
} else {
260+
var result: [Any] = []
261+
result.reserveCapacity(self.count)
262+
for obj in self {
263+
result.append(obj)
264+
}
265+
return result
266+
}
267+
}
268+
269+
public var set: Set<AnyHashable> {
270+
if type(of: self) === NSOrderedSet.self || type(of: self) === NSMutableOrderedSet.self {
271+
return _storage._storage
272+
} else {
273+
var result: Set<AnyHashable> = []
274+
result.reserveCapacity(self.count)
275+
for obj in self {
276+
result.insert(obj as! AnyHashable)
277+
}
278+
return result
279+
}
280+
}
251281

252282
open func enumerateObjects(_ block: (Any, Int, UnsafeMutablePointer<ObjCBool>) -> Swift.Void) {
253283
_orderedStorage.enumerateObjects(block)
@@ -284,8 +314,11 @@ extension NSOrderedSet {
284314
open func indexes(ofObjectsAt s: IndexSet, options opts: NSEnumerationOptions = [], passingTest predicate: (Any, Int, UnsafeMutablePointer<ObjCBool>) -> Bool) -> IndexSet {
285315
return _orderedStorage.indexesOfObjects(at: s, options: opts, passingTest: predicate)
286316
}
287-
288-
open func index(of object: Any, inSortedRange range: NSRange, options opts: NSBinarySearchingOptions = [], usingComparator cmp: (Any, Any) -> ComparisonResult) -> Int { NSUnimplemented() } // binary search
317+
318+
// binary search
319+
open func index(of object: Any, inSortedRange range: NSRange, options opts: NSBinarySearchingOptions = [], usingComparator cmp: (Any, Any) -> ComparisonResult) -> Int {
320+
return _orderedStorage.index(of:object, inSortedRange: range, options: opts, usingComparator: cmp)
321+
}
289322

290323
open func sortedArray(comparator cmptr: (Any, Any) -> ComparisonResult) -> [Any] {
291324
return sortedArray(options: [], usingComparator: cmptr)
@@ -294,13 +327,19 @@ extension NSOrderedSet {
294327
open func sortedArray(options opts: NSSortOptions = [], usingComparator cmptr: (Any, Any) -> ComparisonResult) -> [Any] {
295328
return _orderedStorage.sortedArray(options: opts, usingComparator: cmptr)
296329
}
297-
298-
public func description(withLocale locale: Locale?) -> String { NSUnimplemented() }
299-
public func description(withLocale locale: Locale?, indent level: Int) -> String { NSUnimplemented() }
300-
}
301330

302-
extension NSOrderedSet {
303-
331+
override open var description: String {
332+
return description(withLocale: nil)
333+
}
334+
335+
public func description(withLocale locale: Locale?) -> String {
336+
return description(withLocale: locale, indent: 0)
337+
}
338+
339+
public func description(withLocale locale: Locale?, indent level: Int) -> String {
340+
return _orderedStorage.description(withLocale: locale, indent: level)
341+
}
342+
304343
public convenience init(object: Any) {
305344
self.init(array: [object])
306345
}
@@ -358,10 +397,10 @@ extension NSOrderedSet {
358397

359398
/**************** Mutable Ordered Set ****************/
360399

361-
open class NSMutableOrderedSet : NSOrderedSet {
400+
open class NSMutableOrderedSet: NSOrderedSet {
362401

363-
internal var _mutableStorage: NSMutableSet
364-
internal var _mutableOrderedStorage: NSMutableArray
402+
fileprivate var _mutableStorage: NSMutableSet
403+
fileprivate var _mutableOrderedStorage: NSMutableArray
365404

366405
public override init(objects: UnsafePointer<AnyObject>?, count cnt: Int) {
367406
let storage = NSMutableSet(objects: objects, count: cnt)
@@ -418,8 +457,28 @@ open class NSMutableOrderedSet : NSOrderedSet {
418457
addObjects(from: elements)
419458
}
420459

460+
461+
fileprivate init(mutableStorage: NSMutableSet, mutableOrderedStorage: NSMutableArray) {
462+
_mutableStorage = mutableStorage
463+
_mutableOrderedStorage = mutableOrderedStorage
464+
super.init(objects: [], count: 0)
465+
_storage = _mutableStorage
466+
_orderedStorage = _mutableOrderedStorage
467+
}
468+
421469
public required init?(coder aDecoder: NSCoder) { NSUnimplemented() }
422470

471+
open override func copy(with zone: NSZone? = nil) -> Any {
472+
if type(of: self) === NSMutableOrderedSet.self {
473+
let orderedSet = NSOrderedSet()
474+
orderedSet._storage._storage = self._storage._storage
475+
orderedSet._orderedStorage._storage = self._orderedStorage._storage
476+
return orderedSet
477+
} else {
478+
return NSMutableOrderedSet(mutableStorage: NSMutableSet(set: self.set), mutableOrderedStorage: NSMutableArray(array: self.array))
479+
}
480+
}
481+
423482
fileprivate func _removeObject(_ object: Any) {
424483
guard contains(object) else {
425484
return
@@ -445,11 +504,7 @@ open class NSMutableOrderedSet : NSOrderedSet {
445504
replaceObject(at: idx, with: newValue)
446505
}
447506
}
448-
449-
}
450507

451-
extension NSMutableOrderedSet {
452-
453508
open func add(_ object: Any) {
454509
_insertObject(object)
455510
}
@@ -610,3 +665,23 @@ extension NSMutableOrderedSet {
610665
_mutableOrderedStorage.replaceObjects(in: range, withObjectsFrom: sortedSubrange)
611666
}
612667
}
668+
669+
670+
extension NSOrderedSet: Sequence {
671+
672+
public typealias Iterator = NSEnumerator.Iterator
673+
674+
/// Return a *generator* over the elements of this *sequence*.
675+
///
676+
/// - Complexity: O(1).
677+
public func makeIterator() -> Iterator {
678+
return self.objectEnumerator().makeIterator()
679+
}
680+
}
681+
682+
683+
extension NSOrderedSet: CustomReflectable {
684+
public var customMirror: Mirror {
685+
return Mirror(reflecting: _orderedStorage as Array)
686+
}
687+
}

TestFoundation/TestNSOrderedSet.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -247,6 +247,7 @@ class TestNSOrderedSet : XCTestCase {
247247
set.add("2")
248248
XCTAssertEqual(set[0] as? String, "1")
249249
XCTAssertEqual(set[1] as? String, "2")
250+
XCTAssertEqual(set.count, 2)
250251
}
251252

252253
func test_AddObjects() {

0 commit comments

Comments
 (0)