From fa596fffc65df728f989d19c49755aff71bbc1ce Mon Sep 17 00:00:00 2001 From: Mateusz Pusz Date: Tue, 28 Nov 2023 11:52:37 +0100 Subject: [PATCH] refactor: :boom: `make_xxx` factory functions replaced with two-parameter constructors Resolves #521 --- docs/getting_started/quick_start.md | 6 +- .../character_of_a_quantity.md | 6 +- .../framework_basics/the_affine_space.md | 6 +- .../include/mp-units/bits/quantity_cast.h | 4 +- .../include/mp-units/bits/quantity_concepts.h | 7 -- .../mp-units/bits/quantity_point_concepts.h | 8 -- src/core/include/mp-units/bits/sudo_cast.h | 21 +++-- src/core/include/mp-units/quantity.h | 87 +++++++++---------- src/core/include/mp-units/quantity_point.h | 69 +++++++-------- src/core/include/mp-units/quantity_spec.h | 12 +-- src/core/include/mp-units/reference.h | 12 +-- src/utility/include/mp-units/math.h | 80 +++++++++-------- 12 files changed, 143 insertions(+), 175 deletions(-) diff --git a/docs/getting_started/quick_start.md b/docs/getting_started/quick_start.md index ca0b3e83..594b13ab 100644 --- a/docs/getting_started/quick_start.md +++ b/docs/getting_started/quick_start.md @@ -50,15 +50,15 @@ quantity q = 42 * m; namespace. In case someone doesn't like the multiply syntax or there is an ambiguity between `operator*` -provided by this and other libraries, a quantity can also be created with a dedicated factory -function: +provided by this and other libraries, a quantity can also be created with a two-parameter +constructor: ```cpp #include using namespace mp_units; -quantity q = make_quantity(42); +quantity q{42, si::metre}; ``` diff --git a/docs/users_guide/framework_basics/character_of_a_quantity.md b/docs/users_guide/framework_basics/character_of_a_quantity.md index 8f70509e..3cf18269 100644 --- a/docs/users_guide/framework_basics/character_of_a_quantity.md +++ b/docs/users_guide/framework_basics/character_of_a_quantity.md @@ -191,10 +191,10 @@ Quantity auto q = la_vector{1, 2, 3} * isq::velocity[m / s]; In case there is an ambiguity of `operator*` between **mp-units** and a linear algebra library, we can either: -- use `make_quantity` factory function +- use two-parameter constructor ```cpp - Quantity auto q = make_quantity(la_vector{1, 2, 3}); + Quantity auto q = quantity{la_vector{1, 2, 3}, isq::velocity[m / s]}; ``` - provide a dedicated overload of `operator*` that will resolve the ambiguity and wrap the above @@ -203,7 +203,7 @@ either: template Quantity auto operator*(la_vector rep, R) { - return make_quantity(rep); + return quantity{rep, R{}}; } ``` diff --git a/docs/users_guide/framework_basics/the_affine_space.md b/docs/users_guide/framework_basics/the_affine_space.md index fd328276..003068c1 100644 --- a/docs/users_guide/framework_basics/the_affine_space.md +++ b/docs/users_guide/framework_basics/the_affine_space.md @@ -102,11 +102,11 @@ quantity_point qp3 = mean_sea_level - 42 * m; Similarly to [creation of a quantity](../../getting_started/quick_start.md#creating-a-quantity), if someone does not like the operator-based syntax to create a `quantity_point`, the same results -can be achieved with `make_quantity_point` factory function: +can be achieved with two-parameter constructor: ```cpp -quantity_point qp4 = make_quantity_point(42 * m); -quantity_point qp5 = make_quantity_point(-42 * m); +quantity_point qp4{42 * m, mean_sea_level}; +quantity_point qp5{-42 * m, mean_sea_level}; ``` The provided `quantity` representing an offset from the origin is stored inside the `quantity_point` diff --git a/src/core/include/mp-units/bits/quantity_cast.h b/src/core/include/mp-units/bits/quantity_cast.h index 93954da2..b03c7ea3 100644 --- a/src/core/include/mp-units/bits/quantity_cast.h +++ b/src/core/include/mp-units/bits/quantity_cast.h @@ -51,9 +51,9 @@ template { if constexpr (detail::QuantityKindSpec> && AssociatedUnit>) - return make_quantity(std::forward(q).numerical_value_is_an_implementation_detail_); + return quantity{std::forward(q).numerical_value_is_an_implementation_detail_, Q::unit}; else - return make_quantity{}>(std::forward(q).numerical_value_is_an_implementation_detail_); + return quantity{std::forward(q).numerical_value_is_an_implementation_detail_, reference{}}; } } // namespace mp_units diff --git a/src/core/include/mp-units/bits/quantity_concepts.h b/src/core/include/mp-units/bits/quantity_concepts.h index 56c652b9..83d9c209 100644 --- a/src/core/include/mp-units/bits/quantity_concepts.h +++ b/src/core/include/mp-units/bits/quantity_concepts.h @@ -32,13 +32,6 @@ namespace mp_units { template Rep> class quantity; -#if defined MP_UNITS_COMP_CLANG && MP_UNITS_COMP_CLANG < 17 -template -#else -template -#endif -[[nodiscard]] constexpr quantity> make_quantity(Rep&& v); - namespace detail { template diff --git a/src/core/include/mp-units/bits/quantity_point_concepts.h b/src/core/include/mp-units/bits/quantity_point_concepts.h index b2d1091c..7d2fa735 100644 --- a/src/core/include/mp-units/bits/quantity_point_concepts.h +++ b/src/core/include/mp-units/bits/quantity_point_concepts.h @@ -109,14 +109,6 @@ template auto PO, RepresentationOf Rep> class quantity_point; -#if defined MP_UNITS_COMP_CLANG && MP_UNITS_COMP_CLANG < 17 -template -#else -template - requires ReferenceOf, PO.quantity_spec> -#endif -[[nodiscard]] constexpr quantity_point make_quantity_point(Q&& q); - namespace detail { template diff --git a/src/core/include/mp-units/bits/sudo_cast.h b/src/core/include/mp-units/bits/sudo_cast.h index bdc4f67e..2ce05e7f 100644 --- a/src/core/include/mp-units/bits/sudo_cast.h +++ b/src/core/include/mp-units/bits/sudo_cast.h @@ -57,17 +57,16 @@ template std::constructible_from::rep>) || (std::remove_reference_t::unit != To::unit)) // && scalable_with_)) // TODO how to constrain the second part here? -[[nodiscard]] constexpr Quantity auto sudo_cast(From&& q) +[[nodiscard]] constexpr To sudo_cast(From&& q) { constexpr auto q_unit = std::remove_reference_t::unit; if constexpr (q_unit == To::unit) { // no scaling of the number needed - return make_quantity(static_cast( - std::forward(q) - .numerical_value_is_an_implementation_detail_)); // this is the only (and recommended) way to do - // a truncating conversion on a number, so we are - // using static_cast to suppress all the compiler - // warnings on conversions + return {static_cast(std::forward(q).numerical_value_is_an_implementation_detail_), + To::reference}; // this is the only (and recommended) way to do + // a truncating conversion on a number, so we are + // using static_cast to suppress all the compiler + // warnings on conversions } else { // scale the number constexpr Magnitude auto c_mag = get_canonical_unit(q_unit).mag / get_canonical_unit(To::unit).mag; @@ -79,10 +78,10 @@ template using multiplier_type = conditional, std::common_type_t, c_mag_type>; constexpr auto val = [](Magnitude auto m) { return get_value(m); }; - return static_cast( - static_cast(std::forward(q).numerical_value_is_an_implementation_detail_) * val(num) / - val(den) * val(irr)) * - To::reference; + return {static_cast( + static_cast(std::forward(q).numerical_value_is_an_implementation_detail_) * val(num) / + val(den) * val(irr)), + To::reference}; } } diff --git a/src/core/include/mp-units/quantity.h b/src/core/include/mp-units/quantity.h index 3feacdcb..78839161 100644 --- a/src/core/include/mp-units/quantity.h +++ b/src/core/include/mp-units/quantity.h @@ -94,7 +94,7 @@ using common_quantity_for = quantity Rep = double> class quantity { public: - Rep numerical_value_is_an_implementation_detail_; // needs to be public for a structural type + Rep numerical_value_is_an_implementation_detail_; ///< needs to be public for a structural type // member types and values static constexpr Reference auto reference = R; @@ -107,25 +107,25 @@ public: [[nodiscard]] static constexpr quantity zero() noexcept requires requires { quantity_values::zero(); } { - return quantity(quantity_values::zero()); + return {quantity_values::zero(), R}; } [[nodiscard]] static constexpr quantity one() noexcept requires requires { quantity_values::one(); } { - return quantity(quantity_values::one()); + return {quantity_values::one(), R}; } [[nodiscard]] static constexpr quantity min() noexcept requires requires { quantity_values::min(); } { - return quantity(quantity_values::min()); + return {quantity_values::min(), R}; } [[nodiscard]] static constexpr quantity max() noexcept requires requires { quantity_values::max(); } { - return quantity(quantity_values::max()); + return {quantity_values::max(), R}; } // construction, assignment, destruction @@ -133,6 +133,19 @@ public: quantity(const quantity&) = default; quantity(quantity&&) = default; + template + requires std::same_as, Rep> + constexpr quantity(Value&& v, std::remove_const_t) : + numerical_value_is_an_implementation_detail_(std::forward(v)) + { + } + + template + requires detail::QuantityConvertibleTo>, quantity> + constexpr quantity(Value&& v, R2) : quantity(quantity>{std::forward(v), R2{}}) + { + } + template Q> constexpr explicit(!std::convertible_to) quantity(const Q& q) : numerical_value_is_an_implementation_detail_( @@ -146,7 +159,8 @@ public: constexpr explicit(is_specialization_of::to_numerical_value(std::declval())), convert_explicitly> || !std::convertible_to) quantity(const Q& q) : - quantity(make_quantity::reference>(quantity_like_traits::to_numerical_value(q).value)) + quantity( + ::mp_units::quantity{quantity_like_traits::to_numerical_value(q).value, quantity_like_traits::reference}) { } @@ -238,7 +252,7 @@ public: } -> std::common_with; } { - return make_quantity(+numerical_value_is_an_implementation_detail_); + return ::mp_units::quantity{+numerical_value_is_an_implementation_detail_, reference}; } [[nodiscard]] constexpr Quantity auto operator-() const @@ -248,7 +262,7 @@ public: } -> std::common_with; } { - return make_quantity(-numerical_value_is_an_implementation_detail_); + return ::mp_units::quantity{-numerical_value_is_an_implementation_detail_, reference}; } template @@ -270,7 +284,7 @@ public: } -> std::common_with; } { - return make_quantity(numerical_value_is_an_implementation_detail_++); + return ::mp_units::quantity{numerical_value_is_an_implementation_detail_++, reference}; } template @@ -292,7 +306,7 @@ public: } -> std::common_with; } { - return make_quantity(numerical_value_is_an_implementation_detail_--); + return ::mp_units::quantity{numerical_value_is_an_implementation_detail_--, reference}; } // compound assignment operators @@ -388,23 +402,13 @@ public: lhs.numerical_value_is_an_implementation_detail_ /= rhs.numerical_value_is_an_implementation_detail_; return std::forward(lhs); } - -private: -#if defined MP_UNITS_COMP_CLANG && MP_UNITS_COMP_CLANG < 17 - template -#else - template -#endif - friend constexpr quantity> make_quantity(Rep2&&); - - template - requires std::constructible_from - constexpr explicit quantity(Value&& v) : numerical_value_is_an_implementation_detail_(std::forward(v)) - { - } }; // CTAD +template + requires RepresentationOf +quantity(Value v, R) -> quantity; + template explicit( is_specialization_of::to_numerical_value(std::declval())), convert_explicitly>) @@ -418,8 +422,8 @@ template using ret = detail::common_quantity_for, quantity, quantity>; const ret ret_lhs(lhs); const ret ret_rhs(rhs); - return make_quantity(ret_lhs.numerical_value_ref_in(ret::unit) + - ret_rhs.numerical_value_ref_in(ret::unit)); + return quantity{ret_lhs.numerical_value_ref_in(ret::unit) + ret_rhs.numerical_value_ref_in(ret::unit), + ret::reference}; } template @@ -429,8 +433,8 @@ template using ret = detail::common_quantity_for, quantity, quantity>; const ret ret_lhs(lhs); const ret ret_rhs(rhs); - return make_quantity(ret_lhs.numerical_value_ref_in(ret::unit) - - ret_rhs.numerical_value_ref_in(ret::unit)); + return quantity{ret_lhs.numerical_value_ref_in(ret::unit) - ret_rhs.numerical_value_ref_in(ret::unit), + ret::reference}; } template @@ -442,15 +446,15 @@ template using ret = detail::common_quantity_for, quantity, quantity>; const ret ret_lhs(lhs); const ret ret_rhs(rhs); - return make_quantity(ret_lhs.numerical_value_ref_in(ret::unit) % - ret_rhs.numerical_value_ref_in(ret::unit)); + return quantity{ret_lhs.numerical_value_ref_in(ret::unit) % ret_rhs.numerical_value_ref_in(ret::unit), + ret::reference}; } template requires detail::InvocableQuantities, quantity, quantity> [[nodiscard]] constexpr Quantity auto operator*(const quantity& lhs, const quantity& rhs) { - return make_quantity(lhs.numerical_value_ref_in(get_unit(R1)) * rhs.numerical_value_ref_in(get_unit(R2))); + return quantity{lhs.numerical_value_ref_in(get_unit(R1)) * rhs.numerical_value_ref_in(get_unit(R2)), R1 * R2}; } template @@ -458,7 +462,7 @@ template detail::InvokeResultOf, Rep, const Value&> [[nodiscard]] constexpr Quantity auto operator*(const quantity& q, const Value& v) { - return make_quantity(q.numerical_value_ref_in(get_unit(R)) * v); + return quantity{q.numerical_value_ref_in(get_unit(R)) * v, R}; } template @@ -466,7 +470,7 @@ template detail::InvokeResultOf, const Value&, Rep> [[nodiscard]] constexpr Quantity auto operator*(const Value& v, const quantity& q) { - return make_quantity(v * q.numerical_value_ref_in(get_unit(R))); + return quantity{v * q.numerical_value_ref_in(get_unit(R)), R}; } template @@ -474,7 +478,7 @@ template [[nodiscard]] constexpr Quantity auto operator/(const quantity& lhs, const quantity& rhs) { gsl_ExpectsAudit(rhs != rhs.zero()); - return make_quantity(lhs.numerical_value_ref_in(get_unit(R1)) / rhs.numerical_value_ref_in(get_unit(R2))); + return quantity{lhs.numerical_value_ref_in(get_unit(R1)) / rhs.numerical_value_ref_in(get_unit(R2)), R1 / R2}; } template @@ -483,7 +487,7 @@ template [[nodiscard]] constexpr Quantity auto operator/(const quantity& q, const Value& v) { gsl_ExpectsAudit(v != quantity_values::zero()); - return make_quantity(q.numerical_value_ref_in(get_unit(R)) / v); + return quantity{q.numerical_value_ref_in(get_unit(R)) / v, R}; } template @@ -491,7 +495,7 @@ template detail::InvokeResultOf, const Value&, Rep> [[nodiscard]] constexpr Quantity auto operator/(const Value& v, const quantity& q) { - return make_quantity<::mp_units::one / R>(v / q.numerical_value_ref_in(get_unit(R))); + return quantity{v / q.numerical_value_ref_in(get_unit(R)), ::mp_units::one / R}; } template @@ -516,17 +520,6 @@ template return ct_lhs.numerical_value_ref_in(ct::unit) <=> ct_rhs.numerical_value_ref_in(ct::unit); } -// make_quantity -#if defined MP_UNITS_COMP_CLANG && MP_UNITS_COMP_CLANG < 17 -template -#else -template -#endif -[[nodiscard]] constexpr quantity> make_quantity(Rep&& v) -{ - return quantity>(std::forward(v)); -} - } // namespace mp_units namespace std { diff --git a/src/core/include/mp-units/quantity_point.h b/src/core/include/mp-units/quantity_point.h index ad842a4f..3d7a00ed 100644 --- a/src/core/include/mp-units/quantity_point.h +++ b/src/core/include/mp-units/quantity_point.h @@ -88,13 +88,13 @@ public: [[nodiscard]] static constexpr quantity_point min() noexcept requires requires { quantity_type::min(); } { - return quantity_point{quantity_type::min()}; + return {quantity_type::min(), PO}; } [[nodiscard]] static constexpr quantity_point max() noexcept requires requires { quantity_type::max(); } { - return quantity_point{quantity_type::max()}; + return {quantity_type::max(), PO}; } // construction, assignment, destruction @@ -102,6 +102,24 @@ public: quantity_point(const quantity_point&) = default; quantity_point(quantity_point&&) = default; + template + requires std::same_as, quantity_type> + constexpr quantity_point(Q&& q, std::remove_const_t) : + quantity_from_origin_is_an_implementation_detail_(std::forward(q)) + { + } + + template + requires Quantity> && std::constructible_from && + ReferenceOf::reference)>, PO2::quantity_spec> && + detail::SameAbsolutePointOriginAs + quantity_point(Q&& q, PO2) : + quantity_point( + quantity_point::reference, PO2{}, typename std::remove_reference_t::rep>{ + std::forward(q), PO2{}}) + { + } + template QP> requires std::constructible_from // TODO add perfect forwarding @@ -142,7 +160,7 @@ public: if constexpr (is_same_v>) return *this; else - return make_quantity_point(*this - new_origin); + return ::mp_units::quantity_point{*this - new_origin, new_origin}; } // data access @@ -173,14 +191,14 @@ public: requires detail::QuantityConvertibleTo> [[nodiscard]] constexpr QuantityPoint auto in(U) const { - return make_quantity_point(quantity_ref_from(PO).in(U{})); + return ::mp_units::quantity_point{quantity_ref_from(PO).in(U{}), PO}; } template U> requires requires(quantity_type q) { value_cast(q); } [[nodiscard]] constexpr QuantityPoint auto force_in(U) const { - return make_quantity_point(quantity_ref_from(PO).force_in(U{})); + return ::mp_units::quantity_point{quantity_ref_from(PO).force_in(U{}), PO}; } // conversion operators @@ -234,7 +252,7 @@ public: [[nodiscard]] constexpr quantity_point operator++(int) requires requires { quantity_from_origin_is_an_implementation_detail_++; } { - return quantity_point(quantity_from_origin_is_an_implementation_detail_++); + return {quantity_from_origin_is_an_implementation_detail_++, PO}; } template @@ -249,7 +267,7 @@ public: [[nodiscard]] constexpr quantity_point operator--(int) requires requires { quantity_from_origin_is_an_implementation_detail_--; } { - return quantity_point(quantity_from_origin_is_an_implementation_detail_--); + return {quantity_from_origin_is_an_implementation_detail_--, PO}; } // compound assignment operators @@ -270,25 +288,12 @@ public: qp.quantity_from_origin_is_an_implementation_detail_ -= q; return std::forward(qp); } - -private: -#if defined MP_UNITS_COMP_CLANG && MP_UNITS_COMP_CLANG < 17 - template -#else - template - requires ReferenceOf, PO2.quantity_spec> -#endif - friend constexpr quantity_point make_quantity_point(Q&&); - - template - requires std::constructible_from && - ReferenceOf, PO.quantity_spec> - constexpr explicit quantity_point(Q&& q) : quantity_from_origin_is_an_implementation_detail_(std::forward(q)) - { - } }; // CTAD +template PO> +quantity_point(Q q, PO) -> quantity_point; + template explicit( is_specialization_of::to_quantity(std::declval())), convert_explicitly>) @@ -303,7 +308,7 @@ template const quantity& q) requires requires { qp.quantity_ref_from(PO1) + q; } { - return make_quantity_point(qp.quantity_ref_from(PO1) + q); + return quantity_point{qp.quantity_ref_from(PO1) + q, PO1}; } template @@ -320,7 +325,7 @@ template requires ReferenceOf, PO::quantity_spec> [[nodiscard]] constexpr quantity_point operator+(PO, Q&& q) { - return make_quantity_point(std::forward(q)); + return quantity_point{std::forward(q), PO{}}; } template @@ -337,7 +342,7 @@ template const quantity& q) requires requires { qp.quantity_ref_from(PO1) - q; } { - return make_quantity_point(qp.quantity_ref_from(PO1) - q); + return quantity_point{qp.quantity_ref_from(PO1) - q, PO1}; } template @@ -429,16 +434,4 @@ template QP2> return lhs - lhs.absolute_point_origin == rhs - rhs.absolute_point_origin; } -// make_quantity_point -#if defined MP_UNITS_COMP_CLANG && MP_UNITS_COMP_CLANG < 17 -template -#else -template - requires ReferenceOf, PO.quantity_spec> -#endif -[[nodiscard]] constexpr quantity_point make_quantity_point(Q&& q) -{ - return quantity_point(std::forward(q)); -} - } // namespace mp_units diff --git a/src/core/include/mp-units/quantity_spec.h b/src/core/include/mp-units/quantity_spec.h index 65766906..5f70d034 100644 --- a/src/core/include/mp-units/quantity_spec.h +++ b/src/core/include/mp-units/quantity_spec.h @@ -119,8 +119,8 @@ struct quantity_spec_interface { requires Quantity> && (explicitly_convertible(std::remove_reference_t::quantity_spec, self)) { - return make_quantity::unit>{}>( - std::forward(q).numerical_value_is_an_implementation_detail_); + return quantity{std::forward(q).numerical_value_is_an_implementation_detail_, + reference::unit>{}}; } #else template U> @@ -134,8 +134,8 @@ struct quantity_spec_interface { (explicitly_convertible(std::remove_reference_t::quantity_spec, Self_{})) [[nodiscard]] constexpr Quantity auto operator()(Q&& q) const { - return make_quantity::unit>{}>( - std::forward(q).numerical_value_is_an_implementation_detail_); + return quantity{std::forward(q).numerical_value_is_an_implementation_detail_, + reference::unit>{}}; } #endif }; @@ -311,8 +311,8 @@ struct quantity_spec : std::remove_const_t { (explicitly_convertible(std::remove_reference_t::quantity_spec, Self_{})) [[nodiscard]] constexpr Quantity auto operator()(Q&& q) const { - return make_quantity::unit>{}>( - std::forward(q).numerical_value_is_an_implementation_detail_); + return quantity{std::forward(q).numerical_value_is_an_implementation_detail_, + reference::unit> {}}; } #endif }; diff --git a/src/core/include/mp-units/reference.h b/src/core/include/mp-units/reference.h index 10633f98..607d21b1 100644 --- a/src/core/include/mp-units/reference.h +++ b/src/core/include/mp-units/reference.h @@ -179,14 +179,14 @@ template requires RepresentationOf, get_quantity_spec(R{}).character> [[nodiscard]] constexpr quantity> operator*(Rep&& lhs, R) { - return make_quantity(std::forward(lhs)); + return quantity{std::forward(lhs), R{}}; } template requires RepresentationOf, get_quantity_spec(R{}).character> [[nodiscard]] constexpr quantity> operator/(Rep&& lhs, R) { - return make_quantity(std::forward(lhs)); + return quantity{std::forward(lhs), inverse(R{})}; } template @@ -201,16 +201,16 @@ template requires Quantity> [[nodiscard]] constexpr Quantity auto operator*(Q&& q, R) { - return make_quantity::reference * R{}>( - std::forward(q).numerical_value_is_an_implementation_detail_); + return quantity{std::forward(q).numerical_value_is_an_implementation_detail_, + std::remove_cvref_t::reference * R{}}; } template requires Quantity> [[nodiscard]] constexpr Quantity auto operator/(Q&& q, R) { - return make_quantity::reference / R{}>( - std::forward(q).numerical_value_is_an_implementation_detail_); + return quantity{std::forward(q).numerical_value_is_an_implementation_detail_, + std::remove_cvref_t::reference / R{}}; } template diff --git a/src/utility/include/mp-units/math.h b/src/utility/include/mp-units/math.h index 120f0f09..1a6aaf25 100644 --- a/src/utility/include/mp-units/math.h +++ b/src/utility/include/mp-units/math.h @@ -63,8 +63,9 @@ template return q; } else { using std::pow; - return make_quantity(R)>( - static_cast(pow(q.numerical_value_ref_in(q.unit), static_cast(Num) / static_cast(Den)))); + return { + static_cast(pow(q.numerical_value_ref_in(q.unit), static_cast(Num) / static_cast(Den))), + pow(R)}; } } @@ -82,7 +83,7 @@ template requires { std::sqrt(q.numerical_value_ref_in(q.unit)); } { using std::sqrt; - return make_quantity(static_cast(sqrt(q.numerical_value_ref_in(q.unit)))); + return {static_cast(sqrt(q.numerical_value_ref_in(q.unit))), sqrt(R)}; } /** @@ -99,7 +100,7 @@ template requires { std::cbrt(q.numerical_value_ref_in(q.unit)); } { using std::cbrt; - return make_quantity(static_cast(cbrt(q.numerical_value_ref_in(q.unit)))); + return {static_cast(cbrt(q.numerical_value_ref_in(q.unit))), cbrt(R)}; } /** @@ -117,7 +118,7 @@ template auto R, typename Rep> { using std::exp; return value_cast( - make_quantity(R)>(static_cast(exp(q.force_numerical_value_in(q.unit))))); + quantity{static_cast(exp(q.force_numerical_value_in(q.unit))), detail::clone_reference_with(R)}); } /** @@ -132,7 +133,7 @@ template requires { std::abs(q.numerical_value_ref_in(q.unit)); } { using std::abs; - return make_quantity(static_cast(abs(q.numerical_value_ref_in(q.unit)))); + return {static_cast(abs(q.numerical_value_ref_in(q.unit))), R}; } /** @@ -147,7 +148,7 @@ template requires requires { std::numeric_limits::epsilon(); } [[nodiscard]] constexpr quantity epsilon(R r) noexcept { - return make_quantity(static_cast(std::numeric_limits::epsilon())); + return {static_cast(std::numeric_limits::epsilon()), r}; } /** @@ -174,11 +175,10 @@ template if constexpr (treat_as_floating_point) { using std::floor; if constexpr (To == get_unit(R)) { - return make_quantity(R)>( - static_cast(floor(q.numerical_value_ref_in(q.unit)))); + return {static_cast(floor(q.numerical_value_ref_in(q.unit))), detail::clone_reference_with(R)}; } else { return handle_signed_results( - make_quantity(R)>(static_cast(floor(q.force_numerical_value_in(To))))); + quantity{static_cast(floor(q.force_numerical_value_in(To))), detail::clone_reference_with(R)}); } } else { if constexpr (To == get_unit(R)) { @@ -213,11 +213,10 @@ template if constexpr (treat_as_floating_point) { using std::ceil; if constexpr (To == get_unit(R)) { - return make_quantity(R)>( - static_cast(ceil(q.numerical_value_ref_in(q.unit)))); + return {static_cast(ceil(q.numerical_value_ref_in(q.unit))), detail::clone_reference_with(R)}; } else { return handle_signed_results( - make_quantity(R)>(static_cast(ceil(q.force_numerical_value_in(To))))); + quantity{static_cast(ceil(q.force_numerical_value_in(To))), detail::clone_reference_with(R)}); } } else { if constexpr (To == get_unit(R)) { @@ -248,8 +247,7 @@ template if constexpr (To == get_unit(R)) { if constexpr (treat_as_floating_point) { using std::round; - return make_quantity(R)>( - static_cast(round(q.numerical_value_ref_in(q.unit)))); + return {static_cast(round(q.numerical_value_ref_in(q.unit))), detail::clone_reference_with(R)}; } else { return q.force_in(To); } @@ -299,7 +297,7 @@ template constexpr auto ref = common_reference(R1, R2); constexpr auto unit = get_unit(ref); using std::hypot; - return make_quantity(hypot(x.numerical_value_in(unit), y.numerical_value_in(unit))); + return quantity{hypot(x.numerical_value_in(unit), y.numerical_value_in(unit)), ref}; } /** @@ -323,7 +321,7 @@ template constexpr auto ref = common_reference(R1, R2); constexpr auto unit = get_unit(ref); using std::hypot; - return make_quantity(hypot(x.numerical_value_in(unit), y.numerical_value_in(unit), z.numerical_value_in(unit))); + return quantity{hypot(x.numerical_value_in(unit), y.numerical_value_in(unit), z.numerical_value_in(unit)), ref}; } namespace isq { @@ -338,9 +336,9 @@ template auto R, typename Rep> // check what is the return type when called with the integral value using rep = decltype(sin(q.force_numerical_value_in(si::radian))); // use this type ahead of calling the function to prevent narrowing if a unit conversion is needed - return make_quantity(sin(value_cast(q).numerical_value_in(si::radian))); + return quantity{sin(value_cast(q).numerical_value_in(si::radian)), one}; } else - return make_quantity(sin(q.numerical_value_in(si::radian))); + return quantity{sin(q.numerical_value_in(si::radian)), one}; } template auto R, typename Rep> @@ -353,9 +351,9 @@ template auto R, typename Rep> // check what is the return type when called with the integral value using rep = decltype(cos(q.force_numerical_value_in(si::radian))); // use this type ahead of calling the function to prevent narrowing if a unit conversion is needed - return make_quantity(cos(value_cast(q).numerical_value_in(si::radian))); + return quantity{cos(value_cast(q).numerical_value_in(si::radian)), one}; } else - return make_quantity(cos(q.numerical_value_in(si::radian))); + return quantity{cos(q.numerical_value_in(si::radian)), one}; } template auto R, typename Rep> @@ -368,9 +366,9 @@ template auto R, typename Rep> // check what is the return type when called with the integral value using rep = decltype(tan(q.force_numerical_value_in(si::radian))); // use this type ahead of calling the function to prevent narrowing if a unit conversion is needed - return make_quantity(tan(value_cast(q).numerical_value_in(si::radian))); + return quantity{tan(value_cast(q).numerical_value_in(si::radian)), one}; } else - return make_quantity(tan(q.numerical_value_in(si::radian))); + return quantity{tan(q.numerical_value_in(si::radian)), one}; } template auto R, typename Rep> @@ -383,9 +381,9 @@ template auto R, typename Rep> // check what is the return type when called with the integral value using rep = decltype(asin(q.force_numerical_value_in(one))); // use this type ahead of calling the function to prevent narrowing if a unit conversion is needed - return make_quantity(asin(value_cast(q).numerical_value_in(one))); + return quantity{asin(value_cast(q).numerical_value_in(one)), si::radian}; } else - return make_quantity(asin(q.numerical_value_in(one))); + return quantity{asin(q.numerical_value_in(one)), si::radian}; } template auto R, typename Rep> @@ -398,9 +396,9 @@ template auto R, typename Rep> // check what is the return type when called with the integral value using rep = decltype(acos(q.force_numerical_value_in(one))); // use this type ahead of calling the function to prevent narrowing if a unit conversion is needed - return make_quantity(acos(value_cast(q).numerical_value_in(one))); + return quantity{acos(value_cast(q).numerical_value_in(one)), si::radian}; } else - return make_quantity(acos(q.numerical_value_in(one))); + return quantity{acos(q.numerical_value_in(one)), si::radian}; } template auto R, typename Rep> @@ -413,9 +411,9 @@ template auto R, typename Rep> // check what is the return type when called with the integral value using rep = decltype(atan(q.force_numerical_value_in(one))); // use this type ahead of calling the function to prevent narrowing if a unit conversion is needed - return make_quantity(atan(value_cast(q).numerical_value_in(one))); + return quantity{atan(value_cast(q).numerical_value_in(one)), si::radian}; } else - return make_quantity(atan(q.numerical_value_in(one))); + return quantity{atan(q.numerical_value_in(one)), si::radian}; } } // namespace isq @@ -432,9 +430,9 @@ template auto R, typename Rep> // check what is the return type when called with the integral value using rep = decltype(sin(q.force_numerical_value_in(radian))); // use this type ahead of calling the function to prevent narrowing if a unit conversion is needed - return make_quantity(sin(value_cast(q).numerical_value_in(radian))); + return quantity{sin(value_cast(q).numerical_value_in(radian)), one}; } else - return make_quantity(sin(q.numerical_value_in(radian))); + return quantity{sin(q.numerical_value_in(radian)), one}; } template auto R, typename Rep> @@ -447,9 +445,9 @@ template auto R, typename Rep> // check what is the return type when called with the integral value using rep = decltype(cos(q.force_numerical_value_in(radian))); // use this type ahead of calling the function to prevent narrowing if a unit conversion is needed - return make_quantity(cos(value_cast(q).numerical_value_in(radian))); + return quantity{cos(value_cast(q).numerical_value_in(radian)), one}; } else - return make_quantity(cos(q.numerical_value_in(radian))); + return quantity{cos(q.numerical_value_in(radian)), one}; } template auto R, typename Rep> @@ -462,9 +460,9 @@ template auto R, typename Rep> // check what is the return type when called with the integral value using rep = decltype(tan(q.force_numerical_value_in(radian))); // use this type ahead of calling the function to prevent narrowing if a unit conversion is needed - return make_quantity(tan(value_cast(q).numerical_value_in(radian))); + return quantity{tan(value_cast(q).numerical_value_in(radian)), one}; } else - return make_quantity(tan(q.numerical_value_in(radian))); + return quantity{tan(q.numerical_value_in(radian)), one}; } template auto R, typename Rep> @@ -477,9 +475,9 @@ template auto R, typename Rep> // check what is the return type when called with the integral value using rep = decltype(asin(q.force_numerical_value_in(one))); // use this type ahead of calling the function to prevent narrowing if a unit conversion is needed - return make_quantity(asin(value_cast(q).numerical_value_in(one))); + return quantity{asin(value_cast(q).numerical_value_in(one)), radian}; } else - return make_quantity(asin(q.numerical_value_in(one))); + return quantity{asin(q.numerical_value_in(one)), radian}; } template auto R, typename Rep> @@ -492,9 +490,9 @@ template auto R, typename Rep> // check what is the return type when called with the integral value using rep = decltype(acos(q.force_numerical_value_in(one))); // use this type ahead of calling the function to prevent narrowing if a unit conversion is needed - return make_quantity(acos(value_cast(q).numerical_value_in(one))); + return quantity{acos(value_cast(q).numerical_value_in(one)), radian}; } else - return make_quantity(acos(q.numerical_value_in(one))); + return quantity{acos(q.numerical_value_in(one)), radian}; } template auto R, typename Rep> @@ -507,9 +505,9 @@ template auto R, typename Rep> // check what is the return type when called with the integral value using rep = decltype(atan(q.force_numerical_value_in(one))); // use this type ahead of calling the function to prevent narrowing if a unit conversion is needed - return make_quantity(atan(value_cast(q).numerical_value_in(one))); + return quantity{atan(value_cast(q).numerical_value_in(one)), radian}; } else - return make_quantity(atan(q.numerical_value_in(one))); + return quantity{atan(q.numerical_value_in(one)), radian}; } } // namespace angular