-
-
Save TellowKrinkle/d4f8d95e5a273eb8e48127f4f99b2392 to your computer and use it in GitHub Desktop.
Adjacent Pairs Sequence
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public struct AdjacentPairsSequence<Base: Sequence>: Sequence { | |
public typealias Element = (Base.Element, Base.Element) | |
let base: Base | |
public struct Iterator: IteratorProtocol { | |
var last: Base.Element? | |
var iter: Base.Iterator | |
init(_ iter: Base.Iterator) { | |
self.iter = iter | |
last = self.iter.next() | |
} | |
public mutating func next() -> Element? { | |
guard let oldLast = last else { return nil } | |
last = iter.next() | |
guard let newLast = last else { return nil } | |
return (oldLast, newLast) | |
} | |
} | |
public __consuming func makeIterator() -> Iterator { | |
return Iterator(base.makeIterator()) | |
} | |
public init(_ base: Base) { | |
self.base = base | |
} | |
} | |
extension AdjacentPairsSequence: Collection where Base: Collection { | |
public struct Index: Comparable { | |
public var first: Base.Index | |
public var second: Base.Index | |
public static func < (lhs: Index, rhs: Index) -> Bool { | |
return lhs.second < rhs.second | |
} | |
public static func == (lhs: Index, rhs: Index) -> Bool { | |
return lhs.second == rhs.second | |
} | |
} | |
public var startIndex: Index { | |
let first = base.startIndex | |
guard first != base.endIndex else { return Index(first: first, second: first) } | |
return Index(first: first, second: base.index(after: first)) | |
} | |
public var endIndex: Index { | |
let end = base.endIndex | |
return Index(first: end, second: end) | |
} | |
public subscript(index: Index) -> Element { | |
return (base[index.first], base[index.second]) | |
} | |
public func index(after i: Index) -> Index { | |
return Index(first: i.second, second: base.index(after: i.second)) | |
} | |
} | |
extension AdjacentPairsSequence: BidirectionalCollection where Base: BidirectionalCollection { | |
public var endIndex: Index { | |
let end = base.endIndex | |
guard end != base.startIndex else { return Index(first: end, second: end) } | |
return Index(first: base.index(before: end), second: end) | |
} | |
public func index(before i: Index) -> Index { | |
return Index(first: base.index(before: i.first), second: i.first) | |
} | |
} | |
extension Sequence { | |
var adjacentPairs: AdjacentPairsSequence<Self> { | |
return AdjacentPairsSequence(self) | |
} | |
} | |
func printEndIndex<C: BidirectionalCollection>(_ c: C) { | |
print("End index as viewed from a generic function: \(c.endIndex)") | |
} | |
let col = [1, 2, 3].adjacentPairs | |
print("End index from a non-generic context: \(col.endIndex)") | |
printEndIndex(col) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment