// Type-Erasure // - seealso: [AnyIterator](https://github.com/apple/swift/blob/2fe4254cb712fa101a220f95b6ade8f99f43dc74/stdlib/public/core/ExistentialCollection.swift.gyb#L45) // MARK: remove `Equatable` if not needed public protocol Protocol: Equatable { // MARK: `Protocol` requirements associatedtype AssociatedType func methodOfProtocol() -> Self.AssociatedType } public struct AnyProtocol<AssociatedType> { private let _box: _AnyProtocolBoxBase<AssociatedType> public init<T: Protocol>(_ base: T) where T.AssociatedType == AssociatedType { let box = _ProtocolBox(base) self._box = box // MARK: remove if `Protocol` does not adopt `Equatable` self._isEqual = { box._base == ($0._box as? _ProtocolBox<T>)?._base } } // MARK: remove if `Protocol` does not adopt `Equatable` private let _isEqual: (AnyProtocol) -> Bool public static func == (lhs: AnyProtocol<AssociatedType>, rhs: AnyProtocol<AssociatedType>) -> Bool { return lhs._isEqual(rhs) || rhs._isEqual(lhs) } } extension AnyProtocol: Protocol { // MARK: `Protocol` conformance public func methodOfProtocol() -> AssociatedType { return _box.methodOfProtocol() } } fileprivate class _AnyProtocolBoxBase<AssociatedType>: Protocol { @inline(never) private static func _abstract(file: StaticString = #file, line: UInt = #line) -> Never { fatalError("Method must be overridden!", file: file, line: line) } // MARK: remove if `Protocol` does not adopt `Equatable` @inlinable static func == (lhs: _AnyProtocolBoxBase<AssociatedType>, rhs: _AnyProtocolBoxBase<AssociatedType>) -> Bool { _abstract() } // MARK: `Protocol` conformance @inlinable internal func methodOfProtocol() -> AssociatedType { Self._abstract() } } fileprivate final class _ProtocolBox<Base: Protocol>: _AnyProtocolBoxBase<Base.AssociatedType> { internal var _base: Base internal init(_ base: Base) { self._base = base } // MARK: `Protocol` conformance override func methodOfProtocol() -> Base.AssociatedType { return _base.methodOfProtocol() } }