Created
October 13, 2020 08:57
-
-
Save danielctull/2856fb53525810db1da898d0c1e098ac to your computer and use it in GitHub Desktop.
Another idea for the intersperse index.
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
extension Intersperse: Collection where Base: Collection { | |
public struct Index: Comparable { | |
enum Representation { | |
case end | |
case element(Base.Index) | |
case separator(Base.Index) | |
} | |
let representation: Representation | |
public static func == (lhs: Index, rhs: Index) -> Bool { | |
switch (lhs.representation, rhs.representation) { | |
case (.end, .end): return true | |
case let (.element(lhs), .element(rhs)): return lhs == rhs | |
case let (.separator(lhs), .separator(rhs)): return lhs == rhs | |
default: return false | |
} | |
} | |
public static func < (lhs: Index, rhs: Index) -> Bool { | |
switch (lhs.representation, rhs.representation) { | |
case (.end, .end): return false | |
case (_, .end): return true | |
case (.end, _): return false | |
case let (.element(lhs), .element(rhs)): return lhs < rhs | |
case let (.element(lhs), .separator(rhs)): return lhs <= rhs | |
case let (.separator(lhs), .separator(rhs)): return lhs < rhs | |
case let (.separator(lhs), .element(rhs)): return lhs < rhs | |
} | |
} | |
} | |
public var count: Int { | |
Swift.max(base.count * 2 - 1, 0) | |
} | |
public var startIndex: Index { | |
Index(representation: .element(base.startIndex)) | |
} | |
public var endIndex: Index { | |
Index(representation: .end) | |
} | |
public func index(after i: Index) -> Index { | |
switch i.representation { | |
case .element(let index) where base.index(after: index) < base.endIndex: | |
return Index(representation: .separator(index)) | |
case .element: | |
return endIndex | |
case .end: | |
fatalError() | |
case .separator(let index): | |
return Index(representation: .element(base.index(after: index))) | |
} | |
} | |
public subscript(position: Index) -> Element { | |
switch position.representation { | |
case .end: fatalError() | |
case .element(let index): return base[index] | |
case .separator: return separator | |
} | |
} | |
} | |
extension Intersperse: BidirectionalCollection | |
where Base: BidirectionalCollection | |
{ | |
public func index(before i: Index) -> Index { | |
switch i.representation { | |
case .end: | |
return Index(representation: .element(base.index(before: base.endIndex))) | |
case .element(let index): | |
return Index(representation: .separator(base.index(before: index))) | |
case .separator(let index): | |
return Index(representation: .element(index)) | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment