Is skipping the multiplicative identity OK? A UInt0
type would have to skip it.
I looked through the Swift source and the Apple docs to start with FixedWidthInteger
and see what should be automatically provided. Right now, I got:
// An unsigned integer of zero bits.
struct UInt0: FixedWidthInteger, UnsignedInteger {
static func -=(lhs: inout UInt0, rhs: UInt0) {
let result = lhs.subtractingReportingOverflow(rhs)
assert(!result.overflow)
lhs = result.partialValue
}
static func -(lhs: UInt0, rhs: UInt0) -> UInt0 {
var copy = lhs
copy -= rhs
return copy
}
init<T>(_ source: T) where T : BinaryFloatingPoint { self.init(Int(source)) }
static func +=(lhs: inout UInt0, rhs: UInt0) {
let result = lhs.addingReportingOverflow(rhs)
assert(!result.overflow)
lhs = result.partialValue
}
static func /(lhs: UInt0, rhs: UInt0) -> UInt0 {
var copy = lhs
copy /= rhs
return copy
}
static func /=(lhs: inout UInt0, rhs: UInt0) {
let result = lhs.dividedReportingOverflow(by: rhs)
assert(!result.overflow)
lhs = result.partialValue
}
static func %(lhs: UInt0, rhs: UInt0) -> UInt0 {
var copy = lhs
copy %= rhs
return copy
}
static func %=(lhs: inout UInt0, rhs: UInt0) {
let result = lhs.remainderReportingOverflow(dividingBy: rhs)
assert(!result.overflow)
lhs = result.partialValue
}
static func *(lhs: UInt0, rhs: UInt0) -> UInt0 {
var copy = lhs
copy *= rhs
return copy
}
static func *=(lhs: inout UInt0, rhs: UInt0) {
let result = lhs.multipliedReportingOverflow(by: rhs)
assert(!result.overflow)
lhs = result.partialValue
}
static func +(lhs: UInt0, rhs: UInt0) -> UInt0 {
var copy = lhs
copy += rhs
return copy
}
static var bitWidth: Int { return 0 }
init(_truncatingBits bits: UInt) {}
init(integerLiteral value: UInt) { self.init(_truncatingBits: value) }
var byteSwapped: UInt0 { return self }
var leadingZeroBitCount: Int { return 0 }
var nonzeroBitCount: Int { return 0 }
var trailingZeroBitCount: Int { return 0 }
var words: EmptyCollection<UInt> { return EmptyCollection() }
func addingReportingOverflow(_ rhs: UInt0) -> (partialValue: UInt0, overflow: Bool) {
return (self, false)
}
func dividedReportingOverflow(by rhs: UInt0) -> (partialValue: UInt0, overflow: Bool) {
return (self, true)
}
func multipliedReportingOverflow(by rhs: UInt0) -> (partialValue: UInt0, overflow: Bool) {
return (self, false)
}
func remainderReportingOverflow(dividingBy rhs: UInt0) -> (partialValue: UInt0, overflow: Bool) {
return (self, true)
}
func subtractingReportingOverflow(_ rhs: UInt0) -> (partialValue: UInt0, overflow: Bool) {
return (self, false)
}
func dividingFullWidth(_ dividend: (high: UInt0, low: Magnitude)) -> (quotient: UInt0, remainder: UInt0) {
preconditionFailure("Always have division-by-zero")
}
func multipliedFullWidth(by other: UInt0) -> (high: UInt0, low: Magnitude) {
return (self, magnitude)
}
static func ==(lhs: UInt0, rhs: UInt0) -> Bool { return true }
var hashValue: Int { return 0.hashValue }
static func <(lhs: UInt0, rhs: UInt0) -> Bool { return false }
}
I had to add the init(_truncatingBits:)
initializer you mentioned. Technically, all the stuff before bitWidth
that the compiler insisted I add shouldn't be necessary; automatic implementations should take of those? I guess this is the compiler-forgets-defaults problem you mentioned.
I'll probably just use words.last!
, but I did this quick(?) knock-out out of anger.
Oh, my tests need to go the other way too (Well, just the other way.), beyond UInt64
. I guess I could try that DoubleWidth
you mentioned.