refactor: 💥 make_xxx factory functions replaced with two-parameter constructors

Resolves #521
This commit is contained in:
Mateusz Pusz
2023-11-28 11:52:37 +01:00
parent 80129b32d7
commit fa596fffc6
12 changed files with 143 additions and 175 deletions

View File

@ -50,15 +50,15 @@ quantity q = 42 * m;
namespace. namespace.
In case someone doesn't like the multiply syntax or there is an ambiguity between `operator*` 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 provided by this and other libraries, a quantity can also be created with a two-parameter
function: constructor:
```cpp ```cpp
#include <mp-units/systems/si/si.h> #include <mp-units/systems/si/si.h>
using namespace mp_units; using namespace mp_units;
quantity q = make_quantity<si::metre>(42); quantity q{42, si::metre};
``` ```

View File

@ -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 In case there is an ambiguity of `operator*` between **mp-units** and a linear algebra library, we can
either: either:
- use `make_quantity` factory function - use two-parameter constructor
```cpp ```cpp
Quantity auto q = make_quantity<isq::velocity[m / s]>(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 - provide a dedicated overload of `operator*` that will resolve the ambiguity and wrap the above
@ -203,7 +203,7 @@ either:
template<Reference R> template<Reference R>
Quantity auto operator*(la_vector rep, R) Quantity auto operator*(la_vector rep, R)
{ {
return make_quantity<R{}>(rep); return quantity{rep, R{}};
} }
``` ```

View File

@ -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), 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 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 ```cpp
quantity_point qp4 = make_quantity_point<mean_sea_level>(42 * m); quantity_point qp4{42 * m, mean_sea_level};
quantity_point qp5 = make_quantity_point<mean_sea_level>(-42 * m); quantity_point qp5{-42 * m, mean_sea_level};
``` ```
The provided `quantity` representing an offset from the origin is stored inside the `quantity_point` The provided `quantity` representing an offset from the origin is stored inside the `quantity_point`

View File

@ -51,9 +51,9 @@ template<QuantitySpec auto ToQS, typename Q>
{ {
if constexpr (detail::QuantityKindSpec<std::remove_const_t<decltype(ToQS)>> && if constexpr (detail::QuantityKindSpec<std::remove_const_t<decltype(ToQS)>> &&
AssociatedUnit<std::remove_const_t<decltype(Q::unit)>>) AssociatedUnit<std::remove_const_t<decltype(Q::unit)>>)
return make_quantity<Q::unit>(std::forward<Q>(q).numerical_value_is_an_implementation_detail_); return quantity{std::forward<Q>(q).numerical_value_is_an_implementation_detail_, Q::unit};
else else
return make_quantity<reference<ToQS, Q::unit>{}>(std::forward<Q>(q).numerical_value_is_an_implementation_detail_); return quantity{std::forward<Q>(q).numerical_value_is_an_implementation_detail_, reference<ToQS, Q::unit>{}};
} }
} // namespace mp_units } // namespace mp_units

View File

@ -32,13 +32,6 @@ namespace mp_units {
template<Reference auto R, RepresentationOf<get_quantity_spec(R).character> Rep> template<Reference auto R, RepresentationOf<get_quantity_spec(R).character> Rep>
class quantity; class quantity;
#if defined MP_UNITS_COMP_CLANG && MP_UNITS_COMP_CLANG < 17
template<auto R, typename Rep>
#else
template<Reference auto R, typename Rep>
#endif
[[nodiscard]] constexpr quantity<R, std::remove_cvref_t<Rep>> make_quantity(Rep&& v);
namespace detail { namespace detail {
template<auto R, typename Rep> template<auto R, typename Rep>

View File

@ -109,14 +109,6 @@ template<Reference auto R, PointOriginFor<get_quantity_spec(R)> auto PO,
RepresentationOf<get_quantity_spec(R).character> Rep> RepresentationOf<get_quantity_spec(R).character> Rep>
class quantity_point; class quantity_point;
#if defined MP_UNITS_COMP_CLANG && MP_UNITS_COMP_CLANG < 17
template<auto PO, typename Q>
#else
template<PointOrigin auto PO, Quantity Q>
requires ReferenceOf<std::remove_const_t<decltype(Q::reference)>, PO.quantity_spec>
#endif
[[nodiscard]] constexpr quantity_point<Q::reference, PO, typename Q::rep> make_quantity_point(Q&& q);
namespace detail { namespace detail {
template<auto R, auto PO, typename Rep> template<auto R, auto PO, typename Rep>

View File

@ -57,17 +57,16 @@ template<Quantity To, typename From>
std::constructible_from<typename To::rep, typename std::remove_reference_t<From>::rep>) || std::constructible_from<typename To::rep, typename std::remove_reference_t<From>::rep>) ||
(std::remove_reference_t<From>::unit != To::unit)) // && scalable_with_<typename To::rep>)) (std::remove_reference_t<From>::unit != To::unit)) // && scalable_with_<typename To::rep>))
// TODO how to constrain the second part here? // 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<From>::unit; constexpr auto q_unit = std::remove_reference_t<From>::unit;
if constexpr (q_unit == To::unit) { if constexpr (q_unit == To::unit) {
// no scaling of the number needed // no scaling of the number needed
return make_quantity<To::reference>(static_cast<MP_UNITS_TYPENAME To::rep>( return {static_cast<MP_UNITS_TYPENAME To::rep>(std::forward<From>(q).numerical_value_is_an_implementation_detail_),
std::forward<From>(q) To::reference}; // this is the only (and recommended) way to do
.numerical_value_is_an_implementation_detail_)); // this is the only (and recommended) way to do // a truncating conversion on a number, so we are
// a truncating conversion on a number, so we are // using static_cast to suppress all the compiler
// using static_cast to suppress all the compiler // warnings on conversions
// warnings on conversions
} else { } else {
// scale the number // scale the number
constexpr Magnitude auto c_mag = get_canonical_unit(q_unit).mag / get_canonical_unit(To::unit).mag; constexpr Magnitude auto c_mag = get_canonical_unit(q_unit).mag / get_canonical_unit(To::unit).mag;
@ -79,10 +78,10 @@ template<Quantity To, typename From>
using multiplier_type = using multiplier_type =
conditional<treat_as_floating_point<c_rep_type>, std::common_type_t<c_mag_type, long double>, c_mag_type>; conditional<treat_as_floating_point<c_rep_type>, std::common_type_t<c_mag_type, long double>, c_mag_type>;
constexpr auto val = [](Magnitude auto m) { return get_value<multiplier_type>(m); }; constexpr auto val = [](Magnitude auto m) { return get_value<multiplier_type>(m); };
return static_cast<MP_UNITS_TYPENAME To::rep>( return {static_cast<MP_UNITS_TYPENAME To::rep>(
static_cast<c_rep_type>(std::forward<From>(q).numerical_value_is_an_implementation_detail_) * val(num) / static_cast<c_rep_type>(std::forward<From>(q).numerical_value_is_an_implementation_detail_) * val(num) /
val(den) * val(irr)) * val(den) * val(irr)),
To::reference; To::reference};
} }
} }

View File

@ -94,7 +94,7 @@ using common_quantity_for = quantity<common_reference(Q1::reference, Q2::referen
template<Reference auto R, RepresentationOf<get_quantity_spec(R).character> Rep = double> template<Reference auto R, RepresentationOf<get_quantity_spec(R).character> Rep = double>
class quantity { class quantity {
public: 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 // member types and values
static constexpr Reference auto reference = R; static constexpr Reference auto reference = R;
@ -107,25 +107,25 @@ public:
[[nodiscard]] static constexpr quantity zero() noexcept [[nodiscard]] static constexpr quantity zero() noexcept
requires requires { quantity_values<rep>::zero(); } requires requires { quantity_values<rep>::zero(); }
{ {
return quantity(quantity_values<rep>::zero()); return {quantity_values<rep>::zero(), R};
} }
[[nodiscard]] static constexpr quantity one() noexcept [[nodiscard]] static constexpr quantity one() noexcept
requires requires { quantity_values<rep>::one(); } requires requires { quantity_values<rep>::one(); }
{ {
return quantity(quantity_values<rep>::one()); return {quantity_values<rep>::one(), R};
} }
[[nodiscard]] static constexpr quantity min() noexcept [[nodiscard]] static constexpr quantity min() noexcept
requires requires { quantity_values<rep>::min(); } requires requires { quantity_values<rep>::min(); }
{ {
return quantity(quantity_values<rep>::min()); return {quantity_values<rep>::min(), R};
} }
[[nodiscard]] static constexpr quantity max() noexcept [[nodiscard]] static constexpr quantity max() noexcept
requires requires { quantity_values<rep>::max(); } requires requires { quantity_values<rep>::max(); }
{ {
return quantity(quantity_values<rep>::max()); return {quantity_values<rep>::max(), R};
} }
// construction, assignment, destruction // construction, assignment, destruction
@ -133,6 +133,19 @@ public:
quantity(const quantity&) = default; quantity(const quantity&) = default;
quantity(quantity&&) = default; quantity(quantity&&) = default;
template<typename Value>
requires std::same_as<std::remove_cvref_t<Value>, Rep>
constexpr quantity(Value&& v, std::remove_const_t<decltype(R)>) :
numerical_value_is_an_implementation_detail_(std::forward<Value>(v))
{
}
template<typename Value, Reference R2>
requires detail::QuantityConvertibleTo<quantity<R2{}, std::remove_cvref_t<Value>>, quantity>
constexpr quantity(Value&& v, R2) : quantity(quantity<R2{}, std::remove_cvref_t<Value>>{std::forward<Value>(v), R2{}})
{
}
template<detail::QuantityConvertibleTo<quantity> Q> template<detail::QuantityConvertibleTo<quantity> Q>
constexpr explicit(!std::convertible_to<typename Q::rep, Rep>) quantity(const Q& q) : constexpr explicit(!std::convertible_to<typename Q::rep, Rep>) quantity(const Q& q) :
numerical_value_is_an_implementation_detail_( numerical_value_is_an_implementation_detail_(
@ -146,7 +159,8 @@ public:
constexpr explicit(is_specialization_of<decltype(quantity_like_traits<Q>::to_numerical_value(std::declval<Q>())), constexpr explicit(is_specialization_of<decltype(quantity_like_traits<Q>::to_numerical_value(std::declval<Q>())),
convert_explicitly> || convert_explicitly> ||
!std::convertible_to<typename Q::rep, Rep>) quantity(const Q& q) : !std::convertible_to<typename Q::rep, Rep>) quantity(const Q& q) :
quantity(make_quantity<quantity_like_traits<Q>::reference>(quantity_like_traits<Q>::to_numerical_value(q).value)) quantity(
::mp_units::quantity{quantity_like_traits<Q>::to_numerical_value(q).value, quantity_like_traits<Q>::reference})
{ {
} }
@ -238,7 +252,7 @@ public:
} -> std::common_with<rep>; } -> std::common_with<rep>;
} }
{ {
return make_quantity<reference>(+numerical_value_is_an_implementation_detail_); return ::mp_units::quantity{+numerical_value_is_an_implementation_detail_, reference};
} }
[[nodiscard]] constexpr Quantity auto operator-() const [[nodiscard]] constexpr Quantity auto operator-() const
@ -248,7 +262,7 @@ public:
} -> std::common_with<rep>; } -> std::common_with<rep>;
} }
{ {
return make_quantity<reference>(-numerical_value_is_an_implementation_detail_); return ::mp_units::quantity{-numerical_value_is_an_implementation_detail_, reference};
} }
template<typename Q> template<typename Q>
@ -270,7 +284,7 @@ public:
} -> std::common_with<rep>; } -> std::common_with<rep>;
} }
{ {
return make_quantity<reference>(numerical_value_is_an_implementation_detail_++); return ::mp_units::quantity{numerical_value_is_an_implementation_detail_++, reference};
} }
template<typename Q> template<typename Q>
@ -292,7 +306,7 @@ public:
} -> std::common_with<rep>; } -> std::common_with<rep>;
} }
{ {
return make_quantity<reference>(numerical_value_is_an_implementation_detail_--); return ::mp_units::quantity{numerical_value_is_an_implementation_detail_--, reference};
} }
// compound assignment operators // compound assignment operators
@ -388,23 +402,13 @@ public:
lhs.numerical_value_is_an_implementation_detail_ /= rhs.numerical_value_is_an_implementation_detail_; lhs.numerical_value_is_an_implementation_detail_ /= rhs.numerical_value_is_an_implementation_detail_;
return std::forward<Q1>(lhs); return std::forward<Q1>(lhs);
} }
private:
#if defined MP_UNITS_COMP_CLANG && MP_UNITS_COMP_CLANG < 17
template<auto R2, typename Rep2>
#else
template<Reference auto R2, typename Rep2>
#endif
friend constexpr quantity<R2, std::remove_cvref_t<Rep2>> make_quantity(Rep2&&);
template<typename Value>
requires std::constructible_from<rep, Value&&>
constexpr explicit quantity(Value&& v) : numerical_value_is_an_implementation_detail_(std::forward<Value>(v))
{
}
}; };
// CTAD // CTAD
template<typename Value, Reference R>
requires RepresentationOf<Value, get_quantity_spec(R{}).character>
quantity(Value v, R) -> quantity<R{}, Value>;
template<QuantityLike Q> template<QuantityLike Q>
explicit( explicit(
is_specialization_of<decltype(quantity_like_traits<Q>::to_numerical_value(std::declval<Q>())), convert_explicitly>) is_specialization_of<decltype(quantity_like_traits<Q>::to_numerical_value(std::declval<Q>())), convert_explicitly>)
@ -418,8 +422,8 @@ template<auto R1, typename Rep1, auto R2, typename Rep2>
using ret = detail::common_quantity_for<std::plus<>, quantity<R1, Rep1>, quantity<R2, Rep2>>; using ret = detail::common_quantity_for<std::plus<>, quantity<R1, Rep1>, quantity<R2, Rep2>>;
const ret ret_lhs(lhs); const ret ret_lhs(lhs);
const ret ret_rhs(rhs); const ret ret_rhs(rhs);
return make_quantity<ret::reference>(ret_lhs.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_rhs.numerical_value_ref_in(ret::unit)); ret::reference};
} }
template<auto R1, typename Rep1, auto R2, typename Rep2> template<auto R1, typename Rep1, auto R2, typename Rep2>
@ -429,8 +433,8 @@ template<auto R1, typename Rep1, auto R2, typename Rep2>
using ret = detail::common_quantity_for<std::minus<>, quantity<R1, Rep1>, quantity<R2, Rep2>>; using ret = detail::common_quantity_for<std::minus<>, quantity<R1, Rep1>, quantity<R2, Rep2>>;
const ret ret_lhs(lhs); const ret ret_lhs(lhs);
const ret ret_rhs(rhs); const ret ret_rhs(rhs);
return make_quantity<ret::reference>(ret_lhs.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_rhs.numerical_value_ref_in(ret::unit)); ret::reference};
} }
template<auto R1, typename Rep1, auto R2, typename Rep2> template<auto R1, typename Rep1, auto R2, typename Rep2>
@ -442,15 +446,15 @@ template<auto R1, typename Rep1, auto R2, typename Rep2>
using ret = detail::common_quantity_for<std::modulus<>, quantity<R1, Rep1>, quantity<R2, Rep2>>; using ret = detail::common_quantity_for<std::modulus<>, quantity<R1, Rep1>, quantity<R2, Rep2>>;
const ret ret_lhs(lhs); const ret ret_lhs(lhs);
const ret ret_rhs(rhs); const ret ret_rhs(rhs);
return make_quantity<ret::reference>(ret_lhs.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_rhs.numerical_value_ref_in(ret::unit)); ret::reference};
} }
template<auto R1, typename Rep1, auto R2, typename Rep2> template<auto R1, typename Rep1, auto R2, typename Rep2>
requires detail::InvocableQuantities<std::multiplies<>, quantity<R1, Rep1>, quantity<R2, Rep2>> requires detail::InvocableQuantities<std::multiplies<>, quantity<R1, Rep1>, quantity<R2, Rep2>>
[[nodiscard]] constexpr Quantity auto operator*(const quantity<R1, Rep1>& lhs, const quantity<R2, Rep2>& rhs) [[nodiscard]] constexpr Quantity auto operator*(const quantity<R1, Rep1>& lhs, const quantity<R2, Rep2>& rhs)
{ {
return make_quantity<R1 * R2>(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<auto R, typename Rep, typename Value> template<auto R, typename Rep, typename Value>
@ -458,7 +462,7 @@ template<auto R, typename Rep, typename Value>
detail::InvokeResultOf<get_quantity_spec(R).character, std::multiplies<>, Rep, const Value&> detail::InvokeResultOf<get_quantity_spec(R).character, std::multiplies<>, Rep, const Value&>
[[nodiscard]] constexpr Quantity auto operator*(const quantity<R, Rep>& q, const Value& v) [[nodiscard]] constexpr Quantity auto operator*(const quantity<R, Rep>& q, const Value& v)
{ {
return make_quantity<R>(q.numerical_value_ref_in(get_unit(R)) * v); return quantity{q.numerical_value_ref_in(get_unit(R)) * v, R};
} }
template<typename Value, auto R, typename Rep> template<typename Value, auto R, typename Rep>
@ -466,7 +470,7 @@ template<typename Value, auto R, typename Rep>
detail::InvokeResultOf<get_quantity_spec(R).character, std::multiplies<>, const Value&, Rep> detail::InvokeResultOf<get_quantity_spec(R).character, std::multiplies<>, const Value&, Rep>
[[nodiscard]] constexpr Quantity auto operator*(const Value& v, const quantity<R, Rep>& q) [[nodiscard]] constexpr Quantity auto operator*(const Value& v, const quantity<R, Rep>& q)
{ {
return make_quantity<R>(v * q.numerical_value_ref_in(get_unit(R))); return quantity{v * q.numerical_value_ref_in(get_unit(R)), R};
} }
template<auto R1, typename Rep1, auto R2, typename Rep2> template<auto R1, typename Rep1, auto R2, typename Rep2>
@ -474,7 +478,7 @@ template<auto R1, typename Rep1, auto R2, typename Rep2>
[[nodiscard]] constexpr Quantity auto operator/(const quantity<R1, Rep1>& lhs, const quantity<R2, Rep2>& rhs) [[nodiscard]] constexpr Quantity auto operator/(const quantity<R1, Rep1>& lhs, const quantity<R2, Rep2>& rhs)
{ {
gsl_ExpectsAudit(rhs != rhs.zero()); gsl_ExpectsAudit(rhs != rhs.zero());
return make_quantity<R1 / R2>(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<auto R, typename Rep, typename Value> template<auto R, typename Rep, typename Value>
@ -483,7 +487,7 @@ template<auto R, typename Rep, typename Value>
[[nodiscard]] constexpr Quantity auto operator/(const quantity<R, Rep>& q, const Value& v) [[nodiscard]] constexpr Quantity auto operator/(const quantity<R, Rep>& q, const Value& v)
{ {
gsl_ExpectsAudit(v != quantity_values<Value>::zero()); gsl_ExpectsAudit(v != quantity_values<Value>::zero());
return make_quantity<R>(q.numerical_value_ref_in(get_unit(R)) / v); return quantity{q.numerical_value_ref_in(get_unit(R)) / v, R};
} }
template<typename Value, auto R, typename Rep> template<typename Value, auto R, typename Rep>
@ -491,7 +495,7 @@ template<typename Value, auto R, typename Rep>
detail::InvokeResultOf<get_quantity_spec(R).character, std::divides<>, const Value&, Rep> detail::InvokeResultOf<get_quantity_spec(R).character, std::divides<>, const Value&, Rep>
[[nodiscard]] constexpr Quantity auto operator/(const Value& v, const quantity<R, Rep>& q) [[nodiscard]] constexpr Quantity auto operator/(const Value& v, const quantity<R, Rep>& 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<auto R1, typename Rep1, auto R2, typename Rep2> template<auto R1, typename Rep1, auto R2, typename Rep2>
@ -516,17 +520,6 @@ template<auto R1, typename Rep1, auto R2, typename Rep2>
return ct_lhs.numerical_value_ref_in(ct::unit) <=> ct_rhs.numerical_value_ref_in(ct::unit); 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<auto R, typename Rep>
#else
template<Reference auto R, typename Rep>
#endif
[[nodiscard]] constexpr quantity<R, std::remove_cvref_t<Rep>> make_quantity(Rep&& v)
{
return quantity<R, std::remove_cvref_t<Rep>>(std::forward<Rep>(v));
}
} // namespace mp_units } // namespace mp_units
namespace std { namespace std {

View File

@ -88,13 +88,13 @@ public:
[[nodiscard]] static constexpr quantity_point min() noexcept [[nodiscard]] static constexpr quantity_point min() noexcept
requires requires { quantity_type::min(); } requires requires { quantity_type::min(); }
{ {
return quantity_point{quantity_type::min()}; return {quantity_type::min(), PO};
} }
[[nodiscard]] static constexpr quantity_point max() noexcept [[nodiscard]] static constexpr quantity_point max() noexcept
requires requires { quantity_type::max(); } requires requires { quantity_type::max(); }
{ {
return quantity_point{quantity_type::max()}; return {quantity_type::max(), PO};
} }
// construction, assignment, destruction // construction, assignment, destruction
@ -102,6 +102,24 @@ public:
quantity_point(const quantity_point&) = default; quantity_point(const quantity_point&) = default;
quantity_point(quantity_point&&) = default; quantity_point(quantity_point&&) = default;
template<typename Q>
requires std::same_as<std::remove_cvref_t<Q>, quantity_type>
constexpr quantity_point(Q&& q, std::remove_const_t<decltype(PO)>) :
quantity_from_origin_is_an_implementation_detail_(std::forward<Q>(q))
{
}
template<typename Q, PointOrigin PO2>
requires Quantity<std::remove_cvref_t<Q>> && std::constructible_from<quantity_type, Q> &&
ReferenceOf<std::remove_const_t<decltype(std::remove_reference_t<Q>::reference)>, PO2::quantity_spec> &&
detail::SameAbsolutePointOriginAs<PO2, PO>
quantity_point(Q&& q, PO2) :
quantity_point(
quantity_point<std::remove_reference_t<Q>::reference, PO2{}, typename std::remove_reference_t<Q>::rep>{
std::forward<Q>(q), PO2{}})
{
}
template<QuantityPointOf<absolute_point_origin> QP> template<QuantityPointOf<absolute_point_origin> QP>
requires std::constructible_from<quantity_type, typename QP::quantity_type> requires std::constructible_from<quantity_type, typename QP::quantity_type>
// TODO add perfect forwarding // TODO add perfect forwarding
@ -142,7 +160,7 @@ public:
if constexpr (is_same_v<NewPO, std::remove_const_t<decltype(point_origin)>>) if constexpr (is_same_v<NewPO, std::remove_const_t<decltype(point_origin)>>)
return *this; return *this;
else else
return make_quantity_point<new_origin>(*this - new_origin); return ::mp_units::quantity_point{*this - new_origin, new_origin};
} }
// data access // data access
@ -173,14 +191,14 @@ public:
requires detail::QuantityConvertibleTo<quantity_type, quantity<detail::make_reference(quantity_spec, U{}), Rep>> requires detail::QuantityConvertibleTo<quantity_type, quantity<detail::make_reference(quantity_spec, U{}), Rep>>
[[nodiscard]] constexpr QuantityPoint auto in(U) const [[nodiscard]] constexpr QuantityPoint auto in(U) const
{ {
return make_quantity_point<PO>(quantity_ref_from(PO).in(U{})); return ::mp_units::quantity_point{quantity_ref_from(PO).in(U{}), PO};
} }
template<UnitCompatibleWith<unit, quantity_spec> U> template<UnitCompatibleWith<unit, quantity_spec> U>
requires requires(quantity_type q) { value_cast<U{}>(q); } requires requires(quantity_type q) { value_cast<U{}>(q); }
[[nodiscard]] constexpr QuantityPoint auto force_in(U) const [[nodiscard]] constexpr QuantityPoint auto force_in(U) const
{ {
return make_quantity_point<PO>(quantity_ref_from(PO).force_in(U{})); return ::mp_units::quantity_point{quantity_ref_from(PO).force_in(U{}), PO};
} }
// conversion operators // conversion operators
@ -234,7 +252,7 @@ public:
[[nodiscard]] constexpr quantity_point operator++(int) [[nodiscard]] constexpr quantity_point operator++(int)
requires requires { quantity_from_origin_is_an_implementation_detail_++; } 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<typename QP> template<typename QP>
@ -249,7 +267,7 @@ public:
[[nodiscard]] constexpr quantity_point operator--(int) [[nodiscard]] constexpr quantity_point operator--(int)
requires requires { quantity_from_origin_is_an_implementation_detail_--; } 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 // compound assignment operators
@ -270,25 +288,12 @@ public:
qp.quantity_from_origin_is_an_implementation_detail_ -= q; qp.quantity_from_origin_is_an_implementation_detail_ -= q;
return std::forward<QP>(qp); return std::forward<QP>(qp);
} }
private:
#if defined MP_UNITS_COMP_CLANG && MP_UNITS_COMP_CLANG < 17
template<auto PO2, typename Q>
#else
template<PointOrigin auto PO2, Quantity Q>
requires ReferenceOf<std::remove_const_t<decltype(Q::reference)>, PO2.quantity_spec>
#endif
friend constexpr quantity_point<Q::reference, PO2, typename Q::rep> make_quantity_point(Q&&);
template<Quantity Q>
requires std::constructible_from<quantity_type, Q> &&
ReferenceOf<std::remove_const_t<decltype(Q::reference)>, PO.quantity_spec>
constexpr explicit quantity_point(Q&& q) : quantity_from_origin_is_an_implementation_detail_(std::forward<Q>(q))
{
}
}; };
// CTAD // CTAD
template<Quantity Q, PointOriginFor<Q::quantity_spec> PO>
quantity_point(Q q, PO) -> quantity_point<Q::reference, PO{}, typename Q::rep>;
template<QuantityPointLike QP> template<QuantityPointLike QP>
explicit( explicit(
is_specialization_of<decltype(quantity_point_like_traits<QP>::to_quantity(std::declval<QP>())), convert_explicitly>) is_specialization_of<decltype(quantity_point_like_traits<QP>::to_quantity(std::declval<QP>())), convert_explicitly>)
@ -303,7 +308,7 @@ template<auto R1, auto PO1, typename Rep1, auto R2, typename Rep2>
const quantity<R2, Rep2>& q) const quantity<R2, Rep2>& q)
requires requires { qp.quantity_ref_from(PO1) + q; } requires requires { qp.quantity_ref_from(PO1) + q; }
{ {
return make_quantity_point<PO1>(qp.quantity_ref_from(PO1) + q); return quantity_point{qp.quantity_ref_from(PO1) + q, PO1};
} }
template<auto R1, typename Rep1, auto R2, auto PO2, typename Rep2> template<auto R1, typename Rep1, auto R2, auto PO2, typename Rep2>
@ -320,7 +325,7 @@ template<PointOrigin PO, Quantity Q>
requires ReferenceOf<std::remove_const_t<decltype(Q::reference)>, PO::quantity_spec> requires ReferenceOf<std::remove_const_t<decltype(Q::reference)>, PO::quantity_spec>
[[nodiscard]] constexpr quantity_point<Q::reference, PO{}, typename Q::rep> operator+(PO, Q&& q) [[nodiscard]] constexpr quantity_point<Q::reference, PO{}, typename Q::rep> operator+(PO, Q&& q)
{ {
return make_quantity_point<PO{}>(std::forward<Q>(q)); return quantity_point{std::forward<Q>(q), PO{}};
} }
template<Quantity Q, PointOrigin PO> template<Quantity Q, PointOrigin PO>
@ -337,7 +342,7 @@ template<auto R1, auto PO1, typename Rep1, auto R2, typename Rep2>
const quantity<R2, Rep2>& q) const quantity<R2, Rep2>& q)
requires requires { qp.quantity_ref_from(PO1) - q; } requires requires { qp.quantity_ref_from(PO1) - q; }
{ {
return make_quantity_point<PO1>(qp.quantity_ref_from(PO1) - q); return quantity_point{qp.quantity_ref_from(PO1) - q, PO1};
} }
template<PointOrigin PO, Quantity Q> template<PointOrigin PO, Quantity Q>
@ -429,16 +434,4 @@ template<QuantityPoint QP1, QuantityPointOf<QP1::absolute_point_origin> QP2>
return lhs - lhs.absolute_point_origin == rhs - rhs.absolute_point_origin; 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<auto PO, typename Q>
#else
template<PointOrigin auto PO, Quantity Q>
requires ReferenceOf<std::remove_const_t<decltype(Q::reference)>, PO.quantity_spec>
#endif
[[nodiscard]] constexpr quantity_point<Q::reference, PO, typename Q::rep> make_quantity_point(Q&& q)
{
return quantity_point<Q::reference, PO, typename Q::rep>(std::forward<Q>(q));
}
} // namespace mp_units } // namespace mp_units

View File

@ -119,8 +119,8 @@ struct quantity_spec_interface {
requires Quantity<std::remove_cvref_t<Q>> && requires Quantity<std::remove_cvref_t<Q>> &&
(explicitly_convertible(std::remove_reference_t<Q>::quantity_spec, self)) (explicitly_convertible(std::remove_reference_t<Q>::quantity_spec, self))
{ {
return make_quantity<reference<self, std::remove_cvref_t<Q>::unit>{}>( return quantity{std::forward<Q>(q).numerical_value_is_an_implementation_detail_,
std::forward<Q>(q).numerical_value_is_an_implementation_detail_); reference<self, std::remove_cvref_t<Q>::unit>{}};
} }
#else #else
template<typename Self_ = Self, UnitOf<Self_{}> U> template<typename Self_ = Self, UnitOf<Self_{}> U>
@ -134,8 +134,8 @@ struct quantity_spec_interface {
(explicitly_convertible(std::remove_reference_t<Q>::quantity_spec, Self_{})) (explicitly_convertible(std::remove_reference_t<Q>::quantity_spec, Self_{}))
[[nodiscard]] constexpr Quantity auto operator()(Q&& q) const [[nodiscard]] constexpr Quantity auto operator()(Q&& q) const
{ {
return make_quantity<reference<Self{}, std::remove_cvref_t<Q>::unit>{}>( return quantity{std::forward<Q>(q).numerical_value_is_an_implementation_detail_,
std::forward<Q>(q).numerical_value_is_an_implementation_detail_); reference<Self{}, std::remove_cvref_t<Q>::unit>{}};
} }
#endif #endif
}; };
@ -311,8 +311,8 @@ struct quantity_spec<Self, QS, Args...> : std::remove_const_t<decltype(QS)> {
(explicitly_convertible(std::remove_reference_t<Q>::quantity_spec, Self_{})) (explicitly_convertible(std::remove_reference_t<Q>::quantity_spec, Self_{}))
[[nodiscard]] constexpr Quantity auto operator()(Q&& q) const [[nodiscard]] constexpr Quantity auto operator()(Q&& q) const
{ {
return make_quantity<reference<Self{}, std::remove_cvref_t<Q>::unit>{}>( return quantity{std::forward<Q>(q).numerical_value_is_an_implementation_detail_,
std::forward<Q>(q).numerical_value_is_an_implementation_detail_); reference<Self{}, std::remove_cvref_t<Q>::unit> {}};
} }
#endif #endif
}; };

View File

@ -179,14 +179,14 @@ template<typename Rep, Reference R>
requires RepresentationOf<std::remove_cvref_t<Rep>, get_quantity_spec(R{}).character> requires RepresentationOf<std::remove_cvref_t<Rep>, get_quantity_spec(R{}).character>
[[nodiscard]] constexpr quantity<R{}, std::remove_cvref_t<Rep>> operator*(Rep&& lhs, R) [[nodiscard]] constexpr quantity<R{}, std::remove_cvref_t<Rep>> operator*(Rep&& lhs, R)
{ {
return make_quantity<R{}>(std::forward<Rep>(lhs)); return quantity{std::forward<Rep>(lhs), R{}};
} }
template<typename Rep, Reference R> template<typename Rep, Reference R>
requires RepresentationOf<std::remove_cvref_t<Rep>, get_quantity_spec(R{}).character> requires RepresentationOf<std::remove_cvref_t<Rep>, get_quantity_spec(R{}).character>
[[nodiscard]] constexpr quantity<inverse(R{}), std::remove_cvref_t<Rep>> operator/(Rep&& lhs, R) [[nodiscard]] constexpr quantity<inverse(R{}), std::remove_cvref_t<Rep>> operator/(Rep&& lhs, R)
{ {
return make_quantity<inverse(R{})>(std::forward<Rep>(lhs)); return quantity{std::forward<Rep>(lhs), inverse(R{})};
} }
template<Reference R, typename Rep> template<Reference R, typename Rep>
@ -201,16 +201,16 @@ template<typename Q, Reference R>
requires Quantity<std::remove_cvref_t<Q>> requires Quantity<std::remove_cvref_t<Q>>
[[nodiscard]] constexpr Quantity auto operator*(Q&& q, R) [[nodiscard]] constexpr Quantity auto operator*(Q&& q, R)
{ {
return make_quantity<std::remove_cvref_t<Q>::reference * R{}>( return quantity{std::forward<Q>(q).numerical_value_is_an_implementation_detail_,
std::forward<Q>(q).numerical_value_is_an_implementation_detail_); std::remove_cvref_t<Q>::reference * R{}};
} }
template<typename Q, Reference R> template<typename Q, Reference R>
requires Quantity<std::remove_cvref_t<Q>> requires Quantity<std::remove_cvref_t<Q>>
[[nodiscard]] constexpr Quantity auto operator/(Q&& q, R) [[nodiscard]] constexpr Quantity auto operator/(Q&& q, R)
{ {
return make_quantity<std::remove_cvref_t<Q>::reference / R{}>( return quantity{std::forward<Q>(q).numerical_value_is_an_implementation_detail_,
std::forward<Q>(q).numerical_value_is_an_implementation_detail_); std::remove_cvref_t<Q>::reference / R{}};
} }
template<Reference R, typename Q> template<Reference R, typename Q>

View File

@ -63,8 +63,9 @@ template<std::intmax_t Num, std::intmax_t Den = 1, auto R, typename Rep>
return q; return q;
} else { } else {
using std::pow; using std::pow;
return make_quantity<pow<Num, Den>(R)>( return {
static_cast<Rep>(pow(q.numerical_value_ref_in(q.unit), static_cast<double>(Num) / static_cast<double>(Den)))); static_cast<Rep>(pow(q.numerical_value_ref_in(q.unit), static_cast<double>(Num) / static_cast<double>(Den))),
pow<Num, Den>(R)};
} }
} }
@ -82,7 +83,7 @@ template<auto R, typename Rep>
requires { std::sqrt(q.numerical_value_ref_in(q.unit)); } requires { std::sqrt(q.numerical_value_ref_in(q.unit)); }
{ {
using std::sqrt; using std::sqrt;
return make_quantity<sqrt(R)>(static_cast<Rep>(sqrt(q.numerical_value_ref_in(q.unit)))); return {static_cast<Rep>(sqrt(q.numerical_value_ref_in(q.unit))), sqrt(R)};
} }
/** /**
@ -99,7 +100,7 @@ template<auto R, typename Rep>
requires { std::cbrt(q.numerical_value_ref_in(q.unit)); } requires { std::cbrt(q.numerical_value_ref_in(q.unit)); }
{ {
using std::cbrt; using std::cbrt;
return make_quantity<cbrt(R)>(static_cast<Rep>(cbrt(q.numerical_value_ref_in(q.unit)))); return {static_cast<Rep>(cbrt(q.numerical_value_ref_in(q.unit))), cbrt(R)};
} }
/** /**
@ -117,7 +118,7 @@ template<ReferenceOf<dimensionless> auto R, typename Rep>
{ {
using std::exp; using std::exp;
return value_cast<get_unit(R)>( return value_cast<get_unit(R)>(
make_quantity<detail::clone_reference_with<one>(R)>(static_cast<Rep>(exp(q.force_numerical_value_in(q.unit))))); quantity{static_cast<Rep>(exp(q.force_numerical_value_in(q.unit))), detail::clone_reference_with<one>(R)});
} }
/** /**
@ -132,7 +133,7 @@ template<auto R, typename Rep>
requires { std::abs(q.numerical_value_ref_in(q.unit)); } requires { std::abs(q.numerical_value_ref_in(q.unit)); }
{ {
using std::abs; using std::abs;
return make_quantity<R>(static_cast<Rep>(abs(q.numerical_value_ref_in(q.unit)))); return {static_cast<Rep>(abs(q.numerical_value_ref_in(q.unit))), R};
} }
/** /**
@ -147,7 +148,7 @@ template<Representation Rep, Reference R>
requires requires { std::numeric_limits<Rep>::epsilon(); } requires requires { std::numeric_limits<Rep>::epsilon(); }
[[nodiscard]] constexpr quantity<R{}, Rep> epsilon(R r) noexcept [[nodiscard]] constexpr quantity<R{}, Rep> epsilon(R r) noexcept
{ {
return make_quantity<r>(static_cast<Rep>(std::numeric_limits<Rep>::epsilon())); return {static_cast<Rep>(std::numeric_limits<Rep>::epsilon()), r};
} }
/** /**
@ -174,11 +175,10 @@ template<Unit auto To, auto R, typename Rep>
if constexpr (treat_as_floating_point<Rep>) { if constexpr (treat_as_floating_point<Rep>) {
using std::floor; using std::floor;
if constexpr (To == get_unit(R)) { if constexpr (To == get_unit(R)) {
return make_quantity<detail::clone_reference_with<To>(R)>( return {static_cast<Rep>(floor(q.numerical_value_ref_in(q.unit))), detail::clone_reference_with<To>(R)};
static_cast<Rep>(floor(q.numerical_value_ref_in(q.unit))));
} else { } else {
return handle_signed_results( return handle_signed_results(
make_quantity<detail::clone_reference_with<To>(R)>(static_cast<Rep>(floor(q.force_numerical_value_in(To))))); quantity{static_cast<Rep>(floor(q.force_numerical_value_in(To))), detail::clone_reference_with<To>(R)});
} }
} else { } else {
if constexpr (To == get_unit(R)) { if constexpr (To == get_unit(R)) {
@ -213,11 +213,10 @@ template<Unit auto To, auto R, typename Rep>
if constexpr (treat_as_floating_point<Rep>) { if constexpr (treat_as_floating_point<Rep>) {
using std::ceil; using std::ceil;
if constexpr (To == get_unit(R)) { if constexpr (To == get_unit(R)) {
return make_quantity<detail::clone_reference_with<To>(R)>( return {static_cast<Rep>(ceil(q.numerical_value_ref_in(q.unit))), detail::clone_reference_with<To>(R)};
static_cast<Rep>(ceil(q.numerical_value_ref_in(q.unit))));
} else { } else {
return handle_signed_results( return handle_signed_results(
make_quantity<detail::clone_reference_with<To>(R)>(static_cast<Rep>(ceil(q.force_numerical_value_in(To))))); quantity{static_cast<Rep>(ceil(q.force_numerical_value_in(To))), detail::clone_reference_with<To>(R)});
} }
} else { } else {
if constexpr (To == get_unit(R)) { if constexpr (To == get_unit(R)) {
@ -248,8 +247,7 @@ template<Unit auto To, auto R, typename Rep>
if constexpr (To == get_unit(R)) { if constexpr (To == get_unit(R)) {
if constexpr (treat_as_floating_point<Rep>) { if constexpr (treat_as_floating_point<Rep>) {
using std::round; using std::round;
return make_quantity<detail::clone_reference_with<To>(R)>( return {static_cast<Rep>(round(q.numerical_value_ref_in(q.unit))), detail::clone_reference_with<To>(R)};
static_cast<Rep>(round(q.numerical_value_ref_in(q.unit))));
} else { } else {
return q.force_in(To); return q.force_in(To);
} }
@ -299,7 +297,7 @@ template<auto R1, typename Rep1, auto R2, typename Rep2>
constexpr auto ref = common_reference(R1, R2); constexpr auto ref = common_reference(R1, R2);
constexpr auto unit = get_unit(ref); constexpr auto unit = get_unit(ref);
using std::hypot; using std::hypot;
return make_quantity<ref>(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<auto R1, typename Rep1, auto R2, typename Rep2, auto R3, typename Rep3>
constexpr auto ref = common_reference(R1, R2); constexpr auto ref = common_reference(R1, R2);
constexpr auto unit = get_unit(ref); constexpr auto unit = get_unit(ref);
using std::hypot; using std::hypot;
return make_quantity<ref>(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 { namespace isq {
@ -338,9 +336,9 @@ template<ReferenceOf<angular_measure> auto R, typename Rep>
// check what is the return type when called with the integral value // check what is the return type when called with the integral value
using rep = decltype(sin(q.force_numerical_value_in(si::radian))); 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 // use this type ahead of calling the function to prevent narrowing if a unit conversion is needed
return make_quantity<one>(sin(value_cast<rep>(q).numerical_value_in(si::radian))); return quantity{sin(value_cast<rep>(q).numerical_value_in(si::radian)), one};
} else } else
return make_quantity<one>(sin(q.numerical_value_in(si::radian))); return quantity{sin(q.numerical_value_in(si::radian)), one};
} }
template<ReferenceOf<angular_measure> auto R, typename Rep> template<ReferenceOf<angular_measure> auto R, typename Rep>
@ -353,9 +351,9 @@ template<ReferenceOf<angular_measure> auto R, typename Rep>
// check what is the return type when called with the integral value // check what is the return type when called with the integral value
using rep = decltype(cos(q.force_numerical_value_in(si::radian))); 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 // use this type ahead of calling the function to prevent narrowing if a unit conversion is needed
return make_quantity<one>(cos(value_cast<rep>(q).numerical_value_in(si::radian))); return quantity{cos(value_cast<rep>(q).numerical_value_in(si::radian)), one};
} else } else
return make_quantity<one>(cos(q.numerical_value_in(si::radian))); return quantity{cos(q.numerical_value_in(si::radian)), one};
} }
template<ReferenceOf<angular_measure> auto R, typename Rep> template<ReferenceOf<angular_measure> auto R, typename Rep>
@ -368,9 +366,9 @@ template<ReferenceOf<angular_measure> auto R, typename Rep>
// check what is the return type when called with the integral value // check what is the return type when called with the integral value
using rep = decltype(tan(q.force_numerical_value_in(si::radian))); 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 // use this type ahead of calling the function to prevent narrowing if a unit conversion is needed
return make_quantity<one>(tan(value_cast<rep>(q).numerical_value_in(si::radian))); return quantity{tan(value_cast<rep>(q).numerical_value_in(si::radian)), one};
} else } else
return make_quantity<one>(tan(q.numerical_value_in(si::radian))); return quantity{tan(q.numerical_value_in(si::radian)), one};
} }
template<ReferenceOf<dimensionless> auto R, typename Rep> template<ReferenceOf<dimensionless> auto R, typename Rep>
@ -383,9 +381,9 @@ template<ReferenceOf<dimensionless> auto R, typename Rep>
// check what is the return type when called with the integral value // check what is the return type when called with the integral value
using rep = decltype(asin(q.force_numerical_value_in(one))); 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 // use this type ahead of calling the function to prevent narrowing if a unit conversion is needed
return make_quantity<si::radian>(asin(value_cast<rep>(q).numerical_value_in(one))); return quantity{asin(value_cast<rep>(q).numerical_value_in(one)), si::radian};
} else } else
return make_quantity<si::radian>(asin(q.numerical_value_in(one))); return quantity{asin(q.numerical_value_in(one)), si::radian};
} }
template<ReferenceOf<dimensionless> auto R, typename Rep> template<ReferenceOf<dimensionless> auto R, typename Rep>
@ -398,9 +396,9 @@ template<ReferenceOf<dimensionless> auto R, typename Rep>
// check what is the return type when called with the integral value // check what is the return type when called with the integral value
using rep = decltype(acos(q.force_numerical_value_in(one))); 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 // use this type ahead of calling the function to prevent narrowing if a unit conversion is needed
return make_quantity<si::radian>(acos(value_cast<rep>(q).numerical_value_in(one))); return quantity{acos(value_cast<rep>(q).numerical_value_in(one)), si::radian};
} else } else
return make_quantity<si::radian>(acos(q.numerical_value_in(one))); return quantity{acos(q.numerical_value_in(one)), si::radian};
} }
template<ReferenceOf<dimensionless> auto R, typename Rep> template<ReferenceOf<dimensionless> auto R, typename Rep>
@ -413,9 +411,9 @@ template<ReferenceOf<dimensionless> auto R, typename Rep>
// check what is the return type when called with the integral value // check what is the return type when called with the integral value
using rep = decltype(atan(q.force_numerical_value_in(one))); 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 // use this type ahead of calling the function to prevent narrowing if a unit conversion is needed
return make_quantity<si::radian>(atan(value_cast<rep>(q).numerical_value_in(one))); return quantity{atan(value_cast<rep>(q).numerical_value_in(one)), si::radian};
} else } else
return make_quantity<si::radian>(atan(q.numerical_value_in(one))); return quantity{atan(q.numerical_value_in(one)), si::radian};
} }
} // namespace isq } // namespace isq
@ -432,9 +430,9 @@ template<ReferenceOf<angle> auto R, typename Rep>
// check what is the return type when called with the integral value // check what is the return type when called with the integral value
using rep = decltype(sin(q.force_numerical_value_in(radian))); 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 // use this type ahead of calling the function to prevent narrowing if a unit conversion is needed
return make_quantity<one>(sin(value_cast<rep>(q).numerical_value_in(radian))); return quantity{sin(value_cast<rep>(q).numerical_value_in(radian)), one};
} else } else
return make_quantity<one>(sin(q.numerical_value_in(radian))); return quantity{sin(q.numerical_value_in(radian)), one};
} }
template<ReferenceOf<angle> auto R, typename Rep> template<ReferenceOf<angle> auto R, typename Rep>
@ -447,9 +445,9 @@ template<ReferenceOf<angle> auto R, typename Rep>
// check what is the return type when called with the integral value // check what is the return type when called with the integral value
using rep = decltype(cos(q.force_numerical_value_in(radian))); 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 // use this type ahead of calling the function to prevent narrowing if a unit conversion is needed
return make_quantity<one>(cos(value_cast<rep>(q).numerical_value_in(radian))); return quantity{cos(value_cast<rep>(q).numerical_value_in(radian)), one};
} else } else
return make_quantity<one>(cos(q.numerical_value_in(radian))); return quantity{cos(q.numerical_value_in(radian)), one};
} }
template<ReferenceOf<angle> auto R, typename Rep> template<ReferenceOf<angle> auto R, typename Rep>
@ -462,9 +460,9 @@ template<ReferenceOf<angle> auto R, typename Rep>
// check what is the return type when called with the integral value // check what is the return type when called with the integral value
using rep = decltype(tan(q.force_numerical_value_in(radian))); 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 // use this type ahead of calling the function to prevent narrowing if a unit conversion is needed
return make_quantity<one>(tan(value_cast<rep>(q).numerical_value_in(radian))); return quantity{tan(value_cast<rep>(q).numerical_value_in(radian)), one};
} else } else
return make_quantity<one>(tan(q.numerical_value_in(radian))); return quantity{tan(q.numerical_value_in(radian)), one};
} }
template<ReferenceOf<dimensionless> auto R, typename Rep> template<ReferenceOf<dimensionless> auto R, typename Rep>
@ -477,9 +475,9 @@ template<ReferenceOf<dimensionless> auto R, typename Rep>
// check what is the return type when called with the integral value // check what is the return type when called with the integral value
using rep = decltype(asin(q.force_numerical_value_in(one))); 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 // use this type ahead of calling the function to prevent narrowing if a unit conversion is needed
return make_quantity<radian>(asin(value_cast<rep>(q).numerical_value_in(one))); return quantity{asin(value_cast<rep>(q).numerical_value_in(one)), radian};
} else } else
return make_quantity<radian>(asin(q.numerical_value_in(one))); return quantity{asin(q.numerical_value_in(one)), radian};
} }
template<ReferenceOf<dimensionless> auto R, typename Rep> template<ReferenceOf<dimensionless> auto R, typename Rep>
@ -492,9 +490,9 @@ template<ReferenceOf<dimensionless> auto R, typename Rep>
// check what is the return type when called with the integral value // check what is the return type when called with the integral value
using rep = decltype(acos(q.force_numerical_value_in(one))); 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 // use this type ahead of calling the function to prevent narrowing if a unit conversion is needed
return make_quantity<radian>(acos(value_cast<rep>(q).numerical_value_in(one))); return quantity{acos(value_cast<rep>(q).numerical_value_in(one)), radian};
} else } else
return make_quantity<radian>(acos(q.numerical_value_in(one))); return quantity{acos(q.numerical_value_in(one)), radian};
} }
template<ReferenceOf<dimensionless> auto R, typename Rep> template<ReferenceOf<dimensionless> auto R, typename Rep>
@ -507,9 +505,9 @@ template<ReferenceOf<dimensionless> auto R, typename Rep>
// check what is the return type when called with the integral value // check what is the return type when called with the integral value
using rep = decltype(atan(q.force_numerical_value_in(one))); 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 // use this type ahead of calling the function to prevent narrowing if a unit conversion is needed
return make_quantity<radian>(atan(value_cast<rep>(q).numerical_value_in(one))); return quantity{atan(value_cast<rep>(q).numerical_value_in(one)), radian};
} else } else
return make_quantity<radian>(atan(q.numerical_value_in(one))); return quantity{atan(q.numerical_value_in(one)), radian};
} }
} // namespace angular } // namespace angular