Skip to content

Commit

Permalink
Create SeedableFromSequence protocol
Browse files Browse the repository at this point in the history
  • Loading branch information
nvzqz committed May 4, 2017
1 parent 3caa9ff commit 7109437
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 18 deletions.
24 changes: 7 additions & 17 deletions Sources/RandomKit/Types/RandomGenerator/ChaCha.swift
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,13 @@
/// [1]: http://cr.yp.to/chacha.html
/// [2]: https://en.wikipedia.org/wiki/Salsa20#ChaCha_variant
/// [3]: https://doc.rust-lang.org/rand/rand/chacha/struct.ChaChaRng.html
public struct ChaCha: RandomBytesGenerator, Seedable, SeedableFromRandomGenerator {
public struct ChaCha: RandomBytesGenerator, Seedable, SeedableFromSequence, SeedableFromRandomGenerator {

/// The seed type.
public typealias Seed = UnsafeBufferPointer<UInt32>

/// The seed sequence's element type.
public typealias SeedSequenceElement = UInt32

private typealias _State = _Array16<UInt32>

Expand Down Expand Up @@ -79,12 +85,6 @@ public struct ChaCha: RandomBytesGenerator, Seedable, SeedableFromRandomGenerato
self._index = _index
}

/// Creates an instance from `seed`.
public init(seed: UnsafeBufferPointer<UInt32>) {
self = ._empty
reseed(with: seed)
}

/// Creates an instance from `seed`.
public init<S: Sequence>(seed: S) where S.Iterator.Element == UInt32 {
self = ._empty
Expand Down Expand Up @@ -128,10 +128,6 @@ public struct ChaCha: RandomBytesGenerator, Seedable, SeedableFromRandomGenerato
}
}

private mutating func _reseed<S: Sequence>(with seed: S) where S.Iterator.Element == UInt32 {
reseed(with: seed)
}

/// Sets the internal 128-bit counter.
public mutating func setCounter(low: UInt64, high: UInt64) {
_state.12 = UInt32(truncatingBitPattern: low)
Expand All @@ -141,12 +137,6 @@ public struct ChaCha: RandomBytesGenerator, Seedable, SeedableFromRandomGenerato
_index = ChaCha._stateCount
}

/// Reseeds `self` with `seed`.
public mutating func reseed(with seed: UnsafeBufferPointer<UInt32>) {
// Required to specify method with same name.
_reseed(with: seed)
}

/// Reseeds `self` with `seed`.
public mutating func reseed<S: Sequence>(with seed: S) where S.Iterator.Element == UInt32 {
_reset()
Expand Down
48 changes: 47 additions & 1 deletion Sources/RandomKit/Types/RandomGenerator/Seedable.swift
Original file line number Diff line number Diff line change
Expand Up @@ -40,14 +40,34 @@ public protocol Seedable {
}

extension Seedable {

/// Reseeds `self` with `seed`.
public mutating func reseed(with seed: Seed) {
self = Self(seed: seed)
}
}

/// A type that can be seeded by a sequence.
public protocol SeedableFromSequence {

/// The seed sequence's element type.
associatedtype SeedSequenceElement

/// Creates an instance from `seed`.
init<S: Sequence>(seed: S) where S.Iterator.Element == SeedSequenceElement

/// Reseeds `self` with `seed`.
mutating func reseed<S: Sequence>(with seed: S) where S.Iterator.Element == SeedSequenceElement

}


extension SeedableFromSequence {
/// Reseeds `self` with `seed`.
public mutating func reseed<S: Sequence>(with sequence: S) where S.Iterator.Element == SeedSequenceElement {
self = Self(seed: sequence)
}
}

/// A type that can be seeded by another `randomGenerator`.
public protocol SeedableFromRandomGenerator: Random {

Expand Down Expand Up @@ -113,3 +133,29 @@ extension Seedable where Self: SeedableFromRandomGenerator, Seed: Random {
}

}

extension Seedable where Self: SeedableFromSequence, Seed: Sequence, Seed.Iterator.Element == Self.SeedSequenceElement {

@inline(__always)
private init<S: Sequence>(_seed: S) where S.Iterator.Element == SeedSequenceElement {
self.init(seed: _seed)
}

/// Creates an instance from `seed`.
public init(seed: Seed) {
// Required to specify initializer with same argument.
self.init(_seed: seed)
}

@inline(__always)
private mutating func _reseed<S: Sequence>(with _seed: S) where S.Iterator.Element == SeedSequenceElement {
reseed(with: _seed)
}

/// Reseeds `self` with `seed`.
public mutating func reseed(with seed: Seed) {
// Required to specify method with same name.
_reseed(with: seed)
}

}

0 comments on commit 7109437

Please sign in to comment.