Skip to content

Instantly share code, notes, and snippets.

@klundberg
Last active February 24, 2018 23:13
Show Gist options
  • Save klundberg/f04bfdf837cc5d0e51196d00f0784be6 to your computer and use it in GitHub Desktop.
Save klundberg/f04bfdf837cc5d0e51196d00f0784be6 to your computer and use it in GitHub Desktop.
Potential Swift 4.1 implementation of conditional conformace to Collection for Optional<Collection>
public struct OptionalIndex<InnerIndex: Comparable> {
let inner: InnerIndex?
init(_ base: InnerIndex) {
inner = base
}
init() {
inner = nil
}
}
extension OptionalIndex: CustomStringConvertible {
public var description: String {
return String(describing: inner)
}
}
extension OptionalIndex: Comparable {
public static func < (lhs: OptionalIndex<InnerIndex>, rhs: OptionalIndex<InnerIndex>) -> Bool {
switch (lhs.inner, rhs.inner) {
case let (left?, right?): return left < right
case (_?, nil): return false
case (nil, _?): return true
case (nil, nil): return false
}
}
public static func == (lhs: OptionalIndex<InnerIndex>, rhs: OptionalIndex<InnerIndex>) -> Bool {
return lhs.inner == rhs.inner
}
}
extension Optional: Collection where Wrapped: Collection {
public typealias Element = Wrapped.Element
public typealias Index = OptionalIndex<Wrapped.Index>
public func index(after i: Index) -> Index {
switch (self, i.inner) {
case let (value?, index?):
return Index(value.index(after: index))
default:
return Index()
}
}
public subscript(position: Index) -> Element {
switch (self, position.inner) {
case let (value?, position?):
return value[position]
default:
preconditionFailure("Fatal error: Index out of range")
}
}
public var startIndex: Index {
switch self {
case let value?:
return Index(value.startIndex)
default:
return Index()
}
}
public var endIndex: Index {
switch self {
case let value?:
return Index(value.endIndex)
case nil:
return Index()
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment