Skip to content

Merge the zip2 and zip3 implementations #221

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Oct 20, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 26 additions & 9 deletions Sources/AsyncAlgorithms/Zip/AsyncZip2Sequence.swift
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ public func zip<Base1: AsyncSequence, Base2: AsyncSequence>(
/// An asynchronous sequence that concurrently awaits values from two `AsyncSequence` types
/// and emits a tuple of the values.
public struct AsyncZip2Sequence<Base1: AsyncSequence, Base2: AsyncSequence>: AsyncSequence
where Base1: Sendable, Base1.Element: Sendable, Base2: Sendable, Base2.Element: Sendable {
where Base1: Sendable, Base1.Element: Sendable, Base2: Sendable, Base2.Element: Sendable {
public typealias Element = (Base1.Element, Base2.Element)
public typealias AsyncIterator = Iterator

Expand All @@ -34,21 +34,38 @@ where Base1: Sendable, Base1.Element: Sendable, Base2: Sendable, Base2.Element:
}

public func makeAsyncIterator() -> AsyncIterator {
Iterator(
base1,
base2
)
Iterator(storage: .init(self.base1, self.base2, nil))
}

public struct Iterator: AsyncIteratorProtocol {
let runtime: Zip2Runtime<Base1, Base2>
final class InternalClass {
private let storage: ZipStorage<Base1, Base2, Base2>

init(_ base1: Base1, _ base2: Base2) {
self.runtime = Zip2Runtime(base1, base2)
fileprivate init(storage: ZipStorage<Base1, Base2, Base2>) {
self.storage = storage
}

deinit {
self.storage.iteratorDeinitialized()
}

func next() async rethrows -> Element? {
guard let element = try await self.storage.next() else {
return nil
}

return (element.0, element.1)
}
}

let internalClass: InternalClass

fileprivate init(storage: ZipStorage<Base1, Base2, Base2>) {
self.internalClass = InternalClass(storage: storage)
}

public mutating func next() async rethrows -> Element? {
try await self.runtime.next()
try await self.internalClass.next()
}
}
}
36 changes: 27 additions & 9 deletions Sources/AsyncAlgorithms/Zip/AsyncZip3Sequence.swift
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ public func zip<Base1: AsyncSequence, Base2: AsyncSequence, Base3: AsyncSequence
/// An asynchronous sequence that concurrently awaits values from three `AsyncSequence` types
/// and emits a tuple of the values.
public struct AsyncZip3Sequence<Base1: AsyncSequence, Base2: AsyncSequence, Base3: AsyncSequence>: AsyncSequence
where Base1: Sendable, Base1.Element: Sendable, Base2: Sendable, Base2.Element: Sendable, Base3: Sendable, Base3.Element: Sendable {
where Base1: Sendable, Base1.Element: Sendable, Base2: Sendable, Base2.Element: Sendable, Base3: Sendable, Base3.Element: Sendable {
public typealias Element = (Base1.Element, Base2.Element, Base3.Element)
public typealias AsyncIterator = Iterator

Expand All @@ -37,22 +37,40 @@ where Base1: Sendable, Base1.Element: Sendable, Base2: Sendable, Base2.Element:
}

public func makeAsyncIterator() -> AsyncIterator {
Iterator(
base1,
base2,
base3
Iterator(storage: .init(self.base1, self.base2, self.base3)
)
}

public struct Iterator: AsyncIteratorProtocol {
let runtime: Zip3Runtime<Base1, Base2, Base3>
final class InternalClass {
private let storage: ZipStorage<Base1, Base2, Base3>

init(_ base1: Base1, _ base2: Base2, _ base3: Base3) {
self.runtime = Zip3Runtime(base1, base2, base3)
fileprivate init(storage: ZipStorage<Base1, Base2, Base3>) {
self.storage = storage
}

deinit {
self.storage.iteratorDeinitialized()
}

func next() async rethrows -> Element? {
guard let element = try await self.storage.next() else {
return nil
}

// This force unwrap is safe since there must be a third element.
return (element.0, element.1, element.2!)
}
}

let internalClass: InternalClass

fileprivate init(storage: ZipStorage<Base1, Base2, Base3>) {
self.internalClass = InternalClass(storage: storage)
}

public mutating func next() async rethrows -> Element? {
try await self.runtime.next()
try await self.internalClass.next()
}
}
}
212 changes: 0 additions & 212 deletions Sources/AsyncAlgorithms/Zip/Zip2Runtime.swift

This file was deleted.

Loading