Skip to content

Commit bb77484

Browse files
authored
Merge pull request #16707 from natecook1000/nc-fixes-84-1 (#16711)
1 parent aea6290 commit bb77484

35 files changed

+327
-90
lines changed

docs/Random.md

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
# Random APIs
2+
3+
More documentation to come.
4+
5+
## Platform-Specific Default Random
6+
7+
The implementation of the default random generator varies by platform. The implementation
8+
on each platform must be thread-safe and automatically seeded, and should be
9+
cryptographically secure to the extent possible. Currently supported platforms have the
10+
following implementation details:
11+
12+
- Apple platforms use `arc4random_buf(3)`.
13+
- Linux, FreeBSD, and other UNIX-like platforms use `getrandom(2)` when available;
14+
otherwise, they read from `/dev/urandom`.
15+
- Fuchsia platforms use `getentropy(3)`.
16+
- Windows platforms use `BCryptGenRandom`.

stdlib/public/core/AnyHashable.swift

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -287,11 +287,17 @@ extension AnyHashable : Equatable {
287287
}
288288

289289
extension AnyHashable : Hashable {
290+
/// The hash value.
290291
@inlinable // FIXME(sil-serialize-all)
291292
public var hashValue: Int {
292293
return _box._hashValue
293294
}
294295

296+
/// Hashes the essential components of this value by feeding them into the
297+
/// given hasher.
298+
///
299+
/// - Parameter hasher: The hasher to use when combining the components
300+
/// of this instance.
295301
@inlinable // FIXME(sil-serialize-all)
296302
public func hash(into hasher: inout Hasher) {
297303
_box._hash(into: &hasher)

stdlib/public/core/Arrays.swift.gyb

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2263,6 +2263,11 @@ extension ${Self} : Equatable where Element : Equatable {
22632263
}
22642264

22652265
extension ${Self}: Hashable where Element: Hashable {
2266+
/// Hashes the essential components of this value by feeding them into the
2267+
/// given hasher.
2268+
///
2269+
/// - Parameter hasher: The hasher to use when combining the components
2270+
/// of this instance.
22662271
@inlinable // FIXME(sil-serialize-all)
22672272
public func hash(into hasher: inout Hasher) {
22682273
hasher.combine(count) // discriminator

stdlib/public/core/Bool.swift

Lines changed: 37 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -87,23 +87,48 @@ public struct Bool {
8787
self = value
8888
}
8989

90-
/// Returns a random Boolean value
90+
/// Returns a random Boolean value, using the given generator as a source for
91+
/// randomness.
9192
///
92-
/// - Parameter generator: The random number generator to use when getting a
93-
/// random Boolean.
94-
/// - Returns: A random Boolean value.
93+
/// This method returns `true` and `false` with equal probability. Use this
94+
/// method to generate a random Boolean value when you are using a custom
95+
/// random number generator.
96+
///
97+
/// let flippedHeads = Boolean.random(using: &myGenerator)
98+
/// if flippedHeads {
99+
/// print("Heads, you win!")
100+
/// } else {
101+
/// print("Maybe another try?")
102+
/// }
103+
///
104+
/// - Parameter generator: The random number generator to use when creating
105+
/// the new random value.
106+
/// - Returns: Either `true` or `false`, randomly chosen with equal
107+
/// probability.
95108
@inlinable
96109
public static func random<T: RandomNumberGenerator>(
97110
using generator: inout T
98111
) -> Bool {
99112
return (generator.next() >> 17) & 1 == 0
100113
}
101114

102-
/// Returns a random Boolean value
115+
/// Returns a random Boolean value.
103116
///
104-
/// - Returns: A random Boolean value.
117+
/// This method returns `true` and `false` with equal probability.
105118
///
106-
/// This uses the standard library's default random number generator.
119+
/// let flippedHeads = Boolean.random()
120+
/// if flippedHeads {
121+
/// print("Heads, you win!")
122+
/// } else {
123+
/// print("Maybe another try?")
124+
/// }
125+
///
126+
/// `Bool.random()` uses the default random generator, `Random.default`. The
127+
/// call in the example above is equivalent to
128+
/// `Bool.random(using: &Random.default)`.
129+
///
130+
/// - Returns: Either `true` or `false`, randomly chosen with equal
131+
/// probability.
107132
@inlinable
108133
public static func random() -> Bool {
109134
return Bool.random(using: &Random.default)
@@ -167,6 +192,11 @@ public // COMPILER_INTRINSIC
167192
func _getBool(_ v: Builtin.Int1) -> Bool { return Bool(v) }
168193

169194
extension Bool : Equatable, Hashable {
195+
/// Hashes the essential components of this value by feeding them into the
196+
/// given hasher.
197+
///
198+
/// - Parameter hasher: The hasher to use when combining the components
199+
/// of this instance.
170200
@inlinable // FIXME(sil-serialize-all)
171201
public func hash(into hasher: inout Hasher) {
172202
hasher.combine((self ? 1 : 0) as UInt8)

stdlib/public/core/CTypes.swift

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,11 @@ extension OpaquePointer: Equatable {
174174
}
175175

176176
extension OpaquePointer: Hashable {
177+
/// Hashes the essential components of this value by feeding them into the
178+
/// given hasher.
179+
///
180+
/// - Parameter hasher: The hasher to use when combining the components
181+
/// of this instance.
177182
@inlinable // FIXME(sil-serialize-all)
178183
public func hash(into hasher: inout Hasher) {
179184
hasher.combine(Int(Builtin.ptrtoint_Word(_rawValue)))

stdlib/public/core/Character.swift

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -478,6 +478,11 @@ extension Character : Comparable {
478478

479479
extension Character: Hashable {
480480
// not @inlinable (performance)
481+
/// Hashes the essential components of this value by feeding them into the
482+
/// given hasher.
483+
///
484+
/// - Parameter hasher: The hasher to use when combining the components
485+
/// of this instance.
481486
@effects(releasenone)
482487
public func hash(into hasher: inout Hasher) {
483488
// FIXME(performance): constructing a temporary string is extremely

stdlib/public/core/ClosedRange.swift

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,11 @@ extension ClosedRange.Index : Comparable {
168168

169169
extension ClosedRange.Index: Hashable
170170
where Bound: Strideable, Bound.Stride: SignedInteger, Bound: Hashable {
171+
/// Hashes the essential components of this value by feeding them into the
172+
/// given hasher.
173+
///
174+
/// - Parameter hasher: The hasher to use when combining the components
175+
/// of this instance.
171176
@inlinable // FIXME(sil-serialize-all)
172177
public func hash(into hasher: inout Hasher) {
173178
switch self {

stdlib/public/core/Codable.swift.gyb

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,10 @@ public protocol Decodable {
4545
}
4646

4747
/// A type that can convert itself into and out of an external representation.
48+
///
49+
/// `Codable` is a type alias for the `Encodable` and `Decodable` protocols.
50+
/// When you use `Codable` as a type or a generic constraint, it matches
51+
/// any type that conforms to both protocols.
4852
public typealias Codable = Encodable & Decodable
4953

5054
//===----------------------------------------------------------------------===//
@@ -1095,6 +1099,11 @@ public struct CodingUserInfoKey : RawRepresentable, Equatable, Hashable {
10951099
return self.rawValue.hashValue
10961100
}
10971101

1102+
/// Hashes the essential components of this value by feeding them into the
1103+
/// given hasher.
1104+
///
1105+
/// - Parameter hasher: The hasher to use when combining the components
1106+
/// of this instance.
10981107
@inlinable // FIXME(sil-serialize-all)
10991108
public func hash(into hasher: inout Hasher) {
11001109
hasher.combine(self.rawValue)

stdlib/public/core/Collection.swift

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -812,7 +812,7 @@ public protocol Collection: Sequence where SubSequence: Collection {
812812
///
813813
/// let names = ["Zoey", "Chloe", "Amani", "Amaia"]
814814
/// let randomName = names.randomElement(using: &myGenerator)!
815-
/// // randomName == "Amani" (maybe)
815+
/// // randomName == "Amani"
816816
///
817817
/// - Parameter generator: The random number generator to use when choosing
818818
/// a random element.
@@ -1038,13 +1038,13 @@ extension Collection {
10381038
/// Returns a random element of the collection, using the given generator as
10391039
/// a source for randomness.
10401040
///
1041-
/// You use this method to select a random element from a collection when you
1042-
/// are using a custom random number generator. For example, call
1043-
/// `randomElement(using:)` to select a random element from an array of names.
1041+
/// Call `randomElement(using:)` to select a random element from an array or
1042+
/// another collection when you are using a custom random number generator.
1043+
/// This example picks a name at random from an array:
10441044
///
10451045
/// let names = ["Zoey", "Chloe", "Amani", "Amaia"]
10461046
/// let randomName = names.randomElement(using: &myGenerator)!
1047-
/// // randomName == "Amani" (maybe)
1047+
/// // randomName == "Amani"
10481048
///
10491049
/// - Parameter generator: The random number generator to use when choosing
10501050
/// a random element.
@@ -1065,12 +1065,12 @@ extension Collection {
10651065

10661066
/// Returns a random element of the collection.
10671067
///
1068-
/// For example, call `randomElement()` to select a random element from an
1069-
/// array of names.
1068+
/// Call `randomElement()` to select a random element from an array or
1069+
/// another collection. This example picks a name at random from an array:
10701070
///
10711071
/// let names = ["Zoey", "Chloe", "Amani", "Amaia"]
10721072
/// let randomName = names.randomElement()!
1073-
/// // randomName == "Amani" (perhaps)
1073+
/// // randomName == "Amani"
10741074
///
10751075
/// This method uses the default random generator, `Random.default`. The call
10761076
/// to `names.randomElement()` above is equivalent to calling

stdlib/public/core/Dictionary.swift

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1449,6 +1449,11 @@ extension Dictionary: Equatable where Value: Equatable {
14491449
}
14501450

14511451
extension Dictionary: Hashable where Value: Hashable {
1452+
/// Hashes the essential components of this value by feeding them into the
1453+
/// given hasher.
1454+
///
1455+
/// - Parameter hasher: The hasher to use when combining the components
1456+
/// of this instance.
14521457
@inlinable // FIXME(sil-serialize-all)
14531458
public func hash(into hasher: inout Hasher) {
14541459
var commutativeHash = 0

stdlib/public/core/DropWhile.swift

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -183,11 +183,17 @@ extension LazyDropWhileCollection.Index: Equatable, Comparable {
183183
}
184184

185185
extension LazyDropWhileCollection.Index: Hashable where Base.Index: Hashable {
186+
/// The hash value.
186187
@inlinable // FIXME(sil-serialize-all)
187188
public var hashValue: Int {
188189
return base.hashValue
189190
}
190191

192+
/// Hashes the essential components of this value by feeding them into the
193+
/// given hasher.
194+
///
195+
/// - Parameter hasher: The hasher to use when combining the components
196+
/// of this instance.
191197
@inlinable // FIXME(sil-serialize-all)
192198
public func hash(into hasher: inout Hasher) {
193199
hasher.combine(base)

stdlib/public/core/Flatten.swift

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -229,6 +229,11 @@ extension FlattenCollection.Index : Comparable {
229229

230230
extension FlattenCollection.Index : Hashable
231231
where Base.Index : Hashable, Base.Element.Index : Hashable {
232+
/// Hashes the essential components of this value by feeding them into the
233+
/// given hasher.
234+
///
235+
/// - Parameter hasher: The hasher to use when combining the components
236+
/// of this instance.
232237
@inlinable // FIXME(sil-serialize-all)
233238
public func hash(into hasher: inout Hasher) {
234239
hasher.combine(_outer)

stdlib/public/core/FloatingPointTypes.swift.gyb

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1521,6 +1521,11 @@ extension ${Self} : _ExpressibleByBuiltinFloatLiteral {
15211521
% end
15221522

15231523
extension ${Self} : Hashable {
1524+
/// Hashes the essential components of this value by feeding them into the
1525+
/// given hasher.
1526+
///
1527+
/// - Parameter hasher: The hasher to use when combining the components
1528+
/// of this instance.
15241529
@inlinable // FIXME(sil-serialize-all)
15251530
public func hash(into hasher: inout Hasher) {
15261531
var v = self

stdlib/public/core/Hashable.swift

Lines changed: 27 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -40,9 +40,9 @@
4040
/// from the `Equatable` protocol, so you must also satisfy that protocol's
4141
/// requirements.
4242
///
43-
/// A custom type's `Hashable` and `Equatable` requirements are automatically
44-
/// synthesized by the compiler when you declare `Hashable` conformance in the
45-
/// type's original declaration and your type meets these criteria:
43+
/// The compiler automatically synthesizes your custom type's `Hashable` and
44+
/// requirements when you declare `Hashable` conformance in the type's original
45+
/// declaration and your type meets these criteria:
4646
///
4747
/// - For a `struct`, all its stored properties must conform to `Hashable`.
4848
/// - For an `enum`, all its associated values must conform to `Hashable`. (An
@@ -51,10 +51,14 @@
5151
///
5252
/// To customize your type's `Hashable` conformance, to adopt `Hashable` in a
5353
/// type that doesn't meet the criteria listed above, or to extend an existing
54-
/// type to conform to `Hashable`, implement the `hash(into:)` function in your
55-
/// custom type. To ensure that your type meets the semantic requirements of the
56-
/// `Hashable` and `Equatable` protocols, it's a good idea to also customize
57-
/// your type's `Equatable` conformance to match the `hash(into:)` definition.
54+
/// type to conform to `Hashable`, implement the `hash(into:)` method in your
55+
/// custom type.
56+
///
57+
/// In your `hash(into:)` implementation, call `combine(_:)` on the provided
58+
/// `Hasher` instance with the essential components of your type. To ensure
59+
/// that your type meets the semantic requirements of the `Hashable` and
60+
/// `Equatable` protocols, it's a good idea to also customize your type's
61+
/// `Equatable` conformance to match.
5862
///
5963
/// As an example, consider a `GridPoint` type that describes a location in a
6064
/// grid of buttons. Here's the initial declaration of the `GridPoint` type:
@@ -67,8 +71,8 @@
6771
///
6872
/// You'd like to create a set of the grid points where a user has already
6973
/// tapped. Because the `GridPoint` type is not hashable yet, it can't be used
70-
/// as the `Element` type for a set. To add `Hashable` conformance, provide an
71-
/// `==` operator function and a `hash(into:)` method.
74+
/// in a set. To add `Hashable` conformance, provide an `==` operator function
75+
/// and implement the `hash(into:)` method.
7276
///
7377
/// extension GridPoint: Hashable {
7478
/// static func == (lhs: GridPoint, rhs: GridPoint) -> Bool {
@@ -81,12 +85,9 @@
8185
/// }
8286
/// }
8387
///
84-
/// The `hash(into:)` method in this example feeds the properties `x` and `y`
85-
/// to the supplied hasher; these are the same properties compared by the
86-
/// implementation of the `==` operator function.
87-
///
88-
/// (Because `x` and `y` are both `Hashable` themselves, you could've also let
89-
/// the compiler synthesize these implementations for you.)
88+
/// The `hash(into:)` method in this example feeds the grid point's `x` and `y`
89+
/// properties into the provided hasher. These properties are the same ones
90+
/// used to test for equality in the `==` operator function.
9091
///
9192
/// Now that `GridPoint` conforms to the `Hashable` protocol, you can create a
9293
/// set of previously tapped grid points.
@@ -107,16 +108,19 @@ public protocol Hashable : Equatable {
107108
/// your program. Do not save hash values to use during a future execution.
108109
var hashValue: Int { get }
109110

110-
/// Hash the essential components of this value into the hash function
111-
/// represented by `hasher`, by feeding them into it using its `combine`
112-
/// methods.
111+
/// Hashes the essential components of this value by feeding them into the
112+
/// given hasher.
113+
///
114+
/// Implement this method to conform to the `Hashable` protocol. The
115+
/// components used for hashing must be the same as the components compared
116+
/// in your type's `==` operator implementation. Call `hasher.combine(_:)`
117+
/// with each of these components.
113118
///
114-
/// Essential components are precisely those that are compared in the type's
115-
/// implementation of `Equatable`.
119+
/// - Important: Never call `finalize()` on `hasher`. Doing so may become a
120+
/// compile-time error in the future.
116121
///
117-
/// Note that `hash(into:)` doesn't own the hasher passed into it, so it must
118-
/// not call `finalize()` on it. Doing so may become a compile-time error in
119-
/// the future.
122+
/// - Parameter hasher: The hasher to use when combining the components
123+
/// of this instance.
120124
func hash(into hasher: inout Hasher)
121125
}
122126

stdlib/public/core/Hasher.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -226,7 +226,7 @@ internal struct _BufferingHasher<Core: _HasherCore> {
226226
}
227227
}
228228

229-
/// Represents the universal hash function used by `Set` and `Dictionary`.
229+
/// The universal hash function used by `Set` and `Dictionary`.
230230
///
231231
/// `Hasher` can be used to map an arbitrary sequence of bytes to an integer
232232
/// hash value. You can feed data to the hasher using a series of calls to

stdlib/public/core/Integers.swift.gyb

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3879,6 +3879,11 @@ ${assignmentOperatorComment(x.operator, True)}
38793879
%# end of concrete type: ${Self}
38803880

38813881
extension ${Self} : Hashable {
3882+
/// Hashes the essential components of this value by feeding them into the
3883+
/// given hasher.
3884+
///
3885+
/// - Parameter hasher: The hasher to use when combining the components
3886+
/// of this instance.
38823887
@inlinable // FIXME(sil-serialize-all)
38833888
public func hash(into hasher: inout Hasher) {
38843889
// FIXME(hasher): To correctly bridge `Set`s/`Dictionary`s containing

stdlib/public/core/KeyPath.swift

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,11 +46,17 @@ public class AnyKeyPath: Hashable, _AppendKeyPath {
4646
@usableFromInline // FIXME(sil-serialize-all)
4747
internal final var _kvcKeyPathStringPtr: UnsafePointer<CChar>?
4848

49+
/// The hash value.
4950
@inlinable // FIXME(sil-serialize-all)
5051
final public var hashValue: Int {
5152
return _hashValue(for: self)
5253
}
5354

55+
/// Hashes the essential components of this value by feeding them into the
56+
/// given hasher.
57+
///
58+
/// - Parameter hasher: The hasher to use when combining the components
59+
/// of this instance.
5460
@inlinable // FIXME(sil-serialize-all)
5561
final public func hash(into hasher: inout Hasher) {
5662
return withBuffer {

0 commit comments

Comments
 (0)