Downcasting reworked to allow OFF and AUTO modes

This commit is contained in:
Mateusz Pusz committed 2020-08-19 13:37:57 +02:00
1 parent 12c0177633
commit 5c98924efb
24 files changed
+386 -216

No files matched your search

+16 -16
View File
@@ -43,10 +43,10 @@ concept safe_convertible = // exposition only
std::convertible_to<From, To> &&
(treat_as_floating_point<To> || (!treat_as_floating_point<From>));
template<typename Rep, typename UnitFrom, typename UnitTo>
template<typename Rep, typename QuantityFrom, typename QuantityTo>
concept safe_divisible = // exposition only
treat_as_floating_point<Rep> ||
is_integral(UnitFrom::ratio / UnitTo::ratio);
is_integral(quantity_ratio(QuantityFrom{}) / quantity_ratio(QuantityTo{}));
} // namespace detail
@@ -78,9 +78,9 @@ public:
constexpr explicit quantity(const Value& v) : value_{static_cast<rep>(v)} {}
template<Quantity Q2>
requires equivalent_dim<D, typename Q2::dimension> &&
requires equivalent<D, typename Q2::dimension> &&
detail::safe_convertible<typename Q2::rep, rep> &&
detail::safe_divisible<rep, typename Q2::unit, unit>
detail::safe_divisible<rep, Q2, quantity>
constexpr quantity(const Q2& q) : value_{quantity_cast<quantity>(q).count()} {}
quantity& operator=(const quantity&) = default;
@@ -223,7 +223,7 @@ public:
template<typename D2, typename U2, typename Rep2>
[[nodiscard]] friend constexpr auto operator<=>(const quantity& lhs, const quantity<D2, U2, Rep2>& rhs)
requires equivalent_dim<D, D2> &&
requires equivalent<D, D2> &&
std::three_way_comparable_with<Rep, Rep2>
{
using cq = common_quantity<quantity, quantity<D2, U2, Rep2>>;
@@ -232,7 +232,7 @@ public:
template<typename D2, typename U2, typename Rep2>
[[nodiscard]] friend constexpr bool operator==(const quantity& lhs, const quantity<D2, U2, Rep2>& rhs)
requires equivalent_dim<D, D2> &&
requires equivalent<D, D2> &&
std::equality_comparable_with<Rep, Rep2>
{
using cq = common_quantity<quantity, quantity<D2, U2, Rep2>>;
@@ -243,7 +243,7 @@ public:
template<typename D2, typename U2, typename Rep2>
[[nodiscard]] friend constexpr bool operator==(const quantity& lhs, const quantity<D2, U2, Rep2>& rhs)
requires equivalent_dim<D, D2> &&
requires equivalent<D, D2> &&
std::equality_comparable_with<Rep, Rep2>
{
using cq = common_quantity<quantity, quantity<D2, U2, Rep2>>;
@@ -252,7 +252,7 @@ public:
template<typename D2, typename U2, typename Rep2>
[[nodiscard]] friend constexpr bool operator!=(const quantity& lhs, const quantity<D2, U2, Rep2>& rhs)
requires equivalent_dim<D, D2> &&
requires equivalent<D, D2> &&
std::equality_comparable_with<Rep, Rep2>
{
return !(lhs == rhs);
@@ -260,7 +260,7 @@ public:
template<typename D2, typename U2, typename Rep2>
[[nodiscard]] friend constexpr bool operator<(const quantity& lhs, const quantity<D2, U2, Rep2>& rhs)
requires equivalent_dim<D, D2> &&
requires equivalent<D, D2> &&
std::totally_ordered_with<Rep, Rep2>
{
using cq = common_quantity<quantity, quantity<D2, U2, Rep2>>;
@@ -269,7 +269,7 @@ public:
template<typename D2, typename U2, typename Rep2>
[[nodiscard]] friend constexpr bool operator<=(const quantity& lhs, const quantity<D2, U2, Rep2>& rhs)
requires equivalent_dim<D, D2> &&
requires equivalent<D, D2> &&
std::totally_ordered_with<Rep, Rep2>
{
return !(rhs < lhs);
@@ -277,7 +277,7 @@ public:
template<typename D2, typename U2, typename Rep2>
[[nodiscard]] friend constexpr bool operator>(const quantity& lhs, const quantity<D2, U2, Rep2>& rhs)
requires equivalent_dim<D, D2> &&
requires equivalent<D, D2> &&
std::totally_ordered_with<Rep, Rep2>
{
return rhs < lhs;
@@ -285,7 +285,7 @@ public:
template<typename D2, typename U2, typename Rep2>
[[nodiscard]] friend constexpr bool operator>=(const quantity& lhs, const quantity<D2, U2, Rep2>& rhs)
requires equivalent_dim<D, D2> &&
requires equivalent<D, D2> &&
std::totally_ordered_with<Rep, Rep2>
{
return !(lhs < rhs);
@@ -337,14 +337,14 @@ template<Scalar Value, typename D, typename U, typename Rep>
template<typename D1, typename U1, typename Rep1, typename D2, typename U2, typename Rep2>
[[nodiscard]] constexpr Scalar AUTO operator*(const quantity<D1, U1, Rep1>& lhs, const quantity<D2, U2, Rep2>& rhs)
requires std::regular_invocable<std::multiplies<>, Rep1, Rep2> &&
equivalent_dim<D1, dim_invert<D2>>
equivalent<D1, dim_invert<D2>>
{
using common_rep = decltype(lhs.count() * rhs.count());
const ratio r = U1::ratio * U2::ratio;
if constexpr (treat_as_floating_point<common_rep>) {
return lhs.count() * rhs.count() * static_cast<common_rep>(r.num * fpow10<common_rep>(r.exp)) / static_cast<common_rep>(r.den);
return lhs.count() * rhs.count() * static_cast<common_rep>(r.num * detail::fpow10<common_rep>(r.exp)) / static_cast<common_rep>(r.den);
} else {
return lhs.count() * rhs.count() * static_cast<common_rep>(r.num * ipow10(r.exp)) / static_cast<common_rep>(r.den);
return lhs.count() * rhs.count() * static_cast<common_rep>(r.num * detail::ipow10(r.exp)) / static_cast<common_rep>(r.den);
}
}
@@ -386,7 +386,7 @@ template<typename D, typename U, typename Rep, Scalar Value>
template<typename D1, typename U1, typename Rep1, typename D2, typename U2, typename Rep2>
[[nodiscard]] constexpr Scalar AUTO operator/(const quantity<D1, U1, Rep1>& lhs, const quantity<D2, U2, Rep2>& rhs)
requires std::regular_invocable<std::divides<>, Rep1, Rep2> &&
equivalent_dim<D1, D2>
equivalent<D1, D2>
{
Expects(rhs.count() != 0);