Skip to content

Commit a0aa6d8

Browse files
authored
Merge pull request #36 from 5150VEX/main
Return `double` instead of `Number` when units cancel in division or multiplication.
2 parents 550edc1 + 8636d67 commit a0aa6d8

File tree

2 files changed

+28
-21
lines changed

2 files changed

+28
-21
lines changed

.clangd

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
CompileFlags:
2+
Add: [-std=c++20]

include/units/units.hpp

Lines changed: 26 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
#include <cmath>
55
#include <ratio>
66
#include <iostream>
7+
#include <type_traits>
78
#include <utility>
89
#include <algorithm>
910

@@ -114,6 +115,21 @@ class Quantity {
114115
}
115116
};
116117

118+
/* Number is a special type, because it can be implicitly converted to and from any arithmetic type */
119+
class Number : public Quantity<std::ratio<0>, std::ratio<0>, std::ratio<0>, std::ratio<0>, std::ratio<0>, std::ratio<0>,
120+
std::ratio<0>, std::ratio<0>> {
121+
public:
122+
template <typename T> constexpr Number(T value)
123+
: Quantity<std::ratio<0>, std::ratio<0>, std::ratio<0>, std::ratio<0>, std::ratio<0>, std::ratio<0>,
124+
std::ratio<0>, std::ratio<0>>(double(value)) {}
125+
126+
constexpr Number(Quantity<std::ratio<0>, std::ratio<0>, std::ratio<0>, std::ratio<0>, std::ratio<0>,
127+
std::ratio<0>, std::ratio<0>, std::ratio<0>>
128+
value)
129+
: Quantity<std::ratio<0>, std::ratio<0>, std::ratio<0>, std::ratio<0>, std::ratio<0>, std::ratio<0>,
130+
std::ratio<0>, std::ratio<0>>(value) {};
131+
};
132+
117133
template <typename Q> struct LookupName {
118134
using Named = Q;
119135
};
@@ -221,12 +237,18 @@ template <isQuantity Q> constexpr Q operator*(double multiple, Q quantity) { ret
221237

222238
template <isQuantity Q> constexpr Q operator/(Q quantity, double divisor) { return Q(quantity.internal() / divisor); }
223239

224-
template <isQuantity Q1, isQuantity Q2, isQuantity Q3 = Multiplied<Q1, Q2>> Q3 constexpr operator*(Q1 lhs, Q2 rhs) {
225-
return Q3(lhs.internal() * rhs.internal());
240+
template <isQuantity Q1, isQuantity Q2>
241+
std::conditional_t<std::is_same_v<Number, Multiplied<Q1, Q2>>, double, Multiplied<Q1, Q2>> constexpr operator*(Q1 lhs,
242+
Q2 rhs) {
243+
return std::conditional_t<std::is_same_v<Number, Multiplied<Q1, Q2>>, double, Multiplied<Q1, Q2>>(lhs.internal() *
244+
rhs.internal());
226245
}
227246

228-
template <isQuantity Q1, isQuantity Q2, isQuantity Q3 = Divided<Q1, Q2>> Q3 constexpr operator/(Q1 lhs, Q2 rhs) {
229-
return Q3(lhs.internal() / rhs.internal());
247+
template <isQuantity Q1, isQuantity Q2>
248+
std::conditional_t<std::is_same_v<Number, Multiplied<Q1, Q2>>, double, Divided<Q1, Q2>> constexpr operator/(Q1 lhs,
249+
Q2 rhs) {
250+
return std::conditional_t<std::is_same_v<Number, Multiplied<Q1, Q2>>, double, Divided<Q1, Q2>>(lhs.internal() /
251+
rhs.internal());
230252
}
231253

232254
template <isQuantity Q, isQuantity R> constexpr bool operator==(const Q& lhs, const R& rhs)
@@ -316,23 +338,6 @@ template <isQuantity Q, isQuantity R> constexpr bool operator>(const Q& lhs, con
316338
NEW_UNIT_LITERAL(Name, u##base, base / 1E6) \
317339
NEW_UNIT_LITERAL(Name, n##base, base / 1E9)
318340

319-
/* Number is a special type, because it can be implicitly converted to and from any arithmetic type */
320-
class Number : public Quantity<std::ratio<0>, std::ratio<0>, std::ratio<0>, std::ratio<0>, std::ratio<0>, std::ratio<0>,
321-
std::ratio<0>, std::ratio<0>> {
322-
public:
323-
template <typename T> constexpr Number(T value)
324-
: Quantity<std::ratio<0>, std::ratio<0>, std::ratio<0>, std::ratio<0>, std::ratio<0>, std::ratio<0>,
325-
std::ratio<0>, std::ratio<0>>(double(value)) {}
326-
327-
template <typename T> constexpr explicit operator T() { return T(value); }
328-
329-
constexpr Number(Quantity<std::ratio<0>, std::ratio<0>, std::ratio<0>, std::ratio<0>, std::ratio<0>,
330-
std::ratio<0>, std::ratio<0>, std::ratio<0>>
331-
value)
332-
: Quantity<std::ratio<0>, std::ratio<0>, std::ratio<0>, std::ratio<0>, std::ratio<0>, std::ratio<0>,
333-
std::ratio<0>, std::ratio<0>>(value) {};
334-
};
335-
336341
template <> struct LookupName<Quantity<std::ratio<0>, std::ratio<0>, std::ratio<0>, std::ratio<0>, std::ratio<0>,
337342
std::ratio<0>, std::ratio<0>, std::ratio<0>>> {
338343
using Named = Number;

0 commit comments

Comments
 (0)