mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
The standard library's swiftinterface must temporarily remain buildable when `$TypedThrows` evaluates to false since there are still supported Swift 5.11 compilers that did not have the feature enabled by default. Declarations using typed throws in their signatures are guarded in printed swiftinterface files with `#if $TypedThrows` and therefore `@inlinable` code that uses those declarations must also be conditionalized on `$TypedThrows`.
92 lines
3.3 KiB
Swift
92 lines
3.3 KiB
Swift
//===--- ArrayCast.swift - Casts and conversions for Array ----------------===//
|
|
//
|
|
// 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
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
//
|
|
// Because NSArray is effectively an [AnyObject], casting [T] -> [U]
|
|
// is an integral part of the bridging process and these two issues
|
|
// are handled together.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
/// Called by the casting machinery.
|
|
@_silgen_name("_swift_arrayDownCastIndirect")
|
|
internal func _arrayDownCastIndirect<SourceValue, TargetValue>(
|
|
_ source: UnsafePointer<Array<SourceValue>>,
|
|
_ target: UnsafeMutablePointer<Array<TargetValue>>) {
|
|
target.initialize(to: _arrayForceCast(source.pointee))
|
|
}
|
|
|
|
/// Implements `source as! [TargetElement]`.
|
|
///
|
|
/// - Note: When SourceElement and TargetElement are both bridged verbatim, type
|
|
/// checking is deferred until elements are actually accessed.
|
|
@inlinable //for performance reasons
|
|
public func _arrayForceCast<SourceElement, TargetElement>(
|
|
_ source: Array<SourceElement>
|
|
) -> Array<TargetElement> {
|
|
#if _runtime(_ObjC)
|
|
if _isClassOrObjCExistential(SourceElement.self)
|
|
&& _isClassOrObjCExistential(TargetElement.self) {
|
|
let src = source._buffer
|
|
if let native = src.requestNativeBuffer() {
|
|
if native.storesOnlyElementsOfType(TargetElement.self) {
|
|
// A native buffer that is known to store only elements of the
|
|
// TargetElement can be used directly
|
|
return Array(_buffer: src.cast(toBufferOf: TargetElement.self))
|
|
}
|
|
// Other native buffers must use deferred element type checking
|
|
return Array(_buffer:
|
|
src.downcast(toBufferWithDeferredTypeCheckOf: TargetElement.self))
|
|
}
|
|
return Array(_immutableCocoaArray: source._buffer._asCocoaArray())
|
|
}
|
|
#endif
|
|
#if $TypedThrows
|
|
return source.map { $0 as! TargetElement }
|
|
#else
|
|
return try! source.__rethrows_map { $0 as! TargetElement }
|
|
#endif
|
|
}
|
|
|
|
/// Called by the casting machinery.
|
|
@_silgen_name("_swift_arrayDownCastConditionalIndirect")
|
|
internal func _arrayDownCastConditionalIndirect<SourceValue, TargetValue>(
|
|
_ source: UnsafePointer<Array<SourceValue>>,
|
|
_ target: UnsafeMutablePointer<Array<TargetValue>>
|
|
) -> Bool {
|
|
if let result: Array<TargetValue> = _arrayConditionalCast(source.pointee) {
|
|
target.initialize(to: result)
|
|
return true
|
|
}
|
|
return false
|
|
}
|
|
|
|
/// Implements `source as? [TargetElement]`: convert each element of
|
|
/// `source` to a `TargetElement` and return the resulting array, or
|
|
/// return `nil` if any element fails to convert.
|
|
///
|
|
/// - Complexity: O(n), because each element must be checked.
|
|
@inlinable //for performance reasons
|
|
public func _arrayConditionalCast<SourceElement, TargetElement>(
|
|
_ source: [SourceElement]
|
|
) -> [TargetElement]? {
|
|
var successfulCasts = ContiguousArray<TargetElement>()
|
|
successfulCasts.reserveCapacity(source.count)
|
|
for element in source {
|
|
if let casted = element as? TargetElement {
|
|
successfulCasts.append(casted)
|
|
} else {
|
|
return nil
|
|
}
|
|
}
|
|
return Array(successfulCasts)
|
|
}
|