Files
swift-mirror/stdlib/core/Optional.swift
Dave Abrahams 6d1095f44e Protocol names end in "Type," "ible," or "able"
Mechanically add "Type" to the end of any protocol names that don't end
in "Type," "ible," or "able."  Also, drop "Type" from the end of any
associated type names, except for those of the *LiteralConvertible
protocols.

There are obvious improvements to make in some of these names, which can
be handled with separate commits.

Fixes <rdar://problem/17165920> Protocols `Integer` etc should get
uglier names.

Swift SVN r19883
2014-07-12 17:29:57 +00:00

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>: LogicValueType, 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 @infix 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)
}
}