From e4cd4ea8c8078d669ade5b161def400249db6e3b Mon Sep 17 00:00:00 2001 From: Mateusz Pusz Date: Wed, 6 Nov 2019 20:17:16 +0000 Subject: [PATCH] UnitRep concept introduced --- src/include/units/quantity.h | 77 ++++++++++++++++++------------------ 1 file changed, 39 insertions(+), 38 deletions(-) diff --git a/src/include/units/quantity.h b/src/include/units/quantity.h index f8ab68dc..b7c901ce 100644 --- a/src/include/units/quantity.h +++ b/src/include/units/quantity.h @@ -23,6 +23,7 @@ #pragma once #include +#include #include #include #include @@ -46,11 +47,20 @@ namespace units { concept QuantityOf = Quantity && Dimension && same_dim; // Scalar - template concept Scalar = (!Quantity) && Number; - template + // UnitRep + template + concept UnitRep = Scalar && + (treat_as_floating_point == false || + requires(T&& a) { + { ::units::isfinite(std::forward(a)) } -> bool; + { ::units::isnan(std::forward(a)) } -> bool; + }); + + + template class quantity; namespace detail { @@ -63,7 +73,7 @@ namespace units { // common_quantity namespace detail { - template + template struct common_quantity_impl; template @@ -81,14 +91,9 @@ namespace units { } // namespace detail - template> + template> using common_quantity = detail::common_quantity_impl::type; - // treat_as_floating_point - - template // TODO Conceptify that - inline constexpr bool treat_as_floating_point = std::is_floating_point_v; - // quantity_cast namespace detail { @@ -153,7 +158,7 @@ namespace units { return cast::cast(q); } - template + template [[nodiscard]] constexpr quantity quantity_cast(const quantity& q) { return quantity_cast>(q); @@ -165,7 +170,7 @@ namespace units { return quantity_cast>(q); } - template + template [[nodiscard]] constexpr quantity quantity_cast(const quantity& q) { return quantity_cast>(q); @@ -173,7 +178,7 @@ namespace units { // quantity_values - template + template struct quantity_values { static constexpr Rep zero() noexcept { return Rep(0); } static constexpr Rep one() noexcept { return Rep(1); } @@ -183,7 +188,7 @@ namespace units { // quantity - template + template class quantity { Rep value_; @@ -196,10 +201,10 @@ namespace units { quantity(const quantity&) = default; quantity(quantity&&) = default; - template - requires std::convertible_to && - (treat_as_floating_point || (!treat_as_floating_point)) - constexpr explicit quantity(const Rep2& r): value_{static_cast(r)} + template + requires std::convertible_to && + (treat_as_floating_point || (!treat_as_floating_point)) + constexpr explicit quantity(const Value& r): value_{static_cast(r)} { } @@ -264,9 +269,9 @@ namespace units { return *this; } - template - constexpr quantity& operator%=(const Rep2& rhs) - requires (!treat_as_floating_point && !treat_as_floating_point) + template + constexpr quantity& operator%=(const Value& rhs) + requires (!treat_as_floating_point && !treat_as_floating_point) { value_ %= rhs; return *this; @@ -304,24 +309,22 @@ namespace units { return ret(ret(lhs).count() - ret(rhs).count()); } - template - [[nodiscard]] constexpr Quantity AUTO operator*(const quantity& q, const Rep2& v) - requires (!Quantity) + template + [[nodiscard]] constexpr Quantity AUTO operator*(const quantity& q, const Value& v) { using common_rep = decltype(q.count() * v); using ret = quantity; return ret(q.count() * v); } - template - [[nodiscard]] constexpr Quantity AUTO operator*(const Rep1& v, const quantity& q) - requires (!Quantity) + template + [[nodiscard]] constexpr Quantity AUTO operator*(const Value& v, const quantity& q) { return q * v; } template - [[nodiscard]] constexpr Scalar AUTO operator*(const quantity& lhs, const quantity& rhs) + [[nodiscard]] constexpr UnitRep AUTO operator*(const quantity& lhs, const quantity& rhs) requires same_dim> { using common_rep = decltype(lhs.count() * rhs.count()); @@ -341,9 +344,8 @@ namespace units { return ret(lhs.count() * rhs.count()); } - template - [[nodiscard]] constexpr Quantity AUTO operator/(const Rep1& v, const quantity& q) - requires (!Quantity) + template + [[nodiscard]] constexpr Quantity AUTO operator/(const Value& v, const quantity& q) { Expects(q != std::remove_cvref_t(0)); @@ -353,11 +355,10 @@ namespace units { return ret(v / q.count()); } - template - [[nodiscard]] constexpr Quantity AUTO operator/(const quantity& q, const Rep2& v) - requires (!Quantity) + template + [[nodiscard]] constexpr Quantity AUTO operator/(const quantity& q, const Value& v) { - Expects(v != Rep2{0}); + Expects(v != Value{0}); using common_rep = decltype(q.count() / v); using ret = quantity; @@ -365,7 +366,7 @@ namespace units { } template - [[nodiscard]] constexpr Scalar AUTO operator/(const quantity& lhs, const quantity& rhs) + [[nodiscard]] constexpr UnitRep AUTO operator/(const quantity& lhs, const quantity& rhs) requires same_dim { Expects(rhs != std::remove_cvref_t(0)); @@ -389,9 +390,9 @@ namespace units { return ret(lhs.count() / rhs.count()); } - template - [[nodiscard]] constexpr Quantity AUTO operator%(const quantity& q, const Rep2& v) - requires (!treat_as_floating_point && !treat_as_floating_point) + template + [[nodiscard]] constexpr Quantity AUTO operator%(const quantity& q, const Value& v) + requires (!treat_as_floating_point && !treat_as_floating_point) { using common_rep = decltype(q.count() % v); using ret = quantity;