Skip to content

Commit fe6eab4

Browse files
authored
Merge pull request #25345 from lorentey/foundation-diff-apis
[Foundation] Bridge difference APIs between Foundation and swift stdlib
2 parents 2eaae45 + 6348f14 commit fe6eab4

File tree

1 file changed

+106
-0
lines changed

1 file changed

+106
-0
lines changed
Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
6+
// Licensed under Apache License v2.0 with Runtime Library Exception
7+
//
8+
// See https://swift.org/LICENSE.txt for license information
9+
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10+
//
11+
//===----------------------------------------------------------------------===//
12+
13+
@_exported import Foundation // Clang module
14+
15+
// CollectionDifference<ChangeElement>.Change is conditionally bridged to NSOrderedCollectionChange
16+
@available(iOS 9999, macOS 9999, tvOS 9999, watchOS 9999, *) // FIXME(availability-5.1)
17+
extension CollectionDifference.Change : _ObjectiveCBridgeable {
18+
@_semantics("convertToObjectiveC")
19+
public func _bridgeToObjectiveC() -> NSOrderedCollectionChange {
20+
switch self {
21+
case .insert(offset: let o, element: let e, associatedWith: let a):
22+
return NSOrderedCollectionChange(object: e, type: .insert, index: o, associatedIndex: a ?? NSNotFound)
23+
case .remove(offset: let o, element: let e, associatedWith: let a):
24+
return NSOrderedCollectionChange(object: e, type: .remove, index: o, associatedIndex: a ?? NSNotFound)
25+
}
26+
}
27+
28+
public static func _forceBridgeFromObjectiveC(_ input: NSOrderedCollectionChange, result: inout CollectionDifference.Change?) {
29+
let _ = input.object as! ChangeElement
30+
31+
if !_conditionallyBridgeFromObjectiveC(input, result: &result) {
32+
fatalError("Unable to bridge \(_ObjectiveCType.self) to \(self)")
33+
}
34+
}
35+
36+
public static func _conditionallyBridgeFromObjectiveC(
37+
_ x: NSOrderedCollectionChange, result: inout CollectionDifference.Change?
38+
) -> Bool {
39+
guard let element = x.object as? ChangeElement else { return false }
40+
41+
let a: Int?
42+
if x.associatedIndex == NSNotFound {
43+
a = nil
44+
} else {
45+
a = x.associatedIndex
46+
}
47+
48+
switch x.changeType {
49+
case .insert:
50+
result = .insert(offset: x.index, element: element, associatedWith: a)
51+
case .remove:
52+
result = .remove(offset: x.index, element: element, associatedWith: a)
53+
default:
54+
return false
55+
}
56+
57+
return true
58+
}
59+
60+
@_effects(readonly)
61+
public static func _unconditionallyBridgeFromObjectiveC(_ s: NSOrderedCollectionChange?) -> CollectionDifference.Change {
62+
var result: CollectionDifference<ChangeElement>.Change? = nil
63+
CollectionDifference<ChangeElement>.Change._forceBridgeFromObjectiveC(s!, result: &result)
64+
return result!
65+
}
66+
}
67+
68+
// CollectionDifference<ChangeElement> is conditionally bridged to NSOrderedCollectionDifference
69+
@available(iOS 9999, macOS 9999, tvOS 9999, watchOS 9999, *) // FIXME(availability-5.1)
70+
extension CollectionDifference : _ObjectiveCBridgeable {
71+
@_semantics("convertToObjectiveC")
72+
public func _bridgeToObjectiveC() -> NSOrderedCollectionDifference {
73+
return NSOrderedCollectionDifference(changes: self.map({ $0 as NSOrderedCollectionChange }))
74+
}
75+
76+
public static func _forceBridgeFromObjectiveC(_ input: NSOrderedCollectionDifference, result: inout CollectionDifference?) {
77+
if !_conditionallyBridgeFromObjectiveC(input, result: &result) {
78+
fatalError("Unable to bridge \(_ObjectiveCType.self) to \(self)")
79+
}
80+
}
81+
82+
private static func _formDifference(
83+
from input: NSOrderedCollectionDifference,
84+
_ changeConverter: (Any) -> CollectionDifference<ChangeElement>.Change?
85+
) -> CollectionDifference<ChangeElement>? {
86+
var changes = Array<Change>()
87+
let iteratorSeq = IteratorSequence(NSFastEnumerationIterator(input))
88+
for objc_change in iteratorSeq {
89+
guard let swift_change = changeConverter(objc_change) else { return nil }
90+
changes.append(swift_change)
91+
}
92+
return CollectionDifference(changes)
93+
}
94+
95+
public static func _conditionallyBridgeFromObjectiveC(
96+
_ input: NSOrderedCollectionDifference, result: inout CollectionDifference?
97+
) -> Bool {
98+
result = _formDifference(from: input) { $0 as? Change }
99+
return result != nil
100+
}
101+
102+
@_effects(readonly)
103+
public static func _unconditionallyBridgeFromObjectiveC(_ s: NSOrderedCollectionDifference?) -> CollectionDifference {
104+
return _formDifference(from: s!) { $0 as! Change }!
105+
}
106+
}

0 commit comments

Comments
 (0)