Skip to content

Commit 762666f

Browse files
committed
[stdlib] Add & implement Random._fill(bytes:) requirement
(cherry picked from commit 12a2b32)
1 parent cc31865 commit 762666f

File tree

2 files changed

+28
-9
lines changed

2 files changed

+28
-9
lines changed

stdlib/public/core/Random.swift

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,26 @@ public protocol RandomNumberGenerator {
5454
///
5555
/// - Returns: An unsigned 64-bit random value.
5656
mutating func next() -> UInt64
57+
58+
// FIXME: De-underscore after swift-evolution amendment
59+
mutating func _fill(bytes buffer: UnsafeMutableRawBufferPointer)
60+
}
61+
62+
extension RandomNumberGenerator {
63+
public mutating func _fill(bytes buffer: UnsafeMutableRawBufferPointer) {
64+
// FIXME: Optimize
65+
var chunk: UInt64 = 0
66+
var chunkBytes = 0
67+
for i in 0..<buffer.count {
68+
if chunkBytes == 0 {
69+
chunk = next()
70+
chunkBytes = UInt64.bitWidth / 8
71+
}
72+
buffer[i] = UInt8(truncatingIfNeeded: chunk)
73+
chunk >>= UInt8.bitWidth
74+
chunkBytes -= 1
75+
}
76+
}
5777
}
5878

5979
extension RandomNumberGenerator {
@@ -157,11 +177,10 @@ public struct Random : RandomNumberGenerator {
157177
_stdlib_random(&random, MemoryLayout<T>.size)
158178
return random
159179
}
160-
}
161180

162-
@usableFromInline internal// @testable
163-
func _stdlib_random(_ bytes: UnsafeMutableRawBufferPointer) {
164-
if !bytes.isEmpty {
165-
_stdlib_random(bytes.baseAddress!, bytes.count)
181+
public mutating func _fill(bytes buffer: UnsafeMutableRawBufferPointer) {
182+
if !buffer.isEmpty {
183+
_stdlib_random(buffer.baseAddress!, buffer.count)
184+
}
166185
}
167186
}

test/stdlib/Random.swift

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,9 @@ import StdlibCollectionUnittest
66

77
let RandomTests = TestSuite("Random")
88

9-
// _stdlib_random
9+
// _fill(bytes:)
1010

11-
RandomTests.test("_stdlib_random") {
11+
RandomTests.test("_fill(bytes:)") {
1212
for count in [100, 1000] {
1313
var bytes1 = [UInt8](repeating: 0, count: count)
1414
var bytes2 = [UInt8](repeating: 0, count: count)
@@ -17,11 +17,11 @@ RandomTests.test("_stdlib_random") {
1717
expectEqual(bytes1, zeros)
1818
expectEqual(bytes2, zeros)
1919

20-
bytes1.withUnsafeMutableBytes { _stdlib_random($0) }
20+
bytes1.withUnsafeMutableBytes { Random.default._fill(bytes: $0) }
2121
expectNotEqual(bytes1, bytes2)
2222
expectNotEqual(bytes1, zeros)
2323

24-
bytes2.withUnsafeMutableBytes { _stdlib_random($0) }
24+
bytes2.withUnsafeMutableBytes { Random.default._fill(bytes: $0) }
2525
expectNotEqual(bytes1, bytes2)
2626
expectNotEqual(bytes2, zeros)
2727
}

0 commit comments

Comments
 (0)