blob: bfd1ffe32a266a3cfb8a1d8897da3b6aca0f14bb [file] [log] [blame]
//===----------------------------------------------------------------------===//
//
// 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
//
//===----------------------------------------------------------------------===//
@_exported import Foundation // Clang module
import CoreFoundation
import CoreGraphics
//===----------------------------------------------------------------------===//
// NSObject
//===----------------------------------------------------------------------===//
// These conformances should be located in the `ObjectiveC` module, but they can't
// be placed there because string bridging is not available there.
extension NSObject : CustomStringConvertible {}
extension NSObject : CustomDebugStringConvertible {}
//===----------------------------------------------------------------------===//
// Strings
//===----------------------------------------------------------------------===//
@available(*, unavailable, message: "Please use String or NSString")
public class NSSimpleCString {}
@available(*, unavailable, message: "Please use String or NSString")
public class NSConstantString {}
@_silgen_name("swift_convertStringToNSString")
public // COMPILER_INTRINSIC
func _convertStringToNSString(_ string: String) -> NSString {
return string._bridgeToObjectiveC()
}
extension NSString : ExpressibleByStringLiteral {
/// Create an instance initialized to `value`.
public required convenience init(unicodeScalarLiteral value: StaticString) {
self.init(stringLiteral: value)
}
public required convenience init(
extendedGraphemeClusterLiteral value: StaticString
) {
self.init(stringLiteral: value)
}
/// Create an instance initialized to `value`.
public required convenience init(stringLiteral value: StaticString) {
var immutableResult: NSString
if value.hasPointerRepresentation {
immutableResult = NSString(
bytesNoCopy: UnsafeMutableRawPointer(mutating: value.utf8Start),
length: Int(value.utf8CodeUnitCount),
encoding: value.isASCII ? String.Encoding.ascii.rawValue : String.Encoding.utf8.rawValue,
freeWhenDone: false)!
} else {
var uintValue = value.unicodeScalar
immutableResult = NSString(
bytes: &uintValue,
length: 4,
encoding: String.Encoding.utf32.rawValue)!
}
self.init(string: immutableResult as String)
}
}
extension NSString : _HasCustomAnyHashableRepresentation {
// Must be @nonobjc to prevent infinite recursion trying to bridge
// AnyHashable to NSObject.
@nonobjc
public func _toCustomAnyHashable() -> AnyHashable? {
// Consistently use Swift equality and hashing semantics for all strings.
return AnyHashable(self as String)
}
}
//===----------------------------------------------------------------------===//
// New Strings
//===----------------------------------------------------------------------===//
//
// Conversion from NSString to Swift's native representation
//
extension String {
public init(_ cocoaString: NSString) {
self = String(_cocoaString: cocoaString)
}
}
extension String : _ObjectiveCBridgeable {
@_semantics("convertToObjectiveC")
public func _bridgeToObjectiveC() -> NSString {
// This method should not do anything extra except calling into the
// implementation inside core. (These two entry points should be
// equivalent.)
return unsafeBitCast(_bridgeToObjectiveCImpl() as AnyObject, to: NSString.self)
}
public static func _forceBridgeFromObjectiveC(
_ x: NSString,
result: inout String?
) {
result = String(x)
}
public static func _conditionallyBridgeFromObjectiveC(
_ x: NSString,
result: inout String?
) -> Bool {
self._forceBridgeFromObjectiveC(x, result: &result)
return result != nil
}
public static func _unconditionallyBridgeFromObjectiveC(
_ source: NSString?
) -> String {
// `nil` has historically been used as a stand-in for an empty
// string; map it to an empty string.
if _slowPath(source == nil) { return String() }
return String(source!)
}
}
//===----------------------------------------------------------------------===//
// Numbers
//===----------------------------------------------------------------------===//
@_silgen_name("_swift_Foundation_TypePreservingNSNumberWithInt")
internal func _swift_Foundation_TypePreservingNSNumberWithInt(
_ value: Int
) -> NSNumber
@_silgen_name("_swift_Foundation_TypePreservingNSNumberWithUInt")
internal func _swift_Foundation_TypePreservingNSNumberWithUInt(
_ value: UInt
) -> NSNumber
@_silgen_name("_swift_Foundation_TypePreservingNSNumberWithFloat")
internal func _swift_Foundation_TypePreservingNSNumberWithFloat(
_ value: Float
) -> NSNumber
@_silgen_name("_swift_Foundation_TypePreservingNSNumberWithDouble")
internal func _swift_Foundation_TypePreservingNSNumberWithDouble(
_ value: Double
) -> NSNumber
@_silgen_name("_swift_Foundation_TypePreservingNSNumberWithCGFloat")
internal func _swift_Foundation_TypePreservingNSNumberWithCGFloat(
_ value: CGFloat
) -> NSNumber
@_silgen_name("_swift_Foundation_TypePreservingNSNumberWithBool")
internal func _swift_Foundation_TypePreservingNSNumberWithBool(
_ value: Bool
) -> NSNumber
@_silgen_name("_swift_Foundation_TypePreservingNSNumberGetKind")
internal func _swift_Foundation_TypePreservingNSNumberGetKind(
_ value: NSNumber
) -> UInt32
// This enum has a matching counterpart in TypePreservingNSNumber.mm, please
// update both copies when changing it.
internal enum _SwiftTypePreservingNSNumberTag : Int {
case SwiftInt = 1
case SwiftUInt = 2
case SwiftFloat = 3
case SwiftDouble = 4
case CoreGraphicsCGFloat = 5
case SwiftBool = 6
}
@_silgen_name("_swift_Foundation_TypePreservingNSNumberGetAsInt")
internal func _swift_Foundation_TypePreservingNSNumberGetAsInt(
_ value: NSNumber
) -> Int
@_silgen_name("_swift_Foundation_TypePreservingNSNumberGetAsUInt")
internal func _swift_Foundation_TypePreservingNSNumberGetAsUInt(
_ value: NSNumber
) -> UInt
@_silgen_name("_swift_Foundation_TypePreservingNSNumberGetAsFloat")
internal func _swift_Foundation_TypePreservingNSNumberGetAsFloat(
_ value: NSNumber
) -> Float
@_silgen_name("_swift_Foundation_TypePreservingNSNumberGetAsDouble")
internal func _swift_Foundation_TypePreservingNSNumberGetAsDouble(
_ value: NSNumber
) -> Double
@_silgen_name("_swift_Foundation_TypePreservingNSNumberGetAsCGFloat")
internal func _swift_Foundation_TypePreservingNSNumberGetAsCGFloat(
_ value: NSNumber
) -> CGFloat
@_silgen_name("_swift_Foundation_TypePreservingNSNumberGetAsBool")
internal func _swift_Foundation_TypePreservingNSNumberGetAsBool(
_ value: NSNumber
) -> Bool
// Conversions between NSNumber and various numeric types. The
// conversion to NSNumber is automatic (auto-boxing), while conversion
// back to a specific numeric type requires a cast.
// FIXME: Incomplete list of types.
extension Int : _ObjectiveCBridgeable {
public init(_ number: NSNumber) {
self = number.intValue
}
@_semantics("convertToObjectiveC")
public func _bridgeToObjectiveC() -> NSNumber {
return _swift_Foundation_TypePreservingNSNumberWithInt(self)
}
public static func _forceBridgeFromObjectiveC(
_ x: NSNumber,
result: inout Int?
) {
result = x.intValue
}
public static func _conditionallyBridgeFromObjectiveC(
_ x: NSNumber,
result: inout Int?
) -> Bool {
self._forceBridgeFromObjectiveC(x, result: &result)
return true
}
public static func _unconditionallyBridgeFromObjectiveC(
_ source: NSNumber?
) -> Int {
return source!.intValue
}
}
extension UInt : _ObjectiveCBridgeable {
public init(_ number: NSNumber) {
self = number.uintValue
}
@_semantics("convertToObjectiveC")
public func _bridgeToObjectiveC() -> NSNumber {
return _swift_Foundation_TypePreservingNSNumberWithUInt(self)
}
public static func _forceBridgeFromObjectiveC(
_ x: NSNumber,
result: inout UInt?
) {
result = x.uintValue
}
public static func _conditionallyBridgeFromObjectiveC(
_ x: NSNumber,
result: inout UInt?
) -> Bool {
self._forceBridgeFromObjectiveC(x, result: &result)
return true
}
public static func _unconditionallyBridgeFromObjectiveC(
_ source: NSNumber?
) -> UInt {
return source!.uintValue
}
}
extension Float : _ObjectiveCBridgeable {
public init(_ number: NSNumber) {
self = number.floatValue
}
@_semantics("convertToObjectiveC")
public func _bridgeToObjectiveC() -> NSNumber {
return _swift_Foundation_TypePreservingNSNumberWithFloat(self)
}
public static func _forceBridgeFromObjectiveC(
_ x: NSNumber,
result: inout Float?
) {
result = x.floatValue
}
public static func _conditionallyBridgeFromObjectiveC(
_ x: NSNumber,
result: inout Float?
) -> Bool {
self._forceBridgeFromObjectiveC(x, result: &result)
return true
}
public static func _unconditionallyBridgeFromObjectiveC(
_ source: NSNumber?
) -> Float {
return source!.floatValue
}
}
extension Double : _ObjectiveCBridgeable {
public init(_ number: NSNumber) {
self = number.doubleValue
}
@_semantics("convertToObjectiveC")
public func _bridgeToObjectiveC() -> NSNumber {
return _swift_Foundation_TypePreservingNSNumberWithDouble(self)
}
public static func _forceBridgeFromObjectiveC(
_ x: NSNumber,
result: inout Double?
) {
result = x.doubleValue
}
public static func _conditionallyBridgeFromObjectiveC(
_ x: NSNumber,
result: inout Double?
) -> Bool {
self._forceBridgeFromObjectiveC(x, result: &result)
return true
}
public static func _unconditionallyBridgeFromObjectiveC(
_ source: NSNumber?
) -> Double {
return source!.doubleValue
}
}
extension Bool: _ObjectiveCBridgeable {
public init(_ number: NSNumber) {
self = number.boolValue
}
@_semantics("convertToObjectiveC")
public func _bridgeToObjectiveC() -> NSNumber {
return _swift_Foundation_TypePreservingNSNumberWithBool(self)
}
public static func _forceBridgeFromObjectiveC(
_ x: NSNumber,
result: inout Bool?
) {
result = x.boolValue
}
public static func _conditionallyBridgeFromObjectiveC(
_ x: NSNumber,
result: inout Bool?
) -> Bool {
self._forceBridgeFromObjectiveC(x, result: &result)
return true
}
public static func _unconditionallyBridgeFromObjectiveC(
_ source: NSNumber?
) -> Bool {
return source!.boolValue
}
}
// CGFloat bridging.
extension CGFloat : _ObjectiveCBridgeable {
public init(_ number: NSNumber) {
self.native = CGFloat.NativeType(number)
}
@_semantics("convertToObjectiveC")
public func _bridgeToObjectiveC() -> NSNumber {
return _swift_Foundation_TypePreservingNSNumberWithCGFloat(self)
}
public static func _forceBridgeFromObjectiveC(
_ x: NSNumber,
result: inout CGFloat?
) {
var nativeResult: CGFloat.NativeType? = 0.0
CGFloat.NativeType._forceBridgeFromObjectiveC(x, result: &nativeResult)
result = CGFloat(nativeResult!)
}
public static func _conditionallyBridgeFromObjectiveC(
_ x: NSNumber,
result: inout CGFloat?
) -> Bool {
self._forceBridgeFromObjectiveC(x, result: &result)
return true
}
public static func _unconditionallyBridgeFromObjectiveC(
_ source: NSNumber?
) -> CGFloat {
return CGFloat(
CGFloat.NativeType._unconditionallyBridgeFromObjectiveC(source))
}
}
// Literal support for NSNumber
extension NSNumber
: ExpressibleByFloatLiteral,
ExpressibleByIntegerLiteral,
ExpressibleByBooleanLiteral
{
/// Create an instance initialized to `value`.
public required convenience init(integerLiteral value: Int) {
self.init(value: value)
}
/// Create an instance initialized to `value`.
public required convenience init(floatLiteral value: Double) {
self.init(value: value)
}
/// Create an instance initialized to `value`.
public required convenience init(booleanLiteral value: Bool) {
self.init(value: value)
}
}
extension NSNumber : _HasCustomAnyHashableRepresentation {
// Must be @nonobjc to prevent infinite recursion trying to bridge
// AnyHashable to NSObject.
@nonobjc
public func _toCustomAnyHashable() -> AnyHashable? {
guard let kind = _SwiftTypePreservingNSNumberTag(
rawValue: Int(_swift_Foundation_TypePreservingNSNumberGetKind(self))
) else {
if let nsDecimalNumber: NSDecimalNumber = self as? NSDecimalNumber {
return AnyHashable(nsDecimalNumber as Decimal)
}
return nil
}
switch kind {
case .SwiftInt:
return AnyHashable(_swift_Foundation_TypePreservingNSNumberGetAsInt(self))
case .SwiftUInt:
return AnyHashable(_swift_Foundation_TypePreservingNSNumberGetAsUInt(self))
case .SwiftFloat:
return AnyHashable(_swift_Foundation_TypePreservingNSNumberGetAsFloat(self))
case .SwiftDouble:
return AnyHashable(_swift_Foundation_TypePreservingNSNumberGetAsDouble(self))
case .CoreGraphicsCGFloat:
return AnyHashable(_swift_Foundation_TypePreservingNSNumberGetAsCGFloat(self))
case .SwiftBool:
return AnyHashable(_swift_Foundation_TypePreservingNSNumberGetAsBool(self))
}
}
}
public let NSNotFound: Int = .max
//===----------------------------------------------------------------------===//
// Arrays
//===----------------------------------------------------------------------===//
extension NSArray : ExpressibleByArrayLiteral {
/// Create an instance initialized with `elements`.
public required convenience init(arrayLiteral elements: Any...) {
// Let bridging take care of it.
self.init(array: elements)
}
}
extension Array : _ObjectiveCBridgeable {
/// Private initializer used for bridging.
///
/// The provided `NSArray` will be copied to ensure that the copy can
/// not be mutated by other code.
internal init(_cocoaArray: NSArray) {
_sanityCheck(_isBridgedVerbatimToObjectiveC(Element.self),
"Array can be backed by NSArray only when the element type can be bridged verbatim to Objective-C")
// FIXME: We would like to call CFArrayCreateCopy() to avoid doing an
// objc_msgSend() for instances of CoreFoundation types. We can't do that
// today because CFArrayCreateCopy() copies array contents unconditionally,
// resulting in O(n) copies even for immutable arrays.
//
// <rdar://problem/19773555> CFArrayCreateCopy() is >10x slower than
// -[NSArray copyWithZone:]
//
// The bug is fixed in: OS X 10.11.0, iOS 9.0, all versions of tvOS
// and watchOS.
self = Array(
_immutableCocoaArray:
unsafeBitCast(_cocoaArray.copy() as AnyObject, to: _NSArrayCore.self))
}
@_semantics("convertToObjectiveC")
public func _bridgeToObjectiveC() -> NSArray {
return unsafeBitCast(self._bridgeToObjectiveCImpl(), to: NSArray.self)
}
public static func _forceBridgeFromObjectiveC(
_ source: NSArray,
result: inout Array?
) {
_precondition(
Swift._isBridgedToObjectiveC(Element.self),
"array element type is not bridged to Objective-C")
// If we have the appropriate native storage already, just adopt it.
if let native =
Array._bridgeFromObjectiveCAdoptingNativeStorageOf(source) {
result = native
return
}
if _fastPath(_isBridgedVerbatimToObjectiveC(Element.self)) {
// Forced down-cast (possible deferred type-checking)
result = Array(_cocoaArray: source)
return
}
result = _arrayForceCast([AnyObject](_cocoaArray: source))
}
public static func _conditionallyBridgeFromObjectiveC(
_ source: NSArray,
result: inout Array?
) -> Bool {
// Construct the result array by conditionally bridging each element.
let anyObjectArr = [AnyObject](_cocoaArray: source)
result = _arrayConditionalCast(anyObjectArr)
return result != nil
}
public static func _unconditionallyBridgeFromObjectiveC(
_ source: NSArray?
) -> Array {
// `nil` has historically been used as a stand-in for an empty
// array; map it to an empty array instead of failing.
if _slowPath(source == nil) { return Array() }
// If we have the appropriate native storage already, just adopt it.
if let native =
Array._bridgeFromObjectiveCAdoptingNativeStorageOf(source!) {
return native
}
if _fastPath(_isBridgedVerbatimToObjectiveC(Element.self)) {
// Forced down-cast (possible deferred type-checking)
return Array(_cocoaArray: source!)
}
return _arrayForceCast([AnyObject](_cocoaArray: source!))
}
}
//===----------------------------------------------------------------------===//
// Dictionaries
//===----------------------------------------------------------------------===//
extension NSDictionary : ExpressibleByDictionaryLiteral {
public required convenience init(
dictionaryLiteral elements: (Any, Any)...
) {
// FIXME: Unfortunate that the `NSCopying` check has to be done at runtime.
self.init(
objects: elements.map { $0.1 as AnyObject },
forKeys: elements.map { $0.0 as AnyObject as! NSCopying },
count: elements.count)
}
}
extension Dictionary {
/// Private initializer used for bridging.
///
/// The provided `NSDictionary` will be copied to ensure that the copy can
/// not be mutated by other code.
public init(_cocoaDictionary: _NSDictionary) {
_sanityCheck(
_isBridgedVerbatimToObjectiveC(Key.self) &&
_isBridgedVerbatimToObjectiveC(Value.self),
"Dictionary can be backed by NSDictionary storage only when both key and value are bridged verbatim to Objective-C")
// FIXME: We would like to call CFDictionaryCreateCopy() to avoid doing an
// objc_msgSend() for instances of CoreFoundation types. We can't do that
// today because CFDictionaryCreateCopy() copies dictionary contents
// unconditionally, resulting in O(n) copies even for immutable dictionaries.
//
// <rdar://problem/20690755> CFDictionaryCreateCopy() does not call copyWithZone:
//
// The bug is fixed in: OS X 10.11.0, iOS 9.0, all versions of tvOS
// and watchOS.
self = Dictionary(
_immutableCocoaDictionary:
unsafeBitCast(_cocoaDictionary.copy(with: nil) as AnyObject,
to: _NSDictionary.self))
}
}
// Dictionary<Key, Value> is conditionally bridged to NSDictionary
extension Dictionary : _ObjectiveCBridgeable {
@_semantics("convertToObjectiveC")
public func _bridgeToObjectiveC() -> NSDictionary {
return unsafeBitCast(_bridgeToObjectiveCImpl() as AnyObject,
to: NSDictionary.self)
}
public static func _forceBridgeFromObjectiveC(
_ d: NSDictionary,
result: inout Dictionary?
) {
if let native = [Key : Value]._bridgeFromObjectiveCAdoptingNativeStorageOf(
d as AnyObject) {
result = native
return
}
if _isBridgedVerbatimToObjectiveC(Key.self) &&
_isBridgedVerbatimToObjectiveC(Value.self) {
result = [Key : Value](
_cocoaDictionary: unsafeBitCast(d as AnyObject, to: _NSDictionary.self))
return
}
// `Dictionary<Key, Value>` where either `Key` or `Value` is a value type
// may not be backed by an NSDictionary.
var builder = _DictionaryBuilder<Key, Value>(count: d.count)
d.enumerateKeysAndObjects({
(anyKey: Any, anyValue: Any,
stop: UnsafeMutablePointer<ObjCBool>) in
let anyObjectKey = anyKey as AnyObject
let anyObjectValue = anyValue as AnyObject
builder.add(
key: Swift._forceBridgeFromObjectiveC(anyObjectKey, Key.self),
value: Swift._forceBridgeFromObjectiveC(anyObjectValue, Value.self))
})
result = builder.take()
}
public static func _conditionallyBridgeFromObjectiveC(
_ x: NSDictionary,
result: inout Dictionary?
) -> Bool {
let anyDict = x as [NSObject : AnyObject]
if _isBridgedVerbatimToObjectiveC(Key.self) &&
_isBridgedVerbatimToObjectiveC(Value.self) {
result = Swift._dictionaryDownCastConditional(anyDict)
return result != nil
}
result = Swift._dictionaryBridgeFromObjectiveCConditional(anyDict)
return result != nil
}
public static func _unconditionallyBridgeFromObjectiveC(
_ d: NSDictionary?
) -> Dictionary {
// `nil` has historically been used as a stand-in for an empty
// dictionary; map it to an empty dictionary.
if _slowPath(d == nil) { return Dictionary() }
if let native = [Key : Value]._bridgeFromObjectiveCAdoptingNativeStorageOf(
d! as AnyObject) {
return native
}
if _isBridgedVerbatimToObjectiveC(Key.self) &&
_isBridgedVerbatimToObjectiveC(Value.self) {
return [Key : Value](
_cocoaDictionary: unsafeBitCast(d! as AnyObject, to: _NSDictionary.self))
}
// `Dictionary<Key, Value>` where either `Key` or `Value` is a value type
// may not be backed by an NSDictionary.
var builder = _DictionaryBuilder<Key, Value>(count: d!.count)
d!.enumerateKeysAndObjects({
(anyKey: Any, anyValue: Any,
stop: UnsafeMutablePointer<ObjCBool>) in
builder.add(
key: Swift._forceBridgeFromObjectiveC(anyKey as AnyObject, Key.self),
value: Swift._forceBridgeFromObjectiveC(anyValue as AnyObject, Value.self))
})
return builder.take()
}
}
//===----------------------------------------------------------------------===//
// TextChecking
//===----------------------------------------------------------------------===//
extension NSTextCheckingResult.CheckingType {
public static var allSystemTypes : NSTextCheckingResult.CheckingType {
return NSTextCheckingResult.CheckingType(rawValue: 0xffffffff)
}
public static var allCustomTypes : NSTextCheckingResult.CheckingType {
return NSTextCheckingResult.CheckingType(rawValue: 0xffffffff << 32)
}
public static var allTypes : NSTextCheckingResult.CheckingType {
return NSTextCheckingResult.CheckingType(rawValue: UInt64.max)
}
}
//===----------------------------------------------------------------------===//
// Fast enumeration
//===----------------------------------------------------------------------===//
// NB: This is a class because fast enumeration passes around interior pointers
// to the enumeration state, so the state cannot be moved in memory. We will
// probably need to implement fast enumeration in the compiler as a primitive
// to implement it both correctly and efficiently.
final public class NSFastEnumerationIterator : IteratorProtocol {
var enumerable: NSFastEnumeration
var state: [NSFastEnumerationState]
var n: Int
var count: Int
/// Size of ObjectsBuffer, in ids.
static var STACK_BUF_SIZE: Int { return 4 }
var objects: [Unmanaged<AnyObject>?]
public func next() -> Any? {
if n == count {
// FIXME: Is this check necessary before refresh()?
if count == 0 { return nil }
refresh()
if count == 0 { return nil }
}
let next: Any = state[0].itemsPtr![n]!
n += 1
return next
}
func refresh() {
_sanityCheck(objects.count > 0)
n = 0
objects.withUnsafeMutableBufferPointer {
count = enumerable.countByEnumerating(
with: &state,
objects: AutoreleasingUnsafeMutablePointer($0.baseAddress!),
count: $0.count)
}
}
public init(_ enumerable: NSFastEnumeration) {
self.enumerable = enumerable
self.state = [ NSFastEnumerationState(
state: 0, itemsPtr: nil,
mutationsPtr: _fastEnumerationStorageMutationsPtr,
extra: (0, 0, 0, 0, 0)) ]
self.objects = Array(
repeating: nil, count: NSFastEnumerationIterator.STACK_BUF_SIZE)
self.n = -1
self.count = -1
}
}
extension NSArray : Sequence {
/// Return an *iterator* over the elements of this *sequence*.
///
/// - Complexity: O(1).
final public func makeIterator() -> NSFastEnumerationIterator {
return NSFastEnumerationIterator(self)
}
}
/* TODO: API review
extension NSArray : Swift.Collection {
final public var startIndex: Int {
return 0
}
final public var endIndex: Int {
return count
}
}
*/
extension Set {
/// Private initializer used for bridging.
///
/// The provided `NSSet` will be copied to ensure that the copy can
/// not be mutated by other code.
public init(_cocoaSet: _NSSet) {
_sanityCheck(_isBridgedVerbatimToObjectiveC(Element.self),
"Set can be backed by NSSet _variantStorage only when the member type can be bridged verbatim to Objective-C")
// FIXME: We would like to call CFSetCreateCopy() to avoid doing an
// objc_msgSend() for instances of CoreFoundation types. We can't do that
// today because CFSetCreateCopy() copies dictionary contents
// unconditionally, resulting in O(n) copies even for immutable dictionaries.
//
// <rdar://problem/20697680> CFSetCreateCopy() does not call copyWithZone:
//
// The bug is fixed in: OS X 10.11.0, iOS 9.0, all versions of tvOS
// and watchOS.
self = Set(
_immutableCocoaSet:
unsafeBitCast(_cocoaSet.copy(with: nil) as AnyObject, to: _NSSet.self))
}
}
extension NSSet : Sequence {
/// Return an *iterator* over the elements of this *sequence*.
///
/// - Complexity: O(1).
public func makeIterator() -> NSFastEnumerationIterator {
return NSFastEnumerationIterator(self)
}
}
extension NSOrderedSet : Sequence {
/// Return an *iterator* over the elements of this *sequence*.
///
/// - Complexity: O(1).
public func makeIterator() -> NSFastEnumerationIterator {
return NSFastEnumerationIterator(self)
}
}
// FIXME: move inside NSIndexSet when the compiler supports this.
public struct NSIndexSetIterator : IteratorProtocol {
public typealias Element = Int
internal let _set: NSIndexSet
internal var _first: Bool = true
internal var _current: Int?
internal init(set: NSIndexSet) {
self._set = set
self._current = nil
}
public mutating func next() -> Int? {
if _first {
_current = _set.firstIndex
_first = false
} else if let c = _current {
_current = _set.indexGreaterThanIndex(c)
} else {
// current is already nil
}
if _current == NSNotFound {
_current = nil
}
return _current
}
}
extension NSIndexSet : Sequence {
/// Return an *iterator* over the elements of this *sequence*.
///
/// - Complexity: O(1).
public func makeIterator() -> NSIndexSetIterator {
return NSIndexSetIterator(set: self)
}
}
// Set<Element> is conditionally bridged to NSSet
extension Set : _ObjectiveCBridgeable {
@_semantics("convertToObjectiveC")
public func _bridgeToObjectiveC() -> NSSet {
return unsafeBitCast(_bridgeToObjectiveCImpl() as AnyObject, to: NSSet.self)
}
public static func _forceBridgeFromObjectiveC(_ s: NSSet, result: inout Set?) {
if let native =
Set<Element>._bridgeFromObjectiveCAdoptingNativeStorageOf(s as AnyObject) {
result = native
return
}
if _isBridgedVerbatimToObjectiveC(Element.self) {
result = Set<Element>(_cocoaSet: unsafeBitCast(s, to: _NSSet.self))
return
}
// `Set<Element>` where `Element` is a value type may not be backed by
// an NSSet.
var builder = _SetBuilder<Element>(count: s.count)
s.enumerateObjects({
(anyMember: Any, stop: UnsafeMutablePointer<ObjCBool>) in
builder.add(member: Swift._forceBridgeFromObjectiveC(
anyMember as AnyObject, Element.self))
})
result = builder.take()
}
public static func _conditionallyBridgeFromObjectiveC(
_ x: NSSet, result: inout Set?
) -> Bool {
let anySet = x as Set<NSObject>
if _isBridgedVerbatimToObjectiveC(Element.self) {
result = Swift._setDownCastConditional(anySet)
return result != nil
}
result = Swift._setBridgeFromObjectiveCConditional(anySet)
return result != nil
}
public static func _unconditionallyBridgeFromObjectiveC(_ s: NSSet?) -> Set {
// `nil` has historically been used as a stand-in for an empty
// set; map it to an empty set.
if _slowPath(s == nil) { return Set() }
if let native =
Set<Element>._bridgeFromObjectiveCAdoptingNativeStorageOf(s! as AnyObject) {
return native
}
if _isBridgedVerbatimToObjectiveC(Element.self) {
return Set<Element>(_cocoaSet: unsafeBitCast(s! as AnyObject,
to: _NSSet.self))
}
// `Set<Element>` where `Element` is a value type may not be backed by
// an NSSet.
var builder = _SetBuilder<Element>(count: s!.count)
s!.enumerateObjects({
(anyMember: Any, stop: UnsafeMutablePointer<ObjCBool>) in
builder.add(member: Swift._forceBridgeFromObjectiveC(
anyMember as AnyObject, Element.self))
})
return builder.take()
}
}
/*
FIXME(id-as-any): uncomment this when we can cast NSSet to Set<AnyHashable>.
extension NSSet : _HasCustomAnyHashableRepresentation {
// Must be @nonobjc to avoid infinite recursion during bridging
@nonobjc
public func _toCustomAnyHashable() -> AnyHashable? {
var builder = _SetBuilder<Element>(count: s!.count)
// FIXME(id-as-any): how to get the Hashable conformance here?
s!.enumerateObjects({
(anyMember: Any, stop: UnsafeMutablePointer<ObjCBool>) in
builder.add(member: Swift._forceBridgeFromObjectiveC(
anyMember as AnyObject, Element.self))
})
return AnyHashable(self as Set<AnyHashable>)
}
}
*/
extension NSDictionary : Sequence {
// FIXME: A class because we can't pass a struct with class fields through an
// [objc] interface without prematurely destroying the references.
final public class Iterator : IteratorProtocol {
var _fastIterator: NSFastEnumerationIterator
var _dictionary: NSDictionary {
return _fastIterator.enumerable as! NSDictionary
}
public func next() -> (key: Any, value: Any)? {
if let key = _fastIterator.next() {
// Deliberately avoid the subscript operator in case the dictionary
// contains non-copyable keys. This is rare since NSMutableDictionary
// requires them, but we don't want to paint ourselves into a corner.
return (key: key, value: _dictionary.object(forKey: key)!)
}
return nil
}
internal init(_ _dict: NSDictionary) {
_fastIterator = NSFastEnumerationIterator(_dict)
}
}
// Bridging subscript.
@objc
public subscript(key: Any) -> Any? {
@objc(_swift_objectForKeyedSubscript:)
get {
// Deliberately avoid the subscript operator in case the dictionary
// contains non-copyable keys. This is rare since NSMutableDictionary
// requires them, but we don't want to paint ourselves into a corner.
return self.object(forKey: key)
}
}
/// Return an *iterator* over the elements of this *sequence*.
///
/// - Complexity: O(1).
public func makeIterator() -> Iterator {
return Iterator(self)
}
}
extension NSMutableDictionary {
// Bridging subscript.
override public subscript(key: Any) -> Any? {
get {
return self.object(forKey: key)
}
@objc(_swift_setObject:forKeyedSubscript:)
set {
// FIXME: Unfortunate that the `NSCopying` check has to be done at
// runtime.
self.setObject(newValue, forKey: key as AnyObject as! NSCopying)
}
}
}
extension NSEnumerator : Sequence {
/// Return an *iterator* over the *enumerator*.
///
/// - Complexity: O(1).
public func makeIterator() -> NSFastEnumerationIterator {
return NSFastEnumerationIterator(self)
}
}
//===----------------------------------------------------------------------===//
// Ranges
//===----------------------------------------------------------------------===//
extension NSRange {
public init(_ x: Range<Int>) {
location = x.lowerBound
length = x.count
}
// FIXME(ABI)(compiler limitation): this API should be an extension on Range.
// Can't express it now because the compiler does not support conditional
// extensions with type equality constraints.
public func toRange() -> Range<Int>? {
if location == NSNotFound { return nil }
return location..<(location+length)
}
}
//===----------------------------------------------------------------------===//
// NSLocalizedString
//===----------------------------------------------------------------------===//
/// Returns a localized string, using the main bundle if one is not specified.
public
func NSLocalizedString(_ key: String,
tableName: String? = nil,
bundle: Bundle = Bundle.main,
value: String = "",
comment: String) -> String {
return bundle.localizedString(forKey: key, value:value, table:tableName)
}
//===----------------------------------------------------------------------===//
// NSLog
//===----------------------------------------------------------------------===//
public func NSLog(_ format: String, _ args: CVarArg...) {
withVaList(args) { NSLogv(format, $0) }
}
#if os(OSX)
//===----------------------------------------------------------------------===//
// NSRectEdge
//===----------------------------------------------------------------------===//
// In the SDK, the following NS*Edge constants are defined as macros for the
// corresponding CGRectEdge enumerators. Thus, in the SDK, NS*Edge constants
// have CGRectEdge type. This is not correct for Swift (as there is no
// implicit conversion to NSRectEdge).
@available(*, unavailable, renamed: "NSRectEdge.MinX")
public var NSMinXEdge: NSRectEdge {
fatalError("unavailable property can't be accessed")
}
@available(*, unavailable, renamed: "NSRectEdge.MinY")
public var NSMinYEdge: NSRectEdge {
fatalError("unavailable property can't be accessed")
}
@available(*, unavailable, renamed: "NSRectEdge.MaxX")
public var NSMaxXEdge: NSRectEdge {
fatalError("unavailable property can't be accessed")
}
@available(*, unavailable, renamed: "NSRectEdge.MaxY")
public var NSMaxYEdge: NSRectEdge {
fatalError("unavailable property can't be accessed")
}
extension NSRectEdge {
public init(rectEdge: CGRectEdge) {
self = NSRectEdge(rawValue: UInt(rectEdge.rawValue))!
}
}
extension CGRectEdge {
public init(rectEdge: NSRectEdge) {
self = CGRectEdge(rawValue: UInt32(rectEdge.rawValue))!
}
}
#endif
//===----------------------------------------------------------------------===//
// NSError (as an out parameter).
//===----------------------------------------------------------------------===//
public typealias NSErrorPointer = AutoreleasingUnsafeMutablePointer<NSError?>?
// Note: NSErrorPointer becomes ErrorPointer in Swift 3.
public typealias ErrorPointer = NSErrorPointer
public // COMPILER_INTRINSIC
let _nilObjCError: Error = _GenericObjCError.nilError
@_silgen_name("swift_convertNSErrorToError")
public // COMPILER_INTRINSIC
func _convertNSErrorToError(_ error: NSError?) -> Error {
if let error = error {
return error
}
return _nilObjCError
}
@_silgen_name("swift_convertErrorToNSError")
public // COMPILER_INTRINSIC
func _convertErrorToNSError(_ error: Error) -> NSError {
return unsafeDowncast(_bridgeErrorToNSError(error), to: NSError.self)
}
//===----------------------------------------------------------------------===//
// Variadic initializers and methods
//===----------------------------------------------------------------------===//
extension NSPredicate {
// + (NSPredicate *)predicateWithFormat:(NSString *)predicateFormat, ...;
public
convenience init(format predicateFormat: String, _ args: CVarArg...) {
let va_args = getVaList(args)
self.init(format: predicateFormat, arguments: va_args)
}
}
extension NSExpression {
// + (NSExpression *) expressionWithFormat:(NSString *)expressionFormat, ...;
public
convenience init(format expressionFormat: String, _ args: CVarArg...) {
let va_args = getVaList(args)
self.init(format: expressionFormat, arguments: va_args)
}
}
extension NSString {
public convenience init(format: NSString, _ args: CVarArg...) {
// We can't use withVaList because 'self' cannot be captured by a closure
// before it has been initialized.
let va_args = getVaList(args)
self.init(format: format as String, arguments: va_args)
}
public convenience init(
format: NSString, locale: Locale?, _ args: CVarArg...
) {
// We can't use withVaList because 'self' cannot be captured by a closure
// before it has been initialized.
let va_args = getVaList(args)
self.init(format: format as String, locale: locale, arguments: va_args)
}
public class func localizedStringWithFormat(
_ format: NSString, _ args: CVarArg...
) -> Self {
return withVaList(args) {
self.init(format: format as String, locale: Locale.current, arguments: $0)
}
}
public func appendingFormat(_ format: NSString, _ args: CVarArg...)
-> NSString {
return withVaList(args) {
self.appending(NSString(format: format as String, arguments: $0) as String) as NSString
}
}
}
extension NSMutableString {
public func appendFormat(_ format: NSString, _ args: CVarArg...) {
return withVaList(args) {
self.append(NSString(format: format as String, arguments: $0) as String)
}
}
}
extension NSArray {
// Overlay: - (instancetype)initWithObjects:(id)firstObj, ...
public convenience init(objects elements: Any...) {
self.init(array: elements)
}
}
extension NSOrderedSet {
// - (instancetype)initWithObjects:(id)firstObj, ...
public convenience init(objects elements: Any...) {
self.init(array: elements)
}
}
extension NSSet {
// - (instancetype)initWithObjects:(id)firstObj, ...
public convenience init(objects elements: Any...) {
self.init(array: elements)
}
}
extension NSSet : ExpressibleByArrayLiteral {
public required convenience init(arrayLiteral elements: Any...) {
self.init(array: elements)
}
}
extension NSOrderedSet : ExpressibleByArrayLiteral {
public required convenience init(arrayLiteral elements: Any...) {
self.init(array: elements)
}
}
//===--- "Copy constructors" ----------------------------------------------===//
// These are needed to make Cocoa feel natural since we eliminated
// implicit bridging conversions from Objective-C to Swift
//===----------------------------------------------------------------------===//
extension NSArray {
/// Initializes a newly allocated array by placing in it the objects
/// contained in a given array.
///
/// - Returns: An array initialized to contain the objects in
/// `anArray``. The returned object might be different than the
/// original receiver.
///
/// Discussion: After an immutable array has been initialized in
/// this way, it cannot be modified.
@nonobjc
public convenience init(array anArray: NSArray) {
self.init(array: anArray as Array)
}
}
extension NSString {
/// Returns an `NSString` object initialized by copying the characters
/// from another given string.
///
/// - Returns: An `NSString` object initialized by copying the
/// characters from `aString`. The returned object may be different
/// from the original receiver.
@nonobjc
public convenience init(string aString: NSString) {
self.init(string: aString as String)
}
}
extension NSSet {
/// Initializes a newly allocated set and adds to it objects from
/// another given set.
///
/// - Returns: An initialized objects set containing the objects from
/// `set`. The returned set might be different than the original
/// receiver.
@nonobjc
public convenience init(set anSet: NSSet) {
// FIXME(performance)(compiler limitation): we actually want to do just
// `self = anSet.copy()`, but Swift does not have factory
// initializers right now.
let numElems = anSet.count
let stride = MemoryLayout<Optional<UnsafeRawPointer>>.stride
let alignment = MemoryLayout<Optional<UnsafeRawPointer>>.alignment
let bufferSize = stride * numElems
assert(stride == MemoryLayout<AnyObject>.stride)
assert(alignment == MemoryLayout<AnyObject>.alignment)
let rawBuffer = UnsafeMutableRawPointer.allocate(
bytes: bufferSize, alignedTo: alignment)
defer {
rawBuffer.deallocate(bytes: bufferSize, alignedTo: alignment)
_fixLifetime(anSet)
}
let valueBuffer = rawBuffer.bindMemory(
to: Optional<UnsafeRawPointer>.self, capacity: numElems)
CFSetGetValues(anSet, valueBuffer)
let valueBufferForInit = rawBuffer.assumingMemoryBound(to: AnyObject.self)
self.init(objects: valueBufferForInit, count: numElems)
}
}
extension NSDictionary {
/// Initializes a newly allocated dictionary and adds to it objects from
/// another given dictionary.
///
/// - Returns: An initialized dictionary—which might be different
/// than the original receiver—containing the keys and values
/// found in `otherDictionary`.
@objc(_swiftInitWithDictionary_NSDictionary:)
public convenience init(dictionary otherDictionary: NSDictionary) {
// FIXME(performance)(compiler limitation): we actually want to do just
// `self = otherDictionary.copy()`, but Swift does not have factory
// initializers right now.
let numElems = otherDictionary.count
let stride = MemoryLayout<AnyObject>.stride
let alignment = MemoryLayout<AnyObject>.alignment
let singleSize = stride * numElems
let totalSize = singleSize * 2
_sanityCheck(stride == MemoryLayout<NSCopying>.stride)
_sanityCheck(alignment == MemoryLayout<NSCopying>.alignment)
// Allocate a buffer containing both the keys and values.
let buffer = UnsafeMutableRawPointer.allocate(
bytes: totalSize, alignedTo: alignment)
defer {
buffer.deallocate(bytes: totalSize, alignedTo: alignment)
_fixLifetime(otherDictionary)
}
let valueBuffer = buffer.bindMemory(to: AnyObject.self, capacity: numElems)
let buffer2 = buffer + singleSize
let keyBuffer = buffer2.bindMemory(to: AnyObject.self, capacity: numElems)
_stdlib_NSDictionary_getObjects(
nsDictionary: otherDictionary,
objects: valueBuffer,
andKeys: keyBuffer)
let keyBufferCopying = buffer2.assumingMemoryBound(to: NSCopying.self)
self.init(objects: valueBuffer, forKeys: keyBufferCopying, count: numElems)
}
}
@_silgen_name("__NSDictionaryGetObjects")
func _stdlib_NSDictionary_getObjects(
nsDictionary: NSDictionary,
objects: UnsafeMutablePointer<AnyObject>?,
andKeys keys: UnsafeMutablePointer<AnyObject>?
)
//===----------------------------------------------------------------------===//
// NSUndoManager
//===----------------------------------------------------------------------===//
@_silgen_name("NS_Swift_NSUndoManager_registerUndoWithTargetHandler")
internal func NS_Swift_NSUndoManager_registerUndoWithTargetHandler(
_ self_: AnyObject,
_ target: AnyObject,
_ handler: @escaping @convention(block) (AnyObject) -> Void)
extension UndoManager {
@available(*, unavailable, renamed: "registerUndo(withTarget:handler:)")
public func registerUndoWithTarget<TargetType : AnyObject>(_ target: TargetType, handler: (TargetType) -> Void) {
fatalError("This API has been renamed")
}
@available(OSX 10.11, iOS 9.0, *)
public func registerUndo<TargetType : AnyObject>(withTarget target: TargetType, handler: @escaping (TargetType) -> Void) {
// The generic blocks use a different ABI, so we need to wrap the provided
// handler in something ObjC compatible.
let objcCompatibleHandler: (AnyObject) -> Void = { internalTarget in
handler(internalTarget as! TargetType)
}
NS_Swift_NSUndoManager_registerUndoWithTargetHandler(
self as AnyObject, target as AnyObject, objcCompatibleHandler)
}
}
//===----------------------------------------------------------------------===//
// NSCoder
//===----------------------------------------------------------------------===//
@_silgen_name("NS_Swift_NSCoder_decodeObject")
internal func NS_Swift_NSCoder_decodeObject(
_ self_: AnyObject,
_ error: NSErrorPointer) -> AnyObject?
@_silgen_name("NS_Swift_NSCoder_decodeObjectForKey")
internal func NS_Swift_NSCoder_decodeObjectForKey(
_ self_: AnyObject,
_ key: AnyObject,
_ error: NSErrorPointer) -> AnyObject?
@_silgen_name("NS_Swift_NSCoder_decodeObjectOfClassForKey")
internal func NS_Swift_NSCoder_decodeObjectOfClassForKey(
_ self_: AnyObject,
_ cls: AnyObject,
_ key: AnyObject,
_ error: NSErrorPointer) -> AnyObject?
@_silgen_name("NS_Swift_NSCoder_decodeObjectOfClassesForKey")
internal func NS_Swift_NSCoder_decodeObjectOfClassesForKey(
_ self_: AnyObject,
_ classes: NSSet?,
_ key: AnyObject,
_ error: NSErrorPointer) -> AnyObject?
@available(OSX 10.11, iOS 9.0, *)
internal func resolveError(_ error: NSError?) throws {
if let error = error, error.code != NSCoderValueNotFoundError {
throw error
}
}
extension NSCoder {
@available(*, unavailable, renamed: "decodeObject(of:forKey:)")
public func decodeObjectOfClass<DecodedObjectType>(
_ cls: DecodedObjectType.Type, forKey key: String
) -> DecodedObjectType?
where DecodedObjectType : NSCoding, DecodedObjectType : NSObject {
fatalError("This API has been renamed")
}
public func decodeObject<DecodedObjectType>(
of cls: DecodedObjectType.Type, forKey key: String
) -> DecodedObjectType?
where DecodedObjectType : NSCoding, DecodedObjectType : NSObject {
let result = NS_Swift_NSCoder_decodeObjectOfClassForKey(self as AnyObject, cls as AnyObject, key as AnyObject, nil)
return result as? DecodedObjectType
}
@available(*, unavailable, renamed: "decodeObject(of:forKey:)")
@nonobjc
public func decodeObjectOfClasses(_ classes: NSSet?, forKey key: String) -> AnyObject? {
fatalError("This API has been renamed")
}
@nonobjc
public func decodeObject(of classes: [AnyClass]?, forKey key: String) -> Any? {
var classesAsNSObjects: NSSet? = nil
if let theClasses = classes {
classesAsNSObjects = NSSet(array: theClasses.map { $0 as AnyObject })
}
return NS_Swift_NSCoder_decodeObjectOfClassesForKey(self as AnyObject, classesAsNSObjects, key as AnyObject, nil).map { $0 as Any }
}
@nonobjc
@available(OSX 10.11, iOS 9.0, *)
public func decodeTopLevelObject() throws -> Any? {
var error: NSError?
let result = NS_Swift_NSCoder_decodeObject(self as AnyObject, &error)
try resolveError(error)
return result.map { $0 as Any }
}
@available(*, unavailable, renamed: "decodeTopLevelObject(forKey:)")
public func decodeTopLevelObjectForKey(_ key: String) throws -> AnyObject? {
fatalError("This API has been renamed")
}
@nonobjc
@available(OSX 10.11, iOS 9.0, *)
public func decodeTopLevelObject(forKey key: String) throws -> AnyObject? {
var error: NSError?
let result = NS_Swift_NSCoder_decodeObjectForKey(self as AnyObject, key as AnyObject, &error)
try resolveError(error)
return result
}
@available(*, unavailable, renamed: "decodeTopLevelObject(of:forKey:)")
public func decodeTopLevelObjectOfClass<DecodedObjectType>(
_ cls: DecodedObjectType.Type, forKey key: String
) throws -> DecodedObjectType?
where DecodedObjectType : NSCoding, DecodedObjectType : NSObject {
fatalError("This API has been renamed")
}
@available(OSX 10.11, iOS 9.0, *)
public func decodeTopLevelObject<DecodedObjectType>(
of cls: DecodedObjectType.Type, forKey key: String
) throws -> DecodedObjectType?
where DecodedObjectType : NSCoding, DecodedObjectType : NSObject {
var error: NSError?
let result = NS_Swift_NSCoder_decodeObjectOfClassForKey(self as AnyObject, cls as AnyObject, key as AnyObject, &error)
try resolveError(error)
return result as? DecodedObjectType
}
@nonobjc
@available(*, unavailable, renamed: "decodeTopLevelObject(of:forKey:)")
public func decodeTopLevelObjectOfClasses(_ classes: NSSet?, forKey key: String) throws -> AnyObject? {
fatalError("This API has been renamed")
}
@nonobjc
@available(OSX 10.11, iOS 9.0, *)
public func decodeTopLevelObject(of classes: [AnyClass]?, forKey key: String) throws -> Any? {
var error: NSError? = nil
var classesAsNSObjects: NSSet? = nil
if let theClasses = classes {
classesAsNSObjects = NSSet(array: theClasses.map { $0 as AnyObject })
}
let result = NS_Swift_NSCoder_decodeObjectOfClassesForKey(self as AnyObject, classesAsNSObjects, key as AnyObject, &error)
try resolveError(error)
return result.map { $0 as Any }
}
}
//===----------------------------------------------------------------------===//
// NSKeyedUnarchiver
//===----------------------------------------------------------------------===//
@_silgen_name("NS_Swift_NSKeyedUnarchiver_unarchiveObjectWithData")
internal func NS_Swift_NSKeyedUnarchiver_unarchiveObjectWithData(
_ self_: AnyObject,
_ data: AnyObject,
_ error: NSErrorPointer) -> AnyObject?
extension NSKeyedUnarchiver {
@available(OSX 10.11, iOS 9.0, *)
@nonobjc
public class func unarchiveTopLevelObjectWithData(_ data: NSData) throws -> AnyObject? {
var error: NSError?
let result = NS_Swift_NSKeyedUnarchiver_unarchiveObjectWithData(self, data as AnyObject, &error)
try resolveError(error)
return result
}
}
//===----------------------------------------------------------------------===//
// Mirror/Quick Look Conformance
//===----------------------------------------------------------------------===//
extension NSURL : CustomPlaygroundQuickLookable {
public var customPlaygroundQuickLook: PlaygroundQuickLook {
guard let str = absoluteString else { return .text("Unknown URL") }
return .url(str)
}
}
extension NSRange : CustomReflectable {
public var customMirror: Mirror {
return Mirror(self, children: ["location": location, "length": length])
}
}
extension NSRange : CustomPlaygroundQuickLookable {
public var customPlaygroundQuickLook: PlaygroundQuickLook {
return .range(Int64(location), Int64(length))
}
}
extension NSDate : CustomPlaygroundQuickLookable {
var summary: String {
let df = DateFormatter()
df.dateStyle = .medium
df.timeStyle = .short
return df.string(from: self as Date)
}
public var customPlaygroundQuickLook: PlaygroundQuickLook {
return .text(summary)
}
}
extension NSSet : CustomReflectable {
public var customMirror: Mirror {
return Mirror(reflecting: self as Set<NSObject>)
}
}
extension NSString : CustomPlaygroundQuickLookable {
public var customPlaygroundQuickLook: PlaygroundQuickLook {
return .text(self as String)
}
}
extension NSArray : CustomReflectable {
public var customMirror: Mirror {
return Mirror(reflecting: self as [AnyObject])
}
}
extension NSDictionary : CustomReflectable {
public var customMirror: Mirror {
return Mirror(reflecting: self as [NSObject : AnyObject])
}
}
@available(*, deprecated, renamed:"NSCoding", message: "Please use NSCoding")
typealias Coding = NSCoding
@available(*, deprecated, renamed:"NSCoder", message: "Please use NSCoder")
typealias Coder = NSCoder
@available(*, deprecated, renamed:"NSKeyedUnarchiver", message: "Please use NSKeyedUnarchiver")
typealias KeyedUnarchiver = NSKeyedUnarchiver
@available(*, deprecated, renamed:"NSKeyedArchiver", message: "Please use NSKeyedArchiver")
typealias KeyedArchiver = NSKeyedArchiver
//===----------------------------------------------------------------------===//
// AnyHashable
//===----------------------------------------------------------------------===//
extension AnyHashable : _ObjectiveCBridgeable {
public func _bridgeToObjectiveC() -> NSObject {
// This is unprincipled, but pretty much any object we'll encounter in
// Swift is NSObject-conforming enough to have -hash and -isEqual:.
return unsafeBitCast(base as AnyObject, to: NSObject.self)
}
public static func _forceBridgeFromObjectiveC(
_ x: NSObject,
result: inout AnyHashable?
) {
result = AnyHashable(x)
}
public static func _conditionallyBridgeFromObjectiveC(
_ x: NSObject,
result: inout AnyHashable?
) -> Bool {
self._forceBridgeFromObjectiveC(x, result: &result)
return result != nil
}
public static func _unconditionallyBridgeFromObjectiveC(
_ source: NSObject?
) -> AnyHashable {
// `nil` has historically been used as a stand-in for an empty
// string; map it to an empty string.
if _slowPath(source == nil) { return AnyHashable(String()) }
return AnyHashable(source!)
}
}
//===----------------------------------------------------------------------===//
// CVarArg for bridged types
//===----------------------------------------------------------------------===//
extension CVarArg where Self: _ObjectiveCBridgeable {
/// Default implementation for bridgeable types.
public var _cVarArgEncoding: [Int] {
let object = self._bridgeToObjectiveC()
_autorelease(object)
return _encodeBitsAsWords(object)
}
}
extension String: CVarArg {}
extension Array: CVarArg {}
extension Dictionary: CVarArg {}
extension Set: CVarArg {}