forked from swiftlang/swift-corelibs-foundation
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathBridging.swift
147 lines (121 loc) · 4.34 KB
/
Bridging.swift
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
//===----------------------------------------------------------------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See http://swift.org/LICENSE.txt for license information
// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//
import CoreFoundation
// Support protocols for casting
public protocol _ObjectBridgeable {
func _bridgeToAnyObject() -> AnyObject
}
public protocol _StructBridgeable {
func _bridgeToAny() -> Any
}
/// - Note: This is a similar interface to the _ObjectiveCBridgeable protocol
public protocol _ObjectTypeBridgeable : _ObjectBridgeable {
associatedtype _ObjectType : AnyObject
func _bridgeToObjectiveC() -> _ObjectType
static func _forceBridgeFromObjectiveC(_ source: _ObjectType, result: inout Self?)
@discardableResult
static func _conditionallyBridgeFromObjectiveC(_ source: _ObjectType, result: inout Self?) -> Bool
static func _unconditionallyBridgeFromObjectiveC(_ source: _ObjectType?) -> Self
}
/// - Note: This does not exist currently on Darwin but it is the inverse correlation to the bridge types such that a
/// reference type can be converted via a callout to a conversion method.
public protocol _StructTypeBridgeable : _StructBridgeable {
associatedtype _StructType
func _bridgeToSwift() -> _StructType
}
// Default adoption of the type specific variants to the Any variant
extension _ObjectTypeBridgeable {
public func _bridgeToAnyObject() -> AnyObject {
return _bridgeToObjectiveC()
}
}
extension _StructTypeBridgeable {
public func _bridgeToAny() -> Any {
return _bridgeToSwift()
}
}
// slated for removal, these are the swift-corelibs-only variant of the _ObjectiveCBridgeable
internal protocol _CFBridgeable {
associatedtype CFType
var _cfObject: CFType { get }
}
internal protocol _SwiftBridgeable {
associatedtype SwiftType
var _swiftObject: SwiftType { get }
}
internal protocol _NSBridgeable {
associatedtype NSType
var _nsObject: NSType { get }
}
/// - Note: This is an internal boxing value for containing abstract structures
internal final class _SwiftValue : NSObject, NSCopying {
internal private(set) var value: Any
static func fetch(_ object: AnyObject?) -> Any? {
if let obj = object {
return fetch(nonOptional: obj)
}
return nil
}
static func fetch(nonOptional object: AnyObject) -> Any {
if object === kCFBooleanTrue {
return true
} else if object === kCFBooleanFalse {
return false
} else if let container = object as? _SwiftValue {
return container.value
} else if let val = object as? _StructBridgeable {
return val._bridgeToAny()
} else {
return object
}
}
static func store(_ value: Any?) -> NSObject? {
if let val = value {
return store(val)
}
return nil
}
static func store(_ value: Any) -> NSObject {
if let val = value as? NSObject {
return val
} else if let val = value as? _ObjectBridgeable {
return val._bridgeToAnyObject() as! NSObject
} else {
return _SwiftValue(value)
}
}
init(_ value: Any) {
self.value = value
}
override var hash: Int {
if let hashable = value as? AnyHashable {
return hashable.hashValue
}
return ObjectIdentifier(self).hashValue
}
override func isEqual(_ value: Any?) -> Bool {
switch value {
case let other as _SwiftValue:
guard let left = other.value as? AnyHashable,
let right = self.value as? AnyHashable else { return self === other }
return left == right
case let other as AnyHashable:
guard let hashable = self.value as? AnyHashable else { return false }
return other == hashable
default:
return false
}
}
public func copy(with zone: NSZone?) -> Any {
return _SwiftValue(value)
}
}