blob: ac6464198ad077d8df944ed8165e957378f029b6 [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
//
//===----------------------------------------------------------------------===//
/// An implementation detail used to implement support importing
/// (Objective-)C entities marked with the swift_newtype Clang
/// attribute.
public protocol _SwiftNewtypeWrapper
: RawRepresentable, _HasCustomAnyHashableRepresentation { }
extension _SwiftNewtypeWrapper where Self: Hashable, Self.RawValue: Hashable {
/// The hash value.
@inlinable
public var hashValue: Int {
return rawValue.hashValue
}
/// Hashes the essential components of this value by feeding them into the
/// given hasher.
///
/// - Parameter hasher: The hasher to use when combining the components
/// of this instance.
@inlinable
public func hash(into hasher: inout Hasher) {
hasher.combine(rawValue)
}
@inlinable
public func _rawHashValue(seed: Int) -> Int {
return rawValue._rawHashValue(seed: seed)
}
}
extension _SwiftNewtypeWrapper {
public __consuming func _toCustomAnyHashable() -> AnyHashable? {
return nil
}
}
extension _SwiftNewtypeWrapper where Self: Hashable, Self.RawValue: Hashable {
public __consuming func _toCustomAnyHashable() -> AnyHashable? {
return AnyHashable(_box: _NewtypeWrapperAnyHashableBox(self))
}
}
internal struct _NewtypeWrapperAnyHashableBox<Base>: _AnyHashableBox
where Base: _SwiftNewtypeWrapper & Hashable, Base.RawValue: Hashable {
var _value: Base
init(_ value: Base) {
self._value = value
}
var _canonicalBox: _AnyHashableBox {
return (_value.rawValue as AnyHashable)._box._canonicalBox
}
func _isEqual(to other: _AnyHashableBox) -> Bool? {
_preconditionFailure("_isEqual called on non-canonical AnyHashable box")
}
var _hashValue: Int {
_preconditionFailure("_hashValue called on non-canonical AnyHashable box")
}
func _hash(into hasher: inout Hasher) {
_preconditionFailure("_hash(into:) called on non-canonical AnyHashable box")
}
func _rawHashValue(_seed: Int) -> Int {
_preconditionFailure("_rawHashValue(_seed:) called on non-canonical AnyHashable box")
}
var _base: Any { return _value }
func _unbox<T: Hashable>() -> T? {
return _value as? T ?? _value.rawValue as? T
}
func _downCastConditional<T>(into result: UnsafeMutablePointer<T>) -> Bool {
if let value = _value as? T {
result.initialize(to: value)
return true
}
if let value = _value.rawValue as? T {
result.initialize(to: value)
return true
}
return false
}
}
#if _runtime(_ObjC)
extension _SwiftNewtypeWrapper where Self.RawValue: _ObjectiveCBridgeable {
// Note: This is the only default typealias for _ObjectiveCType, because
// constrained extensions aren't allowed to define types in different ways.
// Fortunately the others don't need it.
public typealias _ObjectiveCType = Self.RawValue._ObjectiveCType
@inlinable
public func _bridgeToObjectiveC() -> Self.RawValue._ObjectiveCType {
return rawValue._bridgeToObjectiveC()
}
@inlinable
public static func _forceBridgeFromObjectiveC(
_ source: Self.RawValue._ObjectiveCType,
result: inout Self?
) {
var innerResult: Self.RawValue?
Self.RawValue._forceBridgeFromObjectiveC(source, result: &innerResult)
result = innerResult.flatMap { Self(rawValue: $0) }
}
@inlinable
public static func _conditionallyBridgeFromObjectiveC(
_ source: Self.RawValue._ObjectiveCType,
result: inout Self?
) -> Bool {
var innerResult: Self.RawValue?
let success = Self.RawValue._conditionallyBridgeFromObjectiveC(
source,
result: &innerResult)
result = innerResult.flatMap { Self(rawValue: $0) }
return success
}
@inlinable
@_effects(readonly)
public static func _unconditionallyBridgeFromObjectiveC(
_ source: Self.RawValue._ObjectiveCType?
) -> Self {
return Self(
rawValue: Self.RawValue._unconditionallyBridgeFromObjectiveC(source))!
}
}
extension _SwiftNewtypeWrapper where Self.RawValue: AnyObject {
@inlinable
public func _bridgeToObjectiveC() -> Self.RawValue {
return rawValue
}
@inlinable
public static func _forceBridgeFromObjectiveC(
_ source: Self.RawValue,
result: inout Self?
) {
result = Self(rawValue: source)
}
@inlinable
public static func _conditionallyBridgeFromObjectiveC(
_ source: Self.RawValue,
result: inout Self?
) -> Bool {
result = Self(rawValue: source)
return result != nil
}
@inlinable
@_effects(readonly)
public static func _unconditionallyBridgeFromObjectiveC(
_ source: Self.RawValue?
) -> Self {
return Self(rawValue: source!)!
}
}
#endif