If the following were added to the standard library:
public extension Sequence where Self: Comparable, Element: Comparable {
@inlinable static func < (lhs: Self, rhs: Self) -> Bool {
var lI = lhs.makeIterator()
var rI = rhs.makeIterator()
var lOV = lI.next()
var rOV = rI.next()
var strictlyLess = lOV == nil && rOV != nil
while let lV = lOV, let rV = rOV {
guard lV <= rV else {
return false
}
strictlyLess = strictlyLess || lV < rV
lOV = lI.next()
rOV = rI.next()
}
return lOV == nil && (rOV != nil || strictlyLess)
}
}
Then a Sequence
could easily opt-in to conforming to Comparable
, e.g.:
extension Array: Comparable where Element: Comparable {}
To test the above extension a test framework is useful:
extension Bool {
var toInt: Int {
return self ? 1 : 0
}
}
func cTest<C>(_ a: C, _ b: C) -> (Bool, Bool, Bool, Int) where C: Comparable {
let e = a == b // One and only one of these should be true.
let l = a < b
let g = b < a
return (e, l, g, e.toInt + l.toInt + g.toInt) // Sum of ints should be 1.
}
Then the extension can be tested:
let t = [Int]()
let t0 = [0]
let t012 = [0, 1, 2]
let t01U = [0, 1, 42]
print(cTest(t, t)) // Equal
print(cTest(t0, t0)) // E
print(cTest(t, t0)) // Less than
print(cTest(t0, t)) // Greater than
print(cTest(t0, t012)) // L
print(cTest(t012, t0)) // G
print(cTest(t012, t01U)) // L
print(cTest(t01U, t012)) // G
What to people think? Worth adding?