Skip to content

Commit

Permalink
Randomness in Stdlib methods (#73).
Browse files Browse the repository at this point in the history
  • Loading branch information
oscbyspro committed Aug 25, 2024
1 parent 2867ed8 commit 9a18f27
Show file tree
Hide file tree
Showing 4 changed files with 114 additions and 21 deletions.
39 changes: 38 additions & 1 deletion Sources/RandomIntKit/FuzzerInt.swift
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ import CoreKit
///
/// - Important: It may use a different algorithm in the future.
///
@frozen public struct FuzzerInt: Randomness, Sendable {
@frozen public struct FuzzerInt: Equatable, Interoperable, Randomness, Sendable {

//=------------------------------------------------------------------------=
// MARK: State
Expand All @@ -39,6 +39,14 @@ import CoreKit
self.state = (seed)
}

@inlinable public init(_ source: consuming Stdlib) {
self = source.base
}

@inlinable public consuming func stdlib() -> Stdlib {
Stdlib(self)
}

//=------------------------------------------------------------------------=
// MARK: Utilities
//=------------------------------------------------------------------------=
Expand All @@ -50,4 +58,33 @@ import CoreKit
next = (next ^ (next &>> 27)) &* 0x94d049bb133111eb
return (next ^ (next &>> 31))
}

//*========================================================================*
// MARK: * Stdlib
//*========================================================================*

@frozen public struct Stdlib: Swift.RandomNumberGenerator {

//=--------------------------------------------------------------------=
// MARK: State
//=--------------------------------------------------------------------=

@usableFromInline var base: FuzzerInt

//=--------------------------------------------------------------------=
// MARK: Initializers
//=--------------------------------------------------------------------=

@inlinable init(_ base: consuming FuzzerInt) {
self.base = base
}

//=--------------------------------------------------------------------=
// MARK: Utilities
//=--------------------------------------------------------------------=

@inlinable public mutating func next() -> Swift.UInt64 {
Swift.UInt64(self.base.next(as: U64.self))
}
}
}
16 changes: 13 additions & 3 deletions Sources/RandomIntKit/RandomInt.swift
Original file line number Diff line number Diff line change
Expand Up @@ -19,20 +19,30 @@ import CoreKit
///
/// It uses Swift's `SystemRandomNumberGenerator`.
///
@frozen public struct RandomInt: Randomness, Sendable {
@frozen public struct RandomInt: Interoperable, Randomness, Sendable {

public typealias Stdlib = Swift.SystemRandomNumberGenerator

//=------------------------------------------------------------------------=
// MARK: State
//=------------------------------------------------------------------------=

@usableFromInline var base: SystemRandomNumberGenerator
@usableFromInline var base: Stdlib

//=------------------------------------------------------------------------=
// MARK: Initializers
//=------------------------------------------------------------------------=

@inlinable public init() {
self.base = SystemRandomNumberGenerator()
self.base = Stdlib()
}

@inlinable public init(_ source: consuming Stdlib) {
self.base = source
}

@inlinable public consuming func stdlib() -> Stdlib {
self.base
}

//=------------------------------------------------------------------------=
Expand Down
52 changes: 35 additions & 17 deletions Tests/RandomIntKitTests/FuzzerInt.swift
Original file line number Diff line number Diff line change
Expand Up @@ -21,32 +21,50 @@ final class FuzzerIntTests: XCTestCase {
// MARK: Tests
//=------------------------------------------------------------------------=

func testMetadata() {
Test().yay(FuzzerInt.self as Any is any Randomness.Type)
Test().yay(FuzzerInt.Stdlib.self as Any is any Swift.RandomNumberGenerator.Type)
}

func testSeeds() {
var randomness: FuzzerInt
var randomness = FuzzerInt(seed: 0)

func expect(_ expectation: U64, line: UInt = #line) {
var copy = randomness
var stdlibX = randomness.stdlib
var stdlibY = randomness.stdlib()

Test(line: line).same(randomness, copy)
Test(line: line).same(randomness .next(), (expectation), "normal")
Test(line: line).same(copy.stdlib.next(), UInt64(expectation), "stdlib modify")
Test(line: line).same(((stdlibX)).next(), UInt64(expectation), "stdlib mutating read")
Test(line: line).same(((stdlibY)).next(), UInt64(expectation), "stdlib consuming get")
Test(line: line).same(randomness, copy)
}

randomness = .init(seed: 0)
Test().same(randomness.next(), 16294208416658607535)
Test().same(randomness.next(), 07960286522194355700)
Test().same(randomness.next(), 00487617019471545679)
Test().same(randomness.next(), 17909611376780542444)
expect(16294208416658607535)
expect(07960286522194355700)
expect(00487617019471545679)
expect(17909611376780542444)

randomness = .init(seed: 1)
Test().same(randomness.next(), 10451216379200822465)
Test().same(randomness.next(), 13757245211066428519)
Test().same(randomness.next(), 17911839290282890590)
Test().same(randomness.next(), 08196980753821780235)
expect(10451216379200822465)
expect(13757245211066428519)
expect(17911839290282890590)
expect(08196980753821780235)

randomness = .init(seed: ~1)
Test().same(randomness.next(), 17519071339639777313)
Test().same(randomness.next(), 13427082724269423081)
Test().same(randomness.next(), 15047954047655532813)
Test().same(randomness.next(), 02229658653670313015)
expect(17519071339639777313)
expect(13427082724269423081)
expect(15047954047655532813)
expect(02229658653670313015)

randomness = .init(seed: ~0)
Test().same(randomness.next(), 16490336266968443936)
Test().same(randomness.next(), 16834447057089888969)
Test().same(randomness.next(), 04048727598324417001)
Test().same(randomness.next(), 07862637804313477842)
expect(16490336266968443936)
expect(16834447057089888969)
expect(04048727598324417001)
expect(07862637804313477842)

randomness = .init(seed: 0)
var unique = Set<U64>()
Expand Down
28 changes: 28 additions & 0 deletions Tests/RandomIntKitTests/RandomInt.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
//=----------------------------------------------------------------------------=
// This source file is part of the Ultimathnum open source project.
//
// Copyright (c) 2023 Oscar Byström Ericsson
// Licensed under Apache License, Version 2.0
//
// See http://www.apache.org/licenses/LICENSE-2.0 for license information.
//=----------------------------------------------------------------------------=

import CoreKit
import RandomIntKit
import TestKit

//*============================================================================*
// MARK: * Random Int
//*============================================================================*

final class RandomIntTests: XCTestCase {

//=------------------------------------------------------------------------=
// MARK: Tests
//=------------------------------------------------------------------------=

func testMetadata() {
Test().yay(RandomInt.self as Any is any Randomness.Type)
Test().yay(RandomInt.Stdlib.self as Any is any Swift.RandomNumberGenerator.Type)
}
}

0 comments on commit 9a18f27

Please sign in to comment.