Skip to content

Commit 85ba7fc

Browse files
authored
Merge pull request #4167 from phausler/Measurement
Measurement
2 parents 4fbf22c + 25e93ad commit 85ba7fc

File tree

2 files changed

+56
-94
lines changed

2 files changed

+56
-94
lines changed

stdlib/public/SDK/Foundation/Measurement.swift

Lines changed: 33 additions & 94 deletions
Original file line numberDiff line numberDiff line change
@@ -110,71 +110,6 @@ extension Measurement where UnitType : Dimension {
110110
return Measurement(value: lhsValueInTermsOfBase - rhsValueInTermsOfBase, unit: type(of: lhs.unit).baseUnit())
111111
}
112112
}
113-
114-
/// Compare two measurements of the same `Dimension`.
115-
///
116-
/// 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.
117-
/// - returns: `true` if the measurements are equal.
118-
public static func ==(lhs: Measurement<UnitType>, rhs: Measurement<UnitType>) -> Bool {
119-
if lhs.unit == rhs.unit {
120-
return lhs.value == rhs.value
121-
} else {
122-
let rhsInLhs = rhs.converted(to: lhs.unit)
123-
return lhs.value == rhsInLhs.value
124-
}
125-
}
126-
127-
/// Compare two measurements of the same `Dimension`.
128-
///
129-
/// 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.
130-
/// - returns: `true` if `lhs` is less than `rhs`.
131-
public static func <(lhs: Measurement<UnitType>, rhs: Measurement<UnitType>) -> Bool {
132-
if lhs.unit == rhs.unit {
133-
return lhs.value < rhs.value
134-
} else {
135-
let rhsInLhs = rhs.converted(to: lhs.unit)
136-
return lhs.value < rhsInLhs.value
137-
}
138-
}
139-
140-
/// Compare two measurements of the same `Dimension`.
141-
///
142-
/// 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.
143-
/// - returns: `true` if `lhs` is greater than `rhs`.
144-
public static func >(lhs: Measurement<UnitType>, rhs: Measurement<UnitType>) -> Bool {
145-
if lhs.unit == rhs.unit {
146-
return lhs.value > rhs.value
147-
} else {
148-
let rhsInLhs = rhs.converted(to: lhs.unit)
149-
return lhs.value > rhsInLhs.value
150-
}
151-
}
152-
153-
/// Compare two measurements of the same `Dimension`.
154-
///
155-
/// 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.
156-
/// - returns: `true` if `lhs` is less than or equal to `rhs`.
157-
public static func <=(lhs: Measurement<UnitType>, rhs: Measurement<UnitType>) -> Bool {
158-
if lhs.unit == rhs.unit {
159-
return lhs.value <= rhs.value
160-
} else {
161-
let rhsInLhs = rhs.converted(to: lhs.unit)
162-
return lhs.value <= rhsInLhs.value
163-
}
164-
}
165-
166-
/// Compare two measurements of the same `Dimension`.
167-
///
168-
/// 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.
169-
/// - returns: `true` if `lhs` is greater or equal to `rhs`.
170-
public static func >=(lhs: Measurement<UnitType>, rhs: Measurement<UnitType>) -> Bool {
171-
if lhs.unit == rhs.unit {
172-
return lhs.value >= rhs.value
173-
} else {
174-
let rhsInLhs = rhs.converted(to: lhs.unit)
175-
return lhs.value >= rhsInLhs.value
176-
}
177-
}
178113
}
179114

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

228-
/// Compare two measurements of the same `Unit`.
229-
/// - returns: `true` if `lhs.value == rhs.value && lhs.unit == rhs.unit`.
230-
public static func ==(lhs: Measurement<UnitType>, rhs: Measurement<UnitType>) -> Bool {
231-
return lhs.value == rhs.value && lhs.unit == rhs.unit
232-
}
233-
234-
/// Compare two measurements of the same `Unit`.
235-
/// - note: This function does not check `==` for the `unit` property of `lhs` and `rhs`.
236-
/// - returns: `lhs.value < rhs.value`
237-
public static func <(lhs: Measurement<UnitType>, rhs: Measurement<UnitType>) -> Bool {
238-
return lhs.value < rhs.value
239-
}
240-
241-
/// Compare two measurements of the same `Unit`.
242-
/// - note: This function does not check `==` for the `unit` property of `lhs` and `rhs`.
243-
/// - returns: `lhs.value > rhs.value`
244-
public static func >(lhs: Measurement<UnitType>, rhs: Measurement<UnitType>) -> Bool {
245-
return lhs.value > rhs.value
246-
}
247-
248-
/// Compare two measurements of the same `Unit`.
249-
/// - note: This function does not check `==` for the `unit` property of `lhs` and `rhs`.
250-
/// - returns: `lhs.value <= rhs.value`
251-
public static func <=(lhs: Measurement<UnitType>, rhs: Measurement<UnitType>) -> Bool {
252-
return lhs.value <= rhs.value
163+
/// Compare two measurements of the same `Dimension`.
164+
///
165+
/// 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.
166+
/// - returns: `true` if the measurements are equal.
167+
public static func ==<LeftHandSideType : Unit, RightHandSideType : Unit>(_ lhs: Measurement<LeftHandSideType>, _ rhs: Measurement<RightHandSideType>) -> Bool {
168+
if lhs.unit == rhs.unit {
169+
return lhs.value == rhs.value
170+
} else {
171+
if let lhsDimensionalUnit = lhs.unit as? Dimension,
172+
let rhsDimensionalUnit = rhs.unit as? Dimension {
173+
if type(of: lhsDimensionalUnit).baseUnit() == type(of: rhsDimensionalUnit).baseUnit() {
174+
let lhsValueInTermsOfBase = lhsDimensionalUnit.converter.baseUnitValue(fromValue: lhs.value)
175+
let rhsValueInTermsOfBase = rhsDimensionalUnit.converter.baseUnitValue(fromValue: rhs.value)
176+
return lhsValueInTermsOfBase == rhsValueInTermsOfBase
177+
}
178+
}
179+
return false
180+
}
253181
}
254182

255183
/// Compare two measurements of the same `Unit`.
256-
/// - note: This function does not check `==` for the `unit` property of `lhs` and `rhs`.
257-
/// - returns: `lhs.value >= rhs.value`
258-
public static func >=(lhs: Measurement<UnitType>, rhs: Measurement<UnitType>) -> Bool {
259-
return lhs.value >= rhs.value
184+
/// - returns: `true` if the measurements can be compared and the `lhs` is less than the `rhs` converted value.
185+
public static func <<LeftHandSideType : Unit, RightHandSideType : Unit>(lhs: Measurement<LeftHandSideType>, rhs: Measurement<RightHandSideType>) -> Bool {
186+
if lhs.unit == rhs.unit {
187+
return lhs.value < rhs.value
188+
} else {
189+
if let lhsDimensionalUnit = lhs.unit as? Dimension,
190+
let rhsDimensionalUnit = rhs.unit as? Dimension {
191+
if type(of: lhsDimensionalUnit).baseUnit() == type(of: rhsDimensionalUnit).baseUnit() {
192+
let lhsValueInTermsOfBase = lhsDimensionalUnit.converter.baseUnitValue(fromValue: lhs.value)
193+
let rhsValueInTermsOfBase = rhsDimensionalUnit.converter.baseUnitValue(fromValue: rhs.value)
194+
return lhsValueInTermsOfBase < rhsValueInTermsOfBase
195+
}
196+
}
197+
fatalError("Attempt to compare measurements with non-equal dimensions")
198+
}
260199
}
261200
}
262201

test/1_stdlib/TestMeasurement.swift

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,27 @@ class TestMeasurement : TestMeasurementSuper {
126126
// Just make sure we get a result at all here
127127
expectFalse(result.isEmpty)
128128
}
129+
130+
func testEquality() {
131+
let fiveKM = Measurement(value: 5, unit: UnitLength.kilometers)
132+
let fiveSeconds = Measurement(value: 5, unit: UnitDuration.seconds)
133+
let fiveThousandM = Measurement(value: 5000, unit: UnitLength.meters)
134+
135+
expectTrue(fiveKM == fiveThousandM)
136+
expectEqual(fiveKM, fiveThousandM)
137+
expectFalse(fiveKM == fiveSeconds)
138+
}
139+
140+
func testComparison() {
141+
let fiveKM = Measurement(value: 5, unit: UnitLength.kilometers)
142+
let fiveThousandM = Measurement(value: 5000, unit: UnitLength.meters)
143+
let sixKM = Measurement(value: 6, unit: UnitLength.kilometers)
144+
let sevenThousandM = Measurement(value: 7000, unit: UnitLength.meters)
145+
146+
expectTrue(fiveKM < sixKM)
147+
expectTrue(fiveKM < sevenThousandM)
148+
expectTrue(fiveKM <= fiveThousandM)
149+
}
129150
}
130151

131152
#if !FOUNDATION_XCTEST
@@ -136,6 +157,8 @@ if #available(OSX 10.12, iOS 10.0, tvOS 10.0, watchOS 3.0, *) {
136157
MeasurementTests.test("testOperators") { TestMeasurement().testOperators() }
137158
MeasurementTests.test("testUnits") { TestMeasurement().testUnits() }
138159
MeasurementTests.test("testMeasurementFormatter") { TestMeasurement().testMeasurementFormatter() }
160+
MeasurementTests.test("testEquality") { TestMeasurement().testEquality() }
161+
MeasurementTests.test("testComparison") { TestMeasurement().testComparison() }
139162
runAllTests()
140163
}
141164
#endif

0 commit comments

Comments
 (0)