@@ -2535,93 +2535,6 @@ ${assignmentOperatorComment(x.operator, False)}
2535
2535
% for Range in [ 'Range', 'ClosedRange'] :
2536
2536
% exampleRange = '1 ..< 100 ' if Range == 'Range' else '1 ... 100 '
2537
2537
2538
- extension ${ Range}
2539
- where Bound: FixedWidthInteger, Bound . Stride : SignedInteger,
2540
- Bound . Magnitude : UnsignedInteger
2541
- {
2542
-
2543
- /// Returns a random element of the range, using the given generator as
2544
- /// a source for randomness.
2545
- ///
2546
- /// You can use this method to select a random element of a range when you
2547
- /// are using a custom random number generator. If you're generating a random
2548
- /// number, in most cases, you should prefer using the `random(in:using:)`
2549
- /// static method of the desired numeric type. That static method is available
2550
- /// for both integer and floating point types, and returns a non-optional
2551
- /// value.
2552
- ///
2553
- /// - Parameter generator: The random number generator to use when choosing
2554
- /// a random element.
2555
- /// - Returns: A random element of the range.
2556
- % if 'Closed' not in Range:
2557
- /// If the range is empty, the method returns `nil`.
2558
- % else :
2559
- /// This method never returns `nil`.
2560
- % end
2561
- @inlinable
2562
- public func randomElement< T: RandomNumberGenerator > (
2563
- using generator: inout T
2564
- ) -> Element ? {
2565
- guard !isEmpty else {
2566
- return nil
2567
- }
2568
- // Compute delta, the distance between the lower and upper bounds. This
2569
- // value may not representable by the type Bound if Bound is signed, but
2570
- // is always representable as Bound.Magnitude.
2571
- % if 'Closed' in Range:
2572
- var delta = Bound . Magnitude ( truncatingIfNeeded: upperBound &- lowerBound)
2573
- % else :
2574
- let delta = Bound . Magnitude ( truncatingIfNeeded: upperBound &- lowerBound)
2575
- % end
2576
- % if 'Closed' in Range:
2577
- // Subtle edge case: if the range is the whole set of representable values,
2578
- // then adding one to delta to account for a closed range will overflow.
2579
- // If we used &+ instead, the result would be zero, which isn't helpful,
2580
- // so we actually need to handle this case separately.
2581
- if delta == Bound . Magnitude. max {
2582
- return Bound ( truncatingIfNeeded: generator. next ( ) as Bound . Magnitude )
2583
- }
2584
- // Need to widen delta to account for the right-endpoint of a closed range.
2585
- delta += 1
2586
- % end
2587
- // The mathematical result we want is lowerBound plus a random value in
2588
- // 0 ..< delta. We need to be slightly careful about how we do this
2589
- // arithmetic; the Bound type cannot generally represent the random value,
2590
- // so we use a wrapping addition on Bound.Magnitude. This will often
2591
- // overflow, but produces the correct bit pattern for the result when
2592
- // converted back to Bound.
2593
- return Bound ( truncatingIfNeeded:
2594
- Bound . Magnitude ( truncatingIfNeeded: lowerBound) &+
2595
- generator. next ( upperBound: delta)
2596
- )
2597
- }
2598
-
2599
- /// Returns a random element of the range, using the given generator as
2600
- /// a source for randomness.
2601
- ///
2602
- /// You can use this method to select a random element of a range when you
2603
- /// are using a custom random number generator. If you're generating a random
2604
- /// number, in most cases, you should prefer using the `random(in:)`
2605
- /// static method of the desired numeric type. That static method is available
2606
- /// for both integer and floating point types, and returns a non-optional
2607
- /// value.
2608
- ///
2609
- /// This method uses the default random generator, `Random.default`. Calling
2610
- /// `(${exampleRange}).randomElement()` is equivalent to calling
2611
- /// `(${exampleRange}).randomElement(using: &Random.default)`.
2612
- ///
2613
- /// - Returns: A random element of the range.
2614
- % if 'Closed' not in Range:
2615
- /// If the range is empty, the method returns `nil`.
2616
- % else :
2617
- /// This method never returns `nil`.
2618
- % end
2619
- @inlinable
2620
- public func randomElement( ) -> Element ? {
2621
- return randomElement ( using: & Random. default)
2622
- }
2623
- }
2624
-
2625
2538
extension FixedWidthInteger
2626
2539
where Self. Stride : SignedInteger,
2627
2540
Self . Magnitude : UnsignedInteger {
@@ -2657,7 +2570,36 @@ where Self.Stride : SignedInteger,
2657
2570
!range. isEmpty,
2658
2571
" Can't get random value with an empty range "
2659
2572
)
2660
- return range. randomElement ( using: & generator) !
2573
+
2574
+ // Compute delta, the distance between the lower and upper bounds. This
2575
+ // value may not representable by the type Bound if Bound is signed, but
2576
+ // is always representable as Bound.Magnitude.
2577
+ % if 'Closed' in Range:
2578
+ var delta = Magnitude ( truncatingIfNeeded: range. upperBound &- range. lowerBound)
2579
+ % else :
2580
+ let delta = Magnitude ( truncatingIfNeeded: range. upperBound &- range. lowerBound)
2581
+ % end
2582
+ % if 'Closed' in Range:
2583
+ // Subtle edge case: if the range is the whole set of representable values,
2584
+ // then adding one to delta to account for a closed range will overflow.
2585
+ // If we used &+ instead, the result would be zero, which isn't helpful,
2586
+ // so we actually need to handle this case separately.
2587
+ if delta == Magnitude . max {
2588
+ return Self ( truncatingIfNeeded: generator. next ( ) as Magnitude )
2589
+ }
2590
+ // Need to widen delta to account for the right-endpoint of a closed range.
2591
+ delta += 1
2592
+ % end
2593
+ // The mathematical result we want is lowerBound plus a random value in
2594
+ // 0 ..< delta. We need to be slightly careful about how we do this
2595
+ // arithmetic; the Bound type cannot generally represent the random value,
2596
+ // so we use a wrapping addition on Bound.Magnitude. This will often
2597
+ // overflow, but produces the correct bit pattern for the result when
2598
+ // converted back to Bound.
2599
+ return Self ( truncatingIfNeeded:
2600
+ Magnitude ( truncatingIfNeeded: range. lowerBound) &+
2601
+ generator. next ( upperBound: delta)
2602
+ )
2661
2603
}
2662
2604
2663
2605
/// Returns a random value within the specified range.
0 commit comments