Avatar
@swift-4.2.4 protocol AnyEquatableBox { func _unbox<T: Equatable>() -> T? func _equals(to box: AnyEquatableBox) -> Bool? } struct ConcreteEquatableBox<Base: Equatable>: AnyEquatableBox { var base: Base init(_ base: Base) { self.base = base } func _unbox<T>() -> T? where T : Equatable { return ((self as AnyEquatableBox) as? ConcreteEquatableBox<T>)?.base } func _equals(to box: AnyEquatableBox) -> Bool? { guard let rhs: Base = box._unbox() else { return nil } return base == rhs } } struct AnyEquatable: Equatable { var box: AnyEquatableBox init<E>(_ base: E) where E: Equatable { box = ConcreteEquatableBox(base) } static func == (lhs: AnyEquatable, rhs: AnyEquatable) -> Bool { return lhs.box._equals(to: rhs.box) ?? false } } class Animal: Equatable { static func == (lhs: Animal, rhs: Animal) -> Bool { return lhs === rhs } } class Cat: Animal { } let cat1 = Cat() let cat2 = cat1 as Animal assert(AnyEquatable(cat1) == AnyEquatable(cat2))