young
(rtSwift)
1
I'm passing around a Binding<T>, where T is numeric value types that NSNumber can handle/support. I need to know if its wrappedValue is signed numeric.
This doesn't work:
extension Binding {
var isSignedNumeric: Bool {
wrappedValue is SignedNumeric. // error: SignedNumeric has `Self` or PAT
}
}
I'm dong this now:
extension Binding {
var isSignedNumeric: Bool {
wrappedValue is Double
|| wrappedValue is Float
|| wrappedValue is Int32
|| wrappedValue is Int
|| wrappedValue is Int64
|| wrappedValue is Int16
}
}
Is there better way?
1 Like
Nevin
2
What exactly do you plan on doing with the value, once you know whether or not it is signed?
This comment explains how you can test for conformance to a PAT, and has links for how to actually do things with that conformance.
But if you are working with a fixed set of known types, you might want to just make your own protocol and conform them to it.
young
(rtSwift)
3
For conditionally showing the right UI. I'm working with this kind of SwiftUI.TextField:
TextField.init<S, T>(_ title: S, value: Binding, formatter: Formatter)
with .keyboardType(.numberPad) attached to the TextField for entering numbers only. The .numberPad keyboard only has numbers 0-9 and delete and nothing else. I'm adding a keyboard toolbar to allow entering negative value only when the type is signed.
I have access to the binding of the TextField.
T can only be the types NSNumber can handle excluding Bool and Char, these:
Double
Float
Int32
Int
Int64
Int16
UInt8
UInt32
UInt
UInt64
UInt16
I don't know how to constrain T to only these, so I do this T: Numeric but Numeric is not exactly the type above. Or T totally unconstrained, like the TextField.init above.
Nevin
4
You make a new protocol with the semantics you want (eg. NSNumberConvertible) and conform the types you want to it.
1 Like
young
(rtSwift)
5
Thank you! This solve my problem:
protocol NSNumberConvertible { }
protocol SignedNSNumberConvertible: NSNumberConvertible { }
protocol UnsignedNSNumberConvertible: NSNumberConvertible { }
// can do this now
... wrappedValue is SignedNSNumberConvertible ...
this also solve my other problem 
For learning, I took your code and changed a little to make it work for test if is SignNumeric:
protocol SignedNumericConformanceMarker {}
enum SignedNumericMarker<T> {}
extension SignedNumericMarker: SignedNumericConformanceMarker where T: SignedNumeric {}
func isSignedNumericType<T>(_ t: T.Type) -> Bool {
return SignedNumericMarker<T>.self is SignedNumericConformanceMarker.Type
}
func isSignedNumeric<T>(_ t: T) -> Bool {
return isSignedNumericType(T.self)
}
let u: UInt = 0
let i = 0
print("isSignedNumeric(u)", isSignedNumeric(u)) // print: isSignedNumeric(u) false
print("isSignedNumeric(i)", isSignedNumeric(i)) // print: isSignedNumeric(i) true
// make it a little fluent
extension Numeric {
var isSigned: Bool {
isSignedNumeric(self)
}
}
print("u.isSigned", u.isSigned)
print("i.isSigned", i.isSigned)
very interesting how you build thing up and then go from T to T.Type. I can never be able to come up with code like this.

