mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
160 lines
4.9 KiB
Swift
160 lines
4.9 KiB
Swift
//===----------------------------------------------------------------------===//
|
|
//
|
|
// This source file is part of the Swift.org open source project
|
|
//
|
|
// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
|
|
// Licensed under Apache License v2.0 with Runtime Library Exception
|
|
//
|
|
// See https://swift.org/LICENSE.txt for license information
|
|
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
@_exported import Foundation // Clang module
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
// 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?
|
|
) {
|
|
// 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!))
|
|
}
|
|
}
|
|
|
|
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 NSArray {
|
|
// Overlay: - (instancetype)initWithObjects:(id)firstObj, ...
|
|
public convenience init(objects elements: Any...) {
|
|
self.init(array: elements)
|
|
}
|
|
}
|
|
|
|
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 NSArray : CustomReflectable {
|
|
public var customMirror: Mirror {
|
|
return Mirror(reflecting: self as [AnyObject])
|
|
}
|
|
}
|
|
|
|
extension Array: CVarArg {}
|