//===--- Integers.swift ---------------------------------------------------===// // // This source file is part of the Swift.org open source project // // Copyright (c) 2014 - 2024 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 // //===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===// //===--- Bits for the Stdlib ----------------------------------------------===// //===----------------------------------------------------------------------===// // FIXME(integers): This should go in the stdlib separately, probably. extension ExpressibleByIntegerLiteral where Self: _ExpressibleByBuiltinIntegerLiteral { @_transparent public init(integerLiteral value: Self) { self = value } } //===----------------------------------------------------------------------===// //===--- AdditiveArithmetic -----------------------------------------------===// //===----------------------------------------------------------------------===// /// A type with values that support addition and subtraction. /// /// The `AdditiveArithmetic` protocol provides a suitable basis for additive /// arithmetic on scalar values, such as integers and floating-point numbers, /// or vectors. You can write generic methods that operate on any numeric type /// in the standard library by using the `AdditiveArithmetic` protocol as a /// generic constraint. /// /// The following code declares a method that calculates the total of any /// sequence with `AdditiveArithmetic` elements. /// /// extension Sequence where Element: AdditiveArithmetic { /// func sum() -> Element { /// return reduce(.zero, +) /// } /// } /// /// The `sum()` method is now available on any sequence with values that /// conform to `AdditiveArithmetic`, whether it is an array of `Double` or a /// range of `Int`. /// /// let arraySum = [1.1, 2.2, 3.3, 4.4, 5.5].sum() /// // arraySum == 16.5 /// /// let rangeSum = (1..<10).sum() /// // rangeSum == 45 /// /// Conforming to the AdditiveArithmetic Protocol /// ============================================= /// /// To add `AdditiveArithmetic` protocol conformance to your own custom type, /// implement the required operators, and provide a static `zero` property. public protocol AdditiveArithmetic: Equatable { /// The zero value. /// /// Zero is the identity element for addition. For any value, /// `x + .zero == x` and `.zero + x == x`. static var zero: Self { get } /// Adds two values and produces their sum. /// /// The addition operator (`+`) calculates the sum of its two arguments. For /// example: /// /// 1 + 2 // 3 /// -10 + 15 // 5 /// -15 + -5 // -20 /// 21.5 + 3.25 // 24.75 /// /// You cannot use `+` with arguments of different types. To add values of /// different types, convert one of the values to the other value's type. /// /// let x: Int8 = 21 /// let y: Int = 1000000 /// Int(x) + y // 1000021 /// /// - Parameters: /// - lhs: The first value to add. /// - rhs: The second value to add. static func +(lhs: Self, rhs: Self) -> Self /// Adds two values and stores the result in the left-hand-side variable. /// /// - Parameters: /// - lhs: The first value to add. /// - rhs: The second value to add. static func +=(lhs: inout Self, rhs: Self) /// Subtracts one value from another and produces their difference. /// /// The subtraction operator (`-`) calculates the difference of its two /// arguments. For example: /// /// 8 - 3 // 5 /// -10 - 5 // -15 /// 100 - -5 // 105 /// 10.5 - 100.0 // -89.5 /// /// You cannot use `-` with arguments of different types. To subtract values /// of different types, convert one of the values to the other value's type. /// /// let x: UInt8 = 21 /// let y: UInt = 1000000 /// y - UInt(x) // 999979 /// /// - Parameters: /// - lhs: A numeric value. /// - rhs: The value to subtract from `lhs`. static func -(lhs: Self, rhs: Self) -> Self /// Subtracts the second value from the first and stores the difference in the /// left-hand-side variable. /// /// - Parameters: /// - lhs: A numeric value. /// - rhs: The value to subtract from `lhs`. static func -=(lhs: inout Self, rhs: Self) } extension AdditiveArithmetic { @_alwaysEmitIntoClient public static func +=(lhs: inout Self, rhs: Self) { lhs = lhs + rhs } @_alwaysEmitIntoClient public static func -=(lhs: inout Self, rhs: Self) { lhs = lhs - rhs } } extension AdditiveArithmetic where Self: ExpressibleByIntegerLiteral { @inlinable @inline(__always) public static var zero: Self { return 0 } } //===----------------------------------------------------------------------===// //===--- Numeric ----------------------------------------------------------===// //===----------------------------------------------------------------------===// /// A type with values that support multiplication. /// /// The `Numeric` protocol provides a suitable basis for arithmetic on /// scalar values, such as integers and floating-point numbers. You can write /// generic methods that operate on any numeric type in the standard library /// by using the `Numeric` protocol as a generic constraint. /// /// The following example extends `Sequence` with a method that returns an /// array with the sequence's values multiplied by two. /// /// extension Sequence where Element: Numeric { /// func doublingAll() -> [Element] { /// return map { $0 * 2 } /// } /// } /// /// With this extension, any sequence with elements that conform to `Numeric` /// has the `doublingAll()` method. For example, you can double the elements of /// an array of doubles or a range of integers: /// /// let observations = [1.5, 2.0, 3.25, 4.875, 5.5] /// let doubledObservations = observations.doublingAll() /// // doubledObservations == [3.0, 4.0, 6.5, 9.75, 11.0] /// /// let integers = 0..<8 /// let doubledIntegers = integers.doublingAll() /// // doubledIntegers == [0, 2, 4, 6, 8, 10, 12, 14] /// /// Conforming to the Numeric Protocol /// ================================== /// /// To add `Numeric` protocol conformance to your own custom type, implement /// the required initializer and operators, and provide a `magnitude` property /// using a type that can represent the magnitude of any value of your custom /// type. public protocol Numeric: AdditiveArithmetic, ExpressibleByIntegerLiteral { /// Creates a new instance from the given integer, if it can be represented /// exactly. /// /// If the value passed as `source` is not representable exactly, the result /// is `nil`. In the following example, the constant `x` is successfully /// created from a value of `100`, while the attempt to initialize the /// constant `y` from `1_000` fails because the `Int8` type can represent /// `127` at maximum: /// /// let x = Int8(exactly: 100) /// // x == Optional(100) /// let y = Int8(exactly: 1_000) /// // y == nil /// /// - Parameter source: A value to convert to this type. init?(exactly source: T) /// A type that can represent the absolute value of any possible value of the /// conforming type. associatedtype Magnitude: Comparable, Numeric /// The magnitude of this value. /// /// For any numeric value `x`, `x.magnitude` is the absolute value of `x`. /// You can use the `magnitude` property in operations that are simpler to /// implement in terms of unsigned values, such as printing the value of an /// integer, which is just printing a '-' character in front of an absolute /// value. /// /// let x = -200 /// // x.magnitude == 200 /// /// The global `abs(_:)` function provides more familiar syntax when you need /// to find an absolute value. In addition, because `abs(_:)` always returns /// a value of the same type, even in a generic context, using the function /// instead of the `magnitude` property is encouraged. var magnitude: Magnitude { get } /// Multiplies two values and produces their product. /// /// The multiplication operator (`*`) calculates the product of its two /// arguments. For example: /// /// 2 * 3 // 6 /// 100 * 21 // 2100 /// -10 * 15 // -150 /// 3.5 * 2.25 // 7.875 /// /// You cannot use `*` with arguments of different types. To multiply values /// of different types, convert one of the values to the other value's type. /// /// let x: Int8 = 21 /// let y: Int = 1000000 /// Int(x) * y // 21000000 /// /// - Parameters: /// - lhs: The first value to multiply. /// - rhs: The second value to multiply. static func *(lhs: Self, rhs: Self) -> Self /// Multiplies two values and stores the result in the left-hand-side /// variable. /// /// - Parameters: /// - lhs: The first value to multiply. /// - rhs: The second value to multiply. static func *=(lhs: inout Self, rhs: Self) } /// A numeric type with a negation operation. /// /// The `SignedNumeric` protocol extends the operations defined by the /// `Numeric` protocol to include a value's additive inverse. /// /// Conforming to the SignedNumeric Protocol /// ======================================== /// /// Because the `SignedNumeric` protocol provides default implementations of /// both of its required methods, you don't need to do anything beyond /// declaring conformance to the protocol and ensuring that the values of your /// type support negation. To customize your type's implementation, provide /// your own mutating `negate()` method. /// /// When the additive inverse of a value is unrepresentable in a conforming /// type, the operation should either trap or return an exceptional value. For /// example, using the negation operator (prefix `-`) with `Int.min` results in /// a runtime error. /// /// let x = Int.min /// let y = -x /// // Overflow error public protocol SignedNumeric: Numeric { /// Returns the additive inverse of the specified value. /// /// The negation operator (prefix `-`) returns the additive inverse of its /// argument. /// /// let x = 21 /// let y = -x /// // y == -21 /// /// The resulting value must be representable in the same type as the /// argument. In particular, negating a signed, fixed-width integer type's /// minimum results in a value that cannot be represented. /// /// let z = -Int8.min /// // Overflow error /// /// - Returns: The additive inverse of this value. static prefix func - (_ operand: Self) -> Self /// Replaces this value with its additive inverse. /// /// The following example uses the `negate()` method to negate the value of /// an integer `x`: /// /// var x = 21 /// x.negate() /// // x == -21 /// /// The resulting value must be representable within the value's type. In /// particular, negating a signed, fixed-width integer type's minimum /// results in a value that cannot be represented. /// /// var y = Int8.min /// y.negate() /// // Overflow error mutating func negate() } extension SignedNumeric { @_transparent public static prefix func - (_ operand: Self) -> Self { var result = operand result.negate() return result } @_transparent public mutating func negate() { self = 0 - self } } /// Returns the absolute value of the given number. /// /// The absolute value of `x` must be representable in the same type. In /// particular, the absolute value of a signed, fixed-width integer type's /// minimum cannot be represented. /// /// let x = Int8.min /// // x == -128 /// let y = abs(x) /// // Overflow error /// /// - Parameter x: A signed number. /// - Returns: The absolute value of `x`. @inlinable public func abs(_ x: T) -> T { if T.self == T.Magnitude.self { return unsafe unsafeBitCast(x.magnitude, to: T.self) } return x < (0 as T) ? -x : x } extension AdditiveArithmetic { /// Returns the given number unchanged. /// /// You can use the unary plus operator (`+`) to provide symmetry in your /// code for positive numbers when also using the unary minus operator. /// /// let x = -21 /// let y = +21 /// // x == -21 /// // y == 21 /// /// - Returns: The given argument without any changes. @_transparent public static prefix func + (x: Self) -> Self { return x } } //===----------------------------------------------------------------------===// //===--- BinaryInteger ----------------------------------------------------===// //===----------------------------------------------------------------------===// /// An integer type with a binary representation. /// /// The `BinaryInteger` protocol is the basis for all the integer types /// provided by the standard library. All of the standard library's integer /// types, such as `Int` and `UInt32`, conform to `BinaryInteger`. /// /// Converting Between Numeric Types /// ================================ /// /// You can create new instances of a type that conforms to the `BinaryInteger` /// protocol from a floating-point number or another binary integer of any /// type. The `BinaryInteger` protocol provides initializers for four /// different kinds of conversion. /// /// Range-Checked Conversion /// ------------------------ /// /// You use the default `init(_:)` initializer to create a new instance when /// you're sure that the value passed is representable in the new type. For /// example, an instance of `Int16` can represent the value `500`, so the /// first conversion in the code sample below succeeds. That same value is too /// large to represent as an `Int8` instance, so the second conversion fails, /// triggering a runtime error. /// /// let x: Int = 500 /// let y = Int16(x) /// // y == 500 /// /// let z = Int8(x) /// // Error: Not enough bits to represent... /// /// When you create a binary integer from a floating-point value using the /// default initializer, the value is rounded toward zero before the range is /// checked. In the following example, the value `127.75` is rounded to `127`, /// which is representable by the `Int8` type. `128.25` is rounded to `128`, /// which is not representable as an `Int8` instance, triggering a runtime /// error. /// /// let e = Int8(127.75) /// // e == 127 /// /// let f = Int8(128.25) /// // Error: Double value cannot be converted... /// /// /// Exact Conversion /// ---------------- /// /// Use the `init?(exactly:)` initializer to create a new instance after /// checking whether the passed value is representable. Instead of trapping on /// out-of-range values, using the failable `init?(exactly:)` /// initializer results in `nil`. /// /// let x = Int16(exactly: 500) /// // x == Optional(500) /// /// let y = Int8(exactly: 500) /// // y == nil /// /// When converting floating-point values, the `init?(exactly:)` initializer /// checks both that the passed value has no fractional part and that the /// value is representable in the resulting type. /// /// let e = Int8(exactly: 23.0) // integral value, representable /// // e == Optional(23) /// /// let f = Int8(exactly: 23.75) // fractional value, representable /// // f == nil /// /// let g = Int8(exactly: 500.0) // integral value, nonrepresentable /// // g == nil /// /// Clamping Conversion /// ------------------- /// /// Use the `init(clamping:)` initializer to create a new instance of a binary /// integer type where out-of-range values are clamped to the representable /// range of the type. For a type `T`, the resulting value is in the range /// `T.min...T.max`. /// /// let x = Int16(clamping: 500) /// // x == 500 /// /// let y = Int8(clamping: 500) /// // y == 127 /// /// let z = UInt8(clamping: -500) /// // z == 0 /// /// Bit Pattern Conversion /// ---------------------- /// /// Use the `init(truncatingIfNeeded:)` initializer to create a new instance /// with the same bit pattern as the passed value, extending or truncating the /// value's representation as necessary. Note that the value may not be /// preserved, particularly when converting between signed to unsigned integer /// types or when the destination type has a smaller bit width than the source /// type. The following example shows how extending and truncating work for /// nonnegative integers: /// /// let q: Int16 = 850 /// // q == 0b00000011_01010010 /// /// let r = Int8(truncatingIfNeeded: q) // truncate 'q' to fit in 8 bits /// // r == 82 /// // == 0b01010010 /// /// let s = Int16(truncatingIfNeeded: r) // extend 'r' to fill 16 bits /// // s == 82 /// // == 0b00000000_01010010 /// /// Any padding is performed by *sign-extending* the passed value. When /// nonnegative integers are extended, the result is padded with zeroes. When /// negative integers are extended, the result is padded with ones. This /// example shows several extending conversions of a negative value---note /// that negative values are sign-extended even when converting to an unsigned /// type. /// /// let t: Int8 = -100 /// // t == -100 /// // t's binary representation == 0b10011100 /// /// let u = UInt8(truncatingIfNeeded: t) /// // u == 156 /// // u's binary representation == 0b10011100 /// /// let v = Int16(truncatingIfNeeded: t) /// // v == -100 /// // v's binary representation == 0b11111111_10011100 /// /// let w = UInt16(truncatingIfNeeded: t) /// // w == 65436 /// // w's binary representation == 0b11111111_10011100 /// /// /// Comparing Across Integer Types /// ============================== /// /// You can use relational operators, such as the less-than and equal-to /// operators (`<` and `==`), to compare instances of different binary integer /// types. The following example compares instances of the `Int`, `UInt`, and /// `UInt8` types: /// /// let x: Int = -23 /// let y: UInt = 1_000 /// let z: UInt8 = 23 /// /// if x < y { /// print("\(x) is less than \(y).") /// } /// // Prints "-23 is less than 1000." /// /// if z > x { /// print("\(z) is greater than \(x).") /// } /// // Prints "23 is greater than -23." public protocol BinaryInteger : Hashable, Numeric, CustomStringConvertible, Strideable where Magnitude: BinaryInteger, Magnitude.Magnitude == Magnitude { /// A Boolean value indicating whether this type is a signed integer type. /// /// *Signed* integer types can represent both positive and negative values. /// *Unsigned* integer types can represent only nonnegative values. static var isSigned: Bool { get } /// Creates an integer from the given floating-point value, if it can be /// represented exactly. /// /// If the value passed as `source` is not representable exactly, the result /// is `nil`. In the following example, the constant `x` is successfully /// created from a value of `21.0`, while the attempt to initialize the /// constant `y` from `21.5` fails: /// /// let x = Int(exactly: 21.0) /// // x == Optional(21) /// let y = Int(exactly: 21.5) /// // y == nil /// /// - Parameter source: A floating-point value to convert to an integer. init?(exactly source: T) /// Creates an integer from the given floating-point value, rounding toward /// zero. /// /// Any fractional part of the value passed as `source` is removed, rounding /// the value toward zero. /// /// let x = Int(21.5) /// // x == 21 /// let y = Int(-21.5) /// // y == -21 /// /// If `source` is outside the bounds of this type after rounding toward /// zero, a runtime error may occur. /// /// let z = UInt(-21.5) /// // Error: ...the result would be less than UInt.min /// /// - Parameter source: A floating-point value to convert to an integer. /// `source` must be representable in this type after rounding toward /// zero. init(_ source: T) /// Creates a new instance from the given integer. /// /// If the value passed as `source` is not representable in this type, a /// runtime error may occur. /// /// let x = -500 as Int /// let y = Int32(x) /// // y == -500 /// /// // -500 is not representable as a 'UInt32' instance /// let z = UInt32(x) /// // Error /// /// - Parameter source: An integer to convert. `source` must be representable /// in this type. init(_ source: T) /// Creates a new instance from the bit pattern of the given instance by /// sign-extending or truncating to fit this type. /// /// When the bit width of `T` (the type of `source`) is equal to or greater /// than this type's bit width, the result is the truncated /// least-significant bits of `source`. For example, when converting a /// 16-bit value to an 8-bit type, only the lower 8 bits of `source` are /// used. /// /// let p: Int16 = -500 /// // 'p' has a binary representation of 11111110_00001100 /// let q = Int8(truncatingIfNeeded: p) /// // q == 12 /// // 'q' has a binary representation of 00001100 /// /// When the bit width of `T` is less than this type's bit width, the result /// is *sign-extended* to fill the remaining bits. That is, if `source` is /// negative, the result is padded with ones; otherwise, the result is /// padded with zeros. /// /// let u: Int8 = 21 /// // 'u' has a binary representation of 00010101 /// let v = Int16(truncatingIfNeeded: u) /// // v == 21 /// // 'v' has a binary representation of 00000000_00010101 /// /// let w: Int8 = -21 /// // 'w' has a binary representation of 11101011 /// let x = Int16(truncatingIfNeeded: w) /// // x == -21 /// // 'x' has a binary representation of 11111111_11101011 /// let y = UInt16(truncatingIfNeeded: w) /// // y == 65515 /// // 'y' has a binary representation of 11111111_11101011 /// /// - Parameter source: An integer to convert to this type. init(truncatingIfNeeded source: T) /// Creates a new instance with the representable value that's closest to the /// given integer. /// /// If the value passed as `source` is greater than the maximum representable /// value in this type, the result is the type's `max` value. If `source` is /// less than the smallest representable value in this type, the result is /// the type's `min` value. /// /// In this example, `x` is initialized as an `Int8` instance by clamping /// `500` to the range `-128...127`, and `y` is initialized as a `UInt` /// instance by clamping `-500` to the range `0...UInt.max`. /// /// let x = Int8(clamping: 500) /// // x == 127 /// // x == Int8.max /// /// let y = UInt(clamping: -500) /// // y == 0 /// /// - Parameter source: An integer to convert to this type. init(clamping source: T) /// A type that represents the words of a binary integer. /// /// The `Words` type must conform to the `RandomAccessCollection` protocol /// with an `Element` type of `UInt` and `Index` type of `Int`. associatedtype Words: RandomAccessCollection where Words.Element == UInt, Words.Index == Int /// A collection containing the words of this value's binary /// representation, in order from the least significant to most significant. /// /// Negative values are returned in two's complement representation, /// regardless of the type's underlying implementation. var words: Words { get } /// The least significant word in this value's binary representation. var _lowWord: UInt { get } /// The number of bits in the current binary representation of this value. /// /// This property is a constant for instances of fixed-width integer /// types. var bitWidth: Int { get } /// Returns the integer binary logarithm of this value. /// /// If the value is negative or zero, a runtime error will occur. func _binaryLogarithm() -> Int /// The number of trailing zeros in this value's binary representation. /// /// For example, in a fixed-width integer type with a `bitWidth` value of 8, /// the number -8 has three trailing zeros. /// /// let x = Int8(bitPattern: 0b1111_1000) /// // x == -8 /// // x.trailingZeroBitCount == 3 /// /// If the value is zero, then `trailingZeroBitCount` is equal to `bitWidth`. var trailingZeroBitCount: Int { get } /// Returns the quotient of dividing the first value by the second. /// /// For integer types, any remainder of the division is discarded. /// /// let x = 21 / 5 /// // x == 4 /// /// - Parameters: /// - lhs: The value to divide. /// - rhs: The value to divide `lhs` by. `rhs` must not be zero. static func /(lhs: Self, rhs: Self) -> Self /// Divides the first value by the second and stores the quotient in the /// left-hand-side variable. /// /// For integer types, any remainder of the division is discarded. /// /// var x = 21 /// x /= 5 /// // x == 4 /// /// - Parameters: /// - lhs: The value to divide. /// - rhs: The value to divide `lhs` by. `rhs` must not be zero. static func /=(lhs: inout Self, rhs: Self) /// Returns the remainder of dividing the first value by the second. /// /// The result of the remainder operator (`%`) has the same sign as `lhs` and /// has a magnitude less than `rhs.magnitude`. /// /// let x = 22 % 5 /// // x == 2 /// let y = 22 % -5 /// // y == 2 /// let z = -22 % -5 /// // z == -2 /// /// For any two integers `a` and `b`, their quotient `q`, and their remainder /// `r`, `a == b * q + r`. /// /// - Parameters: /// - lhs: The value to divide. /// - rhs: The value to divide `lhs` by. `rhs` must not be zero. static func %(lhs: Self, rhs: Self) -> Self /// Divides the first value by the second and stores the remainder in the /// left-hand-side variable. /// /// The result has the same sign as `lhs` and has a magnitude less than /// `rhs.magnitude`. /// /// var x = 22 /// x %= 5 /// // x == 2 /// /// var y = 22 /// y %= -5 /// // y == 2 /// /// var z = -22 /// z %= -5 /// // z == -2 /// /// - Parameters: /// - lhs: The value to divide. /// - rhs: The value to divide `lhs` by. `rhs` must not be zero. static func %=(lhs: inout Self, rhs: Self) /// Adds two values and produces their sum. /// /// The addition operator (`+`) calculates the sum of its two arguments. For /// example: /// /// 1 + 2 // 3 /// -10 + 15 // 5 /// -15 + -5 // -20 /// 21.5 + 3.25 // 24.75 /// /// You cannot use `+` with arguments of different types. To add values of /// different types, convert one of the values to the other value's type. /// /// let x: Int8 = 21 /// let y: Int = 1000000 /// Int(x) + y // 1000021 /// /// The sum of the two arguments must be representable in the arguments' /// type. In the following example, the result of `21 + 120` is greater than /// the maximum representable `Int8` value: /// /// x + 120 // Overflow error /// /// - Note: Overflow checking is not performed in `-Ounchecked` builds. /// /// If you want to opt out of overflow checking and wrap the result in case /// of any overflow, use the overflow addition operator (`&+`). /// /// x &+ 120 // -115 /// /// - Parameters: /// - lhs: The first value to add. /// - rhs: The second value to add. override static func +(lhs: Self, rhs: Self) -> Self /// Adds two values and stores the result in the left-hand-side variable. /// /// The sum of the two arguments must be representable in the arguments' /// type. In the following example, the result of `21 + 120` is greater than /// the maximum representable `Int8` value: /// /// var x: Int8 = 21 /// x += 120 /// // Overflow error /// /// - Note: Overflow checking is not performed in `-Ounchecked` builds. /// /// - Parameters: /// - lhs: The first value to add. /// - rhs: The second value to add. override static func +=(lhs: inout Self, rhs: Self) /// Subtracts one value from another and produces their difference. /// /// The subtraction operator (`-`) calculates the difference of its two /// arguments. For example: /// /// 8 - 3 // 5 /// -10 - 5 // -15 /// 100 - -5 // 105 /// 10.5 - 100.0 // -89.5 /// /// You cannot use `-` with arguments of different types. To subtract values /// of different types, convert one of the values to the other value's type. /// /// let x: UInt8 = 21 /// let y: UInt = 1000000 /// y - UInt(x) // 999979 /// /// The difference of the two arguments must be representable in the /// arguments' type. In the following example, the result of `21 - 50` is /// less than zero, the minimum representable `UInt8` value: /// /// x - 50 // Overflow error /// /// - Note: Overflow checking is not performed in `-Ounchecked` builds. /// /// If you want to opt out of overflow checking and wrap the result in case /// of any overflow, use the overflow subtraction operator (`&-`). /// /// x &- 50 // 227 /// /// - Parameters: /// - lhs: A numeric value. /// - rhs: The value to subtract from `lhs`. override static func -(lhs: Self, rhs: Self) -> Self /// Subtracts the second value from the first and stores the difference in the /// left-hand-side variable. /// /// The difference of the two arguments must be representable in the /// arguments' type. In the following example, the result of `21 - 50` is /// less than zero, the minimum representable `UInt8` value: /// /// var x: UInt8 = 21 /// x -= 50 /// // Overflow error /// /// - Note: Overflow checking is not performed in `-Ounchecked` builds. /// /// - Parameters: /// - lhs: A numeric value. /// - rhs: The value to subtract from `lhs`. override static func -=(lhs: inout Self, rhs: Self) /// Multiplies two values and produces their product. /// /// The multiplication operator (`*`) calculates the product of its two /// arguments. For example: /// /// 2 * 3 // 6 /// 100 * 21 // 2100 /// -10 * 15 // -150 /// 3.5 * 2.25 // 7.875 /// /// You cannot use `*` with arguments of different types. To multiply values /// of different types, convert one of the values to the other value's type. /// /// let x: Int8 = 21 /// let y: Int = 1000000 /// Int(x) * y // 21000000 /// /// The product of the two arguments must be representable in the arguments' /// type. In the following example, the result of `21 * 21` is greater than /// the maximum representable `Int8` value: /// /// x * 21 // Overflow error /// /// - Note: Overflow checking is not performed in `-Ounchecked` builds. /// /// If you want to opt out of overflow checking and wrap the result in case /// of any overflow, use the overflow multiplication operator (`&*`). /// /// x &* 21 // -71 /// /// - Parameters: /// - lhs: The first value to multiply. /// - rhs: The second value to multiply. override static func *(lhs: Self, rhs: Self) -> Self /// Multiplies two values and stores the result in the left-hand-side /// variable. /// /// The product of the two arguments must be representable in the arguments' /// type. In the following example, the result of `21 * 21` is greater than /// the maximum representable `Int8` value: /// /// var x: Int8 = 21 /// x *= 21 /// // Overflow error /// /// - Note: Overflow checking is not performed in `-Ounchecked` builds. /// /// - Parameters: /// - lhs: The first value to multiply. /// - rhs: The second value to multiply. override static func *=(lhs: inout Self, rhs: 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 0 returns a value with every bit /// set to `1`. /// /// let allOnes = ~UInt8.min // 0b11111111 /// /// - Complexity: O(1). static prefix func ~ (_ x: Self) -> Self /// Returns the result of performing a bitwise AND operation on the two given /// values. /// /// A bitwise AND operation results in a value that has each bit set to `1` /// where *both* of its arguments have that bit set to `1`. For example: /// /// let x: UInt8 = 5 // 0b00000101 /// let y: UInt8 = 14 // 0b00001110 /// let z = x & y // 0b00000100 /// // z == 4 /// /// - Parameters: /// - lhs: An integer value. /// - rhs: Another integer value. static func &(lhs: Self, rhs: Self) -> Self /// Stores the result of performing a bitwise AND operation on the two given /// values in the left-hand-side variable. /// /// A bitwise AND operation results in a value that has each bit set to `1` /// where *both* of its arguments have that bit set to `1`. For example: /// /// var x: UInt8 = 5 // 0b00000101 /// let y: UInt8 = 14 // 0b00001110 /// x &= y // 0b00000100 /// /// - Parameters: /// - lhs: An integer value. /// - rhs: Another integer value. static func &=(lhs: inout Self, rhs: Self) /// Returns the result of performing a bitwise OR operation on the two given /// values. /// /// A bitwise OR operation results in a value that has each bit set to `1` /// where *one or both* of its arguments have that bit set to `1`. For /// example: /// /// let x: UInt8 = 5 // 0b00000101 /// let y: UInt8 = 14 // 0b00001110 /// let z = x | y // 0b00001111 /// // z == 15 /// /// - Parameters: /// - lhs: An integer value. /// - rhs: Another integer value. static func |(lhs: Self, rhs: Self) -> Self /// Stores the result of performing a bitwise OR operation on the two given /// values in the left-hand-side variable. /// /// A bitwise OR operation results in a value that has each bit set to `1` /// where *one or both* of its arguments have that bit set to `1`. For /// example: /// /// var x: UInt8 = 5 // 0b00000101 /// let y: UInt8 = 14 // 0b00001110 /// x |= y // 0b00001111 /// /// - Parameters: /// - lhs: An integer value. /// - rhs: Another integer value. static func |=(lhs: inout Self, rhs: Self) /// Returns the result of performing a bitwise XOR operation on the two given /// values. /// /// A bitwise XOR operation, also known as an exclusive OR operation, results /// in a value that has each bit set to `1` where *one or the other but not /// 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 // 0b00001011 /// // z == 11 /// /// - Parameters: /// - lhs: An integer value. /// - rhs: Another integer value. static func ^(lhs: Self, rhs: Self) -> Self /// Stores the result of performing a bitwise XOR operation on the two given /// values in the left-hand-side variable. /// /// A bitwise XOR operation, also known as an exclusive OR operation, results /// in a value that has each bit set to `1` where *one or the other but not /// both* of its arguments had that bit set to `1`. For example: /// /// var x: UInt8 = 5 // 0b00000101 /// let y: UInt8 = 14 // 0b00001110 /// x ^= y // 0b00001011 /// /// - Parameters: /// - lhs: An integer value. /// - rhs: Another integer value. static func ^=(lhs: inout Self, rhs: Self) /// Returns the result of shifting a value's binary representation the /// specified number of digits to the right. /// /// The `>>` operator performs a *smart shift*, which defines a result for a /// shift of any value. /// /// - Using a negative value for `rhs` performs a left shift using /// `abs(rhs)`. /// - Using a value for `rhs` that is greater than or equal to the bit width /// of `lhs` is an *overshift*. An overshift results in `-1` for a /// negative value of `lhs` or `0` for a nonnegative value. /// - Using any other value for `rhs` performs a right shift on `lhs` by that /// amount. /// /// The following example defines `x` as an instance of `UInt8`, an 8-bit, /// unsigned integer type. If you use `2` as the right-hand-side value in an /// operation on `x`, the value is shifted right by two bits. /// /// let x: UInt8 = 30 // 0b00011110 /// let y = x >> 2 /// // y == 7 // 0b00000111 /// /// If you use `11` as `rhs`, `x` is overshifted such that all of its bits /// are set to zero. /// /// let z = x >> 11 /// // z == 0 // 0b00000000 /// /// Using a negative value as `rhs` is the same as performing a left shift /// using `abs(rhs)`. /// /// let a = x >> -3 /// // a == 240 // 0b11110000 /// let b = x << 3 /// // b == 240 // 0b11110000 /// /// Right shift operations on negative values "fill in" the high bits with /// ones instead of zeros. /// /// let q: Int8 = -30 // 0b11100010 /// let r = q >> 2 /// // r == -8 // 0b11111000 /// /// let s = q >> 11 /// // s == -1 // 0b11111111 /// /// - Parameters: /// - lhs: The value to shift. /// - rhs: The number of bits to shift `lhs` to the right. static func >> (lhs: Self, rhs: RHS) -> Self /// Stores the result of shifting a value's binary representation the /// specified number of digits to the right in the left-hand-side variable. /// /// The `>>=` operator performs a *smart shift*, which defines a result for a /// shift of any value. /// /// - Using a negative value for `rhs` performs a left shift using /// `abs(rhs)`. /// - Using a value for `rhs` that is greater than or equal to the bit width /// of `lhs` is an *overshift*. An overshift results in `-1` for a /// negative value of `lhs` or `0` for a nonnegative value. /// - Using any other value for `rhs` performs a right shift on `lhs` by that /// amount. /// /// The following example defines `x` as an instance of `UInt8`, an 8-bit, /// unsigned integer type. If you use `2` as the right-hand-side value in an /// operation on `x`, the value is shifted right by two bits. /// /// var x: UInt8 = 30 // 0b00011110 /// x >>= 2 /// // x == 7 // 0b00000111 /// /// If you use `11` as `rhs`, `x` is overshifted such that all of its bits /// are set to zero. /// /// var y: UInt8 = 30 // 0b00011110 /// y >>= 11 /// // y == 0 // 0b00000000 /// /// Using a negative value as `rhs` is the same as performing a left shift /// using `abs(rhs)`. /// /// var a: UInt8 = 30 // 0b00011110 /// a >>= -3 /// // a == 240 // 0b11110000 /// /// var b: UInt8 = 30 // 0b00011110 /// b <<= 3 /// // b == 240 // 0b11110000 /// /// Right shift operations on negative values "fill in" the high bits with /// ones instead of zeros. /// /// var q: Int8 = -30 // 0b11100010 /// q >>= 2 /// // q == -8 // 0b11111000 /// /// var r: Int8 = -30 // 0b11100010 /// r >>= 11 /// // r == -1 // 0b11111111 /// /// - Parameters: /// - lhs: The value to shift. /// - rhs: The number of bits to shift `lhs` to the right. static func >>= (lhs: inout Self, rhs: RHS) /// Returns the result of shifting a value's binary representation the /// specified number of digits to the left. /// /// The `<<` operator performs a *smart shift*, which defines a result for a /// shift of any value. /// /// - Using a negative value for `rhs` performs a right shift using /// `abs(rhs)`. /// - Using a value for `rhs` that is greater than or equal to the bit width /// of `lhs` is an *overshift*, resulting in zero. /// - Using any other value for `rhs` performs a left shift on `lhs` by that /// amount. /// /// The following example defines `x` as an instance of `UInt8`, an 8-bit, /// unsigned integer type. If you use `2` as the right-hand-side value in an /// operation on `x`, the value is shifted left by two bits. /// /// let x: UInt8 = 30 // 0b00011110 /// let y = x << 2 /// // y == 120 // 0b01111000 /// /// If you use `11` as `rhs`, `x` is overshifted such that all of its bits /// are set to zero. /// /// let z = x << 11 /// // z == 0 // 0b00000000 /// /// Using a negative value as `rhs` is the same as performing a right shift /// with `abs(rhs)`. /// /// let a = x << -3 /// // a == 3 // 0b00000011 /// let b = x >> 3 /// // b == 3 // 0b00000011 /// /// - Parameters: /// - lhs: The value to shift. /// - rhs: The number of bits to shift `lhs` to the left. static func << (lhs: Self, rhs: RHS) -> Self /// Stores the result of shifting a value's binary representation the /// specified number of digits to the left in the left-hand-side variable. /// /// The `<<` operator performs a *smart shift*, which defines a result for a /// shift of any value. /// /// - Using a negative value for `rhs` performs a right shift using /// `abs(rhs)`. /// - Using a value for `rhs` that is greater than or equal to the bit width /// of `lhs` is an *overshift*, resulting in zero. /// - Using any other value for `rhs` performs a left shift on `lhs` by that /// amount. /// /// The following example defines `x` as an instance of `UInt8`, an 8-bit, /// unsigned integer type. If you use `2` as the right-hand-side value in an /// operation on `x`, the value is shifted left by two bits. /// /// var x: UInt8 = 30 // 0b00011110 /// x <<= 2 /// // x == 120 // 0b01111000 /// /// If you use `11` as `rhs`, `x` is overshifted such that all of its bits /// are set to zero. /// /// var y: UInt8 = 30 // 0b00011110 /// y <<= 11 /// // y == 0 // 0b00000000 /// /// Using a negative value as `rhs` is the same as performing a right shift /// with `abs(rhs)`. /// /// var a: UInt8 = 30 // 0b00011110 /// a <<= -3 /// // a == 3 // 0b00000011 /// /// var b: UInt8 = 30 // 0b00011110 /// b >>= 3 /// // b == 3 // 0b00000011 /// /// - Parameters: /// - lhs: The value to shift. /// - rhs: The number of bits to shift `lhs` to the left. static func <<=(lhs: inout Self, rhs: RHS) /// Returns the quotient and remainder of this value divided by the given /// value. /// /// Use this method to calculate the quotient and remainder of a division at /// the same time. /// /// let x = 1_000_000 /// let (q, r) = x.quotientAndRemainder(dividingBy: 933) /// // q == 1071 /// // r == 757 /// /// - Parameter rhs: The value to divide this value by. /// - Returns: A tuple containing the quotient and remainder of this value /// divided by `rhs`. The remainder has the same sign as `lhs`. func quotientAndRemainder(dividingBy rhs: Self) -> (quotient: Self, remainder: Self) /// Returns `true` if this value is a multiple of the given value, and `false` /// otherwise. /// /// For two integers *a* and *b*, *a* is a multiple of *b* if there exists a /// third integer *q* such that _a = q*b_. For example, *6* is a multiple of /// *3* because _6 = 2*3_. Zero is a multiple of everything because _0 = 0*x_ /// for any integer *x*. /// /// Two edge cases are worth particular attention: /// - `x.isMultiple(of: 0)` is `true` if `x` is zero and `false` otherwise. /// - `T.min.isMultiple(of: -1)` is `true` for signed integer `T`, even /// though the quotient `T.min / -1` isn't representable in type `T`. /// /// - Parameter other: The value to test. func isMultiple(of other: Self) -> Bool /// Returns `-1` if this value is negative and `1` if it's positive; /// otherwise, `0`. /// /// - Returns: The sign of this number, expressed as an integer of the same /// type. func signum() -> Self } extension BinaryInteger { /// Creates a new value equal to zero. @_transparent public init() { self = 0 } @inlinable public func signum() -> Self { return (self > (0 as Self) ? 1 : 0) - (self < (0 as Self) ? 1 : 0) } @_transparent public var _lowWord: UInt { var it = words.makeIterator() return it.next() ?? 0 } @inlinable public func _binaryLogarithm() -> Int { _precondition(self > (0 as Self)) var (quotient, remainder) = (bitWidth &- 1).quotientAndRemainder(dividingBy: UInt.bitWidth) remainder = remainder &+ 1 var word = UInt(truncatingIfNeeded: self >> (bitWidth &- remainder)) // If, internally, a variable-width binary integer uses digits of greater // bit width than that of Magnitude.Words.Element (i.e., UInt), then it is // possible that `word` could be zero. Additionally, a signed variable-width // binary integer may have a leading word that is zero to store a clear sign // bit. while word == 0 { quotient = quotient &- 1 remainder = remainder &+ UInt.bitWidth word = UInt(truncatingIfNeeded: self >> (bitWidth &- remainder)) } // Note that the order of operations below is important to guarantee that // we won't overflow. return UInt.bitWidth &* quotient &+ (UInt.bitWidth &- (word.leadingZeroBitCount &+ 1)) } @inlinable public func quotientAndRemainder(dividingBy rhs: Self) -> (quotient: Self, remainder: Self) { return (self / rhs, self % rhs) } @inlinable public func isMultiple(of other: Self) -> Bool { // Nothing but zero is a multiple of zero. if other == 0 { return self == 0 } // Do the test in terms of magnitude, which guarantees there are no other // edge cases. If we write this as `self % other` instead, it could trap // for types that are not symmetric around zero. return self.magnitude % other.magnitude == 0 } //===----------------------------------------------------------------------===// //===--- Homogeneous ------------------------------------------------------===// //===----------------------------------------------------------------------===// @_transparent public static func & (lhs: Self, rhs: Self) -> Self { var lhs = lhs lhs &= rhs return lhs } @_transparent public static func | (lhs: Self, rhs: Self) -> Self { var lhs = lhs lhs |= rhs return lhs } @_transparent public static func ^ (lhs: Self, rhs: Self) -> Self { var lhs = lhs lhs ^= rhs return lhs } //===----------------------------------------------------------------------===// //===--- Heterogeneous non-masking shift in terms of shift-assignment -----===// //===----------------------------------------------------------------------===// @_semantics("optimize.sil.specialize.generic.partial.never") @_transparent public static func >> (lhs: Self, rhs: RHS) -> Self { var r = lhs r >>= rhs return r } @_semantics("optimize.sil.specialize.generic.partial.never") @_transparent public static func << (lhs: Self, rhs: RHS) -> Self { var r = lhs r <<= rhs return r } } //===----------------------------------------------------------------------===// //===--- CustomStringConvertible conformance ------------------------------===// //===----------------------------------------------------------------------===// extension BinaryInteger { internal func _description(radix: Int, uppercase: Bool) -> String { _precondition(2...36 ~= radix, "Radix must be between 2 and 36") if bitWidth <= 64 { let radix_ = Int64(radix) return Self.isSigned ? _int64ToString( Int64(truncatingIfNeeded: self), radix: radix_, uppercase: uppercase) : _uint64ToString( UInt64(truncatingIfNeeded: self), radix: radix_, uppercase: uppercase) } if self == (0 as Self) { return "0" } // Bit shifting can be faster than division when `radix` is a power of two // (although not necessarily the case for builtin types). let isRadixPowerOfTwo = radix.nonzeroBitCount == 1 let radix_ = Magnitude(radix) func _quotientAndRemainder(_ value: Magnitude) -> (Magnitude, Magnitude) { return isRadixPowerOfTwo ? (value >> radix.trailingZeroBitCount, value & (radix_ - 1)) : value.quotientAndRemainder(dividingBy: radix_) } let hasLetters = radix > 10 func _ascii(_ digit: UInt8) -> UInt8 { let base: UInt8 if !hasLetters || digit < 10 { base = UInt8(("0" as Unicode.Scalar).value) } else if uppercase { base = UInt8(("A" as Unicode.Scalar).value) &- 10 } else { base = UInt8(("a" as Unicode.Scalar).value) &- 10 } return base &+ digit } let isNegative = Self.isSigned && self < (0 as Self) var value = magnitude // TODO(FIXME JIRA): All current stdlib types fit in small. Use a stack // buffer instead of an array on the heap. var result: [UInt8] = [] while value != 0 { let (quotient, remainder) = _quotientAndRemainder(value) result.append(_ascii(UInt8(truncatingIfNeeded: remainder))) value = quotient } if isNegative { result.append(UInt8(("-" as Unicode.Scalar).value)) } result.reverse() return unsafe result.withUnsafeBufferPointer { return unsafe String._fromASCII($0) } } /// A textual representation of this value. @_semantics("binaryInteger.description") public var description: String { return _description(radix: 10, uppercase: false) } } //===----------------------------------------------------------------------===// //===--- Strideable conformance -------------------------------------------===// //===----------------------------------------------------------------------===// extension BinaryInteger { /// Returns the distance from this value to the given value, expressed as a /// stride. /// /// For two values `x` and `y`, and a distance `n = x.distance(to: y)`, /// `x.advanced(by: n) == y`. /// /// - Parameter other: The value to calculate the distance to. /// - Returns: The distance from this value to `other`. @inlinable @inline(__always) public func distance(to other: Self) -> Int { if !Self.isSigned { if self > other { if let result = Int(exactly: self - other) { return -result } } else { if let result = Int(exactly: other - self) { return result } } } else { let isNegative = self < (0 as Self) if isNegative == (other < (0 as Self)) { if let result = Int(exactly: other - self) { return result } } else { if let result = Int(exactly: self.magnitude + other.magnitude) { return isNegative ? result : -result } } } _preconditionFailure("Distance is not representable in Int") } /// Returns a value that is offset the specified distance from this value. /// /// Use the `advanced(by:)` method in generic code to offset a value by a /// specified distance. If you're working directly with numeric values, use /// the addition operator (`+`) instead of this method. /// /// For a value `x`, a distance `n`, and a value `y = x.advanced(by: n)`, /// `x.distance(to: y) == n`. /// /// - Parameter n: The distance to advance this value. /// - Returns: A value that is offset from this value by `n`. @inlinable @inline(__always) public func advanced(by n: Int) -> Self { if Self.isSigned { return self.bitWidth < n.bitWidth ? Self(Int(truncatingIfNeeded: self) + n) : self + Self(truncatingIfNeeded: n) } else { return n < (0 as Int) ? self - Self(UInt(bitPattern: ~n &+ 1)) : self + Self(UInt(bitPattern: n)) } } } //===----------------------------------------------------------------------===// //===--- Heterogeneous comparison -----------------------------------------===// //===----------------------------------------------------------------------===// extension BinaryInteger { /// Returns a Boolean value indicating whether the two given values are /// equal. /// /// You can check the equality of instances of any `BinaryInteger` types /// using the equal-to operator (`==`). For example, you can test whether /// the first `UInt8` value in a string's UTF-8 encoding is equal to the /// first `UInt32` value in its Unicode scalar view: /// /// let gameName = "Red Light, Green Light" /// if let firstUTF8 = gameName.utf8.first, /// let firstScalar = gameName.unicodeScalars.first?.value { /// print("First code values are equal: \(firstUTF8 == firstScalar)") /// } /// // Prints "First code values are equal: true" /// /// - Parameters: /// - lhs: An integer to compare. /// - rhs: Another integer to compare. @_transparent public static func == < Other: BinaryInteger >(lhs: Self, rhs: Other) -> Bool { // Use bit pattern conversion to widen the comparand with smaller bit width. if Self.isSigned == Other.isSigned { return lhs.bitWidth >= rhs.bitWidth ? lhs == Self(truncatingIfNeeded: rhs) : Other(truncatingIfNeeded: lhs) == rhs } // If `Self` is signed but `Other` is unsigned, then we have to // be a little more careful about widening, since: // (1) a fixed-width signed type can't represent the largest values of // a fixed-width unsigned type of equal bit width; and // (2) an unsigned type (obviously) can't represent a negative value. if Self.isSigned { return lhs.bitWidth > rhs.bitWidth ? // (1) lhs == Self(truncatingIfNeeded: rhs) : (lhs >= (0 as Self) && Other(truncatingIfNeeded: lhs) == rhs) // (2) } // Analogous reasoning applies if `Other` is signed but `Self` is not. return lhs.bitWidth < rhs.bitWidth ? Other(truncatingIfNeeded: lhs) == rhs : (rhs >= (0 as Other) && lhs == Self(truncatingIfNeeded: rhs)) } /// Returns a Boolean value indicating whether the two given values are not /// equal. /// /// You can check the inequality of instances of any `BinaryInteger` types /// using the not-equal-to operator (`!=`). For example, you can test /// whether the first `UInt8` value in a string's UTF-8 encoding is not /// equal to the first `UInt32` value in its Unicode scalar view: /// /// let gameName = "Red Light, Green Light" /// if let firstUTF8 = gameName.utf8.first, /// let firstScalar = gameName.unicodeScalars.first?.value { /// print("First code values are different: \(firstUTF8 != firstScalar)") /// } /// // Prints "First code values are different: false" /// /// - Parameters: /// - lhs: An integer to compare. /// - rhs: Another integer to compare. @_transparent public static func != < Other: BinaryInteger >(lhs: Self, rhs: Other) -> Bool { return !(lhs == rhs) } /// Returns a Boolean value indicating whether the value of the first /// argument is less than that of the second argument. /// /// You can compare instances of any `BinaryInteger` types using the /// less-than operator (`<`), even if the two instances are of different /// types. /// /// - Parameters: /// - lhs: An integer to compare. /// - rhs: Another integer to compare. @_transparent public static func < (lhs: Self, rhs: Other) -> Bool { // Use bit pattern conversion to widen the comparand with smaller bit width. if Self.isSigned == Other.isSigned { return lhs.bitWidth >= rhs.bitWidth ? lhs < Self(truncatingIfNeeded: rhs) : Other(truncatingIfNeeded: lhs) < rhs } // If `Self` is signed but `Other` is unsigned, then we have to // be a little more careful about widening, since: // (1) a fixed-width signed type can't represent the largest values of // a fixed-width unsigned type of equal bit width; and // (2) an unsigned type (obviously) can't represent a negative value. if Self.isSigned { return lhs.bitWidth > rhs.bitWidth ? // (1) lhs < Self(truncatingIfNeeded: rhs) : (lhs < (0 as Self) || Other(truncatingIfNeeded: lhs) < rhs) // (2) } // Analogous reasoning applies if `Other` is signed but `Self` is not. return lhs.bitWidth < rhs.bitWidth ? Other(truncatingIfNeeded: lhs) < rhs : (rhs > (0 as Other) && lhs < Self(truncatingIfNeeded: rhs)) } /// Returns a Boolean value indicating whether the value of the first /// argument is less than or equal to that of the second argument. /// /// You can compare instances of any `BinaryInteger` types using the /// less-than-or-equal-to operator (`<=`), even if the two instances are of /// different types. /// /// - Parameters: /// - lhs: An integer to compare. /// - rhs: Another integer to compare. @_transparent public static func <= (lhs: Self, rhs: Other) -> Bool { return !(rhs < lhs) } /// Returns a Boolean value indicating whether the value of the first /// argument is greater than or equal to that of the second argument. /// /// You can compare instances of any `BinaryInteger` types using the /// greater-than-or-equal-to operator (`>=`), even if the two instances are /// of different types. /// /// - Parameters: /// - lhs: An integer to compare. /// - rhs: Another integer to compare. @_transparent public static func >= (lhs: Self, rhs: Other) -> Bool { return !(lhs < rhs) } /// Returns a Boolean value indicating whether the value of the first /// argument is greater than that of the second argument. /// /// You can compare instances of any `BinaryInteger` types using the /// greater-than operator (`>`), even if the two instances are of different /// types. /// /// - Parameters: /// - lhs: An integer to compare. /// - rhs: Another integer to compare. @_transparent public static func > (lhs: Self, rhs: Other) -> Bool { return rhs < lhs } } //===----------------------------------------------------------------------===// //===--- Ambiguity breakers -----------------------------------------------===// // // These two versions of the operators are not ordered with respect to one // another, but the compiler chooses the second one, and that results in infinite // recursion. // // (T, T) -> Bool // (T, U) -> Bool // // so we define: // // (T, T) -> Bool // //===----------------------------------------------------------------------===// extension BinaryInteger { @_transparent public static func != (lhs: Self, rhs: Self) -> Bool { return !(lhs == rhs) } @_transparent public static func <= (lhs: Self, rhs: Self) -> Bool { return !(rhs < lhs) } @_transparent public static func >= (lhs: Self, rhs: Self) -> Bool { return !(lhs < rhs) } @_transparent public static func > (lhs: Self, rhs: Self) -> Bool { return rhs < lhs } } #if !$Embedded public typealias _LosslessStringConvertibleOrNone = LosslessStringConvertible #else public protocol _LosslessStringConvertibleOrNone {} #endif //===----------------------------------------------------------------------===// //===--- FixedWidthInteger ------------------------------------------------===// //===----------------------------------------------------------------------===// /// An integer type that uses a fixed size for every instance. /// /// The `FixedWidthInteger` protocol adds binary bitwise operations, bit /// shifts, and overflow handling to the operations supported by the /// `BinaryInteger` protocol. /// /// Use the `FixedWidthInteger` protocol as a constraint or extension point /// when writing operations that depend on bit shifting, performing bitwise /// operations, catching overflows, or having access to the maximum or minimum /// representable value of a type. For example, the following code provides a /// `binaryString` property on every fixed-width integer that represents the /// number's binary representation, split into 8-bit chunks. /// /// extension FixedWidthInteger { /// var binaryString: String { /// var result: [String] = [] /// for i in 0..<(Self.bitWidth / 8) { /// let byte = UInt8(truncatingIfNeeded: self >> (i * 8)) /// let byteString = String(byte, radix: 2) /// let padding = String(repeating: "0", /// count: 8 - byteString.count) /// result.append(padding + byteString) /// } /// return "0b" + result.reversed().joined(separator: "_") /// } /// } /// /// print(Int16.max.binaryString) /// // Prints "0b01111111_11111111" /// print((101 as UInt8).binaryString) /// // Prints "0b01100101" /// /// The `binaryString` implementation uses the static `bitWidth` property and /// the right shift operator (`>>`), both of which are available to any type /// that conforms to the `FixedWidthInteger` protocol. /// /// The next example declares a generic `squared` function, which accepts an /// instance `x` of any fixed-width integer type. The function uses the /// `multipliedReportingOverflow(by:)` method to multiply `x` by itself and /// check whether the result is too large to represent in the same type. /// /// func squared(_ x: T) -> T? { /// let (result, overflow) = x.multipliedReportingOverflow(by: x) /// if overflow { /// return nil /// } /// return result /// } /// /// let (x, y): (Int8, Int8) = (9, 123) /// print(squared(x)) /// // Prints "Optional(81)" /// print(squared(y)) /// // Prints "nil" /// /// Conforming to the FixedWidthInteger Protocol /// ============================================ /// /// To make your own custom type conform to the `FixedWidthInteger` protocol, /// declare the required initializers, properties, and methods. The required /// methods that are suffixed with `ReportingOverflow` serve as the /// customization points for arithmetic operations. When you provide just those /// methods, the standard library provides default implementations for all /// other arithmetic methods and operators. public protocol FixedWidthInteger: BinaryInteger, _LosslessStringConvertibleOrNone where Magnitude: FixedWidthInteger & UnsignedInteger, Stride: FixedWidthInteger & SignedInteger { /// The number of bits used for the underlying binary representation of /// values of this type. /// /// An unsigned, fixed-width integer type can represent values from 0 through /// `(2 ** bitWidth) - 1`, where `**` is exponentiation. A signed, /// fixed-width integer type can represent values from /// `-(2 ** (bitWidth - 1))` through `(2 ** (bitWidth - 1)) - 1`. For example, /// the `Int8` type has a `bitWidth` value of 8 and can store any integer in /// the range `-128...127`. static var bitWidth: Int { get } /// The maximum representable integer in this type. /// /// For unsigned integer types, this value is `(2 ** bitWidth) - 1`, where /// `**` is exponentiation. For signed integer types, this value is /// `(2 ** (bitWidth - 1)) - 1`. static var max: Self { get } /// The minimum representable integer in this type. /// /// For unsigned integer types, this value is always `0`. For signed integer /// types, this value is `-(2 ** (bitWidth - 1))`, where `**` is /// exponentiation. static var min: Self { get } /// Returns the sum of this value and the given value, along with a Boolean /// value indicating whether overflow occurred in the operation. /// /// - Parameter rhs: The value to add to this value. /// - Returns: A tuple containing the result of the addition along with a /// Boolean value indicating whether overflow occurred. If the `overflow` /// component is `false`, the `partialValue` component contains the entire /// sum. If the `overflow` component is `true`, an overflow occurred and /// the `partialValue` component contains the truncated sum of this value /// and `rhs`. func addingReportingOverflow( _ rhs: Self ) -> (partialValue: Self, overflow: Bool) /// Returns the difference obtained by subtracting the given value from this /// value, along with a Boolean value indicating whether overflow occurred in /// the operation. /// /// - Parameter rhs: The value to subtract from this value. /// - Returns: A tuple containing the result of the subtraction along with a /// Boolean value indicating whether overflow occurred. If the `overflow` /// component is `false`, the `partialValue` component contains the entire /// difference. If the `overflow` component is `true`, an overflow occurred /// and the `partialValue` component contains the truncated result of `rhs` /// subtracted from this value. func subtractingReportingOverflow( _ rhs: Self ) -> (partialValue: Self, overflow: Bool) /// Returns the product of this value and the given value, along with a /// Boolean value indicating whether overflow occurred in the operation. /// /// - Parameter rhs: The value to multiply by this value. /// - Returns: A tuple containing the result of the multiplication along with /// a Boolean value indicating whether overflow occurred. If the `overflow` /// component is `false`, the `partialValue` component contains the entire /// product. If the `overflow` component is `true`, an overflow occurred and /// the `partialValue` component contains the truncated product of this /// value and `rhs`. func multipliedReportingOverflow( by rhs: Self ) -> (partialValue: Self, overflow: Bool) /// Returns the quotient obtained by dividing this value by the given value, /// along with a Boolean value indicating whether overflow occurred in the /// operation. /// /// Dividing by zero is not an error when using this method. For a value `x`, /// the result of `x.dividedReportingOverflow(by: 0)` is `(x, true)`. /// /// - Parameter rhs: The value to divide this value by. /// - Returns: A tuple containing the result of the division along with a /// Boolean value indicating whether overflow occurred. If the `overflow` /// component is `false`, the `partialValue` component contains the entire /// quotient. If the `overflow` component is `true`, an overflow occurred /// and the `partialValue` component contains either the truncated quotient /// or, if the quotient is undefined, the dividend. func dividedReportingOverflow( by rhs: Self ) -> (partialValue: Self, overflow: Bool) /// Returns the remainder after dividing this value by the given value, along /// with a Boolean value indicating whether overflow occurred during division. /// /// Dividing by zero is not an error when using this method. For a value `x`, /// the result of `x.remainderReportingOverflow(dividingBy: 0)` is /// `(x, true)`. /// /// - Parameter rhs: The value to divide this value by. /// - Returns: A tuple containing the result of the operation along with a /// Boolean value indicating whether overflow occurred. If the `overflow` /// component is `false`, the `partialValue` component contains the entire /// remainder. If the `overflow` component is `true`, an overflow occurred /// during division and the `partialValue` component contains either the /// entire remainder or, if the remainder is undefined, the dividend. func remainderReportingOverflow( dividingBy rhs: Self ) -> (partialValue: Self, overflow: Bool) /// Returns a tuple containing the high and low parts of the result of /// multiplying this value by the given value. /// /// Use this method to calculate the full result of a product that would /// otherwise overflow. Unlike traditional truncating multiplication, the /// `multipliedFullWidth(by:)` method returns a tuple containing both the /// `high` and `low` parts of the product of this value and `other`. The /// following example uses this method to multiply two `Int8` values that /// normally overflow when multiplied: /// /// let x: Int8 = 48 /// let y: Int8 = -40 /// let result = x.multipliedFullWidth(by: y) /// // result.high == -8 /// // result.low == 128 /// /// The product of `x` and `y` is `-1920`, which is too large to represent in /// an `Int8` instance. The `high` and `low` components of the `result` value /// represent `-1920` when concatenated to form a double-width integer; that /// is, using `result.high` as the high byte and `result.low` as the low byte /// of an `Int16` instance. /// /// let z = Int16(result.high) << 8 | Int16(result.low) /// // z == -1920 /// /// - Parameter other: The value to multiply this value by. /// - Returns: A tuple containing the high and low parts of the result of /// multiplying this value and `other`. func multipliedFullWidth(by other: Self) -> (high: Self, low: Self.Magnitude) /// Returns a tuple containing the quotient and remainder obtained by dividing /// the given value by this value. /// /// The resulting quotient must be representable within the bounds of the /// type. If the quotient is too large to represent in the type, a runtime /// error may occur. /// /// The following example divides a value that is too large to be represented /// using a single `Int` instance by another `Int` value. Because the quotient /// is representable as an `Int`, the division succeeds. /// /// // 'dividend' represents the value 0x506f70652053616e74612049494949 /// let dividend = (22640526660490081, 7959093232766896457 as UInt) /// let divisor = 2241543570477705381 /// /// let (quotient, remainder) = divisor.dividingFullWidth(dividend) /// // quotient == 186319822866995413 /// // remainder == 0 /// /// - Parameter dividend: A tuple containing the high and low parts of a /// double-width integer. /// - Returns: A tuple containing the quotient and remainder obtained by /// dividing `dividend` by this value. func dividingFullWidth(_ dividend: (high: Self, low: Self.Magnitude)) -> (quotient: Self, remainder: Self) init(_truncatingBits bits: UInt) /// The number of bits equal to 1 in this value's binary representation. /// /// For example, in a fixed-width integer type with a `bitWidth` value of 8, /// the number *31* has five bits equal to *1*. /// /// let x: Int8 = 0b0001_1111 /// // x == 31 /// // x.nonzeroBitCount == 5 var nonzeroBitCount: Int { get } /// The number of leading zeros in this value's binary representation. /// /// For example, in a fixed-width integer type with a `bitWidth` value of 8, /// the number *31* has three leading zeros. /// /// let x: Int8 = 0b0001_1111 /// // x == 31 /// // x.leadingZeroBitCount == 3 /// /// If the value is zero, then `leadingZeroBitCount` is equal to `bitWidth`. var leadingZeroBitCount: Int { get } /// Creates an integer from its big-endian representation, changing the byte /// order if necessary. /// /// - Parameter value: A value to use as the big-endian representation of the /// new integer. init(bigEndian value: Self) /// Creates an integer from its little-endian representation, changing the /// byte order if necessary. /// /// - Parameter value: A value to use as the little-endian representation of /// the new integer. init(littleEndian value: Self) /// The big-endian representation of this integer. /// /// If necessary, the byte order of this value is reversed from the typical /// byte order of this integer type. On a big-endian platform, for any /// integer `x`, `x == x.bigEndian`. var bigEndian: Self { get } /// The little-endian representation of this integer. /// /// If necessary, the byte order of this value is reversed from the typical /// byte order of this integer type. On a little-endian platform, for any /// integer `x`, `x == x.littleEndian`. var littleEndian: Self { get } /// A representation of this integer with the byte order swapped. var byteSwapped: Self { get } /// Returns the result of shifting a value's binary representation the /// specified number of digits to the right, masking the shift amount to the /// type's bit width. /// /// Use the masking right shift operator (`&>>`) when you need to perform a /// shift and are sure that the shift amount is in the range /// `0..> 2 /// // y == 7 // 0b00000111 /// /// However, if you use `8` as the shift amount, the method first masks the /// shift amount to zero, and then performs the shift, resulting in no change /// to the original value. /// /// let z = x &>> 8 /// // z == 30 // 0b00011110 /// /// If the bit width of the shifted integer type is a power of two, masking /// is performed using a bitmask; otherwise, masking is performed using a /// modulo operation. /// /// - Parameters: /// - lhs: The value to shift. /// - rhs: The number of bits to shift `lhs` to the right. If `rhs` is /// outside the range `0..>(lhs: Self, rhs: Self) -> Self /// Calculates the result of shifting a value's binary representation the /// specified number of digits to the right, masking the shift amount to the /// type's bit width, and stores the result in the left-hand-side variable. /// /// The `&>>=` operator performs a *masking shift*, where the value passed as /// `rhs` is masked to produce a value in the range `0..>= 2 /// // x == 7 // 0b00000111 /// /// However, if you use `19` as `rhs`, the operation first bitmasks `rhs` to /// `3`, and then uses that masked value as the number of bits to shift `lhs`. /// /// var y: UInt8 = 30 // 0b00011110 /// y &>>= 19 /// // y == 3 // 0b00000011 /// /// - Parameters: /// - lhs: The value to shift. /// - rhs: The number of bits to shift `lhs` to the right. If `rhs` is /// outside the range `0..>=(lhs: inout Self, rhs: Self) /// Returns the result of shifting a value's binary representation the /// specified number of digits to the left, masking the shift amount to the /// type's bit width. /// /// Use the masking left shift operator (`&<<`) when you need to perform a /// shift and are sure that the shift amount is in the range /// `0.. Self /// Returns the result of shifting a value's binary representation the /// specified number of digits to the left, masking the shift amount to the /// type's bit width, and stores the result in the left-hand-side variable. /// /// The `&<<=` operator performs a *masking shift*, where the value used as /// `rhs` is masked to produce a value in the range `0.. Self } extension FixedWidthInteger { @inlinable public var bitWidth: Int { return Self.bitWidth } @inlinable public func _binaryLogarithm() -> Int { _precondition(self > (0 as Self)) return Self.bitWidth &- (leadingZeroBitCount &+ 1) } @inlinable public init(littleEndian value: Self) { #if _endian(little) self = value #else self = value.byteSwapped #endif } @inlinable public init(bigEndian value: Self) { #if _endian(big) self = value #else self = value.byteSwapped #endif } @inlinable public var littleEndian: Self { #if _endian(little) return self #else return byteSwapped #endif } @inlinable public var bigEndian: Self { #if _endian(big) return self #else return byteSwapped #endif } // Default implementation of multipliedFullWidth. // // This implementation is mainly intended for [U]Int64 on 32b platforms. It // will not be especially efficient for other types that do not provide their // own implementation, but neither will it be catastrophically bad. It can // surely be improved on even for Int64, but that is mostly an optimization // problem; the basic algorithm here gives the compiler all the information // that it needs to generate efficient code. @_alwaysEmitIntoClient public func multipliedFullWidth(by other: Self) -> (high: Self, low: Magnitude) { // We define a utility function for splitting an integer into high and low // halves. Note that the low part is always unsigned, while the high part // matches the signedness of the input type. Both result types are the // full width of the original number; this may be surprising at first, but // there are two reasons for it: // // - we're going to use these as inputs to a multiplication operation, and // &* is quite a bit less verbose than `multipliedFullWidth`, so it makes // the rest of the code in this function somewhat easier to read. // // - there's no "half width type" that we can get at from this generic // context, so there's not really another option anyway. // // Fortunately, the compiler is pretty good about propagating the necessary // information to optimize away unnecessary arithmetic. func split(_ x: T) -> (high: T, low: T.Magnitude) { let n = T.bitWidth/2 return (x >> n, T.Magnitude(truncatingIfNeeded: x) & ((1 &<< n) &- 1)) } // Split `self` and `other` into high and low parts, compute the partial // products carrying high words in as we go. We use the wrapping operators // and `truncatingIfNeeded` inits purely as an optimization hint to the // compiler; none of these operations will ever wrap due to the constraints // on the arithmetic. The bounds are documented before each line for signed // types. For unsigned types, the bounds are much more well known and // easier to derive, so I haven't bothered to document them here, but they // all boil down to the fact that a*b + c + d cannot overflow a double- // width result with unsigned a, b, c, d. let (x1, x0) = split(self) let (y1, y0) = split(other) // If B is 2^bitWidth/2, x0 and y0 are in 0 ... B-1, so their product is // in 0 ... B^2-2B+1. For further analysis, we'll need the fact that // the high word is in 0 ... B-2. let p00 = x0 &* y0 // x1 is in -B/2 ... B/2-1, so the product x1*y0 is in // -(B^2-B)/2 ... (B^2-3B+2)/2; after adding the high word of p00, the // result is in -(B^2-B)/2 ... (B^2-B-2)/2. let p01 = x1 &* Self(y0) &+ Self(split(p00).high) // The previous analysis holds for this product as well, and the sum is // in -(B^2-B)/2 ... (B^2-B)/2. let p10 = Self(x0) &* y1 &+ Self(split(p01).low) // No analysis is necessary for this term, because we know the product as // a whole cannot overflow, and this term is the final high word of the // product. let p11 = x1 &* y1 &+ split(p01).high &+ split(p10).high // Now we only need to assemble the low word of the product. return (p11, split(p10).low << (bitWidth/2) | split(p00).low) } @_semantics("optimize.sil.specialize.generic.partial.never") @_transparent public static func &>> (lhs: Self, rhs: Self) -> Self { var lhs = lhs lhs &>>= rhs return lhs } /// Returns the result of shifting a value's binary representation the /// specified number of digits to the right, masking the shift amount to the /// type's bit width. /// /// Use the masking right shift operator (`&>>`) when you need to perform a /// shift and are sure that the shift amount is in the range /// `0..> 2 /// // y == 7 // 0b00000111 /// /// However, if you use `8` as the shift amount, the method first masks the /// shift amount to zero, and then performs the shift, resulting in no change /// to the original value. /// /// let z = x &>> 8 /// // z == 30 // 0b00011110 /// /// If the bit width of the shifted integer type is a power of two, masking /// is performed using a bitmask; otherwise, masking is performed using a /// modulo operation. /// /// - Parameters: /// - lhs: The value to shift. /// - rhs: The number of bits to shift `lhs` to the right. If `rhs` is /// outside the range `0..> < Other: BinaryInteger >(lhs: Self, rhs: Other) -> Self { return lhs &>> Self(truncatingIfNeeded: rhs) } /// Calculates the result of shifting a value's binary representation the /// specified number of digits to the right, masking the shift amount to the /// type's bit width, and stores the result in the left-hand-side variable. /// /// The `&>>=` operator performs a *masking shift*, where the value passed as /// `rhs` is masked to produce a value in the range `0..>= 2 /// // x == 7 // 0b00000111 /// /// However, if you use `19` as `rhs`, the operation first bitmasks `rhs` to /// `3`, and then uses that masked value as the number of bits to shift `lhs`. /// /// var y: UInt8 = 30 // 0b00011110 /// y &>>= 19 /// // y == 3 // 0b00000011 /// /// - Parameters: /// - lhs: The value to shift. /// - rhs: The number of bits to shift `lhs` to the right. If `rhs` is /// outside the range `0..>= < Other: BinaryInteger >(lhs: inout Self, rhs: Other) { lhs = lhs &>> rhs } @_semantics("optimize.sil.specialize.generic.partial.never") @_transparent public static func &<< (lhs: Self, rhs: Self) -> Self { var lhs = lhs lhs &<<= rhs return lhs } /// Returns the result of shifting a value's binary representation the /// specified number of digits to the left, masking the shift amount to the /// type's bit width. /// /// Use the masking left shift operator (`&<<`) when you need to perform a /// shift and are sure that the shift amount is in the range /// `0..(lhs: Self, rhs: Other) -> Self { return lhs &<< Self(truncatingIfNeeded: rhs) } /// Returns the result of shifting a value's binary representation the /// specified number of digits to the left, masking the shift amount to the /// type's bit width, and stores the result in the left-hand-side variable. /// /// The `&<<=` operator performs a *masking shift*, where the value used as /// `rhs` is masked to produce a value in the range `0..(lhs: inout Self, rhs: Other) { lhs = lhs &<< rhs } } extension FixedWidthInteger { /// Returns a random value within the specified range, using the given /// generator as a source for randomness. /// /// Use this method to generate an integer within a specific range when you /// are using a custom random number generator. This example creates three /// new values in the range `1..<100`. /// /// for _ in 1...3 { /// print(Int.random(in: 1..<100, using: &myGenerator)) /// } /// // Prints "7" /// // Prints "44" /// // Prints "21" /// /// - Note: The algorithm used to create random values may change in a future /// version of Swift. If you're passing a generator that results in the /// same sequence of integer values each time you run your program, that /// sequence may change when your program is compiled using a different /// version of Swift. /// /// - Parameters: /// - range: The range in which to create a random value. /// `range` must not be empty. /// - generator: The random number generator to use when creating the /// new random value. /// - Returns: A random value within the bounds of `range`. @inlinable public static func random( in range: Range, using generator: inout T ) -> Self { _precondition( !range.isEmpty, "Can't get random value with an empty range" ) // Compute delta, the distance between the lower and upper bounds. This // value may not representable by the type Bound if Bound is signed, but // is always representable as Bound.Magnitude. let delta = Magnitude(truncatingIfNeeded: range.upperBound &- range.lowerBound) // The mathematical result we want is lowerBound plus a random value in // 0 ..< delta. We need to be slightly careful about how we do this // arithmetic; the Bound type cannot generally represent the random value, // so we use a wrapping addition on Bound.Magnitude. This will often // overflow, but produces the correct bit pattern for the result when // converted back to Bound. return Self(truncatingIfNeeded: Magnitude(truncatingIfNeeded: range.lowerBound) &+ generator.next(upperBound: delta) ) } /// Returns a random value within the specified range. /// /// Use this method to generate an integer within a specific range. This /// example creates three new values in the range `1..<100`. /// /// for _ in 1...3 { /// print(Int.random(in: 1..<100)) /// } /// // Prints "53" /// // Prints "64" /// // Prints "5" /// /// This method is equivalent to calling the version that takes a generator, /// passing in the system's default random generator. /// /// - Parameter range: The range in which to create a random value. /// `range` must not be empty. /// - Returns: A random value within the bounds of `range`. @inlinable public static func random(in range: Range) -> Self { var g = SystemRandomNumberGenerator() return Self.random(in: range, using: &g) } /// Returns a random value within the specified range, using the given /// generator as a source for randomness. /// /// Use this method to generate an integer within a specific range when you /// are using a custom random number generator. This example creates three /// new values in the range `1...100`. /// /// for _ in 1...3 { /// print(Int.random(in: 1...100, using: &myGenerator)) /// } /// // Prints "7" /// // Prints "44" /// // Prints "21" /// /// - Parameters: /// - range: The range in which to create a random value. /// - generator: The random number generator to use when creating the /// new random value. /// - Returns: A random value within the bounds of `range`. @inlinable public static func random( in range: ClosedRange, using generator: inout T ) -> Self { // Compute delta, the distance between the lower and upper bounds. This // value may not representable by the type Bound if Bound is signed, but // is always representable as Bound.Magnitude. var delta = Magnitude(truncatingIfNeeded: range.upperBound &- range.lowerBound) // Subtle edge case: if the range is the whole set of representable values, // then adding one to delta to account for a closed range will overflow. // If we used &+ instead, the result would be zero, which isn't helpful, // so we actually need to handle this case separately. if delta == Magnitude.max { return Self(truncatingIfNeeded: generator.next() as Magnitude) } // Need to widen delta to account for the right-endpoint of a closed range. delta += 1 // The mathematical result we want is lowerBound plus a random value in // 0 ..< delta. We need to be slightly careful about how we do this // arithmetic; the Bound type cannot generally represent the random value, // so we use a wrapping addition on Bound.Magnitude. This will often // overflow, but produces the correct bit pattern for the result when // converted back to Bound. return Self(truncatingIfNeeded: Magnitude(truncatingIfNeeded: range.lowerBound) &+ generator.next(upperBound: delta) ) } /// Returns a random value within the specified range. /// /// Use this method to generate an integer within a specific range. This /// example creates three new values in the range `1...100`. /// /// for _ in 1...3 { /// print(Int.random(in: 1...100)) /// } /// // Prints "53" /// // Prints "64" /// // Prints "5" /// /// This method is equivalent to calling `random(in:using:)`, passing in the /// system's default random generator. /// /// - Parameter range: The range in which to create a random value. /// - Returns: A random value within the bounds of `range`. @inlinable public static func random(in range: ClosedRange) -> Self { var g = SystemRandomNumberGenerator() return Self.random(in: range, using: &g) } } //===----------------------------------------------------------------------===// //===--- Operators on FixedWidthInteger -----------------------------------===// //===----------------------------------------------------------------------===// extension FixedWidthInteger { @_transparent public static prefix func ~ (x: Self) -> Self { return 0 &- x &- 1 } //===----------------------------------------------------------------------===// //=== "Smart right shift", supporting overshifts and negative shifts ------===// //===----------------------------------------------------------------------===// @_semantics("optimize.sil.specialize.generic.partial.never") @_transparent public static func >> < Other: BinaryInteger >(lhs: Self, rhs: Other) -> Self { var lhs = lhs _nonMaskingRightShiftGeneric(&lhs, rhs) return lhs } @_transparent @_semantics("optimize.sil.specialize.generic.partial.never") public static func >>= < Other: BinaryInteger >(lhs: inout Self, rhs: Other) { _nonMaskingRightShiftGeneric(&lhs, rhs) } @_transparent public static func _nonMaskingRightShiftGeneric < Other: BinaryInteger >(_ lhs: inout Self, _ rhs: Other) { let shift = rhs < -Self.bitWidth ? -Self.bitWidth : rhs > Self.bitWidth ? Self.bitWidth : Int(rhs) lhs = _nonMaskingRightShift(lhs, shift) } @_transparent public static func _nonMaskingRightShift(_ lhs: Self, _ rhs: Int) -> Self { let overshiftR = Self.isSigned ? lhs &>> (Self.bitWidth - 1) : 0 let overshiftL: Self = 0 if _fastPath(rhs >= 0) { if _fastPath(rhs < Self.bitWidth) { return lhs &>> Self(truncatingIfNeeded: rhs) } return overshiftR } if _slowPath(rhs <= -Self.bitWidth) { return overshiftL } return lhs &<< -rhs } //===----------------------------------------------------------------------===// //=== "Smart left shift", supporting overshifts and negative shifts -------===// //===----------------------------------------------------------------------===// @_semantics("optimize.sil.specialize.generic.partial.never") @_transparent public static func << < Other: BinaryInteger >(lhs: Self, rhs: Other) -> Self { var lhs = lhs _nonMaskingLeftShiftGeneric(&lhs, rhs) return lhs } @_transparent @_semantics("optimize.sil.specialize.generic.partial.never") public static func <<= < Other: BinaryInteger >(lhs: inout Self, rhs: Other) { _nonMaskingLeftShiftGeneric(&lhs, rhs) } @_transparent public static func _nonMaskingLeftShiftGeneric < Other: BinaryInteger >(_ lhs: inout Self, _ rhs: Other) { let shift = rhs < -Self.bitWidth ? -Self.bitWidth : rhs > Self.bitWidth ? Self.bitWidth : Int(rhs) lhs = _nonMaskingLeftShift(lhs, shift) } @_transparent public static func _nonMaskingLeftShift(_ lhs: Self, _ rhs: Int) -> Self { let overshiftR = Self.isSigned ? lhs &>> (Self.bitWidth - 1) : 0 let overshiftL: Self = 0 if _fastPath(rhs >= 0) { if _fastPath(rhs < Self.bitWidth) { return lhs &<< Self(truncatingIfNeeded: rhs) } return overshiftL } if _slowPath(rhs <= -Self.bitWidth) { return overshiftR } return lhs &>> -rhs } } extension FixedWidthInteger { @inlinable @_semantics("optimize.sil.specialize.generic.partial.never") public // @testable static func _convert( from source: Source ) -> (value: Self?, exact: Bool) { guard _fastPath(!source.isZero) else { return (0, true) } guard _fastPath(source.isFinite) else { return (nil, false) } guard Self.isSigned || source > -1 else { return (nil, false) } let exponent = source.exponent if _slowPath(Self.bitWidth <= exponent) { return (nil, false) } let minBitWidth = source.significandWidth let isExact = (minBitWidth <= exponent) let bitPattern = source.significandBitPattern // Determine the actual number of fractional significand bits. // `Source.significandBitCount` would not reflect the actual number of // fractional significand bits if `Source` is not a fixed-width floating-point // type; we can compute this value as follows if `source` is finite: let bitWidth = minBitWidth &+ bitPattern.trailingZeroBitCount let shift = exponent - Source.Exponent(bitWidth) // Use `Self.Magnitude` to prevent sign extension if `shift < 0`. let shiftedBitPattern = Self.Magnitude.bitWidth > bitWidth ? Self.Magnitude(truncatingIfNeeded: bitPattern) << shift : Self.Magnitude(truncatingIfNeeded: bitPattern << shift) if _slowPath(Self.isSigned && Self.bitWidth &- 1 == exponent) { return source < 0 && shiftedBitPattern == 0 ? (Self.min, isExact) : (nil, false) } let magnitude = ((1 as Self.Magnitude) << exponent) | shiftedBitPattern return ( Self.isSigned && source < 0 ? 0 &- Self(magnitude) : Self(magnitude), isExact) } @inlinable @_semantics("optimize.sil.specialize.generic.partial.never") @inline(__always) public init(_ source: T) { guard let value = Self._convert(from: source).value else { #if !$Embedded fatalError(""" \(T.self) value cannot be converted to \(Self.self) because it is \ outside the representable range """) #else fatalError("value not representable") #endif } self = value } @_semantics("optimize.sil.specialize.generic.partial.never") @inlinable public init?(exactly source: T) { let (temporary, exact) = Self._convert(from: source) guard exact, let value = temporary else { return nil } self = value } @inlinable @_semantics("optimize.sil.specialize.generic.partial.never") public init(clamping source: Other) { if _slowPath(source < Self.min) { self = Self.min } else if _slowPath(source > Self.max) { self = Self.max } else { self = Self(truncatingIfNeeded: source) } } @inlinable // FIXME(inline-always) @inline(__always) public init(truncatingIfNeeded source: T) { if Self.bitWidth <= Int.bitWidth { self = Self(_truncatingBits: source._lowWord) } else { self = Self._truncatingInit(source) } } @_alwaysEmitIntoClient internal static func _truncatingInit(_ source: T) -> Self { let neg = source < (0 as T) var result: Self = neg ? ~0 : 0 var shift: Self = 0 let width = Self(_truncatingBits: Self.bitWidth._lowWord) for word in source.words { guard shift < width else { break } // Masking shift is OK here because we have already ensured // that shift < Self.bitWidth. Not masking results in // infinite recursion. result ^= Self(_truncatingBits: neg ? ~word : word) &<< shift shift += Self(_truncatingBits: Int.bitWidth._lowWord) } return result } @_transparent public // transparent static var _highBitIndex: Self { return Self.init(_truncatingBits: UInt(Self.bitWidth._value) &- 1) } /// Returns the sum of the two given values, wrapping the result in case of /// any overflow. /// /// The overflow addition operator (`&+`) discards any bits that overflow the /// fixed width of the integer type. In the following example, the sum of /// `100` and `121` is greater than the maximum representable `Int8` value, /// so the result is the partial value after discarding the overflowing /// bits. /// /// let x: Int8 = 10 &+ 21 /// // x == 31 /// let y: Int8 = 100 &+ 121 /// // y == -35 (after overflow) /// /// For more about arithmetic with overflow operators, see [Overflow /// Operators][overflow] in *[The Swift Programming Language][tspl]*. /// /// [overflow]: https://docs.swift.org/swift-book/LanguageGuide/AdvancedOperators.html#ID37 /// [tspl]: https://docs.swift.org/swift-book/ /// /// - Parameters: /// - lhs: The first value to add. /// - rhs: The second value to add. @_transparent public static func &+ (lhs: Self, rhs: Self) -> Self { return lhs.addingReportingOverflow(rhs).partialValue } /// Adds two values and stores the result in the left-hand-side variable, /// wrapping any overflow. /// /// The masking addition assignment operator (`&+=`) silently wraps any /// overflow that occurs during the operation. In the following example, the /// sum of `100` and `121` is greater than the maximum representable `Int8` /// value, so the result is the partial value after discarding the /// overflowing bits. /// /// var x: Int8 = 10 /// x &+= 21 /// // x == 31 /// var y: Int8 = 100 /// y &+= 121 /// // y == -35 (after overflow) /// /// For more about arithmetic with overflow operators, see [Overflow /// Operators][overflow] in *[The Swift Programming Language][tspl]*. /// /// [overflow]: https://docs.swift.org/swift-book/LanguageGuide/AdvancedOperators.html#ID37 /// [tspl]: https://docs.swift.org/swift-book/ /// /// - Parameters: /// - lhs: The first value to add. /// - rhs: The second value to add. @_transparent public static func &+= (lhs: inout Self, rhs: Self) { lhs = lhs &+ rhs } /// Returns the difference of the two given values, wrapping the result in /// case of any overflow. /// /// The overflow subtraction operator (`&-`) discards any bits that overflow /// the fixed width of the integer type. In the following example, the /// difference of `10` and `21` is less than zero, the minimum representable /// `UInt` value, so the result is the partial value after discarding the /// overflowing bits. /// /// let x: UInt8 = 21 &- 10 /// // x == 11 /// let y: UInt8 = 10 &- 21 /// // y == 245 (after overflow) /// /// For more about arithmetic with overflow operators, see [Overflow /// Operators][overflow] in *[The Swift Programming Language][tspl]*. /// /// [overflow]: https://docs.swift.org/swift-book/LanguageGuide/AdvancedOperators.html#ID37 /// [tspl]: https://docs.swift.org/swift-book/ /// /// - Parameters: /// - lhs: A numeric value. /// - rhs: The value to subtract from `lhs`. @_transparent public static func &- (lhs: Self, rhs: Self) -> Self { return lhs.subtractingReportingOverflow(rhs).partialValue } /// Subtracts the second value from the first and stores the difference in the /// left-hand-side variable, wrapping any overflow. /// /// The masking subtraction assignment operator (`&-=`) silently wraps any /// overflow that occurs during the operation. In the following example, the /// difference of `10` and `21` is less than zero, the minimum representable /// `UInt` value, so the result is the result is the partial value after /// discarding the overflowing bits. /// /// var x: Int8 = 21 /// x &-= 10 /// // x == 11 /// var y: UInt8 = 10 /// y &-= 21 /// // y == 245 (after overflow) /// /// For more about arithmetic with overflow operators, see [Overflow /// Operators][overflow] in *[The Swift Programming Language][tspl]*. /// /// [overflow]: https://docs.swift.org/swift-book/LanguageGuide/AdvancedOperators.html#ID37 /// [tspl]: https://docs.swift.org/swift-book/ /// /// - Parameters: /// - lhs: A numeric value. /// - rhs: The value to subtract from `lhs`. @_transparent public static func &-= (lhs: inout Self, rhs: Self) { lhs = lhs &- rhs } @_transparent public static func &*(lhs: Self, rhs: Self) -> Self { return rhs.multipliedReportingOverflow(by: lhs).partialValue } /// Multiplies two values and stores the result in the left-hand-side /// variable, wrapping any overflow. /// /// The masking multiplication assignment operator (`&*=`) silently wraps /// any overflow that occurs during the operation. In the following example, /// the product of `10` and `50` is greater than the maximum representable /// `Int8` value, so the result is the partial value after discarding the /// overflowing bits. /// /// var x: Int8 = 10 /// x &*= 5 /// // x == 50 /// var y: Int8 = 10 /// y &*= 50 /// // y == -12 (after overflow) /// /// For more about arithmetic with overflow operators, see [Overflow /// Operators][overflow] in *[The Swift Programming Language][tspl]*. /// /// [overflow]: https://docs.swift.org/swift-book/LanguageGuide/AdvancedOperators.html#ID37 /// [tspl]: https://docs.swift.org/swift-book/ /// /// - Parameters: /// - lhs: The first value to multiply. /// - rhs: The second value to multiply. @_transparent public static func &*= (lhs: inout Self, rhs: Self) { lhs = lhs &* rhs } } extension FixedWidthInteger { @inlinable public static func _random( using generator: inout R ) -> Self { if bitWidth <= UInt64.bitWidth { return Self(truncatingIfNeeded: generator.next()) } let (quotient, remainder) = bitWidth.quotientAndRemainder( dividingBy: UInt64.bitWidth ) var tmp: Self = 0 for i in 0 ..< quotient + remainder.signum() { let next: UInt64 = generator.next() tmp += Self(truncatingIfNeeded: next) &<< (UInt64.bitWidth * i) } return tmp } } //===----------------------------------------------------------------------===// //===--- UnsignedInteger --------------------------------------------------===// //===----------------------------------------------------------------------===// // Implementor's note: UnsignedInteger should have required Magnitude == Self, // because it can necessarily represent the magnitude of every value and every // recursive generic constraint should terminate unless there is a good // semantic reason for it not to do so. // // However, we cannot easily add this constraint because it changes the // mangling of generics constrained on // to be . As a practical matter, // every unsigned type will satisfy this constraint, so converting between // Magnitude and Self in generic code is acceptable. /// An integer type that can represent only nonnegative values. public protocol UnsignedInteger: BinaryInteger { } extension UnsignedInteger { /// The magnitude of this value. /// /// Every unsigned integer is its own magnitude, so for any value `x`, /// `x == x.magnitude`. /// /// The global `abs(_:)` function provides more familiar syntax when you need /// to find an absolute value. In addition, because `abs(_:)` always returns /// a value of the same type, even in a generic context, using the function /// instead of the `magnitude` property is encouraged. @inlinable // FIXME(inline-always) public var magnitude: Self { @inline(__always) get { return self } } /// A Boolean value indicating whether this type is a signed integer type. /// /// This property is always `false` for unsigned integer types. @inlinable // FIXME(inline-always) public static var isSigned: Bool { @inline(__always) get { return false } } } extension UnsignedInteger where Self: FixedWidthInteger { /// Creates a new instance from the given integer. /// /// Use this initializer to convert from another integer type when you know /// the value is within the bounds of this type. Passing a value that can't /// be represented in this type results in a runtime error. /// /// In the following example, the constant `y` is successfully created from /// `x`, an `Int` instance with a value of `100`. Because the `Int8` type /// can represent `127` at maximum, the attempt to create `z` with a value /// of `1000` results in a runtime error. /// /// let x = 100 /// let y = Int8(x) /// // y == 100 /// let z = Int8(x * 10) /// // Error: Not enough bits to represent the given value /// /// - Parameter source: A value to convert to this type of integer. The value /// passed as `source` must be representable in this type. @_semantics("optimize.sil.specialize.generic.partial.never") @_transparent public init(_ source: T) { // This check is potentially removable by the optimizer if T.isSigned { _precondition(source >= (0 as T), "Negative value is not representable") } // This check is potentially removable by the optimizer if source.bitWidth >= Self.bitWidth { _precondition(source <= Self.max, "Not enough bits to represent the passed value") } self.init(truncatingIfNeeded: source) } @_semantics("optimize.sil.specialize.generic.partial.never") @_transparent public init?(exactly source: T) { // This check is potentially removable by the optimizer if T.isSigned && source < (0 as T) { return nil } // The width check can be eliminated by the optimizer if source.bitWidth >= Self.bitWidth && source > Self.max { return nil } self.init(truncatingIfNeeded: source) } /// The maximum representable integer in this type. /// /// For unsigned integer types, this value is `(2 ** bitWidth) - 1`, where /// `**` is exponentiation. @_transparent public static var max: Self { return ~0 } /// The minimum representable integer in this type. /// /// For unsigned integer types, this value is always `0`. @_transparent public static var min: Self { return 0 } @_alwaysEmitIntoClient public func dividingFullWidth( _ dividend: (high: Self, low: Magnitude) ) -> (quotient: Self, remainder: Self) { // Validate preconditions to guarantee that the quotient is representable. precondition(self != .zero, "Division by zero") precondition(dividend.high < self, "Dividend.high must be smaller than divisor") // UnsignedInteger should have a Magnitude = Self constraint, but does not, // so we have to do this conversion (we can't easily add the constraint // because it changes how generic signatures constrained to // are minimized, which changes the mangling). // In practice, "every" UnsignedInteger type will satisfy this, and if one // somehow manages not to in a way that would break this conversion then // a default implementation of this method never could have worked anyway. let low = Self(dividend.low) // The basic algorithm is taken from Knuth (TAoCP, Vol 2, §4.3.1), using // words that are half the size of Self (so the dividend has four words // and the divisor has two). The fact that the denominator has exactly // two words allows for a slight simplification vs. Knuth's Algorithm D, // in that our computed quotient digit is always exactly right, while // in the more general case it can be one too large, requiring a subsequent // borrow. // // Knuth's algorithm (and any long division, really), requires that the // divisor (self) be normalized (meaning that the high-order bit is set). // We begin by counting the leading zeros so we know how many bits we // have to shift to normalize. let lz = leadingZeroBitCount // If the divisor is actually a power of two, division is just a shift, // which we can handle much more efficiently. So we do a check for that // case and early-out if possible. if (self &- 1) & self == .zero { let shift = Self.bitWidth - 1 - lz let q = low &>> shift | dividend.high &<< -shift let r = low & (self &- 1) return (q, r) } // Shift the divisor left by lz bits to normalize it. We shift the // dividend left by the same amount so that we get the quotient is // preserved (we will have to shift right to recover the remainder). // Note that the right shift `low >> (Self.bitWidth - lz)` is // deliberately a non-masking shift because lz might be zero. let v = self &<< lz let uh = dividend.high &<< lz | low >> (Self.bitWidth - lz) let ul = low &<< lz // Now we have a normalized dividend (uh:ul) and divisor (v). Split // v into half-words (vh:vl) so that we can use the "normal" division // on Self as a word / halfword -> halfword division get one halfword // digit of the quotient at a time. let n_2 = Self.bitWidth/2 let mask = Self(1) &<< n_2 &- 1 let vh = v &>> n_2 let vl = v & mask // For the (fairly-common) special case where vl is zero, we can simplify // the arithmetic quite a bit: if vl == .zero { let qh = uh / vh let residual = (uh &- qh &* vh) &<< n_2 | ul &>> n_2 let ql = residual / vh return ( // Assemble quotient from half-word digits quotient: qh &<< n_2 | ql, // Compute remainder (we can re-use the residual to make this simpler). remainder: ((residual &- ql &* vh) &<< n_2 | ul & mask) &>> lz ) } // Helper function: performs a (1½ word)/word division to produce a // half quotient word q. We'll need to use this twice to generate the // full quotient. // // high is the high word of the quotient for this sub-division. // low is the low half-word of the quotient for this sub-division (the // high half of low must be zero). // // returns the quotient half-word digit. In a more general setting, this // computed digit might be one too large, which has to be accounted for // later on (see Knuth, Algorithm D), but when the divisor is only two // half-words (as here), that can never happen, because we use the full // divisor in the check for the while loop. func generateHalfDigit(high: Self, low: Self) -> Self { // Get q̂ satisfying a = vh q̂ + r̂ with 0 ≤ r̂ < vh: var (q̂, r̂) = high.quotientAndRemainder(dividingBy: vh) // Knuth's "Theorem A" establishes that q̂ is an approximation to // the quotient digit q, satisfying q ≤ q̂ ≤ q + 2. We adjust it // downward as needed until we have the correct q. while q̂ > mask || q̂ &* vl > (r̂ &<< n_2 | low) { q̂ &-= 1 r̂ &+= vh if r̂ > mask { break } } return q̂ } // Generate the first quotient digit, subtract off its product with the // divisor to generate the residual, then compute the second quotient // digit from that. let qh = generateHalfDigit(high: uh, low: ul &>> n_2) let residual = (uh &<< n_2 | ul &>> n_2) &- (qh &* v) let ql = generateHalfDigit(high: residual, low: ul & mask) return ( // Assemble quotient from half-word digits quotient: qh &<< n_2 | ql, // Compute remainder (we can re-use the residual to make this simpler). remainder: ((residual &<< n_2 | ul & mask) &- (ql &* v)) &>> lz ) } } //===----------------------------------------------------------------------===// //===--- SignedInteger ----------------------------------------------------===// //===----------------------------------------------------------------------===// /// An integer type that can represent both positive and negative values. public protocol SignedInteger: BinaryInteger, SignedNumeric { // These requirements are needed for binary compatibility; the following: // // func foo(_ a: T) -> T // where T: SignedInteger & FixedWidthInteger { // a &+ 1 // } // // generated a call to `static Swift.SignedInteger._maskingAdd(A, A) -> A` // when compiled with Swift 5.5 and earlier. @available(*, deprecated, message: "Use &+ instead.") static func _maskingAdd(_ lhs: Self, _ rhs: Self) -> Self @available(*, deprecated, message: "Use &- instead.") static func _maskingSubtract(_ lhs: Self, _ rhs: Self) -> Self } extension SignedInteger { /// A Boolean value indicating whether this type is a signed integer type. /// /// This property is always `true` for signed integer types. @inlinable // FIXME(inline-always) public static var isSigned: Bool { @inline(__always) get { return true } } } extension SignedInteger where Self: FixedWidthInteger { /// Creates a new instance from the given integer. /// /// Use this initializer to convert from another integer type when you know /// the value is within the bounds of this type. Passing a value that can't /// be represented in this type results in a runtime error. /// /// In the following example, the constant `y` is successfully created from /// `x`, an `Int` instance with a value of `100`. Because the `Int8` type /// can represent `127` at maximum, the attempt to create `z` with a value /// of `1000` results in a runtime error. /// /// let x = 100 /// let y = Int8(x) /// // y == 100 /// let z = Int8(x * 10) /// // Error: Not enough bits to represent the given value /// /// - Parameter source: A value to convert to this type of integer. The value /// passed as `source` must be representable in this type. @_semantics("optimize.sil.specialize.generic.partial.never") @_transparent public init(_ source: T) { // This check is potentially removable by the optimizer if T.isSigned && source.bitWidth > Self.bitWidth { _precondition(source >= Self.min, "Not enough bits to represent a signed value") } // This check is potentially removable by the optimizer if (source.bitWidth > Self.bitWidth) || (source.bitWidth == Self.bitWidth && !T.isSigned) { _precondition(source <= Self.max, "Not enough bits to represent the passed value") } self.init(truncatingIfNeeded: source) } @_semantics("optimize.sil.specialize.generic.partial.never") @_transparent public init?(exactly source: T) { // This check is potentially removable by the optimizer if T.isSigned && source.bitWidth > Self.bitWidth && source < Self.min { return nil } // The width check can be eliminated by the optimizer if (source.bitWidth > Self.bitWidth || (source.bitWidth == Self.bitWidth && !T.isSigned)) && source > Self.max { return nil } self.init(truncatingIfNeeded: source) } /// The maximum representable integer in this type. /// /// For signed integer types, this value is `(2 ** (bitWidth - 1)) - 1`, /// where `**` is exponentiation. @_transparent public static var max: Self { return ~min } /// The minimum representable integer in this type. /// /// For signed integer types, this value is `-(2 ** (bitWidth - 1))`, where /// `**` is exponentiation. @_transparent public static var min: Self { return (-1 as Self) &<< Self._highBitIndex } @inlinable public func isMultiple(of other: Self) -> Bool { // Nothing but zero is a multiple of zero. if other == 0 { return self == 0 } // Special case to avoid overflow on .min / -1 for signed types. if other == -1 { return true } // Having handled those special cases, this is safe. return self % other == 0 } @_alwaysEmitIntoClient public func dividingFullWidth( _ dividend: (high: Self, low: Magnitude) ) -> (quotient: Self, remainder: Self) { // Get magnitude of dividend: var magnitudeHigh = Magnitude(truncatingIfNeeded: dividend.high) var magnitudeLow = dividend.low if dividend.high < .zero { let carry: Bool (magnitudeLow, carry) = (~magnitudeLow).addingReportingOverflow(1) magnitudeHigh = ~magnitudeHigh &+ (carry ? 1 : 0) } // Do division on magnitudes (using unsigned implementation): let (unsignedQuotient, unsignedRemainder) = magnitude.dividingFullWidth( (high: magnitudeHigh, low: magnitudeLow) ) // Fixup sign: quotient is negative if dividend and divisor disagree. // We will also trap here if the quotient does not fit in Self. let quotient: Self if self ^ dividend.high < .zero { // It is possible that the quotient is representable but its magnitude // is not representable as Self (if quotient is Self.min), so we have // to handle that case carefully here. precondition(unsignedQuotient <= Self.min.magnitude, "Quotient is not representable.") quotient = Self(truncatingIfNeeded: 0 &- unsignedQuotient) } else { quotient = Self(unsignedQuotient) } var remainder = Self(unsignedRemainder) if dividend.high < .zero { remainder = 0 &- remainder } return (quotient, remainder) } } /// Returns the given integer as the equivalent value in a different integer /// type. /// /// Calling the `numericCast(_:)` function is equivalent to calling an /// initializer for the destination type. `numericCast(_:)` traps on overflow /// in `-O` and `-Onone` builds. /// /// - Parameter x: The integer to convert, an instance of type `T`. /// - Returns: The value of `x` converted to type `U`. @inlinable public func numericCast(_ x: T) -> U { return U(x) } // Needed to support user-defined types conformance to SignedInteger. // We need these defaults to exist, but they are not called. extension SignedInteger { @available(*, deprecated, message: "Use &+ instead.") public static func _maskingAdd(_ lhs: Self, _ rhs: Self) -> Self { fatalError("Should be overridden in a more specific type") } @available(*, deprecated, message: "Use &- instead.") public static func _maskingSubtract(_ lhs: Self, _ rhs: Self) -> Self { fatalError("Should be overridden in a more specific type") } } // These symbols have to exist for ABI compatibility, but should not be used // any longer; we want to find the FixedWidthInteger definitions instead. extension SignedInteger where Self: FixedWidthInteger { @available(*, unavailable) public static func &+(lhs: Self, rhs: Self) -> Self { lhs.addingReportingOverflow(rhs).partialValue } // This may be called in rare situations by binaries compiled with // Swift 5.5 and earlier, so we need to keep it around for compatibility. // We can't mark it unavailable, because then the concrete signed integer // types in the standard library would not satisfy the protocol requirements. @available(*, deprecated, message: "Use &+ instead.") public static func _maskingAdd(_ lhs: Self, _ rhs: Self) -> Self { lhs.addingReportingOverflow(rhs).partialValue } @available(*, unavailable) public static func &-(lhs: Self, rhs: Self) -> Self { lhs.subtractingReportingOverflow(rhs).partialValue } // This may be called in rare situations by binaries compiled with // Swift 5.5 and earlier, so we need to keep it around for compatibility. // We can't mark it unavailable, because then the concrete signed integer // types in the standard library would not satisfy the protocol requirements. @available(*, deprecated, message: "Use &- instead.") public static func _maskingSubtract(_ lhs: Self, _ rhs: Self) -> Self { lhs.subtractingReportingOverflow(rhs).partialValue } }