//===----------------------------------------------------------------------===// // // This source file is part of the Swift.org open source project // // Copyright (c) 2014 - 2015 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 // //===----------------------------------------------------------------------===// /// An optional type that allows implicit member access (via compiler /// magic). /// /// The compiler has special knowledge of the existence of /// ImplicitlyUnwrappedOptional, but always interacts with it using the /// library intrinsics below. @public enum ImplicitlyUnwrappedOptional : LogicValue, Reflectable, NilLiteralConvertible { case None case Some(T) @public init() { self = .None } @public init(_ some : T) { self = .Some(some) } @public init(_ v : T?) { switch v { case .Some(let some): self = .Some(some) case .None: self = .None } } // Make nil work with ImplicitlyUnwrappedOptional @transparent @public static func convertFromNilLiteral() -> ImplicitlyUnwrappedOptional { return .None } /// Allow use in a Boolean context. @transparent @public func getLogicValue() -> Bool { switch self { case .Some: return true case .None: return false } } /// Haskell's fmap, which was mis-named @public func map(f: (T)->U) -> ImplicitlyUnwrappedOptional { switch self { case .Some(let y): return .Some(f(y)) case .None: return .None } } @public func getMirror() -> Mirror { // FIXME: This should probably use _OptionalMirror in both cases. if let value = self { return reflect(value) } else { return _OptionalMirror(self) } } } extension ImplicitlyUnwrappedOptional : Printable { @public var description: String { switch self { case .Some(let value): return toString(value) case .None: return "nil" } } } // Intrinsics for use by language features. @transparent @internal func _doesImplicitlyUnwrappedOptionalHaveValue(inout v: T!) -> Builtin.Int1 { return v.getLogicValue().value } @transparent @internal func _getImplicitlyUnwrappedOptionalValue(v: T!) -> T { switch v { case .Some(let x): return x case .None: _preconditionFailure( "unexpectedly found nil while unwrapping an Optional value") } } @transparent @internal func _injectValueIntoImplicitlyUnwrappedOptional(v: T) -> T! { return .Some(v) } @transparent @internal func _injectNothingIntoImplicitlyUnwrappedOptional() -> T! { return .None } extension ImplicitlyUnwrappedOptional : _ConditionallyBridgedToObjectiveC { @public typealias ObjectiveCType = AnyObject @public static func getObjectiveCType() -> Any.Type { return getBridgedObjectiveCType(T.self)! } @public func bridgeToObjectiveC() -> AnyObject { switch self { case .None: _preconditionFailure("attempt to bridge an implicitly unwrapped optional containing nil") case .Some(let x): return Swift.bridgeToObjectiveC(x)! } } @public static func bridgeFromObjectiveC(x: AnyObject) -> T! { return Swift.bridgeFromObjectiveC(x, T.self) } @public static func bridgeFromObjectiveCConditional(x: AnyObject) -> T!? { let bridged: T? = Swift.bridgeFromObjectiveCConditional(x, T.self) if let value = bridged { return value } return .None } @public static func isBridgedToObjectiveC() -> Bool { return Swift.isBridgedToObjectiveC(T.self) } }