Reputation: 6504
I'm trying to write an extension for a genericized class. I want to be able to determine whether a variable of type T
's value is above a certain percentage of its maximum value.
I'm having trouble a) figuring out how to get the max value for the type, and b) getting the types converted right for the comparison.
public class CustomClass<T:BinaryInteger> {
public var someValue:T
...
}
extension CustomClass {
func isOver(threshold:Float) {
// defined for threshold between -1 and +1
let convertedThreshold:Float = threshold * Float(T.MAX_VALUE)
return self.someValue > T(clamping: convertedThreshold)
}
}
Right now I'm stuck on getting the max value of a variable of type T
. The BinaryInteger
docs mention T.min
and T.max
but those seem to not actually be defined.
For clarity:
If threshold is 0.5
and T
is of type UInt8
I want to return true
if the variable is over 127. But if T
is of type UInt16
I want to return true
if the variable is over 32,767.
Upvotes: 1
Views: 250
Reputation: 539965
As JeremyP said, you'll need to restrict T
to the FixedWidthInteger
protocol, which has a required max
property.
For unsigned integer types, the conversation to Float
(or Double
) can be done via the largest unsigned integer type, UInt64
:
extension CustomClass where T: UnsignedInteger {
func isOver(threshold: Float) -> Bool {
return Float(UInt64(self.someValue)) > threshold * Float(UInt64(T.max))
}
}
(and via Int64
for signed integer types).
Full self-contained example:
public class CustomClass<T:FixedWidthInteger> {
public var someValue: T = 0
}
extension CustomClass where T: UnsignedInteger {
func isOver(threshold: Float) -> Bool {
return Float(UInt64(self.someValue)) > threshold * Float(UInt64(T.max))
}
}
let x = CustomClass<UInt16>()
x.someValue = 50_000
print(x.isOver(threshold: 0.5)) // true
Upvotes: 3
Reputation: 86661
BinaryInteger
does not have min
and max
but FixedWidthInteger
does. All the built in integer types have this protocol.
There is a further problem that I haven't figured out yet. It's not easy to convert an arbitrary type that conforms to FixedWidthInteger
to a Float
or Double
.
Upvotes: 3