Created
August 16, 2019 08:38
-
-
Save lmumar/e756cae24e81d5e0e2f767014169d2de to your computer and use it in GitHub Desktop.
AnyComparable sample implementation
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
import Foundation | |
internal protocol _AnyComparableBox { | |
var _canonicalBox: _AnyComparableBox { get } | |
func _isEqual(to box: _AnyComparableBox) -> Bool | |
func _precede(to box: _AnyComparableBox) -> Bool | |
func _unbox<T: Comparable>() -> T? | |
} | |
extension _AnyComparableBox { | |
var _canonicalBox: _AnyComparableBox { | |
return self | |
} | |
} | |
internal struct _ConcreteComparableBox<Base: Comparable>: _AnyComparableBox { | |
internal var _baseComparable: Base | |
internal init(_ base: Base) { | |
self._baseComparable = base | |
} | |
internal func _unbox<T: Comparable>() -> T? { | |
return (self as _AnyComparableBox as? _ConcreteComparableBox<T>)?._baseComparable | |
} | |
func _isEqual(to rhs: _AnyComparableBox) -> Bool { | |
if let rhs: Base = rhs._unbox() { | |
return _baseComparable == rhs | |
} | |
return false | |
} | |
func _precede(to rhs: _AnyComparableBox) -> Bool { | |
if let rhs: Base = rhs._unbox() { | |
return _baseComparable < rhs | |
} | |
return false | |
} | |
} | |
struct AnyComparable { | |
internal var _box: _AnyComparableBox | |
public init<C: Comparable>(_ base: C) { | |
self._box = _ConcreteComparableBox(base) | |
} | |
} | |
extension AnyComparable: Equatable { | |
public static func == (lhs: AnyComparable, rhs: AnyComparable) -> Bool { | |
return lhs._box._isEqual(to: rhs._box) | |
} | |
} | |
extension AnyComparable: Comparable { | |
static func < (lhs: AnyComparable, rhs: AnyComparable) -> Bool { | |
return lhs._box._precede(to: rhs._box) | |
} | |
} | |
extension AnyComparable: CustomStringConvertible { | |
public var description: String { | |
return String(describing: _box._canonicalBox) | |
} | |
} | |
let cs = [ | |
AnyComparable(100), | |
AnyComparable(150), | |
AnyComparable("hello") | |
] | |
print(cs[0]<cs[1]) | |
print(cs[0]) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment