mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
eliminating the @'s from them when used on func's. This is progress towards <rdar://problem/17527000> change operator declarations from "operator prefix" to "prefix operator" & make operator a keyword This also consolidates rejection of custom operator definitions into one place and makes it consistent, and adds postfix "?" to the list of rejected operators. This also changes the demangler to demangle weak/inout/postfix and related things without the @. Swift SVN r19929
213 lines
4.8 KiB
Swift
213 lines
4.8 KiB
Swift
//===----------------------------------------------------------------------===//
|
|
//
|
|
// 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
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
// The compiler has special knowledge of Optional<T>, including the fact that
|
|
// it is an enum with cases named 'None' and 'Some'.
|
|
public enum Optional<T>: BooleanType, Reflectable, NilLiteralConvertible {
|
|
case None
|
|
case Some(T)
|
|
|
|
public init() { self = .None }
|
|
|
|
public init(_ some: T) { self = .Some(some) }
|
|
|
|
/// 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<U>(f: (T)->U) -> U? {
|
|
switch self {
|
|
case .Some(var y):
|
|
return .Some(f(y))
|
|
case .None:
|
|
return .None
|
|
}
|
|
}
|
|
|
|
public func getMirror() -> MirrorType {
|
|
return _OptionalMirror(self)
|
|
}
|
|
|
|
@transparent public
|
|
static func convertFromNilLiteral() -> Optional<T> {
|
|
return .None
|
|
}
|
|
}
|
|
|
|
extension Optional : DebugPrintable {
|
|
public var debugDescription: String {
|
|
switch self {
|
|
case .Some(var value):
|
|
var result = "Optional("
|
|
debugPrint(value, &result)
|
|
result += ")"
|
|
return result
|
|
case .None:
|
|
return "nil"
|
|
}
|
|
}
|
|
}
|
|
|
|
// While this free function may seem obsolete, since an optional is
|
|
// often expressed as (x as T), it can lead to cleaner usage, i.e.
|
|
//
|
|
// map(x as T) { ... }
|
|
// vs
|
|
// (x as T).map { ... }
|
|
//
|
|
/// Haskell's fmap for Optionals.
|
|
public func map<T, U>(x: T?, f: (T)->U) -> U? {
|
|
switch x {
|
|
case .Some(var y):
|
|
return .Some(f(y))
|
|
case .None:
|
|
return .None
|
|
}
|
|
}
|
|
|
|
// Intrinsics for use by language features.
|
|
@transparent internal
|
|
func _doesOptionalHaveValue<T>(inout v: T?) -> Builtin.Int1 {
|
|
return v.getLogicValue().value
|
|
}
|
|
|
|
@transparent internal
|
|
func _getOptionalValue<T>(v: T?) -> T {
|
|
switch v {
|
|
case .Some(var x):
|
|
return x
|
|
case .None:
|
|
_preconditionFailure(
|
|
"unexpectedly found nil while unwrapping an Optional value")
|
|
}
|
|
}
|
|
|
|
@transparent internal
|
|
func _injectValueIntoOptional<T>(v: T) -> Optional<T> {
|
|
return .Some(v)
|
|
}
|
|
|
|
@transparent internal
|
|
func _injectNothingIntoOptional<T>() -> Optional<T> {
|
|
return .None
|
|
}
|
|
|
|
// Comparisons
|
|
public func == <T: Equatable> (lhs: T?, rhs: T?) -> Bool {
|
|
switch (lhs,rhs) {
|
|
case (.Some(let l), .Some(let r)):
|
|
return l == r
|
|
case (.None, .None):
|
|
return true
|
|
default:
|
|
return false
|
|
}
|
|
}
|
|
|
|
public func != <T: Equatable> (lhs: T?, rhs: T?) -> Bool {
|
|
return !(lhs == rhs)
|
|
}
|
|
|
|
// Enable pattern matching against the nil literal, even if the element type
|
|
// isn't equatable.
|
|
public struct _OptionalNilComparisonType : NilLiteralConvertible {
|
|
@transparent
|
|
public static func convertFromNilLiteral() -> _OptionalNilComparisonType {
|
|
return _OptionalNilComparisonType()
|
|
}
|
|
}
|
|
@transparent public
|
|
func ~= <T>(lhs: _OptionalNilComparisonType, rhs: T?) -> Bool {
|
|
return !rhs.getLogicValue()
|
|
}
|
|
|
|
internal struct _OptionalMirror<T> : MirrorType {
|
|
let _value : Optional<T>
|
|
|
|
init(_ x : Optional<T>) {
|
|
_value = x
|
|
}
|
|
|
|
var value: Any { return _value }
|
|
|
|
var valueType: Any.Type { return (_value as Any).dynamicType }
|
|
|
|
var objectIdentifier: ObjectIdentifier? { return .None }
|
|
|
|
var count: Int { return _value ? 1 : 0 }
|
|
|
|
subscript(i: Int) -> (String, MirrorType) {
|
|
switch (_value,i) {
|
|
case (.Some(let contents),0) : return ("Some",reflect(contents))
|
|
default: _preconditionFailure("cannot extract this child index")
|
|
}
|
|
}
|
|
|
|
var summary: String {
|
|
switch _value {
|
|
case .Some(let contents): return reflect(contents).summary
|
|
default: return "nil"
|
|
}
|
|
}
|
|
|
|
var quickLookObject: QuickLookObject? { return .None }
|
|
|
|
var disposition: MirrorDisposition { return .Optional }
|
|
}
|
|
|
|
|
|
public func < <T: _Comparable> (lhs: T?, rhs: T?) -> Bool {
|
|
switch (lhs,rhs) {
|
|
case (.Some(let l), .Some(let r)):
|
|
return l < r
|
|
case (.None, .Some):
|
|
return true
|
|
default:
|
|
return false
|
|
}
|
|
}
|
|
|
|
public func > <T: _Comparable>(lhs: T?, rhs: T?) -> Bool {
|
|
switch (lhs,rhs) {
|
|
case (.Some(let l), .Some(let r)):
|
|
return l > r
|
|
default:
|
|
return rhs < lhs
|
|
}
|
|
}
|
|
|
|
public func <= <T: _Comparable>(lhs: T?, rhs: T?) -> Bool {
|
|
switch (lhs,rhs) {
|
|
case (.Some(let l), .Some(let r)):
|
|
return l <= r
|
|
default:
|
|
return !(rhs < lhs)
|
|
}
|
|
}
|
|
|
|
public func >= <T: _Comparable>(lhs: T?, rhs: T?) -> Bool {
|
|
switch (lhs,rhs) {
|
|
case (.Some(let l), .Some(let r)):
|
|
return l >= r
|
|
default:
|
|
return !(lhs < rhs)
|
|
}
|
|
}
|