1
1
mirror of https://github.com/github/semantic.git synced 2024-12-01 17:59:10 +03:00
semantic/prototype/Doubt/Hash.swift

83 lines
1.5 KiB
Swift
Raw Normal View History

2015-09-30 00:00:26 +03:00
public enum Hash: Hashable {
case Sequence([Hash])
2015-09-30 17:42:43 +03:00
case Label(String)
2015-09-30 17:40:45 +03:00
case Raw(Int)
2015-09-30 00:00:26 +03:00
2015-09-30 17:44:48 +03:00
public init(_ label: String, _ hashes: Hash...) {
self = .Sequence([ Hash(label) ] + hashes)
}
2015-09-30 17:42:27 +03:00
public init(_ string: String) {
self = .Label(string)
}
2015-09-30 17:43:18 +03:00
public init(_ raw: Int) {
self = .Raw(raw)
}
public init<A: AlgebraicHashable>(_ hashable: A) {
self = hashable.hash
}
public init<A: Hashable>(_ hashable: A) {
2015-09-30 17:40:28 +03:00
self = .Raw(hashable.hashValue)
}
2015-09-30 00:00:26 +03:00
2015-09-30 17:40:45 +03:00
public var hashValue: Int {
2015-09-30 00:00:26 +03:00
switch self {
case let .Sequence(s):
// Bob Jenkins one-at-a-time hash: https://en.wikipedia.org/wiki/Jenkins_hash_function
var hash = 0
for each in s {
hash += each.hashValue
hash += hash << 10
hash ^= hash >> 6
}
hash += hash << 3
hash ^= hash >> 11
hash += hash << 15
return hash
2015-09-30 17:42:27 +03:00
case let .Label(s):
2015-09-30 00:00:26 +03:00
return s.hashValue
2015-09-30 17:40:28 +03:00
case let .Raw(i):
2015-09-30 00:00:26 +03:00
return i.hashValue
}
}
}
public func == (left: Hash, right: Hash) -> Bool {
switch (left, right) {
case let (.Sequence(a), .Sequence(b)):
return a == b
2015-09-30 17:42:27 +03:00
case let (.Label(a), .Label(b)):
2015-09-30 00:00:26 +03:00
return a == b
2015-09-30 17:40:28 +03:00
case let (.Raw(a), .Raw(b)):
2015-09-30 00:00:26 +03:00
return a == b
default:
return false
}
}
2015-09-30 22:02:31 +03:00
public protocol AlgebraicHashable: Hashable {
var hash: Hash { get }
}
extension AlgebraicHashable {
public var hashValue: Int {
return hash.hashValue
}
}
extension RawRepresentable where RawValue: Hashable {
public var hash: Hash {
return Hash(rawValue)
}
}
extension RawRepresentable where RawValue: AlgebraicHashable {
public var hash: Hash {
return Hash(rawValue)
}
}