I just want call C function
static inline uint64_t wyhash(const void* key, uint64_t len, uint64_t seed)
from Swift like that
func hash<T: Any>(key: T, seed: UInt64) -> UInt64 { wyhash(...) }
Is it possible?
I just want call C function
static inline uint64_t wyhash(const void* key, uint64_t len, uint64_t seed)
from Swift like that
func hash<T: Any>(key: T, seed: UInt64) -> UInt64 { wyhash(...) }
Is it possible?
Not directly. If you can make your types conform to a protocol, though, then you can use a protocol extension method, because the Self
type inside the extension will be the concrete conforming type:
protocol WyHashable { }
extension WyHashable {
func hash(seed: UInt64) -> UInt64 {
withUnsafeBytes(of: self) {
return wyhash($0.startAddress!, UInt64($0.count), seed)
}
}
}
Is the size calculated correctly in this case?
protocol WyHashable { }
extension WyHashable {
func hash(seed: UInt64) -> UInt64 {
withUnsafeBytes(of: self) {
print($0.count) // 8
return wyhash($0.startAddress!, UInt64($0.count), seed)
}
}
}
extension Array: WyHashable where Element == Int { }
var arr = [21, 21, 21]
arr.hash(seed: ...)
Why the size in this case equals 8? Shouldn't it be 3 *8 ?
The problem with Array
is that withUnsafeBytes
is going to give you only the value representation, which is a pointer to the actual buffer. You might need to make the protocol have different behavior for different types if you want to be able to automatically handle arrays:
protocol WyHashable {
func wyHash(seed: UInt64) -> UInt64 {
}
extension WyHashable {
// Default implementation for trivial types, just hash the
// value representation
func wyHash(seed: UInt64) -> UInt64 {
withUnsafeBytes(of: self) {
return wyhash($0.startAddress!, UInt64($0.count), seed)
}
}
}
// Hash an array by its buffer contents
extension Array: WyHashable {
func wyHash(seed: UInt64) -> UInt64 {
self.withUnsafeBytes {
return wyhash($0.startAddress!, UInt64($0.count), seed)
}
}
}
It's all clear to me now. Thanks!