Skip to content

Commit 6927e9a

Browse files
benrimmingtonAzoy
authored andcommitted
Consolidate _stdlib_random functions (#2)
* Use the `__has_include` and `GRND_RANDOM` macros * Use `getentropy` instead of `getrandom` * Use `std::min` from the <algorithm> header * Move `#if` out of the `_stdlib_random` function * Use `getrandom` with "/dev/urandom" fallback * Use `#pragma comment` to import "Bcrypt.lib" * <https://docs.microsoft.com/en-us/cpp/preprocessor/comment-c-cpp> * <https://clang.llvm.org/docs/UsersManual.html#microsoft-extensions> * Use "/dev/urandom" instead of `SecRandomCopyBytes` * Use `swift::StaticMutex` for shared "/dev/urandom" * Add `getrandom_available`; use `O_CLOEXEC` flag Add platform impl docs Update copyrights Fix docs Add _stdlib_random test Update _stdlib_random test Add missing & Notice about _stdlib_random Fix docs Guard on upperBound = 0 Test full range of 8 bit integers Remove some gyb
1 parent 2f4294b commit 6927e9a

File tree

13 files changed

+148
-126
lines changed

13 files changed

+148
-126
lines changed

benchmark/single-source/RandomShuffle.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
//
33
// This source file is part of the Swift.org open source project
44
//
5-
// Copyright (c) 2014 - 2018 Apple Inc. and the Swift project authors
5+
// Copyright (c) 2018 Apple Inc. and the Swift project authors
66
// Licensed under Apache License v2.0 with Runtime Library Exception
77
//
88
// See https://swift.org/LICENSE.txt for license information

benchmark/single-source/RandomValues.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
//
33
// This source file is part of the Swift.org open source project
44
//
5-
// Copyright (c) 2014 - 2018 Apple Inc. and the Swift project authors
5+
// Copyright (c) 2018 Apple Inc. and the Swift project authors
66
// Licensed under Apache License v2.0 with Runtime Library Exception
77
//
88
// See https://swift.org/LICENSE.txt for license information

benchmark/utils/main.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
//
33
// This source file is part of the Swift.org open source project
44
//
5-
// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
5+
// Copyright (c) 2014 - 2018 Apple Inc. and the Swift project authors
66
// Licensed under Apache License v2.0 with Runtime Library Exception
77
//
88
// See https://swift.org/LICENSE.txt for license information

stdlib/public/SwiftShims/LibcShims.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
//
33
// This source file is part of the Swift.org open source project
44
//
5-
// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
5+
// Copyright (c) 2014 - 2018 Apple Inc. and the Swift project authors
66
// Licensed under Apache License v2.0 with Runtime Library Exception
77
//
88
// See https://swift.org/LICENSE.txt for license information

stdlib/public/core/Bool.swift

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
//
33
// This source file is part of the Swift.org open source project
44
//
5-
// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
5+
// Copyright (c) 2014 - 2018 Apple Inc. and the Swift project authors
66
// Licensed under Apache License v2.0 with Runtime Library Exception
77
//
88
// See https://swift.org/LICENSE.txt for license information
@@ -88,23 +88,21 @@ public struct Bool {
8888
self = value
8989
}
9090

91-
/// Returns a random Boolean
91+
/// Returns a random Boolean value
9292
///
9393
/// - Parameter generator: The random number generator to use when getting a
9494
/// random Boolean.
95-
/// - Returns: A random Boolean.
95+
/// - Returns: A random Boolean value.
9696
@inlinable
9797
public static func random<T: RandomNumberGenerator>(
9898
using generator: inout T
9999
) -> Bool {
100100
return (generator.next() >> 17) & 1 == 0
101101
}
102102

103-
/// Returns a random Boolean
103+
/// Returns a random Boolean value
104104
///
105-
/// - Parameter generator: The random number generator to use when getting a
106-
/// random Boolean.
107-
/// - Returns: A random Boolean.
105+
/// - Returns: A random Boolean value.
108106
///
109107
/// This uses the standard library's default random number generator.
110108
@inlinable

stdlib/public/core/CMakeLists.txt

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
#
33
# This source file is part of the Swift.org open source project
44
#
5-
# Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
5+
# Copyright (c) 2014 - 2018 Apple Inc. and the Swift project authors
66
# Licensed under Apache License v2.0 with Runtime Library Exception
77
#
88
# See https://swift.org/LICENSE.txt for license information
@@ -193,7 +193,6 @@ if(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
193193
list(APPEND swift_core_link_flags "-all_load")
194194
list(APPEND swift_core_framework_depends Foundation)
195195
list(APPEND swift_core_framework_depends CoreFoundation)
196-
list(APPEND swift_core_framework_depends Security)
197196
list(APPEND swift_core_private_link_libraries icucore)
198197
else()
199198
# With the GNU linker the equivalent of -all_load is to tell the linker
@@ -228,10 +227,6 @@ if(CMAKE_SYSTEM_NAME STREQUAL "FreeBSD")
228227
${EXECINFO_LIBRARY})
229228
endif()
230229

231-
if(CMAKE_SYSTEM_NAME STREQUAL "Windows")
232-
list(APPEND swift_core_link_flags "$ENV{SystemRoot}/system32/bcrypt.dll")
233-
endif()
234-
235230
option(SWIFT_CHECK_ESSENTIAL_STDLIB
236231
"Check core standard library layering by linking its essential subset"
237232
FALSE)

stdlib/public/core/Collection.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
//
33
// This source file is part of the Swift.org open source project
44
//
5-
// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
5+
// Copyright (c) 2014 - 2018 Apple Inc. and the Swift project authors
66
// Licensed under Apache License v2.0 with Runtime Library Exception
77
//
88
// See https://swift.org/LICENSE.txt for license information

stdlib/public/core/CollectionAlgorithms.swift

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
//
33
// This source file is part of the Swift.org open source project
44
//
5-
// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
5+
// Copyright (c) 2014 - 2018 Apple Inc. and the Swift project authors
66
// Licensed under Apache License v2.0 with Runtime Library Exception
77
//
88
// See https://swift.org/LICENSE.txt for license information
@@ -304,8 +304,6 @@ extension Sequence {
304304
/// to `numbers.shuffled()` above is equivalent to calling
305305
/// `numbers.shuffled(using: &Random.default)`.
306306
///
307-
/// - Parameter generator: The random number generator to use when shuffling
308-
/// the sequence.
309307
/// - Returns: A shuffled array of this sequence's elements.
310308
///
311309
/// - Complexity: O(*n*)
@@ -335,6 +333,7 @@ extension MutableCollection {
335333
public mutating func shuffle<T: RandomNumberGenerator>(
336334
using generator: inout T
337335
) {
336+
let count = self.count
338337
guard count > 1 else { return }
339338
var amount = count
340339
var currentIndex = startIndex

stdlib/public/core/FloatingPoint.swift.gyb

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
//
33
// This source file is part of the Swift.org open source project
44
//
5-
// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
5+
// Copyright (c) 2014 - 2018 Apple Inc. and the Swift project authors
66
// Licensed under Apache License v2.0 with Runtime Library Exception
77
//
88
// See https://swift.org/LICENSE.txt for license information
@@ -2395,7 +2395,7 @@ where Self.RawSignificand : FixedWidthInteger,
23952395
/// // Prints "14.2286325689993"
23962396
/// // Prints "13.1485686260762"
23972397
///
2398-
/// The `random(using:)` static method chooses a random value from a
2398+
/// The `random(in:using:)` static method chooses a random value from a
23992399
/// continuous uniform distribution in `range`, and then converts that value
24002400
/// to the nearest representable value in this type. Depending on the size and
24012401
/// span of `range`, some concrete values may be represented more frequently
@@ -2414,12 +2414,10 @@ where Self.RawSignificand : FixedWidthInteger,
24142414
in range: ${Range}<Self>,
24152415
using generator: inout T
24162416
) -> Self {
2417-
% if 'Closed' not in Range:
24182417
_precondition(
2419-
range.lowerBound != range.upperBound,
2420-
"Can't get random value with lowerBound == upperBound"
2418+
!range.isEmpty,
2419+
"Can't get random value with an empty range"
24212420
)
2422-
% end
24232421
let delta = range.upperBound - range.lowerBound
24242422
let rand: Self.RawSignificand
24252423
if Self.RawSignificand.bitWidth == Self.significandBitCount + 1 {

stdlib/public/core/Integers.swift.gyb

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
//
33
// This source file is part of the Swift.org open source project
44
//
5-
// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
5+
// Copyright (c) 2014 - 2018 Apple Inc. and the Swift project authors
66
// Licensed under Apache License v2.0 with Runtime Library Exception
77
//
88
// See https://swift.org/LICENSE.txt for license information
@@ -2513,11 +2513,9 @@ extension ${Range}
25132513
public func randomElement<T: RandomNumberGenerator>(
25142514
using generator: inout T
25152515
) -> Element? {
2516-
% if 'Closed' not in Range:
2517-
guard lowerBound != upperBound else {
2516+
guard !isEmpty else {
25182517
return nil
25192518
}
2520-
% end
25212519
let isLowerNegative = Bound.isSigned && lowerBound < 0
25222520
let sameSign = !Bound.isSigned || isLowerNegative == (upperBound < 0)
25232521
% if 'Closed' not in Range:
@@ -2611,12 +2609,10 @@ where Self.Stride : SignedInteger,
26112609
in range: ${Range}<Self>,
26122610
using generator: inout T
26132611
) -> Self {
2614-
% if 'Closed' not in Range:
26152612
_precondition(
2616-
range.lowerBound != range.upperBound,
2617-
"Can't get random value with lowerBound == upperBound"
2613+
!range.isEmpty,
2614+
"Can't get random value with an empty range"
26182615
)
2619-
% end
26202616
return range.randomElement(using: &generator)!
26212617
}
26222618

stdlib/public/core/Random.swift

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
//
33
// This source file is part of the Swift.org open source project
44
//
5-
// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
5+
// Copyright (c) 2018 Apple Inc. and the Swift project authors
66
// Licensed under Apache License v2.0 with Runtime Library Exception
77
//
88
// See https://swift.org/LICENSE.txt for license information
@@ -32,7 +32,7 @@ import SwiftShims
3232
/// }
3333
///
3434
/// static func randomWeekday() -> Weekday {
35-
/// return Weekday.randomWeekday(using: Random.default)
35+
/// return Weekday.randomWeekday(using: &Random.default)
3636
/// }
3737
/// }
3838
///
@@ -94,6 +94,7 @@ extension RandomNumberGenerator {
9494
public mutating func next<T: FixedWidthInteger & UnsignedInteger>(
9595
upperBound: T
9696
) -> T {
97+
guard upperBound != 0 else { return 0 }
9798
let tmp = (T.max % upperBound) + 1
9899
let range = tmp == upperBound ? 0 : tmp
99100
var random: T = 0
@@ -118,8 +119,19 @@ extension RandomNumberGenerator {
118119
///
119120
/// `Random.default` is safe to use in multiple threads, and uses a
120121
/// cryptographically secure algorithm whenever possible.
122+
///
123+
/// Platform Implementation of `Random`
124+
/// ===================================
125+
///
126+
/// - Apple platforms use `arc4random_buf(3)` for newer versions of their OS,
127+
/// and for older versions they will read from `/dev/urandom`.
128+
/// - `Linux`, `Android`, `Cygwin`, `Haiku`, `FreeBSD`, and `PS4` all try to
129+
/// use `getrandom(2)`, but if it doesn't exist then they read from
130+
/// `/dev/urandom`.
131+
/// - `Fuchsia` calls `getentropy(3)`.
132+
/// - `Windows` calls `BCryptGenRandom`.
121133
public struct Random : RandomNumberGenerator {
122-
/// The shared, default instance of the `Range` random number generator.
134+
/// The default instance of the `Random` random number generator.
123135
public static var `default`: Random {
124136
get { return Random() }
125137
set { /* Discard */ }

0 commit comments

Comments
 (0)