Skip to content

Instantly share code, notes, and snippets.

@nubbel
Forked from dabrahams/AnyComparable.swift
Last active August 28, 2017 07:33
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nubbel/d7f74d975961fb1550b808f5046008bf to your computer and use it in GitHub Desktop.
Save nubbel/d7f74d975961fb1550b808f5046008bf to your computer and use it in GitHub Desktop.
Faux Equatable and Comparable Existentials
fileprivate class AnyEquatableBase {
func isEqual(to other: AnyEquatableBase) -> Bool {
fatalError("isEqual(to:) must be overridden in subclass")
}
}
fileprivate final class AnyEquatableBox<T: Equatable> : AnyEquatableBase {
private let value: T
init(_ value: T) {
self.value = value
}
override func isEqual(to other: AnyEquatableBase) -> Bool {
if let otherSelf = other as? AnyEquatableBox<T> {
return self.value == otherSelf.value
}
return false
}
}
public struct AnyEquatable : Equatable {
private let box: AnyEquatableBase
public init<T: Equatable>(_ x: T) {
box = AnyEquatableBox(x)
}
public static func == (lhs: AnyEquatable, rhs: AnyEquatable) -> Bool {
return lhs.box.isEqual(to: rhs.box)
}
}
fileprivate class AnyComparableBase : AnyEquatableBase {
func isLess(than other: AnyComparableBase) -> Bool {
fatalError("isLess(than:) must be overridden in subclass")
}
}
fileprivate final class AnyComparableBox<T: Comparable> : AnyComparableBase {
private let value: T
init(_ value: T) {
self.value = value
}
override func isEqual(to other: AnyEquatableBase) -> Bool {
if let otherSelf = other as? AnyComparableBox<T> {
return self.value == otherSelf.value
}
return false
}
override func isLess(than other: AnyComparableBase) -> Bool {
guard let otherSelf = other as? AnyComparableBox<T> else {
fatalError("mixed type ordering comparison not supported")
}
return self.value < otherSelf.value
}
}
public struct AnyComparable : Comparable {
private let box: AnyComparableBase
public init<T: Comparable>(_ x: T) {
box = AnyComparableBox(x)
}
public static func == (lhs: AnyComparable, rhs: AnyComparable) -> Bool {
return lhs.box.isEqual(to: rhs.box)
}
public static func < (lhs: AnyComparable, rhs: AnyComparable) -> Bool {
return lhs.box.isLess(than: rhs.box)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment