quantity refactoring

This commit is contained in:
Mateusz Pusz
2019-11-02 13:57:55 +01:00
parent ee701cf4e7
commit 7da63eedfd

View File

@@ -94,24 +94,24 @@ namespace units {
namespace detail { namespace detail {
template<typename To, typename CR, typename CRep, bool NumIsOne = false, bool DenIsOne = false> template<typename To, typename CRatio, typename CRep, bool NumIsOne = false, bool DenIsOne = false>
struct quantity_cast_impl { struct quantity_cast_impl {
template<typename Q> template<typename Q>
static constexpr To cast(const Q& q) static constexpr To cast(const Q& q)
{ {
if constexpr(treat_as_floating_point<CRep>) { if constexpr(treat_as_floating_point<CRep>) {
return To(static_cast<To::rep>(static_cast<CRep>(q.count()) * return To(static_cast<To::rep>(static_cast<CRep>(q.count()) *
(static_cast<CRep>(CR::num) / static_cast<CRep>(CR::den)))); (static_cast<CRep>(CRatio::num) / static_cast<CRep>(CRatio::den))));
} }
else { else {
return To( return To(
static_cast<To::rep>(static_cast<CRep>(q.count()) * static_cast<CRep>(CR::num) / static_cast<CRep>(CR::den))); static_cast<To::rep>(static_cast<CRep>(q.count()) * static_cast<CRep>(CRatio::num) / static_cast<CRep>(CRatio::den)));
} }
} }
}; };
template<typename To, typename CR, typename CRep> template<typename To, typename CRatio, typename CRep>
struct quantity_cast_impl<To, CR, CRep, true, true> { struct quantity_cast_impl<To, CRatio, CRep, true, true> {
template<Quantity Q> template<Quantity Q>
static constexpr To cast(const Q& q) static constexpr To cast(const Q& q)
{ {
@@ -119,26 +119,26 @@ namespace units {
} }
}; };
template<typename To, typename CR, typename CRep> template<typename To, typename CRatio, typename CRep>
struct quantity_cast_impl<To, CR, CRep, true, false> { struct quantity_cast_impl<To, CRatio, CRep, true, false> {
template<Quantity Q> template<Quantity Q>
static constexpr To cast(const Q& q) static constexpr To cast(const Q& q)
{ {
if constexpr(treat_as_floating_point<CRep>) { if constexpr(treat_as_floating_point<CRep>) {
return To(static_cast<To::rep>(static_cast<CRep>(q.count()) * (CRep{1} / static_cast<CRep>(CR::den)))); return To(static_cast<To::rep>(static_cast<CRep>(q.count()) * (CRep{1} / static_cast<CRep>(CRatio::den))));
} }
else { else {
return To(static_cast<To::rep>(static_cast<CRep>(q.count()) / static_cast<CRep>(CR::den))); return To(static_cast<To::rep>(static_cast<CRep>(q.count()) / static_cast<CRep>(CRatio::den)));
} }
} }
}; };
template<typename To, typename CR, typename CRep> template<typename To, typename CRatio, typename CRep>
struct quantity_cast_impl<To, CR, CRep, false, true> { struct quantity_cast_impl<To, CRatio, CRep, false, true> {
template<Quantity Q> template<Quantity Q>
static constexpr To cast(const Q& q) static constexpr To cast(const Q& q)
{ {
return To(static_cast<To::rep>(static_cast<CRep>(q.count()) * static_cast<CRep>(CR::num))); return To(static_cast<To::rep>(static_cast<CRep>(q.count()) * static_cast<CRep>(CRatio::num)));
} }
}; };
@@ -195,6 +195,7 @@ namespace units {
quantity() = default; quantity() = default;
quantity(const quantity&) = default; quantity(const quantity&) = default;
quantity(quantity&&) = default;
template<Scalar Rep2> template<Scalar Rep2>
requires std::convertible_to<Rep2, rep> && requires std::convertible_to<Rep2, rep> &&
@@ -213,7 +214,8 @@ namespace units {
{ {
} }
quantity& operator=(const quantity& other) = default; quantity& operator=(const quantity&) = default;
quantity& operator=(quantity&&) = default;
[[nodiscard]] constexpr rep count() const noexcept { return value_; } [[nodiscard]] constexpr rep count() const noexcept { return value_; }
@@ -331,7 +333,7 @@ namespace units {
{ {
using common_rep = decltype(q.count() * v); using common_rep = decltype(q.count() * v);
using ret = quantity<U, common_rep>; using ret = quantity<U, common_rep>;
return ret(ret(q).count() * v); return ret(q.count() * v);
} }
template<Scalar Rep1, typename U, typename Rep2> template<Scalar Rep1, typename U, typename Rep2>
@@ -370,9 +372,8 @@ namespace units {
using dim = dim_invert<typename U::dimension>; using dim = dim_invert<typename U::dimension>;
using common_rep = decltype(v / q.count()); using common_rep = decltype(v / q.count());
using den = quantity<U, common_rep>;
return ret(v / den(q).count());
using ret = quantity<downcast<unit<dim, ratio<U::ratio::den, U::ratio::num>>>, common_rep>; using ret = quantity<downcast<unit<dim, ratio<U::ratio::den, U::ratio::num>>>, common_rep>;
return ret(v / q.count());
} }
template<typename U, typename Rep1, Scalar Rep2> template<typename U, typename Rep1, Scalar Rep2>
@@ -383,7 +384,7 @@ namespace units {
using common_rep = decltype(q.count() / v); using common_rep = decltype(q.count() / v);
using ret = quantity<U, common_rep>; using ret = quantity<U, common_rep>;
return ret(ret(q).count() / v); return ret(q.count() / v);
} }
template<typename U1, typename Rep1, typename U2, typename Rep2> template<typename U1, typename Rep1, typename U2, typename Rep2>
@@ -413,14 +414,16 @@ namespace units {
template<typename U, typename Rep1, Scalar Rep2> template<typename U, typename Rep1, Scalar Rep2>
[[nodiscard]] constexpr Quantity AUTO operator%(const quantity<U, Rep1>& q, const Rep2& v) [[nodiscard]] constexpr Quantity AUTO operator%(const quantity<U, Rep1>& q, const Rep2& v)
requires (!treat_as_floating_point<Rep1> && !treat_as_floating_point<Rep2>)
{ {
using common_rep = decltype(q.count() % v); using common_rep = decltype(q.count() % v);
using ret = quantity<U, common_rep>; using ret = quantity<U, common_rep>;
return ret(ret(q).count() % v); return ret(q.count() % v);
} }
template<typename U1, typename Rep1, typename U2, typename Rep2> template<typename U1, typename Rep1, typename U2, typename Rep2>
[[nodiscard]] constexpr Quantity AUTO operator%(const quantity<U1, Rep1>& lhs, const quantity<U2, Rep2>& rhs) [[nodiscard]] constexpr Quantity AUTO operator%(const quantity<U1, Rep1>& lhs, const quantity<U2, Rep2>& rhs)
requires (!treat_as_floating_point<Rep1> && !treat_as_floating_point<Rep2>)
{ {
using common_rep = decltype(lhs.count() % rhs.count()); using common_rep = decltype(lhs.count() % rhs.count());
using ret = common_quantity<quantity<U1, Rep1>, quantity<U2, Rep2>, common_rep>; using ret = common_quantity<quantity<U1, Rep1>, quantity<U2, Rep2>, common_rep>;
@@ -431,8 +434,8 @@ namespace units {
[[nodiscard]] constexpr bool operator==(const quantity<U1, Rep1>& lhs, const quantity<U2, Rep2>& rhs) [[nodiscard]] constexpr bool operator==(const quantity<U1, Rep1>& lhs, const quantity<U2, Rep2>& rhs)
requires same_dim<typename U1::dimension, typename U2::dimension> requires same_dim<typename U1::dimension, typename U2::dimension>
{ {
using ct = common_quantity<quantity<U1, Rep1>, quantity<U2, Rep2>>; using cq = common_quantity<quantity<U1, Rep1>, quantity<U2, Rep2>>;
return ct(lhs).count() == ct(rhs).count(); return cq(lhs).count() == cq(rhs).count();
} }
template<typename U1, typename Rep1, typename U2, typename Rep2> template<typename U1, typename Rep1, typename U2, typename Rep2>
@@ -446,8 +449,8 @@ namespace units {
[[nodiscard]] constexpr bool operator<(const quantity<U1, Rep1>& lhs, const quantity<U2, Rep2>& rhs) [[nodiscard]] constexpr bool operator<(const quantity<U1, Rep1>& lhs, const quantity<U2, Rep2>& rhs)
requires same_dim<typename U1::dimension, typename U2::dimension> requires same_dim<typename U1::dimension, typename U2::dimension>
{ {
using ct = common_quantity<quantity<U1, Rep1>, quantity<U2, Rep2>>; using cq = common_quantity<quantity<U1, Rep1>, quantity<U2, Rep2>>;
return ct(lhs).count() < ct(rhs).count(); return cq(lhs).count() < cq(rhs).count();
} }
template<typename U1, typename Rep1, typename U2, typename Rep2> template<typename U1, typename Rep1, typename U2, typename Rep2>