From 7f15d906e5ca88daf466c5530708f2af81d095ae Mon Sep 17 00:00:00 2001 From: Nikolai Vazquez Date: Wed, 2 Aug 2017 14:25:16 -0400 Subject: [PATCH 1/3] Create RandomBytesIterator type Allows for consuming and iterating over a RandomBytesGenerator without having to call randomBytes(). --- .../RandomBytesGenerator.swift | 38 ++++++++++++++++++- 1 file changed, 37 insertions(+), 1 deletion(-) diff --git a/Sources/RandomKit/Types/RandomGenerator/RandomBytesGenerator.swift b/Sources/RandomKit/Types/RandomGenerator/RandomBytesGenerator.swift index 6c21439..812c05f 100644 --- a/Sources/RandomKit/Types/RandomGenerator/RandomBytesGenerator.swift +++ b/Sources/RandomKit/Types/RandomGenerator/RandomBytesGenerator.swift @@ -26,7 +26,7 @@ // /// A type that specializes in generating random bytes in the form of a `Bytes` type. -public protocol RandomBytesGenerator: RandomGenerator { +public protocol RandomBytesGenerator: RandomGenerator, Sequence { /// A type that stores bytes within its own value. associatedtype Bytes @@ -34,6 +34,42 @@ public protocol RandomBytesGenerator: RandomGenerator { /// Returns random `Bytes`. mutating func randomBytes() -> Bytes + /// Returns an iterator over the elements of this sequence. + func makeIterator() -> RandomBytesIterator + +} + +/// An iterator over the `Byte`s of a `RandomBytesGenerator` source. +/// +/// ``` +/// func perform(with randomValue: UInt64) -> Bool { +/// ... +/// } +/// +/// for x in Xoroshiro.seeded { +/// guard perform(with: x) else { +/// break +/// } +/// ... +/// } +/// ``` +public struct RandomBytesIterator: IteratorProtocol { + + /// The source generator from which `next()` retrieves values. + public var source: Source + + /// Advances to the next element and returns it. + public mutating func next() -> Source.Bytes? { + return source.randomBytes() + } + +} + +extension RandomBytesGenerator { + /// Returns an iterator over the elements of this sequence. + public func makeIterator() -> RandomBytesIterator { + return RandomBytesIterator(source: self) + } } extension RandomBytesGenerator where Bytes == UInt64 { From b15dead9824be20619eeb9072dfea0503fce050e Mon Sep 17 00:00:00 2001 From: Nikolai Vazquez Date: Wed, 2 Aug 2017 15:48:24 -0400 Subject: [PATCH 2/3] Specify RandomBytesIterator for Swift < 3.1 --- Sources/RandomKit/Types/RandomGenerator/ChaCha.swift | 5 +++++ .../RandomKit/Types/RandomGenerator/MersenneTwister.swift | 5 +++++ Sources/RandomKit/Types/RandomGenerator/Xoroshiro.swift | 5 +++++ Sources/RandomKit/Types/RandomGenerator/Xorshift.swift | 5 +++++ Sources/RandomKit/Types/RandomGenerator/XorshiftStar.swift | 5 +++++ 5 files changed, 25 insertions(+) diff --git a/Sources/RandomKit/Types/RandomGenerator/ChaCha.swift b/Sources/RandomKit/Types/RandomGenerator/ChaCha.swift index 0e99299..d5ab2d4 100644 --- a/Sources/RandomKit/Types/RandomGenerator/ChaCha.swift +++ b/Sources/RandomKit/Types/RandomGenerator/ChaCha.swift @@ -34,6 +34,11 @@ /// [3]: https://doc.rust-lang.org/rand/rand/chacha/struct.ChaChaRng.html public struct ChaCha: RandomBytesGenerator, Seedable, SeedableFromSequence, SeedableFromRandomGenerator { + // Inferred in Swift 3.1+ + #if !swift(>=3.1) + public typealias Iterator = RandomBytesIterator + #endif + /// The seed type. public typealias Seed = [UInt32] diff --git a/Sources/RandomKit/Types/RandomGenerator/MersenneTwister.swift b/Sources/RandomKit/Types/RandomGenerator/MersenneTwister.swift index b642ebf..d4f0b45 100644 --- a/Sources/RandomKit/Types/RandomGenerator/MersenneTwister.swift +++ b/Sources/RandomKit/Types/RandomGenerator/MersenneTwister.swift @@ -44,6 +44,11 @@ /// [MT]: https://en.wikipedia.org/wiki/Mersenne_Twister public struct MersenneTwister: RandomBytesGenerator, Seedable, SeedableFromRandomGenerator { + // Inferred in Swift 3.1+ + #if !swift(>=3.1) + public typealias Iterator = RandomBytesIterator + #endif + /// The number of `UInt64` values in a `_State`. private static let _stateCount: Int = 312 diff --git a/Sources/RandomKit/Types/RandomGenerator/Xoroshiro.swift b/Sources/RandomKit/Types/RandomGenerator/Xoroshiro.swift index 645a05f..85d2399 100644 --- a/Sources/RandomKit/Types/RandomGenerator/Xoroshiro.swift +++ b/Sources/RandomKit/Types/RandomGenerator/Xoroshiro.swift @@ -47,6 +47,11 @@ /// [2]: http://xoroshiro.di.unimi.it/xoroshiro128plus.c public struct Xoroshiro: RandomBytesGenerator, Seedable, SeedableFromRandomGenerator { + // Inferred in Swift 3.1+ + #if !swift(>=3.1) + public typealias Iterator = RandomBytesIterator + #endif + /// A default global instance seeded with `DeviceRandom.default`. public static var `default` = seeded diff --git a/Sources/RandomKit/Types/RandomGenerator/Xorshift.swift b/Sources/RandomKit/Types/RandomGenerator/Xorshift.swift index e0f1c2c..66179d6 100644 --- a/Sources/RandomKit/Types/RandomGenerator/Xorshift.swift +++ b/Sources/RandomKit/Types/RandomGenerator/Xorshift.swift @@ -33,6 +33,11 @@ /// [2]: https://doc.rust-lang.org/rand/rand/struct.XorShiftRng.html public struct Xorshift: RandomBytesGenerator, Seedable, SeedableFromRandomGenerator { + // Inferred in Swift 3.1+ + #if !swift(>=3.1) + public typealias Iterator = RandomBytesIterator + #endif + /// A default global instance seeded with `DeviceRandom.default`. public static var `default` = seeded diff --git a/Sources/RandomKit/Types/RandomGenerator/XorshiftStar.swift b/Sources/RandomKit/Types/RandomGenerator/XorshiftStar.swift index e890d3d..7dbe2dd 100644 --- a/Sources/RandomKit/Types/RandomGenerator/XorshiftStar.swift +++ b/Sources/RandomKit/Types/RandomGenerator/XorshiftStar.swift @@ -30,6 +30,11 @@ /// [1]: http://xoroshiro.di.unimi.it/xorshift1024star.c public struct XorshiftStar: RandomBytesGenerator, Seedable, SeedableFromRandomGenerator { + // Inferred in Swift 3.1+ + #if !swift(>=3.1) + public typealias Iterator = RandomBytesIterator + #endif + /// The seed type. public typealias Seed = ( UInt64, UInt64, UInt64, UInt64, From 829448c248702f0e603a5f75372a8b66f310b8bd Mon Sep 17 00:00:00 2001 From: Nikolai Vazquez Date: Wed, 2 Aug 2017 18:44:30 -0400 Subject: [PATCH 3/3] Make RandomBytesIterator only for Swift 3.1+ --- .../RandomKit/Types/RandomGenerator/ChaCha.swift | 5 ----- .../Types/RandomGenerator/MersenneTwister.swift | 5 ----- .../RandomGenerator/RandomBytesGenerator.swift | 15 ++++++++++++++- .../Types/RandomGenerator/Xoroshiro.swift | 5 ----- .../Types/RandomGenerator/Xorshift.swift | 5 ----- .../Types/RandomGenerator/XorshiftStar.swift | 5 ----- 6 files changed, 14 insertions(+), 26 deletions(-) diff --git a/Sources/RandomKit/Types/RandomGenerator/ChaCha.swift b/Sources/RandomKit/Types/RandomGenerator/ChaCha.swift index d5ab2d4..0e99299 100644 --- a/Sources/RandomKit/Types/RandomGenerator/ChaCha.swift +++ b/Sources/RandomKit/Types/RandomGenerator/ChaCha.swift @@ -34,11 +34,6 @@ /// [3]: https://doc.rust-lang.org/rand/rand/chacha/struct.ChaChaRng.html public struct ChaCha: RandomBytesGenerator, Seedable, SeedableFromSequence, SeedableFromRandomGenerator { - // Inferred in Swift 3.1+ - #if !swift(>=3.1) - public typealias Iterator = RandomBytesIterator - #endif - /// The seed type. public typealias Seed = [UInt32] diff --git a/Sources/RandomKit/Types/RandomGenerator/MersenneTwister.swift b/Sources/RandomKit/Types/RandomGenerator/MersenneTwister.swift index d4f0b45..b642ebf 100644 --- a/Sources/RandomKit/Types/RandomGenerator/MersenneTwister.swift +++ b/Sources/RandomKit/Types/RandomGenerator/MersenneTwister.swift @@ -44,11 +44,6 @@ /// [MT]: https://en.wikipedia.org/wiki/Mersenne_Twister public struct MersenneTwister: RandomBytesGenerator, Seedable, SeedableFromRandomGenerator { - // Inferred in Swift 3.1+ - #if !swift(>=3.1) - public typealias Iterator = RandomBytesIterator - #endif - /// The number of `UInt64` values in a `_State`. private static let _stateCount: Int = 312 diff --git a/Sources/RandomKit/Types/RandomGenerator/RandomBytesGenerator.swift b/Sources/RandomKit/Types/RandomGenerator/RandomBytesGenerator.swift index 812c05f..1f34e4e 100644 --- a/Sources/RandomKit/Types/RandomGenerator/RandomBytesGenerator.swift +++ b/Sources/RandomKit/Types/RandomGenerator/RandomBytesGenerator.swift @@ -25,8 +25,15 @@ // THE SOFTWARE. // +#if swift(>=3.1) +/// A workaround to make `RandomBytesGenerator` a `Sequence` for Swift 3.1+. +public typealias _RandomBytesGeneratorComposition = RandomGenerator & Sequence +#else +public typealias _RandomBytesGeneratorComposition = RandomGenerator +#endif + /// A type that specializes in generating random bytes in the form of a `Bytes` type. -public protocol RandomBytesGenerator: RandomGenerator, Sequence { +public protocol RandomBytesGenerator: _RandomBytesGeneratorComposition { /// A type that stores bytes within its own value. associatedtype Bytes @@ -34,11 +41,15 @@ public protocol RandomBytesGenerator: RandomGenerator, Sequence { /// Returns random `Bytes`. mutating func randomBytes() -> Bytes + #if swift(>=3.1) /// Returns an iterator over the elements of this sequence. func makeIterator() -> RandomBytesIterator + #endif } +#if swift(>=3.1) + /// An iterator over the `Byte`s of a `RandomBytesGenerator` source. /// /// ``` @@ -72,6 +83,8 @@ extension RandomBytesGenerator { } } +#endif + extension RandomBytesGenerator where Bytes == UInt64 { /// Generates a random unsigned 64-bit integer. diff --git a/Sources/RandomKit/Types/RandomGenerator/Xoroshiro.swift b/Sources/RandomKit/Types/RandomGenerator/Xoroshiro.swift index 85d2399..645a05f 100644 --- a/Sources/RandomKit/Types/RandomGenerator/Xoroshiro.swift +++ b/Sources/RandomKit/Types/RandomGenerator/Xoroshiro.swift @@ -47,11 +47,6 @@ /// [2]: http://xoroshiro.di.unimi.it/xoroshiro128plus.c public struct Xoroshiro: RandomBytesGenerator, Seedable, SeedableFromRandomGenerator { - // Inferred in Swift 3.1+ - #if !swift(>=3.1) - public typealias Iterator = RandomBytesIterator - #endif - /// A default global instance seeded with `DeviceRandom.default`. public static var `default` = seeded diff --git a/Sources/RandomKit/Types/RandomGenerator/Xorshift.swift b/Sources/RandomKit/Types/RandomGenerator/Xorshift.swift index 66179d6..e0f1c2c 100644 --- a/Sources/RandomKit/Types/RandomGenerator/Xorshift.swift +++ b/Sources/RandomKit/Types/RandomGenerator/Xorshift.swift @@ -33,11 +33,6 @@ /// [2]: https://doc.rust-lang.org/rand/rand/struct.XorShiftRng.html public struct Xorshift: RandomBytesGenerator, Seedable, SeedableFromRandomGenerator { - // Inferred in Swift 3.1+ - #if !swift(>=3.1) - public typealias Iterator = RandomBytesIterator - #endif - /// A default global instance seeded with `DeviceRandom.default`. public static var `default` = seeded diff --git a/Sources/RandomKit/Types/RandomGenerator/XorshiftStar.swift b/Sources/RandomKit/Types/RandomGenerator/XorshiftStar.swift index 7dbe2dd..e890d3d 100644 --- a/Sources/RandomKit/Types/RandomGenerator/XorshiftStar.swift +++ b/Sources/RandomKit/Types/RandomGenerator/XorshiftStar.swift @@ -30,11 +30,6 @@ /// [1]: http://xoroshiro.di.unimi.it/xorshift1024star.c public struct XorshiftStar: RandomBytesGenerator, Seedable, SeedableFromRandomGenerator { - // Inferred in Swift 3.1+ - #if !swift(>=3.1) - public typealias Iterator = RandomBytesIterator - #endif - /// The seed type. public typealias Seed = ( UInt64, UInt64, UInt64, UInt64,