1
- //===--- Random.swift ---------------------------------------------------- -===//
1
+ //===--- Random.swift.gyb -------------------------------------*- swift -* -===//
2
2
//
3
3
// This source file is part of the Swift.org open source project
4
4
//
@@ -19,8 +19,8 @@ import SwiftShims
19
19
/// that implement their own pseudo-random or cryptographically secure
20
20
/// pseudo-random number generation. Using the RandomNumberGenerator protocol
21
21
/// allows these types to be used with types that conform to `Randomizable`,
22
- /// collections with .random, and collections/sequences with .shuffle() and
23
- /// .shuffled()
22
+ /// collections with .random and .pick(_:) , and collections/sequences with
23
+ /// .shuffle() and . shuffled()
24
24
///
25
25
/// Conforming to the RandomNumberGenerator protocol
26
26
/// ==========================================
@@ -100,20 +100,20 @@ extension RandomNumberGenerator {
100
100
/// Using those functions should be preferred over using this directly. An
101
101
/// example of calling this directly:
102
102
///
103
- /// let random = Random.default.next(Int .self)
104
- /// let randomToTen = Random.default.next(Int .self, upperBound: 10 )
103
+ /// let random = Random.default.next(UInt8 .self)
104
+ /// let randomToTen = Random.default.next(UInt32 .self, upperBound: 128 )
105
105
///
106
106
/// However, you should strive to use the random functions on the numeric types.
107
107
/// Using the preferred way:
108
108
///
109
- /// let random = Int .random
110
- /// let randomToTen = ( 0 ... 10).random
109
+ /// let random = UInt8 .random
110
+ /// let randomToTen = UInt32.random(in: 0 ... 128)
111
111
///
112
112
/// - Note: The default implementation of randomness is cryptographically secure.
113
113
/// It utilizes arc4random on newer versions of macOS, iOS, etc. On older
114
- /// versions of these operating systems it uses /dev/urandom and SecRandomCopyBytes
115
- /// on iOS. For Linux, it tries to use the getrandom(2) system call on newer
116
- /// kernel versions. On older kernel versions, it uses /dev/urandom.
114
+ /// versions of these operating systems it uses SecRandomCopyBytes. For Linux,
115
+ /// it tries to use the getrandom(2) system call on newer kernel versions. On
116
+ /// older kernel versions, it reads from /dev/urandom.
117
117
public struct Random : RandomNumberGenerator {
118
118
/// This random number generator generates the machine's bit width unsigned integer
119
119
public typealias GeneratedNumber = UInt
@@ -150,37 +150,26 @@ public struct Random : RandomNumberGenerator {
150
150
/// =======================================
151
151
///
152
152
/// In order to conform to the Randomizable protocol, all one must implement is
153
- /// the random(using:) function. As an example, below is a custom Date structure:
153
+ /// the random(using:) function. As an example, below is a custom Color structure:
154
154
///
155
- /// struct Date {
156
- /// let year: Int
157
- /// let month: Int
158
- /// let day: Int
155
+ /// struct Color {
156
+ /// let value: UInt32
159
157
/// }
160
158
///
161
- /// In order for `Date ` to conform to `Randomizable`, it must declare conformance
159
+ /// In order for `Color ` to conform to `Randomizable`, it must declare conformance
162
160
/// and implement the random(using:) function.
163
161
///
164
- /// extension Date : Randomizable {
162
+ /// extension Color : Randomizable {
165
163
/// static func random<T: RandomNumberGenerator>(using generator: T) -> Self {
166
- /// let randomYear = (0 ... 3000).random(using: generator)
167
- /// let randomMonth = (1 ... 12).random(using: generator)
168
- /// let randomDay = (1 ... 31).random(using: generator)
169
- /// // This could produce a date with day 31 on months without 31 days
170
- /// // Ideally, you should check for this
171
- /// return Date(year: randomYear, month: randomMonth, day: randomDay)
164
+ /// let value = UInt32.random(in: 0x0 ... 0xFFFFFF, using: generator)
165
+ /// return Color(value: value)
172
166
/// }
173
167
/// }
174
168
///
175
- /// Note how the ranges use the random(using:) function that is defined for them .
169
+ /// Note how the function . random(in: using:) is using custom generator argument .
176
170
/// Make sure to do this for custom types as it allows developers the ability
177
171
/// to use their own random number generators on custom types.
178
172
public protocol Randomizable {
179
- /// The random representation of this type.
180
- ///
181
- /// Shorthand for using the random(using:) function. This uses the default
182
- /// random implementation defined in the standard library.
183
- static var random : Self { get }
184
173
185
174
/// Returns a random representation of this type.
186
175
///
@@ -191,7 +180,7 @@ public protocol Randomizable {
191
180
}
192
181
193
182
extension Randomizable {
194
- /// The random representation of this type.
183
+ /// Returns a random representation of this type.
195
184
///
196
185
/// Shorthand for using the random(using:) function. This uses the default
197
186
/// random implementation defined in the standard library.
@@ -200,3 +189,63 @@ extension Randomizable {
200
189
return self . random ( using: Random . default)
201
190
}
202
191
}
192
+
193
+ % for Range in [ 'Range', 'ClosedRange'] :
194
+
195
+ extension Randomizable where Self: BinaryFloatingPoint {
196
+ /// Returns a random representation of this type within the range
197
+ ///
198
+ /// - Parameter range: The range to select a random value from.
199
+ /// - Returns: A random representation of this type within the range.
200
+ ///
201
+ /// Shorthand for using the random(in:using:) function. This uses the default
202
+ /// random implementation defined in the standard library.
203
+ public static func random( in range: ${ Range} < Self> ) -> Self {
204
+ return range. random!
205
+ }
206
+
207
+ /// Returns a random representation of this type within the range
208
+ ///
209
+ /// - Parameter range: The range to select a random value from.
210
+ /// - Parameter generator: The random number generator to use when getting
211
+ /// a random value from the range.
212
+ /// - Returns: A random representation of this type within the range.
213
+ public static func random< T: RandomNumberGenerator > (
214
+ in range: ${ Range} < Self> ,
215
+ using generator: T
216
+ ) -> Self {
217
+ return range. random ( using: generator) !
218
+ }
219
+ }
220
+
221
+ % end
222
+
223
+ % for Range in [ 'CountableRange', 'CountableClosedRange'] :
224
+
225
+ extension Randomizable where Self: Strideable , Self. Stride: SignedInteger {
226
+ /// Returns a random representation of this type within the range
227
+ ///
228
+ /// - Parameter range: The range to select a random value from.
229
+ /// - Returns: A random representation of this type within the range.
230
+ ///
231
+ /// Shorthand for using the random(in:using:) function. This uses the default
232
+ /// random implementation defined in the standard library.
233
+ public static func random( in range: ${ Range} < Self> ) -> Self {
234
+ return range. random!
235
+ }
236
+
237
+ /// Returns a random representation of this type within the range
238
+ ///
239
+ /// - Parameter range: The range to select a random value from.
240
+ /// - Parameter generator: The random number generator to use when getting
241
+ /// a random value from the range.
242
+ /// - Returns: A random representation of this type within the range.
243
+ public static func random< T: RandomNumberGenerator > (
244
+ in range: ${ Range} < Self> ,
245
+ using generator: T
246
+ ) -> Self {
247
+ return range. random ( using: generator) !
248
+ }
249
+ }
250
+
251
+ % end
0 commit comments