Files
swift-mirror/stdlib/core/BridgeStorage.swift
Dave Abrahams 8a27fb8178 [stdlib] Integrate BridgeStorage into the stdlib
We're going to use it for Array internals.  When we do, it should be
expected to cause a performance hit on arrays of value types until
rdar://18125016 is handled.

Swift SVN r22784
2014-10-15 23:32:44 +00:00

108 lines
2.9 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
enum _BridgeStorage<
NativeType: AnyObject, CocoaType: AnyObject
> {
public // @testable
typealias Native = NativeType
public // @testable
typealias Cocoa = CocoaType
public // @testable
init(_ native: Native, bits: Int) {
_sanityCheck(_usesNativeSwiftReferenceCounting(NativeType.self))
_sanityCheck(!_usesNativeSwiftReferenceCounting(CocoaType.self))
switch bits {
case 0: self = .Native0(native)
case 1: self = .Native1(native)
case 2: self = .Native2(native)
default:
// on i386, we have 2 spare bits. Other platforms have more.
_sanityCheckFailure(
"BridgeStorage can't store bits outside the range 0-2")
}
}
public // @testable
init(_ cocoa: Cocoa) {
_sanityCheck(_usesNativeSwiftReferenceCounting(NativeType.self))
_sanityCheck(!_usesNativeSwiftReferenceCounting(CocoaType.self))
self = .Cocoa0(cocoa)
}
public // @testable
var native: Native? {
switch self {
case Native0(let x):
return x
case Native1(let x):
return x
case Native2(let x):
return x
default:
return nil
}
}
public // @testable
var cocoa: Cocoa? {
switch self {
case Cocoa0(let x):
return x
default:
return nil
}
}
public // @testable
var spareBits: Int {
switch self {
case Native1:
return 1
case Native2:
return 2
default:
return 0
}
}
public // @testable
mutating func isUniquelyReferenced() -> Bool {
if let raw = native.map({ Builtin.bridgeToRawPointer($0) }) {
return _swift_isUniquelyReferenced_nonNull_native(UnsafePointer(raw)) != 0
}
return false
}
//===--- private/internal -----------------------------------------------===//
case Native0(Native)
case Native1(Native)
case Native2(Native)
case Cocoa0(CocoaType)
}