diff --git a/src/include/units/quantity_cast.h b/src/include/units/quantity_cast.h index fcb5296e..873cce4b 100644 --- a/src/include/units/quantity_cast.h +++ b/src/include/units/quantity_cast.h @@ -67,8 +67,49 @@ concept QuantityOf = Quantity && Dimension && equivalent_dim -struct quantity_cast_impl { +template +struct quantity_cast_impl; + +template +struct quantity_cast_impl { + template + static constexpr To cast(const Q& q) + { + return To(static_cast(q.count())); + } +}; + +template +struct quantity_cast_impl { + template + static constexpr To cast(const Q& q) + { + if constexpr (treat_as_floating_point) { + return To(static_cast(static_cast(q.count()) * static_cast(fpow10(CRatio::exp)))); + } else { + if constexpr (CRatio::exp > 0) { + return To(static_cast(static_cast(q.count()) * static_cast(ipow10(CRatio::exp)))); + } + else { + return To(static_cast(static_cast(q.count()) / static_cast(ipow10(-CRatio::exp)))); + } + } + } +}; + +template +struct quantity_cast_impl { + template + static constexpr To cast(const Q& q) + { + return To(static_cast(static_cast(q.count()) * + (static_cast(CRatio::num) / + static_cast(CRatio::den)))); + } +}; + +template +struct quantity_cast_impl { template static constexpr To cast(const Q& q) { @@ -78,50 +119,171 @@ struct quantity_cast_impl { (static_cast(CRatio::num) / static_cast(CRatio::den)))); } else { - return To(static_cast(static_cast(q.count()) * - static_cast(CRatio::num) * - static_cast(CRatio::exp > 0 ? ipow10(CRatio::exp) : 1) / - (static_cast(CRatio::den) * - static_cast(CRatio::exp < 0 ? ipow10(-CRatio::exp) : 1)))); + if constexpr (CRatio::exp > 0) { + return To(static_cast(static_cast(q.count()) * + static_cast(CRatio::num) * + static_cast(ipow10(CRatio::exp)) / + static_cast(CRatio::den))); + } + else { + return To(static_cast(static_cast(q.count()) * + static_cast(CRatio::num) / + (static_cast(CRatio::den) * + static_cast(ipow10(-CRatio::exp))))); + } } } }; -template -struct quantity_cast_impl { +template +struct quantity_cast_impl { template static constexpr To cast(const Q& q) { - if constexpr (treat_as_floating_point) { - return To(static_cast(static_cast(q.count()) * static_cast(fpow10(CRatio::exp)))); - } else { - return To(static_cast(static_cast(q.count()) * static_cast(ipow10(CRatio::exp)))); - } + return To(static_cast(static_cast(q.count()) / static_cast(CRatio::den))); } }; -template -struct quantity_cast_impl { +template +struct quantity_cast_impl { template static constexpr To cast(const Q& q) { if constexpr (treat_as_floating_point) { return To(static_cast(static_cast(q.count()) * static_cast(fpow10(CRatio::exp)) * (CRep{1} / static_cast(CRatio::den)))); } else { - return To(static_cast(static_cast(q.count()) * static_cast(ipow10(CRatio::exp)) / static_cast(CRatio::den))); + if constexpr (CRatio::exp > 0) { + return To(static_cast(static_cast(q.count()) * static_cast(ipow10(CRatio::exp)) / static_cast(CRatio::den))); + } + else { + return To(static_cast(static_cast(q.count()) / (static_cast(ipow10(-CRatio::exp)) * static_cast(CRatio::den)))); + } } } }; -template -struct quantity_cast_impl { +template +struct quantity_cast_impl { + template + static constexpr To cast(const Q& q) + { + return To(static_cast(static_cast(q.count()) * static_cast(CRatio::num))); + } +}; + +template +struct quantity_cast_impl { template static constexpr To cast(const Q& q) { if constexpr (treat_as_floating_point) { return To(static_cast(static_cast(q.count()) * static_cast(CRatio::num) * static_cast(fpow10(CRatio::exp)))); } else { - return To(static_cast(static_cast(q.count()) * static_cast(CRatio::num) * static_cast(ipow10(CRatio::exp)))); + if constexpr (CRatio::exp > 0) { + return To(static_cast(static_cast(q.count()) * static_cast(CRatio::num) * static_cast(ipow10(CRatio::exp)))); + } + else { + return To(static_cast(static_cast(q.count()) * static_cast(CRatio::num) / static_cast(ipow10(-CRatio::exp)))); + } + } + } +}; + +template +struct quantity_cast_impl { + template + static constexpr To cast(const Q& q) + { + if constexpr (treat_as_floating_point) { + return To(static_cast(q.count() * fpow10(CRatio::exp))); + } else { + if constexpr (CRatio::exp > 0) { + return To(static_cast(q.count() * ipow10(CRatio::exp))); + } + else { + return To(static_cast(q.count() / ipow10(-CRatio::exp))); + } + } + } +}; + +template +struct quantity_cast_impl { + template + static constexpr To cast(const Q& q) + { + return To(static_cast(q.count() * (CRatio::num / CRatio::den))); + } +}; + +template +struct quantity_cast_impl { + template + static constexpr To cast(const Q& q) + { + if constexpr (treat_as_floating_point) { + return To(static_cast(q.count() * fpow10(CRatio::exp) * (CRatio::num / CRatio::den))); + } else { + if constexpr (CRatio::exp > 0) { + return To(static_cast(q.count() * CRatio::num * ipow10(CRatio::exp) / CRatio::den)); + } + else { + return To(static_cast(q.count()) * CRatio::num / (CRatio::den * ipow10(-CRatio::exp))); + } + } + } +}; + +template +struct quantity_cast_impl { + template + static constexpr To cast(const Q& q) + { + return To(static_cast(q.count() / CRatio::den)); + } +}; + +template +struct quantity_cast_impl { + template + static constexpr To cast(const Q& q) + { + if constexpr (treat_as_floating_point) { + return To(static_cast(q.count() * fpow10(CRatio::exp) / CRatio::den)); + } else { + if constexpr (CRatio::exp > 0) { + return To(static_cast(q.count() * ipow10(CRatio::exp) / CRatio::den)); + } + else { + return To(static_cast(q.count() / (ipow10(-CRatio::exp) * CRatio::den))); + } + } + } +}; + +template +struct quantity_cast_impl { + template + static constexpr To cast(const Q& q) + { + return To(static_cast(q.count() * CRatio::num)); + } +}; + +template +struct quantity_cast_impl { + template + static constexpr To cast(const Q& q) + { + if constexpr (treat_as_floating_point) { + return To(static_cast(q.count() * CRatio::num * fpow10(CRatio::exp))); + } else { + if constexpr (CRatio::exp > 0) { + return To(static_cast(q.count() * CRatio::num * ipow10(CRatio::exp))); + } + else { + return To(static_cast(q.count() * CRatio::num / ipow10(-CRatio::exp))); + } } } }; @@ -169,7 +331,7 @@ template using c_rep = std::common_type_t; using ret_unit = downcast_unit; using ret = quantity; - using cast = detail::quantity_cast_impl; + using cast = detail::quantity_cast_impl; return cast::cast(q); }