Created
March 15, 2020 20:07
-
-
Save jenox/1175c767595027ad9e8781ae59ff0f98 to your computer and use it in GitHub Desktop.
Conditional conformances and dynamic dispatch
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
import Swift | |
struct ConditionalWrapper<Base> where Base: Sequence { | |
fileprivate let base: Base | |
} | |
extension Sequence { | |
func conditionalWrapper() -> ConditionalWrapper<Self> { | |
return ConditionalWrapper(base: self) | |
} | |
} | |
extension ConditionalWrapper: Sequence { | |
typealias Element = Base.Element | |
typealias Iterator = AnyIterator<Element> | |
func makeIterator() -> AnyIterator<Element> { | |
print("Sequence makeIterator") | |
return AnyIterator(self.base.makeIterator()) | |
} | |
} | |
extension ConditionalWrapper: Collection where Base: Collection { | |
var startIndex: Base.Index { return self.base.startIndex } | |
var endIndex: Base.Index { return self.base.endIndex } | |
func index(after index: Base.Index) -> Base.Index { return self.base.index(after: index) } | |
subscript(position: Base.Index) -> Base.Element { return self.base[position] } | |
func makeIterator() -> AnyIterator<Element> { | |
print("Collection makeIterator") | |
return AnyIterator(IndexingIterator(_elements: self)) | |
} | |
} | |
private func sequence<T>(_ x: T) where T: Sequence { | |
_ = x.makeIterator() | |
} | |
private func unidirectional<T>(_ x: T) where T: Collection { | |
_ = x.makeIterator() | |
} | |
func test_conditional() { | |
let x = [1,2,3,4].conditionalWrapper() | |
sequence(x) // prints "Sequence makeIterator" | |
unidirectional(x) // prints "Sequence makeIterator" (unexpected) | |
_ = x.makeIterator() // prints "Collection makeIterator" | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment