| //===--- FixedPoint.swift.gyb ---------------------------------*- swift -*-===// |
| // |
| // This source file is part of the Swift.org open source project |
| // |
| // Copyright (c) 2014 - 2017 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 |
| // |
| //===----------------------------------------------------------------------===// |
| |
| %{ |
| |
| from SwiftIntTypes import all_integer_types, int_max_bits, should_define_truncating_bit_pattern_init |
| from SwiftFloatingPointTypes import all_floating_point_types, getFtoIBounds |
| |
| # |
| # Utility code for later in this template |
| # |
| def hexify(n): |
| """Return a legible hex representation of n, using '_' separators """ |
| z = '%X' % n |
| l = len(z) |
| r = [] |
| while z: |
| r.insert(0, z[-4:]) |
| z = z[:-4] |
| return '0x' + '_'.join(r) |
| |
| # Number of bits in the Builtin.Word type |
| word_bits = int(CMAKE_SIZEOF_VOID_P) * 8 |
| |
| # Number of bits in integer literals. |
| builtinIntLiteralBits = 2048 |
| |
| def maskBits(n): |
| """Return an n-bit mask in hex""" |
| return hexify((1 << n) - 1) |
| |
| IntMax = 'Int%s' % int_max_bits |
| UIntMax = 'UInt%s' % int_max_bits |
| }% |
| |
| /// The largest native signed integer type. |
| public typealias IntMax = ${IntMax} |
| /// The largest native unsigned integer type. |
| public typealias UIntMax = ${UIntMax} |
| |
| /// This protocol is an implementation detail of `Integer`; do |
| /// not use it directly. |
| @_show_in_interface |
| public protocol _Integer |
| : _ExpressibleByBuiltinIntegerLiteral, |
| ExpressibleByIntegerLiteral, |
| CustomStringConvertible, |
| Hashable, |
| IntegerArithmetic, |
| BitwiseOperations, |
| _Incrementable |
| { |
| } |
| |
| /// A set of common requirements for Swift's integer types. |
| public protocol Integer : _Integer, Strideable {} |
| |
| /// This protocol is an implementation detail of `SignedInteger`; |
| /// do not use it directly. |
| @_show_in_interface |
| public protocol _SignedInteger : _Integer, SignedNumber { |
| /// Represent this number using Swift's widest native signed integer |
| /// type. |
| func toIntMax() -> IntMax |
| |
| /// Convert from Swift's widest signed integer type, trapping on |
| /// overflow. |
| init(_: IntMax) |
| } |
| |
| /// A set of common requirements for Swift's signed integer types. |
| public protocol SignedInteger : _SignedInteger, Integer { |
| /// Represent this number using Swift's widest native signed integer |
| /// type. |
| func toIntMax() -> IntMax |
| |
| /// Convert from Swift's widest signed integer type, trapping on |
| /// overflow. |
| init(_: IntMax) |
| } |
| |
| extension SignedInteger { |
| // FIXME(ABI)#29 : using Int as the return value is wrong. |
| @_transparent |
| public func distance(to other: Self) -> Int { |
| return numericCast((numericCast(other) as IntMax) - numericCast(self)) |
| } |
| |
| // FIXME(ABI)#30 : using Int as the argument is wrong. |
| @_transparent |
| public func advanced(by n: Int) -> Self { |
| return numericCast((numericCast(self) as IntMax) + numericCast(n)) |
| } |
| } |
| |
| /// This protocol is an implementation detail of `UnsignedInteger`; |
| /// do not use it directly. |
| @_show_in_interface |
| public protocol _DisallowMixedSignArithmetic : _Integer { |
| // Used to create a deliberate ambiguity in cases like UInt(1) + |
| // Int(1), which would otherwise compile due to the arithmetic |
| // operators defined for Strideable types (unsigned types are |
| // Strideable). |
| associatedtype _DisallowMixedSignArithmetic : SignedInteger = Int |
| } |
| |
| /// A set of common requirements for Swift's unsigned integer types. |
| public protocol UnsignedInteger : _DisallowMixedSignArithmetic, Integer { |
| /// Represent this number using Swift's widest native unsigned |
| /// integer type. |
| func toUIntMax() -> UIntMax |
| |
| /// Convert from Swift's widest unsigned integer type, trapping on |
| /// overflow. |
| init(_: UIntMax) |
| } |
| |
| extension UnsignedInteger { |
| // FIXME(ABI)#31 : using Int as the return value is wrong. |
| @_transparent |
| public func distance(to other: Self) -> Int { |
| return numericCast((numericCast(other) as IntMax) - numericCast(self)) |
| } |
| |
| // FIXME(ABI)#32 : using Int as the return value is wrong. |
| @_transparent |
| public func advanced(by n: Int) -> Self { |
| return numericCast((numericCast(self) as IntMax) + numericCast(n)) |
| } |
| } |
| |
| /// Convert `x` to type `U`, trapping on overflow in -Onone and -O |
| /// builds. |
| /// |
| /// Typically used to do conversion to any contextually-deduced |
| /// integer type: |
| /// |
| /// func f(_ x: Int32) {} |
| /// func g(_ x: Int64) { f(numericCast(x)) } |
| public func numericCast< |
| T : _SignedInteger, U : _SignedInteger |
| >(_ x: T) -> U { |
| return U(x.toIntMax()) |
| } |
| |
| /// Convert `x` to type `U`, trapping on overflow in -Onone and -O |
| /// builds. |
| /// |
| /// Typically used to do conversion to any contextually-deduced |
| /// integer type: |
| /// |
| /// func f(_ x: UInt32) {} |
| /// func g(_ x: UInt64) { f(numericCast(x)) } |
| public func numericCast< |
| T : UnsignedInteger, U : UnsignedInteger |
| >(_ x: T) -> U { |
| return U(x.toUIntMax()) |
| } |
| |
| /// Convert `x` to type `U`, trapping on overflow in -Onone and -O |
| /// builds. |
| /// |
| /// Typically used to do conversion to any contextually-deduced |
| /// integer type: |
| /// |
| /// func f(_ x: UInt32) {} |
| /// func g(_ x: Int64) { f(numericCast(x)) } |
| public func numericCast< |
| T : _SignedInteger, U : UnsignedInteger |
| >(_ x: T) -> U { |
| return U(UIntMax(x.toIntMax())) |
| } |
| |
| /// Convert `x` to type `U`, trapping on overflow in -Onone and -O |
| /// builds. |
| /// |
| /// Typically used to do conversion to any contextually-deduced |
| /// integer type: |
| /// |
| /// func f(_ x: Int32) {} |
| /// func g(_ x: UInt64) { f(numericCast(x)) } |
| public func numericCast< |
| T : UnsignedInteger, U : _SignedInteger |
| >(_ x: T) -> U { |
| return U(IntMax(x.toUIntMax())) |
| } |
| |
| //===--- Loop over all integer types --------------------------------------===// |
| % for self_ty in all_integer_types(word_bits): |
| % bits = self_ty.bits |
| % signed = self_ty.is_signed |
| % (sign, ext) = ('s', 'sext') if signed else ('u', 'zext') |
| % Self = self_ty.stdlib_name |
| % BuiltinName = self_ty.builtin_name |
| % OtherSelf = self_ty.get_opposite_signedness().stdlib_name |
| % Article = 'An' if bits == 8 else 'A' |
| |
| % if self_ty.is_word: |
| /// ${'An un' if sign == 'u' else 'A '}signed integer value type. |
| /// |
| /// On 32-bit platforms, `${Self}` is the same size as `${Self}32`, and |
| /// on 64-bit platforms, `${Self}` is the same size as `${Self}64`. |
| % else: |
| /// ${Article} ${bits}-bit ${'un' if sign == 'u' else ''}signed integer value |
| /// type. |
| % end |
| @_fixed_layout |
| public struct ${Self} |
| : ${'SignedInteger' if sign == 's' else 'UnsignedInteger'}, |
| Comparable, Equatable { |
| public // @testable |
| var _value: Builtin.${BuiltinName} |
| |
| // FIXME: this declaration should be inferred. |
| // <rdar://problem/18379938> Type checker refuses to use the default for |
| // Int.Distance associated type |
| |
| /// Create an instance initialized to zero. |
| @_transparent public |
| init() { |
| let maxWidthZero: IntMax = 0 |
| self._value = Builtin.truncOrBitCast_Int${int_max_bits}_${BuiltinName}( |
| maxWidthZero._value) |
| } |
| |
| @_transparent public |
| init(_ _v: Builtin.${BuiltinName}) { |
| self._value = _v |
| } |
| |
| @_transparent public |
| init(_bits: Builtin.${BuiltinName}) { |
| self._value = _bits |
| } |
| |
| % if self_ty.is_word: |
| @_transparent |
| public // @testable |
| init(_ _v: Builtin.Word) { |
| % if BuiltinName == 'Int32': |
| self._value = Builtin.truncOrBitCast_Word_Int32(_v) |
| % elif BuiltinName == 'Int64': |
| self._value = Builtin.zextOrBitCast_Word_Int64(_v) |
| % end |
| } |
| |
| @_transparent |
| public // @testable |
| var _builtinWordValue: Builtin.Word { |
| % if BuiltinName == 'Int32': |
| return Builtin.zextOrBitCast_Int32_Word(_value) |
| % elif BuiltinName == 'Int64': |
| return Builtin.truncOrBitCast_Int64_Word(_value) |
| % end |
| } |
| % end |
| |
| |
| % if bits > 8: |
| /// Creates an integer from its big-endian representation, changing the |
| /// byte order if necessary. |
| @_transparent public |
| init(bigEndian value: ${Self}) { |
| #if _endian(big) |
| self = value |
| #else |
| self = ${Self}(Builtin.int_bswap_${BuiltinName}(value._value)) |
| #endif |
| } |
| |
| /// Creates an integer from its little-endian representation, changing the |
| /// byte order if necessary. |
| @_transparent public |
| init(littleEndian value: ${Self}) { |
| #if _endian(little) |
| self = value |
| #else |
| self = ${Self}(Builtin.int_bswap_${BuiltinName}(value._value)) |
| #endif |
| } |
| % end |
| |
| @_transparent public |
| init(_builtinIntegerLiteral value: Builtin.Int${builtinIntLiteralBits}) { |
| self = ${Self}(Builtin.s_to_${sign}_checked_trunc_Int${builtinIntLiteralBits}_${BuiltinName}(value).0) |
| } |
| |
| /// Create an instance initialized to `value`. |
| @_transparent public |
| init(integerLiteral value: ${Self}) { |
| self = value |
| } |
| |
| % if bits > 8: |
| /// Returns the big-endian representation of the integer, changing the |
| /// byte order if necessary. |
| public var bigEndian: ${Self} { |
| #if _endian(big) |
| return self |
| #else |
| return ${Self}(Builtin.int_bswap_${BuiltinName}(_value)) |
| #endif |
| } |
| /// Returns the little-endian representation of the integer, changing the |
| /// byte order if necessary. |
| public var littleEndian: ${Self} { |
| #if _endian(little) |
| return self |
| #else |
| return ${Self}(Builtin.int_bswap_${BuiltinName}(_value)) |
| #endif |
| } |
| % end |
| |
| % if bits > 8: |
| /// Returns the current integer with the byte order swapped. |
| public var byteSwapped: ${Self} { |
| return ${Self}(Builtin.int_bswap_${BuiltinName}(_value)) |
| } |
| % end |
| |
| % max = maskBits((bits - 1) if signed else bits) |
| @_transparent public |
| static var max: ${Self} { return ${max} } |
| @_transparent public |
| static var min: ${Self} { return ${'-%s-1' % max if signed else '0'} } |
| @_transparent |
| public static var _sizeInBits: ${Self} { return ${bits} } |
| public static var _sizeInBytes: ${Self} { return ${bits}/8 } |
| } |
| |
| extension ${Self} : Hashable { |
| /// The hash value. |
| /// |
| /// **Axiom:** `x == y` implies `x.hashValue == y.hashValue`. |
| /// |
| /// - Note: The hash value is not guaranteed to be stable across |
| /// different invocations of the same program. Do not persist the |
| /// hash value across program runs. |
| public var hashValue: Int { |
| @inline(__always) |
| get { |
| % if bits <= word_bits and signed: |
| // Sign extend the value. |
| return Int(self) |
| % elif bits <= word_bits and not signed: |
| // Sign extend the value. |
| return Int(${OtherSelf}(bitPattern: self)) |
| % elif bits == word_bits * 2: |
| // We have twice as many bits as we need to return. |
| return |
| Int(truncatingBitPattern: self) ^ |
| Int(truncatingBitPattern: self >> 32) |
| % else: |
| _Unimplemented() |
| % end |
| } |
| } |
| } |
| |
| extension ${Self} : CustomStringConvertible { |
| /// A textual representation of `self`. |
| public var description: String { |
| % if signed: |
| return _int64ToString(self.toIntMax()) |
| % else: |
| return _uint64ToString(self.toUIntMax()) |
| % end |
| } |
| } |
| |
| // Operations that return an overflow bit in addition to a partial result, |
| // helpful for checking for overflow when you want to handle it. |
| extension ${Self} { |
| % for Method, op in [('add', 'add'), ('subtract', 'sub'), ('multiply', 'mul')]: |
| /// ${Method.capitalize()} `lhs` and `rhs`, returning a result and a |
| /// `Bool` that is `true` iff the operation caused an arithmetic |
| /// overflow. |
| @_transparent public |
| static func ${Method}WithOverflow(_ lhs: ${Self}, _ rhs: ${Self}) -> (${Self}, overflow: Bool) { |
| let tmp = Builtin.${sign}${op}_with_overflow_${BuiltinName}(lhs._value, rhs._value, false._value) |
| return (${Self}(tmp.0), Bool(tmp.1)) |
| } |
| % end |
| |
| % for Method, op in [('divide', 'div'), ('remainder', 'rem')]: |
| /// Divide `lhs` and `rhs`, returning |
| /// ${'a result' if op == 'div' else 'the remainder'} and a `Bool` |
| /// that is `true` iff the operation caused an arithmetic overflow. |
| @_transparent public |
| static func ${Method}WithOverflow(_ lhs: ${Self}, _ rhs: ${Self}) -> (${Self}, overflow: Bool) { |
| if rhs == 0 { |
| return (0, true) |
| } |
| % if signed: |
| if lhs == ${Self}.min && rhs == -1 { |
| return (0, true) |
| } |
| % end |
| // FIXME: currently doesn't detect overflow -- blocked by: |
| // <rdar://15735295> Need [su]{div,rem}_with_overflow IR |
| let tmp = Builtin.${sign}${op}_${BuiltinName}(lhs._value, rhs._value) |
| return (${Self}(tmp), false) |
| } |
| %end |
| |
| % (U, un) = ('','') if signed else ('U','un') |
| /// Represent this number using Swift's widest native ${un}signed |
| /// integer type. |
| @_transparent public |
| func to${U}IntMax() -> ${U}IntMax { |
| return ${'self' if Self == U+'Int%s'%int_max_bits else U+'IntMax(self)'} |
| } |
| % if not signed: |
| /// Explicitly convert to `IntMax`${', trapping on overflow (except in -Ounchecked builds)' if bits == int_max_bits else ''}. |
| @_transparent public |
| func toIntMax() -> IntMax { |
| return IntMax(toUIntMax()) |
| } |
| % end |
| } |
| |
| % if signed: |
| extension ${Self} : SignedNumber {} |
| % end |
| |
| |
| %{ |
| import gyb |
| |
| fixed_fixed_conversion_function = gyb.parse_template("fixed_fixed_conversion_function", |
| """ |
| % |
| let src = value._value |
| let result: (value: Builtin.${BuiltinName}, error: Builtin.Int1) |
| % |
| % if srcBits == bits and srcSign == sign: # Exact same size/signedness. |
| result = (src, false._value) |
| % |
| % elif srcBits == bits: # Same size, switching signs. |
| result = Builtin.${srcSign}_to_${sign}_checked_conversion_Int${srcBits}(src) |
| % |
| % elif srcBits > bits: # Larger input, check for truncation. |
| result = Builtin.${srcSign}_to_${sign}_checked_trunc_Int${srcBits}_Int${bits}(src) |
| % |
| % elif srcSigned and not signed: # Smaller size input, signed going to unsigned. |
| let (tmp, signError) = Builtin.s_to_u_checked_conversion_Int${srcBits}(src) |
| result = (Builtin.${srcExt}_Int${srcBits}_Int${bits}(tmp), signError) |
| % |
| % else: # Smaller size input, unsigned to signed or unsigned to unsigned. |
| result = (Builtin.${srcExt}_Int${srcBits}_Int${bits}(src), false._value) |
| % end |
| % |
| % if not safelyConvertible: |
| ${error_check} |
| % end |
| self._value = result.value |
| """) |
| }% |
| |
| % for src_ty in all_integer_types(word_bits): |
| % srcBits = src_ty.bits |
| % srcSigned = src_ty.is_signed |
| % Src = src_ty.stdlib_name |
| % (srcSign, srcExt) = ('s', 'sext') if srcSigned else ('u', 'zext') |
| % safelyConvertible = (srcBits < bits and (srcSign == sign or signed)) or (srcBits == bits and srcSign == sign) |
| |
| extension ${Self} { |
| |
| @_transparent |
| public init(_ value: ${Src}) { |
| ${gyb.execute_template( |
| fixed_fixed_conversion_function, |
| error_check="Builtin.condfail(result.error)", |
| **locals() |
| ) |
| } |
| } |
| |
| % if safelyConvertible: |
| @available(*, message: "Converting ${Src} to ${Self} will always succeed.") |
| % end |
| @_transparent |
| public init?(exactly value: ${Src}) { |
| ${gyb.execute_template( |
| fixed_fixed_conversion_function, |
| error_check="if Bool(result.error) == true { return nil }", |
| **locals() |
| ) |
| } |
| } |
| |
| % if should_define_truncating_bit_pattern_init(src_ty=src_ty, dst_ty=self_ty): |
| /// Construct a `${Self}` having the same bitwise representation as |
| /// the least significant bits of the provided bit pattern. |
| /// |
| /// No range or overflow checking occurs. |
| @_transparent |
| public init(truncatingBitPattern: ${Src}) { |
| % |
| let src = truncatingBitPattern._value |
| % |
| % if self_ty.bits == src_ty.bits: |
| let dstNotWord = src |
| % else: |
| let dstNotWord = Builtin.trunc_Int${srcBits}_Int${bits}(src) |
| % end |
| % |
| self._value = dstNotWord |
| } |
| |
| % end |
| } |
| % end |
| |
| extension ${Self} { |
| // Construction of integers from floating point numbers. |
| % for src_type in all_floating_point_types(): |
| % Src = src_type.stdlib_name |
| % srcBits = src_type.bits |
| % (lower, upper) = getFtoIBounds(floatBits=srcBits, intBits=int(bits), signed=signed) |
| |
| % if srcBits == 80: |
| #if !os(Windows) && (arch(i386) || arch(x86_64)) |
| % end |
| |
| /// Creates a new instance by rounding the given floating-point value toward |
| /// zero. |
| /// |
| /// - Parameter other: A floating-point value. When `other` is rounded toward |
| /// zero, the result must be within the range `${Self}.min...${Self}.max`. |
| @_transparent |
| public init(_ value: ${Src}) { |
| _precondition(value.isFinite, |
| "${Src} value cannot be converted to ${Self} because it is either infinite or NaN") |
| _precondition(value > ${str(lower)}.0, |
| "${Src} value cannot be converted to ${Self} because the result would be less than ${Self}.min") |
| _precondition(value < ${str(upper)}.0, |
| "${Src} value cannot be converted to ${Self} because the result would be greater than ${Self}.max") |
| self._value = Builtin.fpto${sign}i_FPIEEE${srcBits}_${BuiltinName}(value._value) |
| } |
| |
| /// Creates a ${Self} whose value is `value` |
| /// if no rounding is necessary, nil otherwise. |
| @inline(__always) |
| public init?(exactly value: ${Src}) { |
| self._value = Builtin.fpto${sign}i_FPIEEE${srcBits}_${BuiltinName}(value._value) |
| if ${Src}(self) != value { |
| return nil |
| } |
| } |
| % if srcBits == 80: |
| #endif |
| % end |
| % end |
| |
| /// Construct a `${Self}` having the same memory representation as |
| /// the `${OtherSelf}` `bitPattern`. No range or overflow checking |
| /// occurs, and the resulting `${Self}` may not have the same numeric |
| /// value as `bitPattern`--it is only guaranteed to use the same |
| /// pattern of bits. |
| @_transparent |
| public init(bitPattern: ${OtherSelf}) { |
| self._value = bitPattern._value |
| } |
| } |
| |
| // Operations with potentially-static overflow checking |
| // |
| // FIXME: must use condfail in these operators, rather than |
| // overflowChecked, pending <rdar://problem/16271923> so that we don't |
| // foil static checking for numeric overflows. |
| % for op, method in ('+','add'), ('*','mul'), ('-','sub'): |
| @_transparent |
| public func ${op} (lhs: ${Self}, rhs: ${Self}) -> ${Self} { |
| let (result, error) = Builtin.${sign}${method}_with_overflow_${BuiltinName}( |
| lhs._value, rhs._value, true._value) |
| // return overflowChecked((${Self}(result), Bool(error))) |
| Builtin.condfail(error) |
| return ${Self}(result) |
| } |
| % end |
| |
| % for op, inst in [('/', 'div'), ('%', 'rem')]: |
| @_transparent |
| public func ${op}(lhs: ${Self}, rhs: ${Self}) -> ${Self} { |
| Builtin.condfail((rhs == 0)._value) |
| % if signed: |
| Builtin.condfail(((lhs == ${Self}.min) && (rhs == -1))._value) |
| % end |
| // FIXME: currently doesn't detect overflow -- blocked by: |
| // <rdar://15735295> Need [su]{div,rem}_with_overflow IR |
| let tmp = Builtin.${sign}${inst}_${BuiltinName}(lhs._value, rhs._value) |
| return ${Self}(tmp) |
| } |
| %end |
| |
| // Bitwise negate |
| /// Returns the inverse of the bits set in the argument. |
| /// |
| /// - SeeAlso: `BitwiseOperations` |
| @_transparent |
| public prefix func ~ (rhs: ${Self}) -> ${Self} { |
| let mask = ${Self}.subtractWithOverflow(0, 1).0 |
| return ${Self}(Builtin.xor_${BuiltinName}(rhs._value, mask._value)) |
| } |
| |
| % for op, name, comment in ( |
| % ('==', 'eq', 'the two arguments have equal values'), |
| % ('!=', 'ne', 'the two arguments have unequal values'), |
| % ('<', sign + 'lt', 'the first argument is less than the second argument'), |
| % ('<=', sign + 'le', 'the first argument is less than or equal to the second argument'), |
| % ('>', sign + 'gt', 'the first argument is greater than the second argument'), |
| % ('>=', sign + 'ge', 'the first argument is greater than or equal to the second argument'), |
| % ): |
| /// Returns a Boolean value that indicates whether |
| /// ${comment}. |
| /// |
| /// - SeeAlso: `Equatable`, `Comparable` |
| @_transparent |
| public func ${op} (lhs: ${Self}, rhs: ${Self}) -> Bool { |
| return Bool(Builtin.cmp_${name}_${BuiltinName}(lhs._value, rhs._value)) |
| } |
| % end |
| |
| % for op, name in (('<<','shl'), ('>>','ashr' if signed else 'lshr')): |
| @_transparent |
| public func ${op} (lhs: ${Self}, rhs: ${Self}) -> ${Self} { |
| % if signed: |
| _precondition(U${Self}(rhs) < U${Self}._sizeInBits, |
| "shift amount is larger than type size in bits") |
| % else: |
| _precondition(rhs < ${Self}._sizeInBits, |
| "shift amount is larger than type size in bits") |
| % end |
| return ${Self}(Builtin.${name}_${BuiltinName}(lhs._value, rhs._value)) |
| } |
| % end |
| |
| % for op, name, comment in ( |
| % ('&', 'and', 'intersection of bits set in'), |
| % ('^', 'xor', 'bits that are set in exactly one of'), |
| % ('|', 'or', 'union of bits set in'), |
| % ): |
| /// Returns the ${comment} the two arguments. |
| /// |
| /// - SeeAlso: `BitwiseOperations` |
| @_transparent |
| public func ${op} (lhs: ${Self}, rhs: ${Self}) -> ${Self} { |
| return ${Self}(Builtin.${name}_${BuiltinName}(lhs._value, rhs._value)) |
| } |
| |
| /// Calculates the ${comment} the two arguments |
| /// and stores the result in the first argument. |
| /// |
| /// - SeeAlso: `BitwiseOperations` |
| @_transparent |
| public func ${op}=(lhs: inout ${Self}, rhs: ${Self}) { |
| lhs = lhs ${op} rhs |
| } |
| % end |
| |
| // Bitwise operations |
| extension ${Self} : BitwiseOperations { |
| /// The empty bitset of type `${Self}`. |
| @_transparent |
| public static var allZeros: ${Self} { return 0 } |
| } |
| |
| // Compound assignments |
| % for op in '+', '-', '*', '<<', '>>': |
| @_transparent |
| public func ${op}=(lhs: inout ${Self}, rhs: ${Self}) { |
| lhs = lhs ${op} rhs |
| } |
| % end |
| |
| // Create an ambiguity when indexing or slicing |
| // Range[OfStrideable]<${Self}> outside a generic context. See |
| // Range.swift for details. |
| extension ${Self} { |
| public typealias _DisabledRangeIndex = ${Self} |
| } |
| |
| // Prefix and postfix increment and decrement. |
| |
| @_transparent |
| @available(*, unavailable, message: "it has been removed in Swift 3") |
| @discardableResult |
| public prefix func ++ (x: inout ${Self}) -> ${Self} { |
| x = x + 1 |
| return x |
| } |
| |
| @_transparent |
| @available(*, unavailable, message: "it has been removed in Swift 3") |
| @discardableResult |
| public postfix func ++ (x: inout ${Self}) -> ${Self} { |
| let ret = x |
| x = x + 1 |
| return ret |
| } |
| |
| @_transparent |
| @available(*, unavailable, message: "it has been removed in Swift 3") |
| @discardableResult |
| public prefix func -- (x: inout ${Self}) -> ${Self} { |
| x = x - 1 |
| return x |
| } |
| |
| @_transparent |
| @available(*, unavailable, message: "it has been removed in Swift 3") |
| @discardableResult |
| public postfix func -- (x: inout ${Self}) -> ${Self} { |
| let ret = x |
| x = x - 1 |
| return ret |
| } |
| |
| % if signed: |
| // TODO: Consider removing the underscore. |
| /// Returns the argument and specifies that the value is not negative. |
| /// It has only an effect if the argument is a load or call. |
| @_transparent |
| public func _assumeNonNegative(_ x: ${Self}) -> ${Self} { |
| _sanityCheck(x >= 0) |
| return ${Self}(Builtin.assumeNonNegative_${BuiltinName}(x._value)) |
| } |
| % end |
| |
| % end |
| |
| % fixedBitWidths = [2**x for x in range(3, 8) if 2**x <= 2 * word_bits] |
| % for bits in fixedBitWidths: |
| @_transparent |
| public func _leadingZeros(_ x: Builtin.Int${bits}) -> Builtin.Int${bits} { |
| return Builtin.int_ctlz_Int${bits}(x, true._value) |
| } |
| % end |
| |
| //===--- End loop over all integer types ----------------------------------===// |
| |
| internal func _unsafePlus(_ lhs: Int, _ rhs: Int) -> Int { |
| #if INTERNAL_CHECKS_ENABLED |
| return lhs + rhs |
| #else |
| return lhs &+ rhs |
| #endif |
| } |
| |
| internal func _unsafeMinus(_ lhs: Int, _ rhs: Int) -> Int { |
| #if INTERNAL_CHECKS_ENABLED |
| return lhs - rhs |
| #else |
| return lhs &- rhs |
| #endif |
| } |
| |
| internal func _unsafeMultiply(_ lhs: Int, _ rhs: Int) -> Int { |
| #if INTERNAL_CHECKS_ENABLED |
| return lhs * rhs |
| #else |
| return lhs &* rhs |
| #endif |
| } |
| |
| @available(*, unavailable, renamed: "Integer") |
| public typealias IntegerType = Integer |
| |
| @available(*, unavailable, renamed: "SignedInteger") |
| public typealias SignedIntegerType = SignedInteger |
| |
| @available(*, unavailable, renamed: "UnsignedInteger") |
| public typealias UnsignedIntegerType = UnsignedInteger |
| |
| // ${'Local Variables'}: |
| // eval: (read-only-mode 1) |
| // End: |