mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
[stdlib] Remoiving old integers
This commit is contained in:
@@ -53,7 +53,6 @@ set(SWIFTLIB_ESSENTIAL
|
||||
ErrorType.swift
|
||||
Existential.swift
|
||||
Filter.swift.gyb
|
||||
#FixedPoint.swift.gyb
|
||||
FlatMap.swift
|
||||
Flatten.swift.gyb
|
||||
FloatingPoint.swift.gyb
|
||||
@@ -72,7 +71,6 @@ set(SWIFTLIB_ESSENTIAL
|
||||
Index.swift
|
||||
Indices.swift.gyb
|
||||
InputStream.swift
|
||||
#IntegerArithmetic.swift.gyb
|
||||
IntegerParsing.swift.gyb
|
||||
Integers.swift.gyb
|
||||
Join.swift
|
||||
|
||||
@@ -1,792 +0,0 @@
|
||||
//===--- 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)) }
|
||||
@_inlineable
|
||||
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)) }
|
||||
@_inlineable
|
||||
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)) }
|
||||
@_inlineable
|
||||
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)) }
|
||||
@_inlineable
|
||||
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: `FixedWidthInteger`
|
||||
@_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: `FixedWidthInteger`
|
||||
@_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: `FixedWidthInteger`
|
||||
@_transparent
|
||||
public func ${op}=(lhs: inout ${Self}, rhs: ${Self}) {
|
||||
lhs = lhs ${op} rhs
|
||||
}
|
||||
% end
|
||||
|
||||
// Bitwise operations
|
||||
extension ${Self} : FixedWidthInteger {
|
||||
/// 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:
|
||||
@@ -122,8 +122,6 @@
|
||||
{
|
||||
"Integers": [
|
||||
"Integers.swift",
|
||||
"IntegerArithmetic.swift",
|
||||
"FixedPoint.swift",
|
||||
"IntegerParsing.swift"],
|
||||
"Floating": [
|
||||
"FloatingPoint.swift",
|
||||
|
||||
@@ -1,163 +0,0 @@
|
||||
//===--- IntegerArithmetic.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
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
%# Ignore the following admonition; it applies to the resulting .swift file only
|
||||
|
||||
// Automatically Generated From IntegerArithmetic.swift.gyb. Do Not Edit
|
||||
// Directly!
|
||||
|
||||
%{
|
||||
integerBinaryOps = [
|
||||
('add', '+', 'Adds', 'the result'),
|
||||
('subtract', '-', 'Subtracts', 'the result'),
|
||||
('multiply', '*', 'Multiplies', 'the result'),
|
||||
('divide', '/', 'Divides', 'the result'),
|
||||
('remainder', '%', 'Divides', 'the remainder')
|
||||
]
|
||||
}%
|
||||
|
||||
/// This protocol is an implementation detail of `IntegerArithmetic`; do
|
||||
/// not use it directly.
|
||||
///
|
||||
/// Its requirements are inherited by `IntegerArithmetic` and thus must
|
||||
/// be satisfied by types conforming to that protocol.
|
||||
@_show_in_interface
|
||||
public protocol _IntegerArithmetic {
|
||||
% for name, _, Action, result in integerBinaryOps:
|
||||
/// ${Action} `lhs` and `rhs`, returning ${result} and a `Bool` that is
|
||||
/// `true` iff the operation caused an arithmetic overflow.
|
||||
static func ${name}WithOverflow(_ lhs: Self, _ rhs: Self) -> (Self, overflow: Bool)
|
||||
% end
|
||||
}
|
||||
|
||||
/// The common requirements for types that support integer arithmetic.
|
||||
public protocol IntegerArithmetic : _IntegerArithmetic, Comparable {
|
||||
// Checked arithmetic functions. Specific implementations in
|
||||
// FixedPoint.swift.gyb support static checking for integer types.
|
||||
% for name, op, Action, result in integerBinaryOps:
|
||||
/// ${Action} `lhs` and `rhs`, returning ${result} and trapping in case of
|
||||
/// arithmetic overflow (except in -Ounchecked builds).
|
||||
static func ${op} (lhs: Self, rhs: Self) -> Self
|
||||
% end
|
||||
|
||||
/// Explicitly convert to `IntMax`, trapping on overflow (except in
|
||||
/// -Ounchecked builds).
|
||||
func toIntMax() -> IntMax
|
||||
}
|
||||
|
||||
% for name, op, Action, result in integerBinaryOps:
|
||||
/// ${Action} `lhs` and `rhs`, returning ${result} and trapping in case of
|
||||
/// arithmetic overflow (except in -Ounchecked builds).
|
||||
@_transparent
|
||||
public func ${op} <T : _IntegerArithmetic>(lhs: T, rhs: T) -> T {
|
||||
return _overflowChecked(T.${name}WithOverflow(lhs, rhs))
|
||||
}
|
||||
|
||||
% if (op != '/') and (op != '%'):
|
||||
/// ${Action} `lhs` and `rhs`, silently discarding any overflow.
|
||||
@_transparent
|
||||
public func &${op} <T : _IntegerArithmetic>(lhs: T, rhs: T) -> T {
|
||||
return T.${name}WithOverflow(lhs, rhs).0
|
||||
}
|
||||
% end
|
||||
|
||||
/// ${Action} `lhs` and `rhs` and stores ${result} in `lhs`, trapping in
|
||||
/// case of arithmetic overflow (except in -Ounchecked builds).
|
||||
@_transparent
|
||||
public func ${op}= <T : _IntegerArithmetic>(lhs: inout T, rhs: T) {
|
||||
lhs = lhs ${op} rhs
|
||||
}
|
||||
% end
|
||||
|
||||
//===--- SignedNumber -----------------------------------------------------===//
|
||||
// A numeric type that supports abs(x), +x and -x
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// SignedNumber itself contains only operator requirements having
|
||||
// default implementations on the base protocol.
|
||||
/// Instances of conforming types can be subtracted, arithmetically
|
||||
/// negated, and initialized from `0`.
|
||||
///
|
||||
/// Axioms:
|
||||
///
|
||||
/// - `x - 0 == x`
|
||||
/// - `-x == 0 - x`
|
||||
/// - `-(-x) == x`
|
||||
public protocol SignedNumber : Comparable, ExpressibleByIntegerLiteral {
|
||||
/// Returns the result of negating `x`.
|
||||
static prefix func - (x: Self) -> Self
|
||||
|
||||
/// Returns the difference between `lhs` and `rhs`.
|
||||
static func - (lhs: Self, rhs: Self) -> Self
|
||||
|
||||
// Do not use this operator directly; call abs(x) instead
|
||||
static func ~> (_:Self,_:(_Abs, ())) -> Self
|
||||
}
|
||||
|
||||
// Unary negation in terms of subtraction. This is a default
|
||||
// implementation; models of SignedNumber can provide their own
|
||||
// implementations.
|
||||
@_transparent
|
||||
public prefix func - <T : SignedNumber>(x: T) -> T {
|
||||
return 0 - x
|
||||
}
|
||||
|
||||
// Unary +
|
||||
@_transparent
|
||||
public prefix func + <T : SignedNumber>(x: T) -> T {
|
||||
return x
|
||||
}
|
||||
|
||||
//===--- abs(x) -----------------------------------------------------------===//
|
||||
public struct _Abs {}
|
||||
|
||||
@_versioned
|
||||
internal func _abs<Args>(_ args: Args) -> (_Abs, Args) {
|
||||
return (_Abs(), args)
|
||||
}
|
||||
|
||||
// Do not use this operator directly; call abs(x) instead
|
||||
@_transparent
|
||||
public func ~> <T : SignedNumber>(x:T,_:(_Abs, ())) -> T {
|
||||
return x < 0 ? -x : x
|
||||
}
|
||||
|
||||
// FIXME: should this be folded into SignedNumber?
|
||||
/// A type that supports an "absolute value" function.
|
||||
public protocol AbsoluteValuable : SignedNumber {
|
||||
/// Returns the absolute value of `x`.
|
||||
static func abs(_ x: Self) -> Self
|
||||
}
|
||||
|
||||
// Do not use this operator directly; call abs(x) instead
|
||||
@_transparent
|
||||
public func ~> <T : AbsoluteValuable>(x:T,_:(_Abs, ())) -> T {
|
||||
return T.abs(x)
|
||||
}
|
||||
|
||||
/// Returns the absolute value of `x`.
|
||||
///
|
||||
/// Concrete instances of `SignedNumber` can specialize this
|
||||
/// function by conforming to `AbsoluteValuable`.
|
||||
@_transparent
|
||||
public func abs<T : SignedNumber>(_ x: T) -> T {
|
||||
return x~>_abs()
|
||||
}
|
||||
|
||||
@available(*, unavailable, renamed: "IntegerArithmetic")
|
||||
public typealias IntegerArithmeticType = IntegerArithmetic
|
||||
|
||||
@available(*, unavailable, renamed: "SignedNumber")
|
||||
public typealias SignedNumberType = SignedNumber
|
||||
|
||||
// ${'Local Variables'}:
|
||||
// eval: (read-only-mode 1)
|
||||
// End:
|
||||
Reference in New Issue
Block a user