Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
127 changes: 33 additions & 94 deletions stdlib/public/SDK/Foundation/Measurement.swift
Original file line number Diff line number Diff line change
Expand Up @@ -110,71 +110,6 @@ extension Measurement where UnitType : Dimension {
return Measurement(value: lhsValueInTermsOfBase - rhsValueInTermsOfBase, unit: type(of: lhs.unit).baseUnit())
}
}

/// Compare two measurements of the same `Dimension`.
///
/// If `lhs.unit == rhs.unit`, returns `lhs.value == rhs.value`. Otherwise, converts `rhs` to the same unit as `lhs` and then compares the resulting values.
/// - returns: `true` if the measurements are equal.
public static func ==(lhs: Measurement<UnitType>, rhs: Measurement<UnitType>) -> Bool {
if lhs.unit == rhs.unit {
return lhs.value == rhs.value
} else {
let rhsInLhs = rhs.converted(to: lhs.unit)
return lhs.value == rhsInLhs.value
}
}

/// Compare two measurements of the same `Dimension`.
///
/// If `lhs.unit == rhs.unit`, returns `lhs.value < rhs.value`. Otherwise, converts `rhs` to the same unit as `lhs` and then compares the resulting values.
/// - returns: `true` if `lhs` is less than `rhs`.
public static func <(lhs: Measurement<UnitType>, rhs: Measurement<UnitType>) -> Bool {
if lhs.unit == rhs.unit {
return lhs.value < rhs.value
} else {
let rhsInLhs = rhs.converted(to: lhs.unit)
return lhs.value < rhsInLhs.value
}
}

/// Compare two measurements of the same `Dimension`.
///
/// If `lhs.unit == rhs.unit`, returns `lhs.value > rhs.value`. Otherwise, converts `rhs` to the same unit as `lhs` and then compares the resulting values.
/// - returns: `true` if `lhs` is greater than `rhs`.
public static func >(lhs: Measurement<UnitType>, rhs: Measurement<UnitType>) -> Bool {
if lhs.unit == rhs.unit {
return lhs.value > rhs.value
} else {
let rhsInLhs = rhs.converted(to: lhs.unit)
return lhs.value > rhsInLhs.value
}
}

/// Compare two measurements of the same `Dimension`.
///
/// If `lhs.unit == rhs.unit`, returns `lhs.value < rhs.value`. Otherwise, converts `rhs` to the same unit as `lhs` and then compares the resulting values.
/// - returns: `true` if `lhs` is less than or equal to `rhs`.
public static func <=(lhs: Measurement<UnitType>, rhs: Measurement<UnitType>) -> Bool {
if lhs.unit == rhs.unit {
return lhs.value <= rhs.value
} else {
let rhsInLhs = rhs.converted(to: lhs.unit)
return lhs.value <= rhsInLhs.value
}
}

/// Compare two measurements of the same `Dimension`.
///
/// If `lhs.unit == rhs.unit`, returns `lhs.value >= rhs.value`. Otherwise, converts `rhs` to the same unit as `lhs` and then compares the resulting values.
/// - returns: `true` if `lhs` is greater or equal to `rhs`.
public static func >=(lhs: Measurement<UnitType>, rhs: Measurement<UnitType>) -> Bool {
if lhs.unit == rhs.unit {
return lhs.value >= rhs.value
} else {
let rhsInLhs = rhs.converted(to: lhs.unit)
return lhs.value >= rhsInLhs.value
}
}
}

@available(OSX 10.12, iOS 10.0, watchOS 3.0, tvOS 10.0, *)
Expand Down Expand Up @@ -225,38 +160,42 @@ extension Measurement {
return Measurement(value: lhs / rhs.value, unit: rhs.unit)
}

/// Compare two measurements of the same `Unit`.
/// - returns: `true` if `lhs.value == rhs.value && lhs.unit == rhs.unit`.
public static func ==(lhs: Measurement<UnitType>, rhs: Measurement<UnitType>) -> Bool {
return lhs.value == rhs.value && lhs.unit == rhs.unit
}

/// Compare two measurements of the same `Unit`.
/// - note: This function does not check `==` for the `unit` property of `lhs` and `rhs`.
/// - returns: `lhs.value < rhs.value`
public static func <(lhs: Measurement<UnitType>, rhs: Measurement<UnitType>) -> Bool {
return lhs.value < rhs.value
}

/// Compare two measurements of the same `Unit`.
/// - note: This function does not check `==` for the `unit` property of `lhs` and `rhs`.
/// - returns: `lhs.value > rhs.value`
public static func >(lhs: Measurement<UnitType>, rhs: Measurement<UnitType>) -> Bool {
return lhs.value > rhs.value
}

/// Compare two measurements of the same `Unit`.
/// - note: This function does not check `==` for the `unit` property of `lhs` and `rhs`.
/// - returns: `lhs.value <= rhs.value`
public static func <=(lhs: Measurement<UnitType>, rhs: Measurement<UnitType>) -> Bool {
return lhs.value <= rhs.value
/// Compare two measurements of the same `Dimension`.
///
/// If `lhs.unit == rhs.unit`, returns `lhs.value == rhs.value`. Otherwise, converts `rhs` to the same unit as `lhs` and then compares the resulting values.
/// - returns: `true` if the measurements are equal.
public static func ==<LeftHandSideType : Unit, RightHandSideType : Unit>(_ lhs: Measurement<LeftHandSideType>, _ rhs: Measurement<RightHandSideType>) -> Bool {
if lhs.unit == rhs.unit {
return lhs.value == rhs.value
} else {
if let lhsDimensionalUnit = lhs.unit as? Dimension,
let rhsDimensionalUnit = rhs.unit as? Dimension {
if type(of: lhsDimensionalUnit).baseUnit() == type(of: rhsDimensionalUnit).baseUnit() {
let lhsValueInTermsOfBase = lhsDimensionalUnit.converter.baseUnitValue(fromValue: lhs.value)
let rhsValueInTermsOfBase = rhsDimensionalUnit.converter.baseUnitValue(fromValue: rhs.value)
return lhsValueInTermsOfBase == rhsValueInTermsOfBase
}
}
return false
}
}

/// Compare two measurements of the same `Unit`.
/// - note: This function does not check `==` for the `unit` property of `lhs` and `rhs`.
/// - returns: `lhs.value >= rhs.value`
public static func >=(lhs: Measurement<UnitType>, rhs: Measurement<UnitType>) -> Bool {
return lhs.value >= rhs.value
/// - returns: `true` if the measurements can be compared and the `lhs` is less than the `rhs` converted value.
public static func <<LeftHandSideType : Unit, RightHandSideType : Unit>(lhs: Measurement<LeftHandSideType>, rhs: Measurement<RightHandSideType>) -> Bool {
if lhs.unit == rhs.unit {
return lhs.value < rhs.value
} else {
if let lhsDimensionalUnit = lhs.unit as? Dimension,
let rhsDimensionalUnit = rhs.unit as? Dimension {
if type(of: lhsDimensionalUnit).baseUnit() == type(of: rhsDimensionalUnit).baseUnit() {
let lhsValueInTermsOfBase = lhsDimensionalUnit.converter.baseUnitValue(fromValue: lhs.value)
let rhsValueInTermsOfBase = rhsDimensionalUnit.converter.baseUnitValue(fromValue: rhs.value)
return lhsValueInTermsOfBase < rhsValueInTermsOfBase
}
}
fatalError("Attempt to compare measurements with non-equal dimensions")
}
}
}

Expand Down
23 changes: 23 additions & 0 deletions test/1_stdlib/TestMeasurement.swift
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,27 @@ class TestMeasurement : TestMeasurementSuper {
// Just make sure we get a result at all here
expectFalse(result.isEmpty)
}

func testEquality() {
let fiveKM = Measurement(value: 5, unit: UnitLength.kilometers)
let fiveSeconds = Measurement(value: 5, unit: UnitDuration.seconds)
let fiveThousandM = Measurement(value: 5000, unit: UnitLength.meters)

expectTrue(fiveKM == fiveThousandM)
expectEqual(fiveKM, fiveThousandM)
expectFalse(fiveKM == fiveSeconds)
}

func testComparison() {
let fiveKM = Measurement(value: 5, unit: UnitLength.kilometers)
let fiveThousandM = Measurement(value: 5000, unit: UnitLength.meters)
let sixKM = Measurement(value: 6, unit: UnitLength.kilometers)
let sevenThousandM = Measurement(value: 7000, unit: UnitLength.meters)

expectTrue(fiveKM < sixKM)
expectTrue(fiveKM < sevenThousandM)
expectTrue(fiveKM <= fiveThousandM)
}
}

#if !FOUNDATION_XCTEST
Expand All @@ -136,6 +157,8 @@ if #available(OSX 10.12, iOS 10.0, tvOS 10.0, watchOS 3.0, *) {
MeasurementTests.test("testOperators") { TestMeasurement().testOperators() }
MeasurementTests.test("testUnits") { TestMeasurement().testUnits() }
MeasurementTests.test("testMeasurementFormatter") { TestMeasurement().testMeasurementFormatter() }
MeasurementTests.test("testEquality") { TestMeasurement().testEquality() }
MeasurementTests.test("testComparison") { TestMeasurement().testComparison() }
runAllTests()
}
#endif