Here's the current implementation of index(before:):
extension ZipLongest2Collection: BidirectionalCollection, RandomAccessCollection where
Collection1: RandomAccessCollection, Collection2: RandomAccessCollection {
@inlinable public func index (before index: Index) -> Index {
switch (index.index1, index.index2) {
case (collection1.startIndex, collection2.startIndex):
preconditionFailure("Can't decrement beyond startIndex")
case (let index1, collection2.endIndex) where
collection1.distance(from: collection1.startIndex, to: index1) >
collection2.distance(from: collection2.startIndex, to: collection2.endIndex):
return Index(collection1.index(before: index1), collection2.endIndex)
case (collection1.endIndex, let index2) where
collection2.distance(from: collection2.startIndex, to: index2) >
collection1.distance(from: collection1.startIndex, to: collection1.endIndex):
return Index(collection1.endIndex, collection2.index(before: index2))
case (collection1.startIndex, _), (_, collection2.startIndex):
preconditionFailure("Can't decrement beyond startIndex")
case let (index1, index2):
return Index(collection1.index(before: index1), collection2.index(before: index2))
}
}
}
To answer your question:
typealias Index = ZipLongest2Collection<[Int], [Int]>.Index
let xs = zipLongest([Int](), [0, 1]) // (Or zip(longest:_:), still undecided.)
assert(xs.endIndex == Index(0, 2))
assert(xs.index(before: xs.endIndex) == Index(0, 1))
assert(xs.index(before: xs.index(before: xs.endIndex)) == xs.startIndex)
I'll post a repo containing a Swift package with the implementation and unit tests later today so people can follow along and play with (and poke holes in) it.