mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
Mostly NFC, this is just plumbing for the next patch. Note that isNever() returns true for any uninhabited enum. It should be generalized so that stuff like (Never, Int) is also known to be uninhabited, or even to support generic substitutions that yield uninhabited types, but for now I really see no reason to go that far, and the current check for an enum with no cases seems perfectly adequate.
663 lines
25 KiB
Swift
663 lines
25 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 uninhabited type
|
|
//===----------------------------------------------------------------------===//
|
|
/// The return type of functions that do not return normally; a type with no
|
|
/// values.
|
|
///
|
|
/// Use `Never` as the return type when declarting 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")
|
|
/// }
|
|
|
|
@_fixed_layout
|
|
public enum Never {}
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
// 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
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#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).
|
|
static 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).
|
|
static 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).
|
|
static 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).
|
|
static 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
|
|
|