Skip to content

Commit

Permalink
Merge pull request #36 from 5150VEX/main
Browse files Browse the repository at this point in the history
Return `double` instead of `Number` when units cancel in division or multiplication.
  • Loading branch information
sufferiing authored Jan 7, 2025
2 parents 550edc1 + 8636d67 commit a0aa6d8
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 21 deletions.
2 changes: 2 additions & 0 deletions .clangd
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
CompileFlags:
Add: [-std=c++20]
47 changes: 26 additions & 21 deletions include/units/units.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include <cmath>
#include <ratio>
#include <iostream>
#include <type_traits>
#include <utility>
#include <algorithm>

Expand Down Expand Up @@ -114,6 +115,21 @@ class Quantity {
}
};

/* Number is a special type, because it can be implicitly converted to and from any arithmetic type */
class Number : public Quantity<std::ratio<0>, std::ratio<0>, std::ratio<0>, std::ratio<0>, std::ratio<0>, std::ratio<0>,
std::ratio<0>, std::ratio<0>> {
public:
template <typename T> constexpr Number(T value)
: Quantity<std::ratio<0>, std::ratio<0>, std::ratio<0>, std::ratio<0>, std::ratio<0>, std::ratio<0>,
std::ratio<0>, std::ratio<0>>(double(value)) {}

constexpr Number(Quantity<std::ratio<0>, std::ratio<0>, std::ratio<0>, std::ratio<0>, std::ratio<0>,
std::ratio<0>, std::ratio<0>, std::ratio<0>>
value)
: Quantity<std::ratio<0>, std::ratio<0>, std::ratio<0>, std::ratio<0>, std::ratio<0>, std::ratio<0>,
std::ratio<0>, std::ratio<0>>(value) {};
};

template <typename Q> struct LookupName {
using Named = Q;
};
Expand Down Expand Up @@ -221,12 +237,18 @@ template <isQuantity Q> constexpr Q operator*(double multiple, Q quantity) { ret

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

template <isQuantity Q1, isQuantity Q2, isQuantity Q3 = Multiplied<Q1, Q2>> Q3 constexpr operator*(Q1 lhs, Q2 rhs) {
return Q3(lhs.internal() * rhs.internal());
template <isQuantity Q1, isQuantity Q2>
std::conditional_t<std::is_same_v<Number, Multiplied<Q1, Q2>>, double, Multiplied<Q1, Q2>> constexpr operator*(Q1 lhs,
Q2 rhs) {
return std::conditional_t<std::is_same_v<Number, Multiplied<Q1, Q2>>, double, Multiplied<Q1, Q2>>(lhs.internal() *
rhs.internal());
}

template <isQuantity Q1, isQuantity Q2, isQuantity Q3 = Divided<Q1, Q2>> Q3 constexpr operator/(Q1 lhs, Q2 rhs) {
return Q3(lhs.internal() / rhs.internal());
template <isQuantity Q1, isQuantity Q2>
std::conditional_t<std::is_same_v<Number, Multiplied<Q1, Q2>>, double, Divided<Q1, Q2>> constexpr operator/(Q1 lhs,
Q2 rhs) {
return std::conditional_t<std::is_same_v<Number, Multiplied<Q1, Q2>>, double, Divided<Q1, Q2>>(lhs.internal() /
rhs.internal());
}

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

/* Number is a special type, because it can be implicitly converted to and from any arithmetic type */
class Number : public Quantity<std::ratio<0>, std::ratio<0>, std::ratio<0>, std::ratio<0>, std::ratio<0>, std::ratio<0>,
std::ratio<0>, std::ratio<0>> {
public:
template <typename T> constexpr Number(T value)
: Quantity<std::ratio<0>, std::ratio<0>, std::ratio<0>, std::ratio<0>, std::ratio<0>, std::ratio<0>,
std::ratio<0>, std::ratio<0>>(double(value)) {}

template <typename T> constexpr explicit operator T() { return T(value); }

constexpr Number(Quantity<std::ratio<0>, std::ratio<0>, std::ratio<0>, std::ratio<0>, std::ratio<0>,
std::ratio<0>, std::ratio<0>, std::ratio<0>>
value)
: Quantity<std::ratio<0>, std::ratio<0>, std::ratio<0>, std::ratio<0>, std::ratio<0>, std::ratio<0>,
std::ratio<0>, std::ratio<0>>(value) {};
};

template <> struct LookupName<Quantity<std::ratio<0>, std::ratio<0>, std::ratio<0>, std::ratio<0>, std::ratio<0>,
std::ratio<0>, std::ratio<0>, std::ratio<0>>> {
using Named = Number;
Expand Down

0 comments on commit a0aa6d8

Please sign in to comment.