Last active
August 25, 2016 17:39
-
-
Save MainasuK/66a707046ba3abdd8eb6695ab3872a2e to your computer and use it in GitHub Desktop.
List: Collection
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
//: The up to date code snippet (Xcode 8 beta 6) for List which comforms Collection — *Advanced Swift* | |
import UIKit | |
private enum ListNode<Element> { | |
case end | |
indirect case node(Element, next: ListNode<Element>) | |
func cons(x: Element) -> ListNode<Element> { | |
return .node(x, next: self) | |
} | |
} | |
public struct ListIndex<Element>: Comparable { | |
fileprivate let node: ListNode<Element> | |
fileprivate let tag: Int | |
static public func == <T>(_ lhs: ListIndex<T>, _ rhs: ListIndex<T>) -> Bool { | |
return lhs.tag == rhs.tag | |
} | |
static public func < <T>(_ lhs: ListIndex<T>, _ rhs: ListIndex<T>) -> Bool { | |
return lhs.tag < rhs.tag | |
} | |
} | |
public struct List<Element>: Collection { | |
public typealias Index = ListIndex<Element> | |
public var startIndex: Index | |
public var endIndex: Index | |
public subscript(_ idx: Index) -> Element { | |
switch idx.node { | |
case .end: | |
fatalError("Subscript out of range") | |
case .node(let x, _): | |
return x | |
} | |
} | |
public func index(after i: Index) -> Index { | |
switch i.node { | |
case .node(_, let next): | |
return ListIndex(node: next, tag: i.tag.distance(to: -1)) | |
case .end: | |
fatalError("Cannot increment endIndex") | |
} | |
} | |
} | |
extension List: ExpressibleByArrayLiteral { | |
public init(arrayLiteral elements: Element...) { | |
startIndex = ListIndex(node: elements.reversed().reduce(.end) { $0.cons(x: $1) }, tag: elements.count) | |
endIndex = ListIndex(node: .end, tag: 0) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment