Files
swift-mirror/stdlib/public/core/Policy.swift
2016-07-15 14:07:23 -07:00

709 lines
27 KiB
Swift

//===----------------------------------------------------------------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2016 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
//
//===----------------------------------------------------------------------===//
// Swift Standard Prolog Library.
//===----------------------------------------------------------------------===//
//===----------------------------------------------------------------------===//
// Standardized aliases
//===----------------------------------------------------------------------===//
/// The return type of functions that don't explicitly specify a return type;
/// an empty tuple (i.e., `()`).
///
/// 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 '\(isBool.dynamicType)'")
/// // 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
//===----------------------------------------------------------------------===//
// Integer literals are limited to 2048 bits.
// The intent is to have arbitrary-precision literals, but implementing that
// requires more work.
//
// Rationale: 1024 bits are enough to represent the absolute value of min/max
// IEEE Binary64, and we need 1 bit to represent the sign. Instead of using
// 1025, we use the next round number -- 2048.
public typealias _MaxBuiltinIntegerType = Builtin.Int2048
#if !os(Windows) && (arch(i386) || arch(x86_64))
public typealias _MaxBuiltinFloatType = Builtin.FPIEEE80
#else
public typealias _MaxBuiltinFloatType = Builtin.FPIEEE64
#endif
//===----------------------------------------------------------------------===//
// Standard protocols
//===----------------------------------------------------------------------===//
/// The protocol to which all types implicitly conform.
///
/// The `Any` protocol can be used as the concrete type for an instance of any
/// type in Swift: a class, struct, or enumeration; a metatype, such as
/// `Int.self`; a tuple with any types of components; or a closure or function
/// type.
///
/// Casting Any Instances to a Known Type
/// =====================================
///
/// When you use `Any` as a concrete type, you must cast your instance back to
/// a known type before you can access its properties or methods. Instances
/// with a concrete type of `Any` maintain their original dynamic type and can
/// be cast to that type using one of the type-cast operators (`as`, `as?`, or
/// `as!`).
///
/// For example, use `as?` to conditionally downcast the first object
/// in a heterogeneous array to a `String`.
///
/// let mixed: [Any] = ["one", "two", 3, true, {(x: Int) -> Int in x * 2 }]
///
/// let first = = numberObjects.firstObject
/// if let first = mixed.first as? String {
/// print("The first item, '\(first)', is a String")
/// }
/// // Prints("The first item, 'one', is a String")
///
/// If you have prior knowledge that an `Any` instance is an instance of
/// a particular type, you can use the `as!` operator to unconditionally
/// downcast. Performing an invalid cast results in a runtime error.
///
/// let second = mixed[1] as! String
/// print("'\(second)' is also a String")
/// // Prints "'two' is also a String"
///
/// In a `switch` statement, a value is cast to a type only when pattern
/// matching with that type succeeds. For that reason, you use the `as`
/// operator instead of the conditional `as?` or unconditional `as!`
/// operators.
///
/// for item in mixed {
/// switch item {
/// case let s as String:
/// print("String: \(s)")
/// case let i as Int:
/// print("Integer: \(i)")
/// case let b as Bool:
/// print("Bool: \(b)")
/// case let f as Int -> Int:
/// print("Function: 2 * 5 = \(f(5))")
/// default:
/// print("Unrecognized type")
/// }
/// }
/// // Prints "String: one"
/// // Prints "String: two"
/// // Prints "Integer: 3"
/// // Prints "Bool: true"
/// // Prints "Function: 2 * 5 = 10"
///
/// - SeeAlso: `AnyObject`, `AnyClass`
public typealias Any = protocol<>
#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."
/// print(s is NSString)
/// // Prints "true"
///
/// let v: AnyObject = 100
/// print(v.dynamicType)
/// // 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!`).
///
/// In the code samples that follow, the elements of the `NSArray` instance
/// `numberObjects` have `AnyObject` as their type. The first example uses the
/// conditional downcast operator (`as?`) to conditionally cast the first
/// object in the `numberObjects` array to an instance of Swift's `String`
/// type.
///
/// let numberObjects: NSArray = ["one", "two", 3, 4]
///
/// let first: AnyObject = numberObjects[0]
/// if let first = first as? String {
/// print("The first object, '\(first)', is a String")
/// }
/// // Prints("The first object, 'one', is a 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 second = numberObjects.object(at: 1) as! String
/// print("'\(second)' is also a String")
/// // Prints "'two' is also a String"
///
/// let badCase = numberObjects.object(at: 2) as! NSDate
/// // Runtime error
///
/// Casting is always safe in the context of a `switch` statement.
///
/// for object in numberObjects {
/// switch object {
/// case let x as String:
/// print("'\(x)' is a String")
/// default:
/// print("'\(object)' is not a String")
/// }
/// }
/// // Prints "'one' is a String"
/// // Prints "'two' is a String"
/// // Prints "'3' is not a String"
/// // Prints "'4' is not a String"
///
/// You can call a method that takes an `AnyObject` parameter with an instance
/// of any class, `@objc` protocol, or type that bridges to Objective-C. In
/// the following example, the `toFind` constant is of type `Int`, which
/// bridges to `NSNumber` when passed to an `NSArray` method that expects an
/// `AnyObject` parameter:
///
/// let toFind = 3
/// let i = numberObjects.index(of: toFind)
/// if i != NSNotFound {
/// print("Found '\(numberObjects[i])' at index \(i)")
/// } else {
/// print("Couldn't find \(toFind)")
/// }
/// // Prints "Found '3' at index 2"
///
/// 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 x: AnyObject = getObject()
///
/// In the example, `x` has a static type of `AnyObject` and a dynamic type of
/// `IntegerRef`. You can use optional chaining to call the `@objc` method
/// `getIntegerValue()` on `x` safely. If you're sure of the dynamic type of
/// `x`, you can call `getIntegerValue()` directly.
///
/// let possibleValue = x.getIntegerValue?()
/// print(possibleValue)
/// // Prints "Optional(100)"
///
/// let certainValue = x.getIntegerValue()
/// print(certainValue)
/// // Prints "100"
///
/// If the dynamic type of `x` doesn't implement a `getIntegerValue()` method,
/// the system returns a runtime error when you initialize `certainValue`.
///
/// Alternatively, if you need to test whether `x.getValue()` exists, use
/// optional binding before calling the method.
///
/// if let f = x.getIntegerValue {
/// print("The value of 'x' is \(f())")
/// } else {
/// print("'x' does not have a 'getIntegerValue()' method")
/// }
/// // Prints "The value of 'x' is 100"
///
/// - SeeAlso: `AnyClass`, `Any`
@objc
public protocol AnyObject : class {}
#else
/// The protocol to which all classes implicitly conform.
///
/// - SeeAlso: `AnyClass`
public protocol AnyObject : class {}
#endif
// Implementation note: the `AnyObject` protocol *must* not have any method or
// property requirements.
// FIXME: AnyObject should have an alternate version for non-objc without
// the @objc attribute, but AnyObject needs to be not be an address-only
// type to be able to be the target of castToNativeObject and an empty
// non-objc protocol appears not to be. There needs to be another way to make
// this the right kind of object.
/// 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"
///
/// - SeeAlso: `AnyObject`, `Any`
public typealias AnyClass = AnyObject.Type
/// A type that supports standard bitwise arithmetic operators.
///
/// Types that conform to the `BitwiseOperations` protocol implement operators
/// for bitwise arithmetic. The integer types in the standard library all
/// conform to `BitwiseOperations` by default. When you use bitwise operators
/// with an integer, you perform operations on the raw data bits that store
/// the integer's value.
///
/// In the following examples, the binary representation of any values are
/// shown in a comment to the right, like this:
///
/// let x: UInt8 = 5 // 0b00000101
///
/// Here are the required operators for the `BitwiseOperations` protocol:
///
/// - The bitwise OR operator (`|`) returns a value that has each bit set to
/// `1` where *one or both* of its arguments had that bit set to `1`. This
/// is equivalent to the union of two sets. For example:
///
/// let x: UInt8 = 5 // 0b00000101
/// let y: UInt8 = 14 // 0b00001110
/// let z = x | y // 0b00001111
///
/// Performing a bitwise OR operation with a value and `allZeros` always
/// returns the same value.
///
/// print(x | .allZeros) // 0b00000101
/// // Prints "5"
///
/// - The bitwise AND operator (`&`) returns a value that has each bit set to
/// `1` where *both* of its arguments had that bit set to `1`. This is
/// equivalent to the intersection of two sets. For example:
///
/// let x: UInt8 = 5 // 0b00000101
/// let y: UInt8 = 14 // 0b00001110
/// let z = x & y // 0b00000100
///
/// Performing a bitwise AND operation with a value and `allZeros` always
/// returns `allZeros`.
///
/// print(x & .allZeros) // 0b00000000
/// // Prints "0"
///
/// - The bitwise XOR operator (`^`), or exclusive OR operator, returns a value
/// that has each bit set to `1` where *one or the other but not both* of
/// its operators has that bit set to `1`. This is equivalent to the
/// symmetric difference of two sets. For example:
///
/// let x: UInt8 = 5 // 0b00000101
/// let y: UInt8 = 14 // 0b00001110
/// let z = x ^ y // 0b00001011
///
/// Performing a bitwise XOR operation with a value and `allZeros` always
/// returns the same value.
///
/// print(x ^ .allZeros) // 0b00000101
/// // Prints "5"
///
/// - The bitwise NOT operator (`~`) is a prefix operator that returns a value
/// where all the bits of its argument are flipped: Bits that are `1` in the
/// argument are `0` in the result, and bits that are `0` in the argument
/// are `1` in the result. This is equivalent to the inverse of a set. For
/// example:
///
/// let x: UInt8 = 5 // 0b00000101
/// let notX = ~x // 0b11111010
///
/// Performing a bitwise NOT operation on `allZeros` returns a value with
/// every bit set to `1`.
///
/// let allOnes = ~UInt8.allZeros // 0b11111111
///
/// The `OptionSet` protocol uses a raw value that conforms to
/// `BitwiseOperations` to provide mathematical set operations like
/// `union(_:)`, `intersection(_:)` and `contains(_:)` with O(1) performance.
///
/// Conforming to the BitwiseOperations Protocol
/// ============================================
///
/// To make your custom type conform to `BitwiseOperations`, add a static
/// `allZeros` property and declare the four required operator functions. Any
/// type that conforms to `BitwiseOperations`, where `x` is an instance of the
/// conforming type, must satisfy the following conditions:
///
/// - `x | Self.allZeros == x`
/// - `x ^ Self.allZeros == x`
/// - `x & Self.allZeros == .allZeros`
/// - `x & ~Self.allZeros == x`
/// - `~x == x ^ ~Self.allZeros`
///
/// - SeeAlso: `OptionSet`
public protocol BitwiseOperations {
/// Returns the intersection of bits set in the two arguments.
///
/// The bitwise AND operator (`&`) returns a value that has each bit set to
/// `1` where *both* of its arguments had that bit set to `1`. This is
/// equivalent to the intersection of two sets. For example:
///
/// let x: UInt8 = 5 // 0b00000101
/// let y: UInt8 = 14 // 0b00001110
/// let z = x & y // 0b00000100
///
/// Performing a bitwise AND operation with a value and `allZeros` always
/// returns `allZeros`.
///
/// print(x & .allZeros) // 0b00000000
/// // Prints "0"
///
/// - Complexity: O(1).
func & (lhs: Self, rhs: Self) -> Self
/// Returns the union of bits set in the two arguments.
///
/// The bitwise OR operator (`|`) returns a value that has each bit set to
/// `1` where *one or both* of its arguments had that bit set to `1`. For
/// example:
///
/// let x: UInt8 = 5 // 0b00000101
/// let y: UInt8 = 14 // 0b00001110
/// let z = x | y // 0b00001111
///
/// Performing a bitwise OR operation with a value and `allZeros` always
/// returns the same value.
///
/// print(x | .allZeros) // 0b00000101
/// // Prints "5"
///
/// - Complexity: O(1).
func | (lhs: Self, rhs: Self) -> Self
/// Returns the bits that are set in exactly one of the two arguments.
///
/// The bitwise XOR operator (`^`), or exclusive OR operator, returns a value
/// that has each bit set to `1` where *one or the other but not both* of
/// its operators has that bit set to `1`. This is equivalent to the
/// symmetric difference of two sets. For example:
///
/// let x: UInt8 = 5 // 0b00000101
/// let y: UInt8 = 14 // 0b00001110
/// let z = x ^ y // 0b00001011
///
/// Performing a bitwise XOR with a value and `allZeros` always returns the
/// same value:
///
/// print(x ^ .allZeros) // 0b00000101
/// // Prints "5"
///
/// - Complexity: O(1).
func ^ (lhs: Self, rhs: Self) -> Self
/// Returns the inverse of the bits set in the argument.
///
/// The bitwise NOT operator (`~`) is a prefix operator that returns a value
/// in which all the bits of its argument are flipped: Bits that are `1` in the
/// argument are `0` in the result, and bits that are `0` in the argument
/// are `1` in the result. This is equivalent to the inverse of a set. For
/// example:
///
/// let x: UInt8 = 5 // 0b00000101
/// let notX = ~x // 0b11111010
///
/// Performing a bitwise NOT operation on `allZeros` returns a value with
/// every bit set to `1`.
///
/// let allOnes = ~UInt8.allZeros // 0b11111111
///
/// - Complexity: O(1).
prefix func ~ (x: Self) -> Self
/// The empty bitset.
///
/// The `allZeros` static property is the [identity element][] for bitwise OR
/// and XOR operations and the [fixed point][] for bitwise AND operations.
/// For example:
///
/// let x: UInt8 = 5 // 0b00000101
///
/// // Identity
/// x | .allZeros // 0b00000101
/// x ^ .allZeros // 0b00000101
///
/// // Fixed point
/// x & .allZeros // 0b00000000
///
/// [identity element]:http://en.wikipedia.org/wiki/Identity_element
/// [fixed point]:http://en.wikipedia.org/wiki/Fixed_point_(mathematics)
static var allZeros: Self { get }
}
/// Calculates the union of bits sets in the two arguments and stores the result
/// in the first argument.
///
/// - Parameters:
/// - lhs: A value to update with the union of bits set in the two arguments.
/// - rhs: Another value.
public func |= <T : BitwiseOperations>(lhs: inout T, rhs: T) {
lhs = lhs | rhs
}
/// Calculates the intersections of bits sets in the two arguments and stores
/// the result in the first argument.
///
/// - Parameters:
/// - lhs: A value to update with the intersections of bits set in the two
/// arguments.
/// - rhs: Another value.
public func &= <T : BitwiseOperations>(lhs: inout T, rhs: T) {
lhs = lhs & rhs
}
/// Calculates the bits that are set in exactly one of the two arguments and
/// stores the result in the first argument.
///
/// - Parameters:
/// - lhs: A value to update with the bits that are set in exactly one of the
/// two arguments.
/// - rhs: Another value.
public func ^= <T : BitwiseOperations>(lhs: inout T, rhs: T) {
lhs = lhs ^ rhs
}
//===----------------------------------------------------------------------===//
// Standard pattern matching forms
//===----------------------------------------------------------------------===//
// Equatable types can be matched in patterns by value equality.
@_transparent
public func ~= <T : Equatable> (a: T, b: T) -> Bool {
return a == b
}
//===----------------------------------------------------------------------===//
// Standard operators
//===----------------------------------------------------------------------===//
// Standard postfix operators.
postfix operator ++ {}
postfix operator -- {}
// 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 ! {}
prefix operator ~ {}
prefix operator + {}
prefix operator - {}
// Standard infix operators.
// "Exponentiative"
infix operator << { associativity none precedence 160 }
infix operator >> { associativity none precedence 160 }
// "Multiplicative"
infix operator * { associativity left precedence 150 }
infix operator &* { associativity left precedence 150 }
infix operator / { associativity left precedence 150 }
infix operator % { associativity left precedence 150 }
infix operator & { associativity left precedence 150 }
// "Additive"
infix operator + { associativity left precedence 140 }
infix operator &+ { associativity left precedence 140 }
infix operator - { associativity left precedence 140 }
infix operator &- { associativity left precedence 140 }
infix operator | { associativity left precedence 140 }
infix operator ^ { associativity left precedence 140 }
// FIXME: is this the right precedence level for "..." ?
infix operator ... { associativity none precedence 135 }
infix operator ..< { associativity none precedence 135 }
// The cast operators 'as' and 'is' are hardcoded as if they had the
// following attributes:
// infix operator as { associativity none precedence 132 }
// "Coalescing"
infix operator ?? { associativity right precedence 131 }
// "Comparative"
infix operator < { associativity none precedence 130 }
infix operator <= { associativity none precedence 130 }
infix operator > { associativity none precedence 130 }
infix operator >= { associativity none precedence 130 }
infix operator == { associativity none precedence 130 }
infix operator != { associativity none precedence 130 }
infix operator === { associativity none precedence 130 }
infix operator !== { associativity none precedence 130 }
// FIXME: ~= will be built into the compiler.
infix operator ~= { associativity none precedence 130 }
// "Conjunctive"
infix operator && { associativity left precedence 120 }
// "Disjunctive"
infix operator || { associativity left precedence 110 }
// User-defined ternary operators are not supported. The ? : operator is
// hardcoded as if it had the following attributes:
// operator ternary ? : { associativity right precedence 100 }
// User-defined assignment operators are not supported. The = operator is
// hardcoded as if it had the following attributes:
// infix operator = { associativity right precedence 90 }
// Compound
infix operator *= { associativity right precedence 90 assignment }
infix operator /= { associativity right precedence 90 assignment }
infix operator %= { associativity right precedence 90 assignment }
infix operator += { associativity right precedence 90 assignment }
infix operator -= { associativity right precedence 90 assignment }
infix operator <<= { associativity right precedence 90 assignment }
infix operator >>= { associativity right precedence 90 assignment }
infix operator &= { associativity right precedence 90 assignment }
infix operator ^= { associativity right precedence 90 assignment }
infix operator |= { associativity right precedence 90 assignment }
// 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 ~> { associativity left precedence 255 }
@available(*, unavailable, renamed: "BitwiseOperations")
public typealias BitwiseOperationsType = BitwiseOperations