Files
swift-mirror/stdlib/public/core/Policy.swift
Saleem Abdulrasool d0048ccc61 stdlib: android does not support FP80
Correct the maximal floating point width.  Although technically, Android
could support FP128 on AArch64, Swift does not currently support FP128.
For now, ensure that we use FP64 on Android.
2020-04-13 12:23:26 -07:00

487 lines
18 KiB
Swift

//===----------------------------------------------------------------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2018 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
//
//===----------------------------------------------------------------------===//
// Swift Standard Prolog Library.
//===----------------------------------------------------------------------===//
//===----------------------------------------------------------------------===//
// Standardized uninhabited type
//===----------------------------------------------------------------------===//
/// The return type of functions that do not return normally, that is, a type
/// with no values.
///
/// Use `Never` as the return type when declaring a closure, function, or
/// method that unconditionally throws an error, traps, or otherwise does
/// not terminate.
///
/// func crashAndBurn() -> Never {
/// fatalError("Something very, very bad happened")
/// }
@frozen
public enum Never {}
extension Never: Error {}
extension Never: Equatable, Comparable, Hashable {}
//===----------------------------------------------------------------------===//
// Standardized aliases
//===----------------------------------------------------------------------===//
/// The return type of functions that don't explicitly specify a return type,
/// that is, an empty tuple `()`.
///
/// When declaring a function or method, you don't need to specify a return
/// type if no value will be returned. However, the type of a function,
/// method, or closure always includes a return type, which is `Void` if
/// otherwise unspecified.
///
/// Use `Void` or an empty tuple as the return type when declaring a closure,
/// function, or method that doesn't return a value.
///
/// // No return type declared:
/// func logMessage(_ s: String) {
/// print("Message: \(s)")
/// }
///
/// let logger: (String) -> Void = logMessage
/// logger("This is a void function")
/// // Prints "Message: This is a void function"
public typealias Void = ()
//===----------------------------------------------------------------------===//
// Aliases for floating point types
//===----------------------------------------------------------------------===//
// FIXME: it should be the other way round, Float = Float32, Double = Float64,
// but the type checker loses sugar currently, and ends up displaying 'FloatXX'
// in diagnostics.
/// A 32-bit floating point type.
public typealias Float32 = Float
/// A 64-bit floating point type.
public typealias Float64 = Double
//===----------------------------------------------------------------------===//
// Default types for unconstrained literals
//===----------------------------------------------------------------------===//
/// The default type for an otherwise-unconstrained integer literal.
public typealias IntegerLiteralType = Int
/// The default type for an otherwise-unconstrained floating point literal.
public typealias FloatLiteralType = Double
/// The default type for an otherwise-unconstrained Boolean literal.
///
/// When you create a constant or variable using one of the Boolean literals
/// `true` or `false`, the resulting type is determined by the
/// `BooleanLiteralType` alias. For example:
///
/// let isBool = true
/// print("isBool is a '\(type(of: isBool))'")
/// // Prints "isBool is a 'Bool'"
///
/// The type aliased by `BooleanLiteralType` must conform to the
/// `ExpressibleByBooleanLiteral` protocol.
public typealias BooleanLiteralType = Bool
/// The default type for an otherwise-unconstrained unicode scalar literal.
public typealias UnicodeScalarType = String
/// The default type for an otherwise-unconstrained Unicode extended
/// grapheme cluster literal.
public typealias ExtendedGraphemeClusterType = String
/// The default type for an otherwise-unconstrained string literal.
public typealias StringLiteralType = String
//===----------------------------------------------------------------------===//
// Default types for unconstrained number literals
//===----------------------------------------------------------------------===//
#if !(os(Windows) || os(Android)) && (arch(i386) || arch(x86_64))
public typealias _MaxBuiltinFloatType = Builtin.FPIEEE80
#else
public typealias _MaxBuiltinFloatType = Builtin.FPIEEE64
#endif
//===----------------------------------------------------------------------===//
// Standard protocols
//===----------------------------------------------------------------------===//
#if _runtime(_ObjC)
/// The protocol to which all classes implicitly conform.
///
/// You use `AnyObject` when you need the flexibility of an untyped object or
/// when you use bridged Objective-C methods and properties that return an
/// untyped result. `AnyObject` can be used as the concrete type for an
/// instance of any class, class type, or class-only protocol. For example:
///
/// class FloatRef {
/// let value: Float
/// init(_ value: Float) {
/// self.value = value
/// }
/// }
///
/// let x = FloatRef(2.3)
/// let y: AnyObject = x
/// let z: AnyObject = FloatRef.self
///
/// `AnyObject` can also be used as the concrete type for an instance of a type
/// that bridges to an Objective-C class. Many value types in Swift bridge to
/// Objective-C counterparts, like `String` and `Int`.
///
/// let s: AnyObject = "This is a bridged string." as NSString
/// print(s is NSString)
/// // Prints "true"
///
/// let v: AnyObject = 100 as NSNumber
/// print(type(of: v))
/// // Prints "__NSCFNumber"
///
/// The flexible behavior of the `AnyObject` protocol is similar to
/// Objective-C's `id` type. For this reason, imported Objective-C types
/// frequently use `AnyObject` as the type for properties, method parameters,
/// and return values.
///
/// Casting AnyObject Instances to a Known Type
/// ===========================================
///
/// Objects with a concrete type of `AnyObject` maintain a specific dynamic
/// type and can be cast to that type using one of the type-cast operators
/// (`as`, `as?`, or `as!`).
///
/// This example uses the conditional downcast operator (`as?`) to
/// conditionally cast the `s` constant declared above to an instance of
/// Swift's `String` type.
///
/// if let message = s as? String {
/// print("Successful cast to String: \(message)")
/// }
/// // Prints "Successful cast to String: This is a bridged string."
///
/// If you have prior knowledge that an `AnyObject` instance has a particular
/// type, you can use the unconditional downcast operator (`as!`). Performing
/// an invalid cast triggers a runtime error.
///
/// let message = s as! String
/// print("Successful cast to String: \(message)")
/// // Prints "Successful cast to String: This is a bridged string."
///
/// let badCase = v as! String
/// // Runtime error
///
/// Casting is always safe in the context of a `switch` statement.
///
/// let mixedArray: [AnyObject] = [s, v]
/// for object in mixedArray {
/// switch object {
/// case let x as String:
/// print("'\(x)' is a String")
/// default:
/// print("'\(object)' is not a String")
/// }
/// }
/// // Prints "'This is a bridged string.' is a String"
/// // Prints "'100' is not a String"
///
/// Accessing Objective-C Methods and Properties
/// ============================================
///
/// When you use `AnyObject` as a concrete type, you have at your disposal
/// every `@objc` method and property---that is, methods and properties
/// imported from Objective-C or marked with the `@objc` attribute. Because
/// Swift can't guarantee at compile time that these methods and properties
/// are actually available on an `AnyObject` instance's underlying type, these
/// `@objc` symbols are available as implicitly unwrapped optional methods and
/// properties, respectively.
///
/// This example defines an `IntegerRef` type with an `@objc` method named
/// `getIntegerValue()`.
///
/// class IntegerRef {
/// let value: Int
/// init(_ value: Int) {
/// self.value = value
/// }
///
/// @objc func getIntegerValue() -> Int {
/// return value
/// }
/// }
///
/// func getObject() -> AnyObject {
/// return IntegerRef(100)
/// }
///
/// let obj: AnyObject = getObject()
///
/// In the example, `obj` has a static type of `AnyObject` and a dynamic type
/// of `IntegerRef`. You can use optional chaining to call the `@objc` method
/// `getIntegerValue()` on `obj` safely. If you're sure of the dynamic type of
/// `obj`, you can call `getIntegerValue()` directly.
///
/// let possibleValue = obj.getIntegerValue?()
/// print(possibleValue)
/// // Prints "Optional(100)"
///
/// let certainValue = obj.getIntegerValue()
/// print(certainValue)
/// // Prints "100"
///
/// If the dynamic type of `obj` doesn't implement a `getIntegerValue()`
/// method, the system returns a runtime error when you initialize
/// `certainValue`.
///
/// Alternatively, if you need to test whether `obj.getIntegerValue()` exists,
/// use optional binding before calling the method.
///
/// if let f = obj.getIntegerValue {
/// print("The value of 'obj' is \(f())")
/// } else {
/// print("'obj' does not have a 'getIntegerValue()' method")
/// }
/// // Prints "The value of 'obj' is 100"
public typealias AnyObject = Builtin.AnyObject
#else
/// The protocol to which all classes implicitly conform.
public typealias AnyObject = Builtin.AnyObject
#endif
/// The protocol to which all class types implicitly conform.
///
/// You can use the `AnyClass` protocol as the concrete type for an instance of
/// any class. When you do, all known `@objc` class methods and properties are
/// available as implicitly unwrapped optional methods and properties,
/// respectively. For example:
///
/// class IntegerRef {
/// @objc class func getDefaultValue() -> Int {
/// return 42
/// }
/// }
///
/// func getDefaultValue(_ c: AnyClass) -> Int? {
/// return c.getDefaultValue?()
/// }
///
/// The `getDefaultValue(_:)` function uses optional chaining to safely call
/// the implicitly unwrapped class method on `c`. Calling the function with
/// different class types shows how the `getDefaultValue()` class method is
/// only conditionally available.
///
/// print(getDefaultValue(IntegerRef.self))
/// // Prints "Optional(42)"
///
/// print(getDefaultValue(NSString.self))
/// // Prints "nil"
public typealias AnyClass = AnyObject.Type
//===----------------------------------------------------------------------===//
// Standard pattern matching forms
//===----------------------------------------------------------------------===//
/// Returns a Boolean value indicating whether two arguments match by value
/// equality.
///
/// The pattern-matching operator (`~=`) is used internally in `case`
/// statements for pattern matching. When you match against an `Equatable`
/// value in a `case` statement, this operator is called behind the scenes.
///
/// let weekday = 3
/// let lunch: String
/// switch weekday {
/// case 3:
/// lunch = "Taco Tuesday!"
/// default:
/// lunch = "Pizza again."
/// }
/// // lunch == "Taco Tuesday!"
///
/// In this example, the `case 3` expression uses this pattern-matching
/// operator to test whether `weekday` is equal to the value `3`.
///
/// - Note: In most cases, you should use the equal-to operator (`==`) to test
/// whether two instances are equal. The pattern-matching operator is
/// primarily intended to enable `case` statement pattern matching.
///
/// - Parameters:
/// - lhs: A value to compare.
/// - rhs: Another value to compare.
@_transparent
public func ~= <T: Equatable>(a: T, b: T) -> Bool {
return a == b
}
//===----------------------------------------------------------------------===//
// Standard precedence groups
//===----------------------------------------------------------------------===//
precedencegroup AssignmentPrecedence {
assignment: true
associativity: right
}
precedencegroup FunctionArrowPrecedence {
associativity: right
higherThan: AssignmentPrecedence
}
precedencegroup TernaryPrecedence {
associativity: right
higherThan: FunctionArrowPrecedence
}
precedencegroup DefaultPrecedence {
higherThan: TernaryPrecedence
}
precedencegroup LogicalDisjunctionPrecedence {
associativity: left
higherThan: TernaryPrecedence
}
precedencegroup LogicalConjunctionPrecedence {
associativity: left
higherThan: LogicalDisjunctionPrecedence
}
precedencegroup ComparisonPrecedence {
higherThan: LogicalConjunctionPrecedence
}
precedencegroup NilCoalescingPrecedence {
associativity: right
higherThan: ComparisonPrecedence
}
precedencegroup CastingPrecedence {
higherThan: NilCoalescingPrecedence
}
precedencegroup RangeFormationPrecedence {
higherThan: CastingPrecedence
}
precedencegroup AdditionPrecedence {
associativity: left
higherThan: RangeFormationPrecedence
}
precedencegroup MultiplicationPrecedence {
associativity: left
higherThan: AdditionPrecedence
}
precedencegroup BitwiseShiftPrecedence {
higherThan: MultiplicationPrecedence
}
//===----------------------------------------------------------------------===//
// Standard operators
//===----------------------------------------------------------------------===//
// Standard postfix operators.
postfix operator ++
postfix operator --
postfix operator ...: Comparable
// Optional<T> unwrapping operator is built into the compiler as a part of
// postfix expression grammar.
//
// postfix operator !
// Standard prefix operators.
prefix operator ++
prefix operator --
prefix operator !: Bool
prefix operator ~: BinaryInteger
prefix operator +: AdditiveArithmetic
prefix operator -: SignedNumeric
prefix operator ...: Comparable
prefix operator ..<: Comparable
// Standard infix operators.
// "Exponentiative"
infix operator <<: BitwiseShiftPrecedence, BinaryInteger
infix operator &<<: BitwiseShiftPrecedence, FixedWidthInteger
infix operator >>: BitwiseShiftPrecedence, BinaryInteger
infix operator &>>: BitwiseShiftPrecedence, FixedWidthInteger
// "Multiplicative"
infix operator *: MultiplicationPrecedence, Numeric
infix operator &*: MultiplicationPrecedence, FixedWidthInteger
infix operator /: MultiplicationPrecedence, BinaryInteger, FloatingPoint
infix operator %: MultiplicationPrecedence, BinaryInteger
infix operator &: MultiplicationPrecedence, BinaryInteger
// "Additive"
infix operator +: AdditionPrecedence, AdditiveArithmetic, String, Array, Strideable
infix operator &+: AdditionPrecedence, FixedWidthInteger
infix operator -: AdditionPrecedence, AdditiveArithmetic, Strideable
infix operator &-: AdditionPrecedence, FixedWidthInteger
infix operator |: AdditionPrecedence, BinaryInteger
infix operator ^: AdditionPrecedence, BinaryInteger
// FIXME: is this the right precedence level for "..." ?
infix operator ...: RangeFormationPrecedence, Comparable
infix operator ..<: RangeFormationPrecedence, Comparable
// The cast operators 'as' and 'is' are hardcoded as if they had the
// following attributes:
// infix operator as: CastingPrecedence
// "Coalescing"
infix operator ??: NilCoalescingPrecedence
// "Comparative"
infix operator <: ComparisonPrecedence, Comparable
infix operator <=: ComparisonPrecedence, Comparable
infix operator >: ComparisonPrecedence, Comparable
infix operator >=: ComparisonPrecedence, Comparable
infix operator ==: ComparisonPrecedence, Equatable
infix operator !=: ComparisonPrecedence, Equatable
infix operator ===: ComparisonPrecedence
infix operator !==: ComparisonPrecedence
// FIXME: ~= will be built into the compiler.
infix operator ~=: ComparisonPrecedence
// "Conjunctive"
infix operator &&: LogicalConjunctionPrecedence, Bool
// "Disjunctive"
infix operator ||: LogicalDisjunctionPrecedence, Bool
// User-defined ternary operators are not supported. The ? : operator is
// hardcoded as if it had the following attributes:
// operator ternary ? : : TernaryPrecedence
// User-defined assignment operators are not supported. The = operator is
// hardcoded as if it had the following attributes:
// infix operator =: AssignmentPrecedence
// Compound
infix operator *=: AssignmentPrecedence, Numeric
infix operator &*=: AssignmentPrecedence, FixedWidthInteger
infix operator /=: AssignmentPrecedence, BinaryInteger
infix operator %=: AssignmentPrecedence, BinaryInteger
infix operator +=: AssignmentPrecedence, AdditiveArithmetic, String, Array, Strideable
infix operator &+=: AssignmentPrecedence, FixedWidthInteger
infix operator -=: AssignmentPrecedence, AdditiveArithmetic, Strideable
infix operator &-=: AssignmentPrecedence, FixedWidthInteger
infix operator <<=: AssignmentPrecedence, BinaryInteger
infix operator &<<=: AssignmentPrecedence, FixedWidthInteger
infix operator >>=: AssignmentPrecedence, BinaryInteger
infix operator &>>=: AssignmentPrecedence, FixedWidthInteger
infix operator &=: AssignmentPrecedence, BinaryInteger
infix operator ^=: AssignmentPrecedence, BinaryInteger
infix operator |=: AssignmentPrecedence, BinaryInteger
// Workaround for <rdar://problem/14011860> SubTLF: Default
// implementations in protocols. Library authors should ensure
// that this operator never needs to be seen by end-users. See
// test/Prototypes/GenericDispatch.swift for a fully documented
// example of how this operator is used, and how its use can be hidden
// from users.
infix operator ~>