Skip to content

Instantly share code, notes, and snippets.

@jenox
Created March 15, 2020 20:07
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jenox/1175c767595027ad9e8781ae59ff0f98 to your computer and use it in GitHub Desktop.
Save jenox/1175c767595027ad9e8781ae59ff0f98 to your computer and use it in GitHub Desktop.
Conditional conformances and dynamic dispatch
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