Files
swift-mirror/stdlib/core/BridgeStorage.swift
Joe Groff b60a30c84b stdlib: Make isUniquelyReferenced shims properly return bool.
rdar://problem/18573806 is fixed.

Swift SVN r23547
2014-11-22 05:36:38 +00:00

134 lines
3.8 KiB
Swift

//===--- BridgeStorage.swift - Discriminated storage for bridged types ----===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2015 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
//
//===----------------------------------------------------------------------===//
//
// Types that are bridged to Objective-C need to manage an object
// that may be either some native class or the @objc Cocoa
// equivalent. Ideally we would have a Builtin type that could
// discriminate between these two possibilities and store a few extra
// bits when the stored type is native. _BridgeStorage is an
// abstraction layer that will allow us to seamlessly integrate that
// type, when it becomes available.
//
//===----------------------------------------------------------------------===//
import SwiftShims
public // @testable
struct _BridgeStorage<
NativeClass: AnyObject, ObjCClass: AnyObject
> {
public // @testable
typealias Native = NativeClass
public // @testable
typealias ObjC = ObjCClass
@inline(__always)
public // @testable
init(native: Native, bits: Int) {
_sanityCheck(_usesNativeSwiftReferenceCounting(NativeClass.self))
_sanityCheck(0..<3 ~= bits,
"BridgeStorage can't store bits outside the range 0..<3")
rawValue = _makeNativeBridgeObject(
native, UInt(bits) << _objectPointerLowSpareBitShift)
}
@inline(__always)
public // @testable
init(objC: ObjC) {
_sanityCheck(_usesNativeSwiftReferenceCounting(NativeClass.self))
rawValue = _makeObjCBridgeObject(objC)
}
@inline(__always)
public // @testable
init(native: Native) {
_sanityCheck(_usesNativeSwiftReferenceCounting(NativeClass.self))
rawValue = Builtin.reinterpretCast(native)
}
public // @testable
var spareBits: Int {
@inline(__always) get {
_sanityCheck(isNative)
return Int(
_nonPointerBits(rawValue) >> _objectPointerLowSpareBitShift)
}
}
@inline(__always)
public // @testable
mutating func isUniquelyReferencedNative() -> Bool {
return _swift_isUniquelyReferencedNonObjC_nonNull_bridgeObject(
_bitPattern(rawValue)
)
}
public // @testable
var isNative: Bool {
@inline(__always) get {
return !_isTagged && _nonPointerBits(rawValue) != _objectPointerSpareBits
}
}
public // @testable
var isObjC: Bool {
@inline(__always) get {
return _isTagged || _nonPointerBits(rawValue) == _objectPointerSpareBits
}
}
public // @testable
var nativeInstance: Native {
@inline(__always) get {
_sanityCheck(isNative)
return Builtin.castReferenceFromBridgeObject(rawValue)
}
}
public // @testable
var nativeInstance_noSpareBits: Native {
@inline(__always) get {
_sanityCheck(isNative)
_sanityCheck(_nonPointerBits(rawValue) == 0)
return Builtin.reinterpretCast(rawValue)
}
}
@inline(__always)
public // @testable
mutating func isUniquelyReferenced_native_noSpareBits() -> Bool {
_sanityCheck(isNative)
_sanityCheck(_nonPointerBits(rawValue) == 0)
let p: UnsafePointer<HeapObject> = Builtin.reinterpretCast(rawValue)
return _swift_isUniquelyReferenced_nonNull_native(p)
}
public // @testable
var objCInstance: ObjC {
@inline(__always) get {
_sanityCheck(isObjC)
return Builtin.castReferenceFromBridgeObject(rawValue)
}
}
//===--- private --------------------------------------------------------===//
internal var _isTagged: Bool {
@inline(__always) get {
return _isObjCTaggedPointer(
Builtin.castReferenceFromBridgeObject(rawValue))
}
}
internal let rawValue: Builtin.BridgeObject
}