Files
swift-mirror/stdlib/core/FixedPoint.swift.gyb
Dave Abrahams c33a59c6a7 [build] Complete gyb support
Remove all gyb-generated files and generate them automatically from .gyb
files.  Rename the proof-of-concept UnsafeArray.swift.gyb back to
UnsafeArray.swift.  Never forget to update the .gyb file or regenerate
again!

Swift SVN r14445
2014-02-27 03:01:16 +00:00

375 lines
10 KiB
Swift

@# -*- mode: swift -*-
@# Ignore the following admonition; it applies to the resulting .swift file only
//// Automatically Generated From FixedPoint.gyb. Do Not Edit Directly!
//===----------------------------------------------------------------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See http://swift.org/LICENSE.txt for license information
// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//
@{
#
# 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)
# Bit counts for all int types
allNames = [8, 16, 32, 64, 'Int']
# Number of bits in the biggest int type
maxBits = 64
# Number of bits in the Builtin.Word type
wordBits = int(CMAKE_SIZEOF_VOID_P) * 8
# Number of bits in integer literals.
builtinIntLiteralBits = 2048
# FIXME: checked and unchecked conversions of Word types
CastFromWord = 'zextOrBitCast_Word_Int64' if wordBits==64 else 'truncOrBitCast_Word_Int32'
CastToWord = 'truncOrBitCast_Int64_Word' if wordBits==64 else 'zextOrBitCast_Int32_Word'
def maskBits(n):
"""Return an n-bit mask in hex"""
return hexify((1 << n) - 1)
def allInts():
for name in allNames:
for signed in False, True:
yield str(name), int(wordBits if name=='Int' else name), signed
def baseIntName(name):
return 'Int' if name == 'Int' else 'Int' + str(name)
def builtinIntName(name):
return 'Word' if name == 'Int' else 'Int' + str(name)
def intName(name, signed):
return ('' if signed else 'U') + baseIntName(name)
def otherIntName(name, signed):
return ('U' if signed else '') + baseIntName(name)
}@
typealias IntMax = Int${maxBits}
typealias UIntMax = UInt${maxBits}
@ for (name, bits, signed) in allInts():
@ (sign, ext) = ('s', 'sext') if signed else ('u', 'zext')
@ BuiltinName = builtinIntName(name)
@ Self = intName(name, signed)
@ OtherSelf = otherIntName(name, signed)
@ ConstructIntType = 'Int' if Self != 'Int' else ''
@ ArrayBound = 'ArrayBound, ' if bits <= 64 else ''
struct ${Self} : BuiltinIntegerLiteralConvertible, IntegerLiteralConvertible,
${ArrayBound}ReplPrintable {
var value: Builtin.${BuiltinName}
@@transparent
init() {
var maxWidthZero: IntMax = 0
value = Builtin.truncOrBitCast_Int${maxBits}_${BuiltinName}(maxWidthZero.value)
}
@@transparent
init(v: Builtin.${BuiltinName}) {
value = v
}
@@transparent
static func _convertFromBuiltinIntegerLiteral(value: Builtin.Int${builtinIntLiteralBits}) -> ${Self} {
return ${Self}(Builtin.s_to_${sign}_checked_trunc_Int${builtinIntLiteralBits}_${BuiltinName}(value).0)
}
@@transparent
static func convertFromIntegerLiteral(value: ${Self}) -> ${Self} {
return value
}
@ if ArrayBound:
@@transparent
func _getBuiltinArrayBoundValue() -> Builtin.Word {
@ if bits < wordBits:
return Builtin.${ext}OrBitCast_${BuiltinName}_Word(self.value)
@ elif bits > wordBits:
return Builtin.truncOrBitCast_${BuiltinName}_Word(self.value)
@ elif BuiltinName == 'Word':
return self.value
@ else:
return Builtin.${CastToWord}(self.value)
@ end
}
typealias ArrayBoundType = ${Self}
func getArrayBoundValue() -> ${Self} {
return self
}
@ end
func replPrint() {
print(${
'self' if BuiltinName == 'Int64'
else (('String' if bits > 64 else 'Int64' if signed else 'UInt64') + '(self)')})
}
@ max = maskBits((bits - 1) if signed else bits)
@@transparent
static var max: ${Self} { return ${max} }
@@transparent
static var min: ${Self} { return ${'-%s-1' % max if signed else '0'} }
}
extension ${Self} : Hashable {
func hashValue() -> Int {
@ if bits < wordBits:
return Int(Builtin.sextOrBitCast_${BuiltinName}_Word(self.value))
@ elif bits > wordBits:
var result: Int = 0
for var i = 0; i < (sizeof(self) * 8); i += sizeof(Int.self) * 8 {
result ^= Int(self >> ${Self}(i)) & ~0
}
return result
@ elif BuiltinName == 'Word':
return Int(self.value)
@ else:
return Int(Builtin.${CastToWord}(self.value))
@ end
}
}
@@transparent
extension ${Self} : RandomAccessIndex {
@@transparent
func succ() -> ${Self} {
return self + 1
}
@@transparent
func pred() -> ${Self} {
return self - 1
}
@@transparent
func distanceTo(other: ${Self}) -> Int {
return ${ConstructIntType}(other - self)
}
typealias DistanceType = ${Self}
@@transparent
static func sub(lhs: ${Self}, rhs: ${Self}, reportOverflow: Bool) -> (DistanceType, Bool) {
var tmp = Builtin.${sign}sub_with_overflow_${BuiltinName}(lhs.value, rhs.value, reportOverflow.value)
return (${Self}(tmp.0), Bool(tmp.1))
}
@@transparent
static func add(lhs: ${Self}, rhs: DistanceType, reportOverflow: Bool) -> (${Self}, Bool) {
var tmp = Builtin.${sign}add_with_overflow_${BuiltinName}(lhs.value, rhs.value, reportOverflow.value)
return (${Self}(tmp.0), Bool(tmp.1))
}
@@transparent
static func mul(lhs: ${Self}, rhs: ${Self}, reportOverflow: Bool) -> (${Self}, Bool) {
var tmp = Builtin.${sign}mul_with_overflow_${BuiltinName}(lhs.value, rhs.value, reportOverflow.value)
return (${Self}(tmp.0), Bool(tmp.1))
}
@@transparent
static func div(lhs: ${Self}, rhs: ${Self}, reportOverflow: Bool) -> (${Self}, Bool) {
if rhs == 0 {
return (0, true)
}
@ if signed:
if lhs == ${Self}.min && rhs == -1 {
return (lhs, true)
}
@ end
var tmp = Builtin.${sign}div_${BuiltinName}(lhs.value, rhs.value)
return (${Self}(tmp), false)
}
@@transparent
static func rem(lhs: ${Self}, rhs: ${Self}, reportOverflow: Bool) -> (${Self}, Bool) {
if rhs == 0 {
return (0, true)
}
@ if signed:
if lhs == ${Self}.min && rhs == -1 {
return (0, true)
}
@ end
var tmp = Builtin.${sign}rem_${BuiltinName}(lhs.value, rhs.value)
return (${Self}(tmp), false)
}
@@transparent
static func sub(lhs: ${Self}, rhs: ${Self}) -> (DistanceType, Bool) {
return sub(lhs, rhs, true)
}
@@transparent
static func add(lhs: ${Self}, rhs: DistanceType) -> (${Self}, Bool) {
return add(lhs, rhs, true)
}
@@transparent
static func mul(lhs: ${Self}, rhs: ${Self}) -> (${Self}, Bool) {
return mul(lhs, rhs, true)
}
@@transparent
static func div(lhs: ${Self}, rhs: ${Self}) -> (${Self}, Bool) {
return div(lhs, rhs, true)
}
@@transparent
static func rem(lhs: ${Self}, rhs: ${Self}) -> (${Self}, Bool) {
return rem(lhs, rhs, true)
}
@@transparent
func toIntMax() -> IntMax {
return ${'self' if Self == 'Int%s' % maxBits else 'IntMax(self)'}
}
}
@ if signed:
@@transparent
extension ${Self} : SignedNumber {
@@transparent
static func negate(rhs: ${Self}) -> (${Self}, Bool) {
return ${Self}.sub(0, rhs)
}
@@transparent
static func abs(rhs: ${Self}) -> (${Self}, Bool) {
return rhs.isNegative() ? ${Self}.negate(rhs) : (rhs, false)
}
@@transparent
func isNegative() -> Bool { return self < 0 }
}
@ end
@# FIXME: checked conversions of Word types
// construction from other integer types
@@transparent
extension ${Self} {
@ for (srcName, srcBits, srcSigned) in allInts():
@ Src = intName(srcName, srcSigned)
@ srcBuiltinName = builtinIntName(srcName)
@ (srcSign, srcExt) = ('s', 'sext') if srcSigned else ('u', 'zext')
@ if Self != Src:
init(v: ${Src}) {
@
@ if srcBuiltinName == 'Word':
var srcNotWord = Builtin.${CastFromWord}(v.value)
@ else:
var srcNotWord = v.value
@ end
@
@ if srcBits == bits and srcSign == sign:
var dstNotWord = srcNotWord
@
@ elif srcBits == bits:
var tmp = Builtin.${srcSign}_to_${sign}_checked_conversion_Int${srcBits}(srcNotWord)
Builtin.condfail(tmp.1)
var dstNotWord = tmp.0
@
@ elif srcBits > bits:
var tmp = Builtin.${srcSign}_to_${sign}_checked_trunc_Int${srcBits}_Int${bits}(srcNotWord)
Builtin.condfail(tmp.1)
var dstNotWord = tmp.0
@
@ elif srcSigned and not signed:
var tmp = Builtin.s_to_u_checked_conversion_Int${srcBits}(srcNotWord)
Builtin.condfail(tmp.1)
var dstNotWord = Builtin.${srcExt}_Int${srcBits}_Int${bits}(tmp.0)
@
@ else:
var dstNotWord = Builtin.${srcExt}_Int${srcBits}_Int${bits}(srcNotWord)
@ end
@
@ if BuiltinName == 'Word':
value = Builtin.${CastToWord}(dstNotWord)
@ else:
value = dstNotWord
@ end
}
@ end
@ end
func as${'Unsigned' if signed else 'Signed'}() -> ${OtherSelf} {
return ${OtherSelf}(value)
}
}
// Operations with masking and non-masking versions
@ for op,method in ('+','add'), ('*','mul'), ('-','sub'):
@@transparent
func &${op} (lhs: ${Self}, rhs: ${Self}) -> ${Self} {
return ${Self}.${method}(lhs, rhs, false).0
}
@@transparent
func ${op} (lhs: ${Self}, rhs: ${Self}) -> ${Self} {
var tmp = ${Self}.${method}(lhs, rhs)
Builtin.condfail(tmp.1.value)
return tmp.0
}
@ end
// Bitwise negate
@@transparent @@prefix
func ~(rhs: ${Self}) -> ${Self} {
let mask = ${Self}.sub(0, 1).0
return ${Self}(Builtin.xor_${BuiltinName}(rhs.value, mask.value))
}
@ for op, name in (
@ ('==','eq'), ('!=','ne'),
@ ('<',sign+'lt'), ('<=',sign+'le'),
@ ('>',sign+'gt'), ('>=',sign+'ge')):
@@transparent
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
func ${op} (lhs: ${Self}, rhs: ${Self}) -> ${Self} {
@ if signed:
assert(U${Self}(rhs) < U${Self}(sizeof(rhs) * 8))
@ else:
assert(rhs < ${Self}(sizeof(rhs) * 8))
@ end
return ${Self}(Builtin.${name}_${BuiltinName}(lhs.value, rhs.value))
}
@ end
@ for op, name in (('&','and'), ('^','xor'), ('|','or')):
@@transparent
func ${op} (lhs: ${Self}, rhs: ${Self}) -> ${Self} {
return ${Self}(Builtin.${name}_${BuiltinName}(lhs.value, rhs.value))
}
@ end
// bitwise operations
@@transparent
extension ${Self} : BitwiseOperations {
static func allZeros() -> ${Self} { return 0 }
}
// Compound assignments
@ for op in '+', '-', '*', '<<', '>>', '&', '|', '^':
@@transparent @@assignment
func ${op}=(inout lhs: ${Self}, rhs: ${Self}) {
lhs = lhs ${op} rhs
}
@ end
@ end # for bits in allInts
typealias Word = Int
typealias UWord = UInt