Skip to content

Instantly share code, notes, and snippets.

@jayrhynas
Last active March 14, 2017 18:13
Show Gist options
  • Save jayrhynas/d65bf917d83fdc227c8a1aecf398dfae to your computer and use it in GitHub Desktop.
Save jayrhynas/d65bf917d83fdc227c8a1aecf398dfae to your computer and use it in GitHub Desktop.
zip gyb + example
%{
arities = range(3, int(maxArity) + 1)
def iterateWith(str, sep):
return sep.join([str.format(i) for i in indexes])
}%
%for arity in arities:
%indexes = range(1, arity + 1)
// MARK: - zip${arity} implemenetation
public struct Zip${arity}Iterator<${iterateWith("Iterator{0}: IteratorProtocol", ", ")}> : IteratorProtocol {
public typealias Element = (${iterateWith("Iterator{0}.Element", ", ")})
${iterateWith("private var itr{0}: Iterator{0}", "\n")}
private var done = false
fileprivate init(${iterateWith("_ itr{0}: Iterator{0}", ", ")}) {
${iterateWith("self.itr{0} = itr{0}", "\n")}
}
public mutating func next() -> Element? {
if !done, ${iterateWith("let e{0} = itr{0}.next()", ", ")} {
return (${iterateWith("e{0}", ", ")})
}
done = true
return nil
}
}
public struct Zip${arity}Sequence<${iterateWith("Sequence{0}: Sequence", ", ")}> : Sequence {
${iterateWith("public typealias Stream{0} = Sequence{0}.Iterator", "\n")}
public typealias Iterator = Zip${arity}Iterator<${iterateWith("Stream{0}", ", ")}>
${iterateWith("private var seq{0}: Sequence{0}", "\n")}
fileprivate init(${iterateWith("_ seq{0}: Sequence{0}", ", ")}) {
${iterateWith("self.seq{0} = seq{0}", "\n")}
}
public func makeIterator() -> Iterator {
return Zip${arity}Iterator(${iterateWith("self.seq{0}.makeIterator()", ", ")})
}
}
public func zip<${iterateWith("Sequence{0}: Sequence", ", ")}>(${iterateWith("_ seq{0}: Sequence{0}", ", ")}) -> Zip${arity}Sequence<${iterateWith("Sequence{0}", ", ")}> {
return Zip${arity}Sequence(${iterateWith("seq{0}", ", ")})
}
%end
// MARK: - zip3 implemenetation
public struct Zip3Iterator<Iterator1: IteratorProtocol, Iterator2: IteratorProtocol, Iterator3: IteratorProtocol> : IteratorProtocol {
public typealias Element = (Iterator1.Element, Iterator2.Element, Iterator3.Element)
private var itr1: Iterator1
private var itr2: Iterator2
private var itr3: Iterator3
private var done = false
fileprivate init(_ itr1: Iterator1, _ itr2: Iterator2, _ itr3: Iterator3) {
self.itr1 = itr1
self.itr2 = itr2
self.itr3 = itr3
}
public mutating func next() -> Element? {
if !done, let e1 = itr1.next(), let e2 = itr2.next(), let e3 = itr3.next() {
return (e1, e2, e3)
}
done = true
return nil
}
}
public struct Zip3Sequence<Sequence1: Sequence, Sequence2: Sequence, Sequence3: Sequence> : Sequence {
public typealias Stream1 = Sequence1.Iterator
public typealias Stream2 = Sequence2.Iterator
public typealias Stream3 = Sequence3.Iterator
public typealias Iterator = Zip3Iterator<Stream1, Stream2, Stream3>
private var seq1: Sequence1
private var seq2: Sequence2
private var seq3: Sequence3
fileprivate init(_ seq1: Sequence1, _ seq2: Sequence2, _ seq3: Sequence3) {
self.seq1 = seq1
self.seq2 = seq2
self.seq3 = seq3
}
public func makeIterator() -> Iterator {
return Zip3Iterator(self.seq1.makeIterator(), self.seq2.makeIterator(), self.seq3.makeIterator())
}
}
public func zip<Sequence1: Sequence, Sequence2: Sequence, Sequence3: Sequence>(_ seq1: Sequence1, _ seq2: Sequence2, _ seq3: Sequence3) -> Zip3Sequence<Sequence1, Sequence2, Sequence3> {
return Zip3Sequence(seq1, seq2, seq3)
}
@jayrhynas
Copy link
Author

You can get gyb from the swift repo.

Execute the following, changing maxArity to whichever value you'd like:

python gyb.py --line-directive '' -DmaxArity=4 zip.swift.gyb > zip.swift

If you have sourcekitten installed (brew install sourcekitten), you can clean up the output:

sourcekitten format --file zip.swift

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment