10
10
11
11
This proposal's main focus is to create a unified random API, and a secure random API for all platforms.
12
12
13
- * This idea has been floating around swift-evolution for a while now, but this is the thread that started this proposal: https://lists .swift.org/pipermail/swift-evolution/Week-of-Mon-20170904/039605.html *
13
+ * This idea has been floating around swift-evolution for a while now, but this is the thread that started this proposal: https://forums .swift.org/t/proposal-random-unification/6626 *
14
14
15
15
## Motivation
16
16
@@ -93,29 +93,17 @@ To kick this off, we will be discussing the rngs that each operating system will
93
93
94
94
#### Linux Platform
95
95
96
- We require that the kernel version be >= 3.17 as this was the release that introduced the ` getrandom(2) ` system call. We also require that glibc be >= 2.25 because this released exposed the ` <sys/random.h> ` header.
96
+ We require that the kernel version be >= 3.17 as this was the release that introduced the ` getrandom(2) ` system call. We also require that glibc be >= 2.25 because this release exposed the ` <sys/random.h> ` header.
97
97
98
98
| Kernel Version < 3.17 && Glibc Version < 2.25 | Kernel Version >= 3.17 && Glibc Version >= 2.25 |
99
99
| :---------------------------------------------:| :-----------------------------------------------:|
100
100
| Read from ` /dev/urandom ` | Use ` getrandom(2) ` |
101
101
102
- #### Android (Bionic) and Cygwin
102
+ #### Other Platforms
103
103
104
- | Bionic and Cygwin |
105
- | :------------------:|
106
- | Use ` getrandom(2) ` |
107
-
108
- #### Fuchsia
109
-
110
- | Fuchsia |
111
- | :-------------------:|
112
- | Use ` getentropy(2) ` |
113
-
114
- #### Windows
115
-
116
- | Windows |
117
- | :----------------------:|
118
- | Use ` BCryptoGenRandom ` |
104
+ | Android (Bionic) and Cygwin | Fuchsia | Windows |
105
+ | :---------------------------:| :-------------------:| :----------------------:|
106
+ | Use ` getrandom(2) ` | Use ` getentropy(2) ` | Use ` BCryptoGenRandom ` |
119
107
120
108
### Random API
121
109
@@ -224,16 +212,21 @@ public struct Random : RandomNumberGenerator {
224
212
225
213
public protocol Collection {
226
214
// Returns a random element from the collection
227
- func random (using generator : RandomNumberGenerator ) -> Element ?
215
+ func random < T : RandomNumberGenerator > (using generator : T ) -> Element ?
228
216
}
229
217
230
218
// Default implementation
231
219
extension Collection {
232
- // Returns a random element from the collection (defaults to using Random.default)
220
+ // Returns a random element from the collection
233
221
// Can return nil if isEmpty is true
234
- public func random (
235
- using generator : RandomNumberGenerator = Random. default
222
+ public func random < T : RandomNumberGenerator > (
223
+ using generator : T
236
224
) -> Element ?
225
+
226
+ /// Uses the standard library's default rng
227
+ public func random () -> Element ? {
228
+ return random (using : Random.default )
229
+ }
237
230
}
238
231
239
232
// We have to add this extension to support syntax like (Int.min ..< Int.max).random()
@@ -242,11 +235,16 @@ extension Collection {
242
235
extension Range
243
236
where Bound : FixedWidthInteger ,
244
237
Bound.Magnitude : UnsignedInteger {
245
- // Returns a random element within lowerBound and upperBound (defaults to using Random.default)
238
+ // Returns a random element within lowerBound and upperBound
246
239
// Can return nil if lowerBound == upperBound
247
- public func random (
248
- using generator : RandomNumberGenerator = Random. default
240
+ public func random < T : RandomNumberGenerator > (
241
+ using generator : T
249
242
) -> Element ?
243
+
244
+ /// Uses the standard library's default rng
245
+ public func random () -> Element ? {
246
+ return random (using : Random.default )
247
+ }
250
248
}
251
249
252
250
// We have to add this extension to support syntax like (Int.min ... Int.max).random()
@@ -255,10 +253,15 @@ where Bound : FixedWidthInteger,
255
253
extension ClosedRange
256
254
where Bound : FixedWidthInteger ,
257
255
Bound.Magnitude : UnsignedInteger {
258
- // Returns a random element within lowerBound and upperBound (defaults to using Random.default)
259
- public func random (
260
- using generator : RandomNumberGenerator = Random. default
256
+ // Returns a random element within lowerBound and upperBound
257
+ public func random < T : RandomNumberGenerator > (
258
+ using generator : T
261
259
) -> Element ?
260
+
261
+ /// Uses the standard library's default rng
262
+ public func random () -> Element ? {
263
+ return random (using : Random.default )
264
+ }
262
265
}
263
266
264
267
// Enables developers to use things like Int.random(in: 5 ..< 12) which does not use modulo bias.
@@ -274,15 +277,25 @@ extension FixedWidthInteger
274
277
where Self .Stride : SignedInteger ,
275
278
Self .Magnitude : UnsignedInteger {
276
279
277
- public static func random (
280
+ public static func random < T : RandomNumberGenerator > (
278
281
in range : Range <Self >,
279
- using generator : RandomNumberGenerator = Random. default
282
+ using generator : T
280
283
) -> Self
281
284
282
- public static func random (
285
+ /// Uses the standard library's default rng
286
+ public static func random (in range : Range <Self >) -> Self {
287
+ return Self .random (in : range, using : Random.default )
288
+ }
289
+
290
+ public static func random <T : RandomNumberGenerator >(
283
291
in range : ClosedRange <Self >,
284
- using generator : RandomNumberGenerator = Random. default
292
+ using generator : T
285
293
) -> Self
294
+
295
+ /// Uses the standard library's default rng
296
+ public static func random (in range : ClosedRange <Self >) -> Self {
297
+ return Self .random (in : range, using : Random.default )
298
+ }
286
299
}
287
300
288
301
// Enables developers to use things like Double.random(in: 5 ..< 12) which does not use modulo bias.
@@ -299,15 +312,25 @@ where Self.RawSignificand : FixedWidthInteger,
299
312
Self .RawSignificand .Stride : SignedInteger & FixedWidthInteger ,
300
313
Self .RawSignificand .Magnitude : UnsignedInteger {
301
314
302
- public static func random (
315
+ public static func random < T : RandomNumberGenerator > (
303
316
in range : Range <Self >,
304
- using generator : RandomNumberGenerator = Random. default
317
+ using generator : T
305
318
) -> Self
306
319
307
- public static func random (
320
+ /// Uses the standard library's default rng
321
+ public static func random (in range : Range <Self >) -> Self {
322
+ return Self .random (in : range, using : Random.default )
323
+ }
324
+
325
+ public static func random <T : RandomNumberGenerator >(
308
326
in range : ClosedRange <Self >,
309
- using generator : RandomNumberGenerator = Random. default
327
+ using generator : T
310
328
) -> Self
329
+
330
+ /// Uses the standard library's default rng
331
+ public static func random (in range : ClosedRange <Self >) -> Self {
332
+ return Self .random (in : range, using : Random.default )
333
+ }
311
334
}
312
335
313
336
// We add this as a convenience to something like:
@@ -316,25 +339,40 @@ where Self.RawSignificand : FixedWidthInteger,
316
339
// understand what is going on. This extension methods helps bring clarity to
317
340
// operations like these.
318
341
extension Bool {
319
- public static func random (
320
- using generator : RandomNumberGenerator = Random. default
342
+ public static func random < T : RandomNumberGenerator > (
343
+ using generator : T
321
344
) -> Bool
345
+
346
+ /// Uses the standard library's default rng
347
+ public static func random () -> Bool {
348
+ return Bool .random (using : Random.default )
349
+ }
322
350
}
323
351
324
352
// Shuffle API
325
353
326
354
// The shuffle API will utilize the Fisher Yates algorithm
327
355
328
356
extension Sequence {
329
- public func shuffled (
330
- using generator : RandomNumberGenerator = Random. default
357
+ public func shuffled < T : RandomNumberGenerator > (
358
+ using generator : T
331
359
) -> [Element ]
360
+
361
+ /// Uses the standard library's default rng
362
+ public func shuffled () -> [Element ] {
363
+ return shuffled (using : Random.default )
364
+ }
332
365
}
333
366
334
367
extension MutableCollection {
335
- public mutating func shuffle (
336
- using generator : RandomNumberGenerator = Random. default
368
+ public mutating func shuffle < T : RandomNumberGenerator > (
369
+ using generator : T
337
370
)
371
+
372
+ /// Uses the standard library's default rng
373
+ public mutating func shuffle () {
374
+ shuffle (using : Random.default )
375
+ }
338
376
}
339
377
```
340
378
0 commit comments