diff --git a/stdlib/public/core/Algorithm.swift b/stdlib/public/core/Algorithm.swift index 15b2fd94f918a..a3fe61253d54a 100644 --- a/stdlib/public/core/Algorithm.swift +++ b/stdlib/public/core/Algorithm.swift @@ -44,47 +44,50 @@ public func find< } /// Returns the lesser of `x` and `y`. +/// +/// If `x == y`, returns `x`. @warn_unused_result public func min(x: T, _ y: T) -> T { - var r = x - if y < x { - r = y - } - return r + // In case `x == y` we pick `x`. + // This preserves any pre-existing order in case `T` has identity, + // which is important for e.g. the stability of sorting algorithms. + // `(min(x, y), max(x, y))` should return `(x, y)` in case `x == y`. + return y < x ? y : x } /// Returns the least argument passed. +/// +/// If there are multiple equal least arguments, returns the first one. @warn_unused_result public func min(x: T, _ y: T, _ z: T, _ rest: T...) -> T { - var r = x - if y < x { - r = y - } - if z < r { - r = z + var minValue = min(min(x, y), z) + // In case `value == minValue`, we pick `minValue`. See min(_:_:). + for value in rest where value < minValue { + minValue = value } - for t in rest { - if t < r { - r = t - } - } - return r + return minValue } /// Returns the greater of `x` and `y`. +/// +/// If `x == y`, returns `y`. @warn_unused_result public func max(x: T, _ y: T) -> T { + // In case `x == y`, we pick `y`. See min(_:_:). return y >= x ? y : x } /// Returns the greatest argument passed. +/// +/// If there are multiple equal greatest arguments, returns the last one. @warn_unused_result public func max(x: T, _ y: T, _ z: T, _ rest: T...) -> T { - var r = max(max(x, y), z) - for t in rest where t >= r { - r = t + var maxValue = max(max(x, y), z) + // In case `value == maxValue`, we pick `value`. See min(_:_:). + for value in rest where value >= maxValue { + maxValue = value } - return r + return maxValue } /// Returns the result of slicing `elements` into sub-sequences that