Avatar
internal var _canonicalBox: _AnyHashableBox { // We need to follow NSNumber semantics here; the AnyHashable forms of // integer types holding the same mathematical value should compare equal. // Sign-extend value to a 64-bit integer. This will generate hash conflicts // between, say -1 and UInt.max, but that's fine. if _value < 0 { return _IntegerAnyHashableBox<Int64>(Int64(truncatingIfNeeded: _value)) } return _IntegerAnyHashableBox<UInt64>(UInt64(truncatingIfNeeded: _value)) }
9:27 AM
% if bits != 16: internal struct _${Self}AnyHashableBox: _AnyHashableBox { internal typealias Base = ${Self} internal let _value: Base internal init(_ value: Base) { self._value = value } internal var _canonicalBox: _AnyHashableBox { // Float and Double are bridged with NSNumber, so we have to follow // NSNumber's rules for equality. I.e., we need to make sure equal // numerical values end up in identical boxes after canonicalization, so // that _isEqual will consider them equal and they're hashed the same way. // // Note that these AnyHashable boxes don't currently feed discriminator bits // to the hasher, so we allow repeatable collisions. E.g., -1 will always // collide with UInt64.max. if _value < 0 { if let i = Int64(exactly: _value) { return _IntegerAnyHashableBox(i) } } else { if let i = UInt64(exactly: _value) { return _IntegerAnyHashableBox(i) } } if let d = Double(exactly: _value) { return _DoubleAnyHashableBox(d) } // If a value can't be represented by a Double, keep it in its original // representation so that it won't compare equal to approximations. (So that // we don't round off Float80 values.) return self }
9:27 AM
Floatのほうが Int64(exactly:) つかって _IntegerAnyHashableBox にすり寄っていくらしい