diff --git a/src/include/units/quantity.h b/src/include/units/quantity.h index 0cf29bbf..5381907f 100644 --- a/src/include/units/quantity.h +++ b/src/include/units/quantity.h @@ -439,6 +439,102 @@ public: return *this; } + template + [[nodiscard]] friend constexpr Quantity AUTO operator+(const quantity& lhs, const quantity& rhs) + requires detail::basic_arithmetic + { + using common_rep = decltype(lhs.count() + rhs.count()); + using ret = common_quantity, common_rep>; + return ret(ret(lhs).count() + ret(rhs).count()); + } + + template + [[nodiscard]] friend constexpr Quantity AUTO operator-(const quantity& lhs, const quantity& rhs) + requires detail::basic_arithmetic + { + using common_rep = decltype(lhs.count() - rhs.count()); + using ret = common_quantity, common_rep>; + return ret(ret(lhs).count() - ret(rhs).count()); + } + + template + [[nodiscard]] friend constexpr Quantity AUTO operator%(const quantity& q, const Value& v) + requires (!treat_as_floating_point) && + (!treat_as_floating_point) && + std::magma + { + using common_rep = decltype(q.count() % v); + using ret = quantity; + return ret(q.count() % v); + } + + template + [[nodiscard]] friend constexpr Quantity AUTO operator%(const quantity& lhs, const quantity& rhs) + requires (!treat_as_floating_point) && + (!treat_as_floating_point) && + std::magma + { + using common_rep = decltype(lhs.count() % rhs.count()); + using ret = common_quantity, common_rep>; + return ret(ret(lhs).count() % ret(rhs).count()); + } + + template + [[nodiscard]] friend constexpr bool operator==(const quantity& lhs, const quantity& rhs) + requires equivalent_dim && + detail::basic_arithmetic && + std::equality_comparable_with + { + using cq = common_quantity>; + return cq(lhs).count() == cq(rhs).count(); + } + + template + [[nodiscard]] friend constexpr bool operator!=(const quantity& lhs, const quantity& rhs) + requires equivalent_dim && + detail::basic_arithmetic && + std::equality_comparable_with + { + return !(lhs == rhs); + } + + template + [[nodiscard]] friend constexpr bool operator<(const quantity& lhs, const quantity& rhs) + requires equivalent_dim && + detail::basic_arithmetic && + std::totally_ordered_with + { + using cq = common_quantity>; + return cq(lhs).count() < cq(rhs).count(); + } + + template + [[nodiscard]] friend constexpr bool operator<=(const quantity& lhs, const quantity& rhs) + requires equivalent_dim && + detail::basic_arithmetic && + std::totally_ordered_with + { + return !(rhs < lhs); + } + + template + [[nodiscard]] friend constexpr bool operator>(const quantity& lhs, const quantity& rhs) + requires equivalent_dim && + detail::basic_arithmetic && + std::totally_ordered_with + { + return rhs < lhs; + } + + template + [[nodiscard]] friend constexpr bool operator>=(const quantity& lhs, const quantity& rhs) + requires equivalent_dim && + detail::basic_arithmetic && + std::totally_ordered_with + { + return !(lhs < rhs); + } + template friend std::basic_ostream& operator<<(std::basic_ostream& os, const quantity& q) { @@ -446,23 +542,7 @@ public: } }; -template -[[nodiscard]] constexpr Quantity AUTO operator+(const quantity& lhs, const quantity& rhs) - requires detail::basic_arithmetic -{ - using common_rep = decltype(lhs.count() + rhs.count()); - using ret = common_quantity, quantity, common_rep>; - return ret(ret(lhs).count() + ret(rhs).count()); -} - -template -[[nodiscard]] constexpr Quantity AUTO operator-(const quantity& lhs, const quantity& rhs) - requires detail::basic_arithmetic -{ - using common_rep = decltype(lhs.count() - rhs.count()); - using ret = common_quantity, quantity, common_rep>; - return ret(ret(lhs).count() - ret(rhs).count()); -} +// TODO make hidden friends when moved to gcc-10 template [[nodiscard]] constexpr Quantity AUTO operator*(const quantity& q, const Value& v) @@ -510,7 +590,7 @@ template [[nodiscard]] constexpr Quantity AUTO operator/(const Value& v, const quantity& q) requires std::magma { - Expects(q != std::remove_cvref_t(0)); + Expects(q.count() != 0); using dim = dim_invert; using ratio = ratio; @@ -535,7 +615,7 @@ template& lhs, const quantity& rhs) requires detail::basic_arithmetic && equivalent_dim { - Expects(rhs != std::remove_cvref_t(0)); + Expects(rhs.count() != 0); using common_rep = decltype(lhs.count() / rhs.count()); using cq = common_quantity, quantity, common_rep>; @@ -548,7 +628,7 @@ template || (ratio_divide::den == 1)) { - Expects(rhs != std::remove_cvref_t(0)); + Expects(rhs.count() != 0); using common_rep = decltype(lhs.count() / rhs.count()); using dim = dimension_divide; @@ -560,82 +640,4 @@ template -[[nodiscard]] constexpr Quantity AUTO operator%(const quantity& q, const Value& v) - requires (!treat_as_floating_point) && - (!treat_as_floating_point) && - std::magma -{ - using common_rep = decltype(q.count() % v); - using ret = quantity; - return ret(q.count() % v); -} - -template -[[nodiscard]] constexpr Quantity AUTO operator%(const quantity& lhs, const quantity& rhs) - requires (!treat_as_floating_point) && - (!treat_as_floating_point) && - std::magma -{ - using common_rep = decltype(lhs.count() % rhs.count()); - using ret = common_quantity, quantity, common_rep>; - return ret(ret(lhs).count() % ret(rhs).count()); -} - -template -[[nodiscard]] constexpr bool operator==(const quantity& lhs, const quantity& rhs) - requires equivalent_dim && - detail::basic_arithmetic && - std::equality_comparable_with -{ - using cq = common_quantity, quantity>; - return cq(lhs).count() == cq(rhs).count(); -} - -template -[[nodiscard]] constexpr bool operator!=(const quantity& lhs, const quantity& rhs) - requires equivalent_dim && - detail::basic_arithmetic && - std::equality_comparable_with -{ - return !(lhs == rhs); -} - -template -[[nodiscard]] constexpr bool operator<(const quantity& lhs, const quantity& rhs) - requires equivalent_dim && - detail::basic_arithmetic && - std::totally_ordered_with -{ - using cq = common_quantity, quantity>; - return cq(lhs).count() < cq(rhs).count(); -} - -template -[[nodiscard]] constexpr bool operator<=(const quantity& lhs, const quantity& rhs) - requires equivalent_dim && - detail::basic_arithmetic && - std::totally_ordered_with -{ - return !(rhs < lhs); -} - -template -[[nodiscard]] constexpr bool operator>(const quantity& lhs, const quantity& rhs) - requires equivalent_dim && - detail::basic_arithmetic && - std::totally_ordered_with -{ - return rhs < lhs; -} - -template -[[nodiscard]] constexpr bool operator>=(const quantity& lhs, const quantity& rhs) - requires equivalent_dim && - detail::basic_arithmetic && - std::totally_ordered_with -{ - return !(lhs < rhs); -} - } // namespace units