| //===----------------------------------------------------------------------===// |
| // |
| // This source file is part of the Swift.org open source project |
| // |
| // Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors |
| // Licensed under Apache License v2.0 with Runtime Library Exception |
| // |
| // See https://swift.org/LICENSE.txt for license information |
| // See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors |
| // |
| //===----------------------------------------------------------------------===// |
| |
| /// A type that can be hashed into a `Hasher` to produce an integer hash value. |
| /// |
| /// You can use any type that conforms to the `Hashable` protocol in a set or as |
| /// a dictionary key. Many types in the standard library conform to `Hashable`: |
| /// Strings, integers, floating-point and Boolean values, and even sets are |
| /// hashable by default. Some other types, such as optionals, arrays and ranges |
| /// automatically become hashable when their type arguments implement the same. |
| /// |
| /// Your own custom types can be hashable as well. When you define an |
| /// enumeration without associated values, it gains `Hashable` conformance |
| /// automatically, and you can add `Hashable` conformance to your other custom |
| /// types by implementing the `hash(into:)` method. For structs whose stored |
| /// properties are all `Hashable`, and for enum types that have all-`Hashable` |
| /// associated values, the compiler is able to provide an implementation of |
| /// `hash(into:)` automatically. |
| /// |
| /// Hashing a value means feeding its essential components into a hash function, |
| /// represented by the `Hasher` type. Essential components are those that |
| /// contribute to the type's implementation of `Equatable`. Two instances that |
| /// are equal must feed the same values to `Hasher` in `hash(into:)`, in the |
| /// same order. |
| /// |
| /// Conforming to the Hashable Protocol |
| /// =================================== |
| /// |
| /// To use your own custom type in a set or as the key type of a dictionary, |
| /// add `Hashable` conformance to your type. The `Hashable` protocol inherits |
| /// from the `Equatable` protocol, so you must also satisfy that protocol's |
| /// requirements. |
| /// |
| /// The compiler automatically synthesizes your custom type's `Hashable` and |
| /// requirements when you declare `Hashable` conformance in the type's original |
| /// declaration and your type meets these criteria: |
| /// |
| /// - For a `struct`, all its stored properties must conform to `Hashable`. |
| /// - For an `enum`, all its associated values must conform to `Hashable`. (An |
| /// `enum` without associated values has `Hashable` conformance even without |
| /// the declaration.) |
| /// |
| /// To customize your type's `Hashable` conformance, to adopt `Hashable` in a |
| /// type that doesn't meet the criteria listed above, or to extend an existing |
| /// type to conform to `Hashable`, implement the `hash(into:)` method in your |
| /// custom type. |
| /// |
| /// In your `hash(into:)` implementation, call `combine(_:)` on the provided |
| /// `Hasher` instance with the essential components of your type. To ensure |
| /// that your type meets the semantic requirements of the `Hashable` and |
| /// `Equatable` protocols, it's a good idea to also customize your type's |
| /// `Equatable` conformance to match. |
| /// |
| /// As an example, consider a `GridPoint` type that describes a location in a |
| /// grid of buttons. Here's the initial declaration of the `GridPoint` type: |
| /// |
| /// /// A point in an x-y coordinate system. |
| /// struct GridPoint { |
| /// var x: Int |
| /// var y: Int |
| /// } |
| /// |
| /// You'd like to create a set of the grid points where a user has already |
| /// tapped. Because the `GridPoint` type is not hashable yet, it can't be used |
| /// in a set. To add `Hashable` conformance, provide an `==` operator function |
| /// and implement the `hash(into:)` method. |
| /// |
| /// extension GridPoint: Hashable { |
| /// static func == (lhs: GridPoint, rhs: GridPoint) -> Bool { |
| /// return lhs.x == rhs.x && lhs.y == rhs.y |
| /// } |
| /// |
| /// func hash(into hasher: inout Hasher) { |
| /// hasher.combine(x) |
| /// hasher.combine(y) |
| /// } |
| /// } |
| /// |
| /// The `hash(into:)` method in this example feeds the grid point's `x` and `y` |
| /// properties into the provided hasher. These properties are the same ones |
| /// used to test for equality in the `==` operator function. |
| /// |
| /// Now that `GridPoint` conforms to the `Hashable` protocol, you can create a |
| /// set of previously tapped grid points. |
| /// |
| /// var tappedPoints: Set = [GridPoint(x: 2, y: 3), GridPoint(x: 4, y: 1)] |
| /// let nextTap = GridPoint(x: 0, y: 1) |
| /// if tappedPoints.contains(nextTap) { |
| /// print("Already tapped at (\(nextTap.x), \(nextTap.y)).") |
| /// } else { |
| /// tappedPoints.insert(nextTap) |
| /// print("New tap detected at (\(nextTap.x), \(nextTap.y)).") |
| /// } |
| /// // Prints "New tap detected at (0, 1).") |
| public protocol Hashable : Equatable { |
| /// The hash value. |
| /// |
| /// Hash values are not guaranteed to be equal across different executions of |
| /// your program. Do not save hash values to use during a future execution. |
| /// |
| /// - Important: `hashValue` is deprecated as a `Hashable` requirement. To |
| /// conform to `Hashable`, implement the `hash(into:)` requirement instead. |
| var hashValue: Int { get } |
| |
| /// Hashes the essential components of this value by feeding them into the |
| /// given hasher. |
| /// |
| /// Implement this method to conform to the `Hashable` protocol. The |
| /// components used for hashing must be the same as the components compared |
| /// in your type's `==` operator implementation. Call `hasher.combine(_:)` |
| /// with each of these components. |
| /// |
| /// - Important: Never call `finalize()` on `hasher`. Doing so may become a |
| /// compile-time error in the future. |
| /// |
| /// - Parameter hasher: The hasher to use when combining the components |
| /// of this instance. |
| func hash(into hasher: inout Hasher) |
| |
| // Raw top-level hashing interface. Some standard library types (mostly |
| // primitives) specialize this to eliminate small resiliency overheads. (This |
| // only matters for tiny keys.) |
| func _rawHashValue(seed: Int) -> Int |
| } |
| |
| extension Hashable { |
| @inlinable |
| @inline(__always) |
| public func _rawHashValue(seed: Int) -> Int { |
| var hasher = Hasher(_seed: seed) |
| hasher.combine(self) |
| return hasher._finalize() |
| } |
| } |
| |
| // Called by synthesized `hashValue` implementations. |
| @inlinable |
| @inline(__always) |
| public func _hashValue<H: Hashable>(for value: H) -> Int { |
| return value._rawHashValue(seed: 0) |
| } |
| |
| // Called by the SwiftValue implementation. |
| @_silgen_name("_swift_stdlib_Hashable_isEqual_indirect") |
| internal func Hashable_isEqual_indirect<T : Hashable>( |
| _ lhs: UnsafePointer<T>, |
| _ rhs: UnsafePointer<T> |
| ) -> Bool { |
| return lhs.pointee == rhs.pointee |
| } |
| |
| // Called by the SwiftValue implementation. |
| @_silgen_name("_swift_stdlib_Hashable_hashValue_indirect") |
| internal func Hashable_hashValue_indirect<T : Hashable>( |
| _ value: UnsafePointer<T> |
| ) -> Int { |
| return value.pointee.hashValue |
| } |