Skip to content

[Measurement] Group operators into just two extensions #1350

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Dec 1, 2017
Merged
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
189 changes: 80 additions & 109 deletions Foundation/Measurement.swift
Original file line number Diff line number Diff line change
Expand Up @@ -69,23 +69,7 @@ extension Measurement where UnitType : Dimension {
public mutating func convert(to otherUnit: UnitType) {
self = converted(to: otherUnit)
}

}

extension Measurement {
/// Add two measurements of the same Unit.
/// - precondition: The `unit` of `lhs` and `rhs` must be `isEqual`.
/// - returns: A measurement of value `lhs.value + rhs.value` and unit `lhs.unit`.
public static func +(lhs: Measurement<UnitType>, rhs: Measurement<UnitType>) -> Measurement<UnitType> {
if lhs.unit.isEqual(rhs.unit) {
return Measurement(value: lhs.value + rhs.value, unit: lhs.unit)
} else {
fatalError("Attempt to add measurements with non-equal units")
}
}
}

extension Measurement where UnitType : Dimension {
/// Add two measurements of the same Dimension.
///
/// If the `unit` of the `lhs` and `rhs` are `isEqual`, then this returns the result of adding the `value` of each `Measurement`. If they are not equal, then this will convert both to the base unit of the `Dimension` and return the result as a `Measurement` of that base unit.
Expand All @@ -99,22 +83,7 @@ extension Measurement where UnitType : Dimension {
return Measurement(value: lhsValueInTermsOfBase + rhsValueInTermsOfBase, unit: type(of: lhs.unit).baseUnit())
}
}
}

extension Measurement {
/// Subtract two measurements of the same Unit.
/// - precondition: The `unit` of `lhs` and `rhs` must be `isEqual`.
/// - returns: A measurement of value `lhs.value - rhs.value` and unit `lhs.unit`.
public static func -(lhs: Measurement<UnitType>, rhs: Measurement<UnitType>) -> Measurement<UnitType> {
if lhs.unit.isEqual(rhs.unit) {
return Measurement(value: lhs.value - rhs.value, unit: lhs.unit)
} else {
fatalError("Attempt to subtract measurements with non-equal units")
}
}
}

extension Measurement where UnitType : Dimension {
/// Subtract two measurements of the same Dimension.
///
/// If the `unit` of the `lhs` and `rhs` are `==`, then this returns the result of subtracting the `value` of each `Measurement`. If they are not equal, then this will convert both to the base unit of the `Dimension` and return the result as a `Measurement` of that base unit.
Expand All @@ -128,41 +97,7 @@ extension Measurement where UnitType : Dimension {
return Measurement(value: lhsValueInTermsOfBase - rhsValueInTermsOfBase, unit: type(of: lhs.unit).baseUnit())
}
}
}

extension Measurement {
/// Multiply a measurement by a scalar value.
/// - returns: A measurement of value `lhs.value * rhs` with the same unit as `lhs`.
public static func *(lhs: Measurement<UnitType>, rhs: Double) -> Measurement<UnitType> {
return Measurement(value: lhs.value * rhs, unit: lhs.unit)
}

/// Multiply a scalar value by a measurement.
/// - returns: A measurement of value `lhs * rhs.value` with the same unit as `rhs`.
public static func *(lhs: Double, rhs: Measurement<UnitType>) -> Measurement<UnitType> {
return Measurement(value: lhs * rhs.value, unit: rhs.unit)
}

/// Divide a measurement by a scalar value.
/// - returns: A measurement of value `lhs.value / rhs` with the same unit as `lhs`.
public static func /(lhs: Measurement<UnitType>, rhs: Double) -> Measurement<UnitType> {
return Measurement(value: lhs.value / rhs, unit: lhs.unit)
}

/// Divide a scalar value by a measurement.
/// - returns: A measurement of value `lhs / rhs.value` with the same unit as `rhs`.
public static func /(lhs: Double, rhs: Measurement<UnitType>) -> Measurement<UnitType> {
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
}
}

extension Measurement where UnitType : Dimension {
/// 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.
Expand All @@ -175,18 +110,7 @@ extension Measurement where UnitType : Dimension {
return lhs.value == rhsInLhs.value
}
}
}

extension Measurement {
/// 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
}
}

extension Measurement where UnitType : Dimension {
/// 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.
Expand All @@ -199,18 +123,7 @@ extension Measurement where UnitType : Dimension {
return lhs.value < rhsInLhs.value
}
}
}

extension Measurement {
/// 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
}
}

extension Measurement where UnitType : Dimension {
/// 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.
Expand All @@ -223,18 +136,7 @@ extension Measurement where UnitType : Dimension {
return lhs.value > rhsInLhs.value
}
}
}

extension Measurement {
/// 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
}
}

extension Measurement where UnitType : Dimension {
/// 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.
Expand All @@ -247,18 +149,7 @@ extension Measurement where UnitType : Dimension {
return lhs.value <= rhsInLhs.value
}
}
}

extension Measurement {
/// 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
}
}

extension Measurement where UnitType : Dimension {
/// 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.
Expand All @@ -273,6 +164,86 @@ extension Measurement where UnitType : Dimension {
}
}

extension Measurement {
/// Add two measurements of the same Unit.
/// - precondition: The `unit` of `lhs` and `rhs` must be `isEqual`.
/// - returns: A measurement of value `lhs.value + rhs.value` and unit `lhs.unit`.
public static func +(lhs: Measurement<UnitType>, rhs: Measurement<UnitType>) -> Measurement<UnitType> {
if lhs.unit.isEqual(rhs.unit) {
return Measurement(value: lhs.value + rhs.value, unit: lhs.unit)
} else {
fatalError("Attempt to add measurements with non-equal units")
}
}

/// Subtract two measurements of the same Unit.
/// - precondition: The `unit` of `lhs` and `rhs` must be `isEqual`.
/// - returns: A measurement of value `lhs.value - rhs.value` and unit `lhs.unit`.
public static func -(lhs: Measurement<UnitType>, rhs: Measurement<UnitType>) -> Measurement<UnitType> {
if lhs.unit.isEqual(rhs.unit) {
return Measurement(value: lhs.value - rhs.value, unit: lhs.unit)
} else {
fatalError("Attempt to subtract measurements with non-equal units")
}
}

public static func *(lhs: Measurement<UnitType>, rhs: Double) -> Measurement<UnitType> {
return Measurement(value: lhs.value * rhs, unit: lhs.unit)
}

/// Multiply a scalar value by a measurement.
/// - returns: A measurement of value `lhs * rhs.value` with the same unit as `rhs`.
public static func *(lhs: Double, rhs: Measurement<UnitType>) -> Measurement<UnitType> {
return Measurement(value: lhs * rhs.value, unit: rhs.unit)
}

/// Divide a measurement by a scalar value.
/// - returns: A measurement of value `lhs.value / rhs` with the same unit as `lhs`.
public static func /(lhs: Measurement<UnitType>, rhs: Double) -> Measurement<UnitType> {
return Measurement(value: lhs.value / rhs, unit: lhs.unit)
}

/// Divide a scalar value by a measurement.
/// - returns: A measurement of value `lhs / rhs.value` with the same unit as `rhs`.
public static func /(lhs: Double, rhs: Measurement<UnitType>) -> Measurement<UnitType> {
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 `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
}
}

// Implementation note: similar to NSArray, NSDictionary, etc., NSMeasurement's import as an ObjC generic type is suppressed by the importer. Eventually we will need a more general purpose mechanism to correctly import generic types.

extension Measurement : _ObjectTypeBridgeable {
Expand Down