blob: adecca6c4bf72d42689fd4be6c901f243edeca45 [file] [log] [blame]
//===----------------------------------------------------------------------===//
//
// 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 {}