Last active
July 17, 2020 09:33
-
-
Save dabrahams/c6368b58cd3d3ef9659d84ebe24d299c to your computer and use it in GitHub Desktop.
Motivation for non-public conformances providing public API
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
/// A collection formed by adapting some `Base` collection, typically | |
/// displaying some altered form of the base collection's behavior. | |
/// | |
/// Default implementations of all requirements are provided, forwarding their | |
/// implementations to the `Base` collection instance. | |
public protocol CollectionAdapter: Collection { | |
/// The type of the underlying collection being adapted. | |
associatedtype Base: Collection | |
/// The instance of the underlying collection being adapted. | |
var base: Base { get } | |
// Redeclarations of associated types allow us to attach defaults. | |
associatedtype Index = Base.Index | |
associatedtype Element = Base.Element | |
} | |
/// Default implementations depending on the `Index` type. | |
extension CollectionAdapter where Index == Base.Index { | |
public var startIndex: Index { base.startIndex } | |
public var endIndex: Index { base.endIndex } | |
public func index(after i: Index) -> Index { base.index(after: i) } | |
} | |
/// Default implementations depending on the `Index` and `Element` types. | |
extension CollectionAdapter where Index == Base.Index, Element == Base.Element { | |
public subscript(i: Index) -> Element { base[i] } | |
} | |
extension BidirectionalCollection | |
where Self: CollectionAdapter, | |
Base: BidirectionalCollection, Index == Base.Index | |
{ | |
public func index(before i: Index) -> Index { base.index(before: i) } | |
} | |
public struct FilterCollection<Base: Collection>: CollectionAdapter { | |
public typealias Index = Base.Index // https://bugs.swift.org/browse/SR-12923 | |
public var base: Base | |
var isIncluded: (Base.Element)->Bool // https://bugs.swift.org/browse/SR-12923 | |
private func advancedTillValid(_ i: Index) -> Index { | |
var j = i | |
while j != endIndex && !isIncluded(base[j]) { | |
j = base.index(after: j) | |
} | |
return j | |
} | |
public var startIndex: Index { | |
return advancedTillValid(base.startIndex) | |
} | |
public func index(after i: Index) -> Index { | |
return advancedTillValid(base.index(after: i)) | |
} | |
} | |
extension FilterCollection: BidirectionalCollection | |
where Base: BidirectionalCollection | |
{ | |
public func index(before i: Index) -> Index { | |
var j = base.index(before: i) | |
while !isIncluded(base[j]) { | |
if j == base.startIndex { return i } | |
j = base.index(before: j) | |
} | |
return j | |
} | |
} | |
public struct MapCollection<Base: Collection, Element>: CollectionAdapter, Collection { | |
public typealias Index = Base.Index // https://bugs.swift.org/browse/SR-12923 | |
public typealias Element = Element | |
public var base: Base | |
var mapping: (Base.Element)->Element | |
public subscript(_ i: Index) -> Element { mapping(base[i]) } | |
} | |
extension MapCollection: BidirectionalCollection | |
where Base: BidirectionalCollection {} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment