From 41410bc1ea9c0706cc9eb24f2bfc8793e14c8dba Mon Sep 17 00:00:00 2001 From: Thomas Van Lenten Date: Thu, 7 Apr 2022 13:44:29 -0400 Subject: [PATCH] Drop the Hashable support for < 4.2 Progress on #1210 --- Sources/SwiftProtobuf/AnyMessageStorage.swift | 15 - Sources/SwiftProtobuf/Enum.swift | 6 - .../ExtensionFieldValueSet.swift | 11 - Sources/SwiftProtobuf/ExtensionFields.swift | 101 ------ .../Google_Protobuf_Any+Extensions.swift | 6 - Sources/SwiftProtobuf/HashVisitor.swift | 333 ++++-------------- Sources/SwiftProtobuf/Message.swift | 14 - Sources/SwiftProtobuf/NameMap.swift | 16 - 8 files changed, 63 insertions(+), 439 deletions(-) diff --git a/Sources/SwiftProtobuf/AnyMessageStorage.swift b/Sources/SwiftProtobuf/AnyMessageStorage.swift index 754a3f065..c92e44982 100644 --- a/Sources/SwiftProtobuf/AnyMessageStorage.swift +++ b/Sources/SwiftProtobuf/AnyMessageStorage.swift @@ -15,11 +15,6 @@ import Foundation -#if !swift(>=4.2) -private let i_2166136261 = Int(bitPattern: 2166136261) -private let i_16777619 = Int(16777619) -#endif - fileprivate func serializeAnyJSON( for message: Message, typeURL: String, @@ -323,7 +318,6 @@ extension AnyMessageStorage { /// test. Of course, regardless of the above, we must guarantee that /// hashValue is compatible with equality. extension AnyMessageStorage { -#if swift(>=4.2) // Can't use _valueData for a few reasons: // 1. Since decode is done on demand, two objects could be equal // but created differently (one from JSON, one for Message, etc.), @@ -338,15 +332,6 @@ extension AnyMessageStorage { hasher.combine(_typeURL) } } -#else // swift(>=4.2) - var hashValue: Int { - var hash: Int = i_2166136261 - if !_typeURL.isEmpty { - hash = (hash &* i_16777619) ^ _typeURL.hashValue - } - return hash - } -#endif // swift(>=4.2) func isEqualTo(other: AnyMessageStorage) -> Bool { if (_typeURL != other._typeURL) { diff --git a/Sources/SwiftProtobuf/Enum.swift b/Sources/SwiftProtobuf/Enum.swift index e3fdd93e0..c8b8da6cb 100644 --- a/Sources/SwiftProtobuf/Enum.swift +++ b/Sources/SwiftProtobuf/Enum.swift @@ -39,15 +39,9 @@ public protocol Enum: RawRepresentable, Hashable, CaseIterable, _ProtoSendable { } extension Enum { -#if swift(>=4.2) public func hash(into hasher: inout Hasher) { hasher.combine(rawValue) } -#else // swift(>=4.2) - public var hashValue: Int { - return rawValue - } -#endif // swift(>=4.2) /// Internal convenience property representing the name of the enum value (or /// `nil` if it is an `UNRECOGNIZED` value or doesn't provide names). diff --git a/Sources/SwiftProtobuf/ExtensionFieldValueSet.swift b/Sources/SwiftProtobuf/ExtensionFieldValueSet.swift index fc48b0e2b..28fdacc18 100644 --- a/Sources/SwiftProtobuf/ExtensionFieldValueSet.swift +++ b/Sources/SwiftProtobuf/ExtensionFieldValueSet.swift @@ -41,7 +41,6 @@ public struct ExtensionFieldValueSet: Hashable { public init() {} -#if swift(>=4.2) public func hash(into hasher: inout Hasher) { // AnyExtensionField is not Hashable, and the Self constraint that would // add breaks some of the uses of it; so the only choice is to manually @@ -56,16 +55,6 @@ public struct ExtensionFieldValueSet: Hashable { } hasher.combine(hash) } -#else // swift(>=4.2) - public var hashValue: Int { - var hash = 16777619 - for (fieldNumber, v) in values { - // Note: This calculation cannot depend on the order of the items. - hash = hash &+ fieldNumber &+ v.hashValue - } - return hash - } -#endif // swift(>=4.2) public func traverse(visitor: inout V, start: Int, end: Int) throws { let validIndexes = values.keys.filter {$0 >= start && $0 < end} diff --git a/Sources/SwiftProtobuf/ExtensionFields.swift b/Sources/SwiftProtobuf/ExtensionFields.swift index 7aefd00c1..e69a2fa91 100644 --- a/Sources/SwiftProtobuf/ExtensionFields.swift +++ b/Sources/SwiftProtobuf/ExtensionFields.swift @@ -12,11 +12,6 @@ /// // ----------------------------------------------------------------------------- -#if !swift(>=4.2) -private let i_2166136261 = Int(bitPattern: 2166136261) -private let i_16777619 = Int(16777619) -#endif - // TODO: `AnyExtensionField` should require `Sendable` but we cannot do so yet without possibly breaking compatibility. // @@ -30,11 +25,7 @@ private let i_16777619 = Int(16777619) // so you can't actually access the contained value itself. // public protocol AnyExtensionField: CustomDebugStringConvertible { -#if swift(>=4.2) func hash(into hasher: inout Hasher) -#else - var hashValue: Int { get } -#endif var protobufExtension: AnyMessageExtension { get } func isEqual(other: AnyExtensionField) -> Bool @@ -89,15 +80,9 @@ public struct OptionalExtensionField: ExtensionField { } } -#if swift(>=4.2) public func hash(into hasher: inout Hasher) { hasher.combine(value) } -#else // swift(>=4.2) - public var hashValue: Int { - get { return value.hashValue } - } -#endif // swift(>=4.2) public func isEqual(other: AnyExtensionField) -> Bool { let o = other as! OptionalExtensionField @@ -146,21 +131,9 @@ public struct RepeatedExtensionField: ExtensionField { self.value = value } -#if swift(>=4.2) public func hash(into hasher: inout Hasher) { hasher.combine(value) } -#else // swift(>=4.2) - public var hashValue: Int { - get { - var hash = i_2166136261 - for e in value { - hash = (hash &* i_16777619) ^ e.hashValue - } - return hash - } - } -#endif // swift(>=4.2) public func isEqual(other: AnyExtensionField) -> Bool { let o = other as! RepeatedExtensionField @@ -210,21 +183,9 @@ public struct PackedExtensionField: ExtensionField { self.value = value } -#if swift(>=4.2) public func hash(into hasher: inout Hasher) { hasher.combine(value) } -#else // swift(>=4.2) - public var hashValue: Int { - get { - var hash = i_2166136261 - for e in value { - hash = (hash &* i_16777619) ^ e.hashValue - } - return hash - } - } -#endif // swift(>=4.2) public func isEqual(other: AnyExtensionField) -> Bool { let o = other as! PackedExtensionField @@ -277,15 +238,9 @@ public struct OptionalEnumExtensionField: ExtensionField where E.RawVal } } -#if swift(>=4.2) public func hash(into hasher: inout Hasher) { hasher.combine(value) } -#else // swift(>=4.2) - public var hashValue: Int { - get { return value.hashValue } - } -#endif // swift(>=4.2) public func isEqual(other: AnyExtensionField) -> Bool { let o = other as! OptionalEnumExtensionField @@ -336,21 +291,9 @@ public struct RepeatedEnumExtensionField: ExtensionField where E.RawVal self.value = value } -#if swift(>=4.2) public func hash(into hasher: inout Hasher) { hasher.combine(value) } -#else // swift(>=4.2) - public var hashValue: Int { - get { - var hash = i_2166136261 - for e in value { - hash = (hash &* i_16777619) ^ e.hashValue - } - return hash - } - } -#endif // swift(>=4.2) public func isEqual(other: AnyExtensionField) -> Bool { let o = other as! RepeatedEnumExtensionField @@ -402,21 +345,9 @@ public struct PackedEnumExtensionField: ExtensionField where E.RawValue self.value = value } -#if swift(>=4.2) public func hash(into hasher: inout Hasher) { hasher.combine(value) } -#else // swift(>=4.2) - public var hashValue: Int { - get { - var hash = i_2166136261 - for e in value { - hash = (hash &* i_16777619) ^ e.hashValue - } - return hash - } - } -#endif // swift(>=4.2) public func isEqual(other: AnyExtensionField) -> Bool { let o = other as! PackedEnumExtensionField @@ -472,13 +403,9 @@ public struct OptionalMessageExtensionField: } } -#if swift(>=4.2) public func hash(into hasher: inout Hasher) { value.hash(into: &hasher) } -#else // swift(>=4.2) - public var hashValue: Int {return value.hashValue} -#endif // swift(>=4.2) public func isEqual(other: AnyExtensionField) -> Bool { let o = other as! OptionalMessageExtensionField @@ -530,23 +457,11 @@ public struct RepeatedMessageExtensionField: self.value = value } -#if swift(>=4.2) public func hash(into hasher: inout Hasher) { for e in value { e.hash(into: &hasher) } } -#else // swift(>=4.2) - public var hashValue: Int { - get { - var hash = i_2166136261 - for e in value { - hash = (hash &* i_16777619) ^ e.hashValue - } - return hash - } - } -#endif // swift(>=4.2) public func isEqual(other: AnyExtensionField) -> Bool { let o = other as! RepeatedMessageExtensionField @@ -602,13 +517,9 @@ public struct OptionalGroupExtensionField: self.value = value } -#if swift(>=4.2) public func hash(into hasher: inout Hasher) { hasher.combine(value) } -#else // swift(>=4.2) - public var hashValue: Int {return value.hashValue} -#endif // swift(>=4.2) public var debugDescription: String { get {return value.debugDescription} } @@ -662,21 +573,9 @@ public struct RepeatedGroupExtensionField: self.value = value } -#if swift(>=4.2) public func hash(into hasher: inout Hasher) { hasher.combine(value) } -#else // swift(>=4.2) - public var hashValue: Int { - get { - var hash = i_2166136261 - for e in value { - hash = (hash &* i_16777619) ^ e.hashValue - } - return hash - } - } -#endif // swift(>=4.2) public var debugDescription: String { return "[" + value.map{$0.debugDescription}.joined(separator: ",") + "]" diff --git a/Sources/SwiftProtobuf/Google_Protobuf_Any+Extensions.swift b/Sources/SwiftProtobuf/Google_Protobuf_Any+Extensions.swift index 2c59dec57..2557140dd 100644 --- a/Sources/SwiftProtobuf/Google_Protobuf_Any+Extensions.swift +++ b/Sources/SwiftProtobuf/Google_Protobuf_Any+Extensions.swift @@ -98,15 +98,9 @@ extension Google_Protobuf_Any { return _storage.isA(type) } -#if swift(>=4.2) public func hash(into hasher: inout Hasher) { _storage.hash(into: &hasher) } -#else // swift(>=4.2) - public var hashValue: Int { - return _storage.hashValue - } -#endif // swift(>=4.2) } extension Google_Protobuf_Any { diff --git a/Sources/SwiftProtobuf/HashVisitor.swift b/Sources/SwiftProtobuf/HashVisitor.swift index 395af2acf..67ccea36b 100644 --- a/Sources/SwiftProtobuf/HashVisitor.swift +++ b/Sources/SwiftProtobuf/HashVisitor.swift @@ -27,359 +27,167 @@ private let i_16777619 = Int(16777619) /// message fields they want to include. internal struct HashVisitor: Visitor { -#if swift(>=4.2) internal private(set) var hasher: Hasher -#else // swift(>=4.2) - // Roughly based on FNV hash: http://tools.ietf.org/html/draft-eastlake-fnv-03 - private(set) var hashValue = i_2166136261 - private mutating func mix(_ hash: Int) { - hashValue = (hashValue ^ hash) &* i_16777619 - } - - private mutating func mixMap(map: Dictionary) { - var mapHash = 0 - for (k, v) in map { - // Note: This calculation cannot depend on the order of the items. - mapHash = mapHash &+ (k.hashValue ^ v.hashValue) - } - mix(mapHash) - } -#endif // swift(>=4.2) - -#if swift(>=4.2) init(_ hasher: Hasher) { self.hasher = hasher } -#else - init() {} -#endif mutating func visitUnknown(bytes: Data) throws { - #if swift(>=4.2) - hasher.combine(bytes) - #else - mix(bytes.hashValue) - #endif + hasher.combine(bytes) } mutating func visitSingularDoubleField(value: Double, fieldNumber: Int) throws { - #if swift(>=4.2) - hasher.combine(fieldNumber) - hasher.combine(value) - #else - mix(fieldNumber) - mix(value.hashValue) - #endif + hasher.combine(fieldNumber) + hasher.combine(value) } mutating func visitSingularInt64Field(value: Int64, fieldNumber: Int) throws { - #if swift(>=4.2) - hasher.combine(fieldNumber) - hasher.combine(value) - #else - mix(fieldNumber) - mix(value.hashValue) - #endif + hasher.combine(fieldNumber) + hasher.combine(value) } mutating func visitSingularUInt64Field(value: UInt64, fieldNumber: Int) throws { - #if swift(>=4.2) - hasher.combine(fieldNumber) - hasher.combine(value) - #else - mix(fieldNumber) - mix(value.hashValue) - #endif + hasher.combine(fieldNumber) + hasher.combine(value) } mutating func visitSingularBoolField(value: Bool, fieldNumber: Int) throws { - #if swift(>=4.2) - hasher.combine(fieldNumber) - hasher.combine(value) - #else - mix(fieldNumber) - mix(value.hashValue) - #endif + hasher.combine(fieldNumber) + hasher.combine(value) } mutating func visitSingularStringField(value: String, fieldNumber: Int) throws { - #if swift(>=4.2) - hasher.combine(fieldNumber) - hasher.combine(value) - #else - mix(fieldNumber) - mix(value.hashValue) - #endif + hasher.combine(fieldNumber) + hasher.combine(value) } mutating func visitSingularBytesField(value: Data, fieldNumber: Int) throws { - #if swift(>=4.2) - hasher.combine(fieldNumber) - hasher.combine(value) - #else - mix(fieldNumber) - mix(value.hashValue) - #endif + hasher.combine(fieldNumber) + hasher.combine(value) } mutating func visitSingularEnumField(value: E, fieldNumber: Int) { - #if swift(>=4.2) - hasher.combine(fieldNumber) - hasher.combine(value) - #else - mix(fieldNumber) - mix(value.hashValue) - #endif + hasher.combine(fieldNumber) + hasher.combine(value) } mutating func visitSingularMessageField(value: M, fieldNumber: Int) { - #if swift(>=4.2) - hasher.combine(fieldNumber) - value.hash(into: &hasher) - #else - mix(fieldNumber) - mix(value.hashValue) - #endif + hasher.combine(fieldNumber) + value.hash(into: &hasher) } mutating func visitRepeatedFloatField(value: [Float], fieldNumber: Int) throws { assert(!value.isEmpty) - #if swift(>=4.2) - hasher.combine(fieldNumber) - hasher.combine(value) - #else - mix(fieldNumber) - for v in value { - mix(v.hashValue) - } - #endif + hasher.combine(fieldNumber) + hasher.combine(value) } mutating func visitRepeatedDoubleField(value: [Double], fieldNumber: Int) throws { assert(!value.isEmpty) - #if swift(>=4.2) - hasher.combine(fieldNumber) - hasher.combine(value) - #else - mix(fieldNumber) - for v in value { - mix(v.hashValue) - } - #endif + hasher.combine(fieldNumber) + hasher.combine(value) } mutating func visitRepeatedInt32Field(value: [Int32], fieldNumber: Int) throws { assert(!value.isEmpty) - #if swift(>=4.2) - hasher.combine(fieldNumber) - hasher.combine(value) - #else - mix(fieldNumber) - for v in value { - mix(v.hashValue) - } - #endif + hasher.combine(fieldNumber) + hasher.combine(value) } mutating func visitRepeatedInt64Field(value: [Int64], fieldNumber: Int) throws { assert(!value.isEmpty) - #if swift(>=4.2) - hasher.combine(fieldNumber) - hasher.combine(value) - #else - mix(fieldNumber) - for v in value { - mix(v.hashValue) - } - #endif + hasher.combine(fieldNumber) + hasher.combine(value) } mutating func visitRepeatedUInt32Field(value: [UInt32], fieldNumber: Int) throws { assert(!value.isEmpty) - #if swift(>=4.2) - hasher.combine(fieldNumber) - hasher.combine(value) - #else - mix(fieldNumber) - for v in value { - mix(v.hashValue) - } - #endif + hasher.combine(fieldNumber) + hasher.combine(value) } mutating func visitRepeatedUInt64Field(value: [UInt64], fieldNumber: Int) throws { assert(!value.isEmpty) - #if swift(>=4.2) - hasher.combine(fieldNumber) - hasher.combine(value) - #else - mix(fieldNumber) - for v in value { - mix(v.hashValue) - } - #endif + hasher.combine(fieldNumber) + hasher.combine(value) } mutating func visitRepeatedSInt32Field(value: [Int32], fieldNumber: Int) throws { assert(!value.isEmpty) - #if swift(>=4.2) - hasher.combine(fieldNumber) - hasher.combine(value) - #else - mix(fieldNumber) - for v in value { - mix(v.hashValue) - } - #endif + hasher.combine(fieldNumber) + hasher.combine(value) } mutating func visitRepeatedSInt64Field(value: [Int64], fieldNumber: Int) throws { assert(!value.isEmpty) - #if swift(>=4.2) - hasher.combine(fieldNumber) - hasher.combine(value) - #else - mix(fieldNumber) - for v in value { - mix(v.hashValue) - } - #endif + hasher.combine(fieldNumber) + hasher.combine(value) } mutating func visitRepeatedFixed32Field(value: [UInt32], fieldNumber: Int) throws { assert(!value.isEmpty) - #if swift(>=4.2) - hasher.combine(fieldNumber) - hasher.combine(value) - #else - mix(fieldNumber) - for v in value { - mix(v.hashValue) - } - #endif + hasher.combine(fieldNumber) + hasher.combine(value) } mutating func visitRepeatedFixed64Field(value: [UInt64], fieldNumber: Int) throws { assert(!value.isEmpty) - #if swift(>=4.2) - hasher.combine(fieldNumber) - hasher.combine(value) - #else - mix(fieldNumber) - for v in value { - mix(v.hashValue) - } - #endif + hasher.combine(fieldNumber) + hasher.combine(value) } mutating func visitRepeatedSFixed32Field(value: [Int32], fieldNumber: Int) throws { assert(!value.isEmpty) - #if swift(>=4.2) - hasher.combine(fieldNumber) - hasher.combine(value) - #else - mix(fieldNumber) - for v in value { - mix(v.hashValue) - } - #endif + hasher.combine(fieldNumber) + hasher.combine(value) } mutating func visitRepeatedSFixed64Field(value: [Int64], fieldNumber: Int) throws { assert(!value.isEmpty) - #if swift(>=4.2) - hasher.combine(fieldNumber) - hasher.combine(value) - #else - mix(fieldNumber) - for v in value { - mix(v.hashValue) - } - #endif + hasher.combine(fieldNumber) + hasher.combine(value) } mutating func visitRepeatedBoolField(value: [Bool], fieldNumber: Int) throws { assert(!value.isEmpty) - #if swift(>=4.2) - hasher.combine(fieldNumber) - hasher.combine(value) - #else - mix(fieldNumber) - for v in value { - mix(v.hashValue) - } - #endif + hasher.combine(fieldNumber) + hasher.combine(value) } mutating func visitRepeatedStringField(value: [String], fieldNumber: Int) throws { assert(!value.isEmpty) - #if swift(>=4.2) - hasher.combine(fieldNumber) - hasher.combine(value) - #else - mix(fieldNumber) - for v in value { - mix(v.hashValue) - } - #endif + hasher.combine(fieldNumber) + hasher.combine(value) } mutating func visitRepeatedBytesField(value: [Data], fieldNumber: Int) throws { assert(!value.isEmpty) - #if swift(>=4.2) - hasher.combine(fieldNumber) - hasher.combine(value) - #else - mix(fieldNumber) - for v in value { - mix(v.hashValue) - } - #endif + hasher.combine(fieldNumber) + hasher.combine(value) } mutating func visitRepeatedEnumField(value: [E], fieldNumber: Int) throws { assert(!value.isEmpty) - #if swift(>=4.2) - hasher.combine(fieldNumber) - hasher.combine(value) - #else - mix(fieldNumber) - for v in value { - mix(v.hashValue) - } - #endif + hasher.combine(fieldNumber) + hasher.combine(value) } mutating func visitRepeatedMessageField(value: [M], fieldNumber: Int) throws { assert(!value.isEmpty) - #if swift(>=4.2) - hasher.combine(fieldNumber) - for v in value { - v.hash(into: &hasher) - } - #else - mix(fieldNumber) - for v in value { - mix(v.hashValue) - } - #endif + hasher.combine(fieldNumber) + for v in value { + v.hash(into: &hasher) + } } mutating func visitRepeatedGroupField(value: [G], fieldNumber: Int) throws { assert(!value.isEmpty) - #if swift(>=4.2) - hasher.combine(fieldNumber) - for v in value { - v.hash(into: &hasher) - } - #else - mix(fieldNumber) - for v in value { - mix(v.hashValue) - } - #endif + hasher.combine(fieldNumber) + for v in value { + v.hash(into: &hasher) + } } mutating func visitMapField( @@ -387,13 +195,8 @@ internal struct HashVisitor: Visitor { value: _ProtobufMap.BaseType, fieldNumber: Int ) throws { - #if swift(>=4.2) - hasher.combine(fieldNumber) - hasher.combine(value) - #else - mix(fieldNumber) - mixMap(map: value) - #endif + hasher.combine(fieldNumber) + hasher.combine(value) } mutating func visitMapField( @@ -401,13 +204,8 @@ internal struct HashVisitor: Visitor { value: _ProtobufEnumMap.BaseType, fieldNumber: Int ) throws where ValueType.RawValue == Int { - #if swift(>=4.2) - hasher.combine(fieldNumber) - hasher.combine(value) - #else - mix(fieldNumber) - mixMap(map: value) - #endif + hasher.combine(fieldNumber) + hasher.combine(value) } mutating func visitMapField( @@ -415,12 +213,7 @@ internal struct HashVisitor: Visitor { value: _ProtobufMessageMap.BaseType, fieldNumber: Int ) throws { - #if swift(>=4.2) - hasher.combine(fieldNumber) - hasher.combine(value) - #else - mix(fieldNumber) - mixMap(map: value) - #endif + hasher.combine(fieldNumber) + hasher.combine(value) } } diff --git a/Sources/SwiftProtobuf/Message.swift b/Sources/SwiftProtobuf/Message.swift index 22e3db3ae..098f36b62 100644 --- a/Sources/SwiftProtobuf/Message.swift +++ b/Sources/SwiftProtobuf/Message.swift @@ -102,15 +102,9 @@ public protocol Message: CustomDebugStringConvertible, _ProtoSendable { // so can be overridden in user code by defining custom extensions to // the generated struct. -#if swift(>=4.2) /// An implementation of hash(into:) to provide conformance with the /// `Hashable` protocol. func hash(into hasher: inout Hasher) -#else // swift(>=4.2) - /// The hash value generated from this message's contents, for conformance - /// with the `Hashable` protocol. - var hashValue: Int { get } -#endif // swift(>=4.2) /// Helper to compare `Message`s when not having a specific type to use /// normal `Equatable`. `Equatable` is provided with specific generated @@ -129,19 +123,11 @@ extension Message { } /// A hash based on the message's full contents. -#if swift(>=4.2) public func hash(into hasher: inout Hasher) { var visitor = HashVisitor(hasher) try? traverse(visitor: &visitor) hasher = visitor.hasher } -#else // swift(>=4.2) - public var hashValue: Int { - var visitor = HashVisitor() - try? traverse(visitor: &visitor) - return visitor.hashValue - } -#endif // swift(>=4.2) /// A description generated by recursively visiting all fields in the message, /// including messages. diff --git a/Sources/SwiftProtobuf/NameMap.swift b/Sources/SwiftProtobuf/NameMap.swift index 14cbf148d..e835c9899 100644 --- a/Sources/SwiftProtobuf/NameMap.swift +++ b/Sources/SwiftProtobuf/NameMap.swift @@ -67,12 +67,6 @@ fileprivate class InternPool { } } -#if !swift(>=4.2) -// Constants for FNV hash http://tools.ietf.org/html/draft-eastlake-fnv-03 -private let i_2166136261 = Int(bitPattern: 2166136261) -private let i_16777619 = Int(16777619) -#endif - /// An immutable bidirectional mapping between field/enum-case names /// and numbers, used to record field names for text-based /// serialization (JSON and text). These maps are lazily instantiated @@ -135,21 +129,11 @@ public struct _NameMap: ExpressibleByDictionaryLiteral { } } - #if swift(>=4.2) public func hash(into hasher: inout Hasher) { for byte in utf8Buffer { hasher.combine(byte) } } - #else // swift(>=4.2) - public var hashValue: Int { - var h = i_2166136261 - for byte in utf8Buffer { - h = (h ^ Int(byte)) &* i_16777619 - } - return h - } - #endif // swift(>=4.2) public static func ==(lhs: Name, rhs: Name) -> Bool { if lhs.utf8Buffer.count != rhs.utf8Buffer.count {