mirror of
https://github.com/mpusz/mp-units.git
synced 2025-07-31 19:04:27 +02:00
refactor: perfect forwarding interfaces improved
This commit is contained in:
@@ -91,10 +91,10 @@ struct conversion_value_traits {
|
||||
*
|
||||
* @tparam To a target quantity type to cast to
|
||||
*/
|
||||
template<Quantity To, typename FwdFrom, typename From = std::remove_cvref_t<FwdFrom>>
|
||||
requires Quantity<From> && (castable(From::quantity_spec, To::quantity_spec)) &&
|
||||
((From::unit == To::unit && std::constructible_from<typename To::rep, typename From::rep>) ||
|
||||
(From::unit != To::unit)) // && scalable_with_<typename To::rep>))
|
||||
template<Quantity To, typename FwdFrom, Quantity From = std::remove_cvref_t<FwdFrom>>
|
||||
requires(castable(From::quantity_spec, To::quantity_spec)) &&
|
||||
((From::unit == To::unit && std::constructible_from<typename To::rep, typename From::rep>) ||
|
||||
(From::unit != To::unit)) // && scalable_with_<typename To::rep>))
|
||||
// TODO how to constrain the second part here?
|
||||
[[nodiscard]] constexpr To sudo_cast(FwdFrom&& q)
|
||||
{
|
||||
@@ -143,17 +143,17 @@ template<Quantity To, typename FwdFrom, typename From = std::remove_cvref_t<FwdF
|
||||
*
|
||||
* @tparam ToQP a target quantity point type to which to cast to
|
||||
*/
|
||||
template<QuantityPoint ToQP, typename FwdFromQP, typename FromQP = std::remove_cvref_t<FwdFromQP>>
|
||||
requires QuantityPoint<FromQP> && (castable(FromQP::quantity_spec, ToQP::quantity_spec)) &&
|
||||
(detail::same_absolute_point_origins(ToQP::point_origin, FromQP::point_origin)) &&
|
||||
((FromQP::unit == ToQP::unit && std::constructible_from<typename ToQP::rep, typename FromQP::rep>) ||
|
||||
(FromQP::unit != ToQP::unit))
|
||||
template<QuantityPoint ToQP, typename FwdFromQP, QuantityPoint FromQP = std::remove_cvref_t<FwdFromQP>>
|
||||
requires(castable(FromQP::quantity_spec, ToQP::quantity_spec)) &&
|
||||
(detail::same_absolute_point_origins(ToQP::point_origin, FromQP::point_origin)) &&
|
||||
((FromQP::unit == ToQP::unit && std::constructible_from<typename ToQP::rep, typename FromQP::rep>) ||
|
||||
(FromQP::unit != ToQP::unit))
|
||||
[[nodiscard]] constexpr QuantityPoint auto sudo_cast(FwdFromQP&& qp)
|
||||
{
|
||||
if constexpr (is_same_v<std::remove_const_t<decltype(ToQP::point_origin)>,
|
||||
std::remove_const_t<decltype(FromQP::point_origin)>>) {
|
||||
return quantity_point{
|
||||
sudo_cast<typename ToQP::quantity_type>(std::forward<FromQP>(qp).quantity_from(FromQP::point_origin)),
|
||||
sudo_cast<typename ToQP::quantity_type>(std::forward<FwdFromQP>(qp).quantity_from(FromQP::point_origin)),
|
||||
FromQP::point_origin};
|
||||
} else {
|
||||
// it's unclear how hard we should try to avoid truncation here. For now, the only corner case we cater for,
|
||||
@@ -176,7 +176,7 @@ template<QuantityPoint ToQP, typename FwdFromQP, typename FromQP = std::remove_c
|
||||
// unit, we obtain the largest possible range while not causing truncation of fractional values. This is optimal
|
||||
// for the offset computation.
|
||||
return sudo_cast<ToQP>(
|
||||
sudo_cast<quantity_point<FromQP::reference, FromQP::point_origin, c_rep_type>>(std::forward<FromQP>(qp))
|
||||
sudo_cast<quantity_point<FromQP::reference, FromQP::point_origin, c_rep_type>>(std::forward<FwdFromQP>(qp))
|
||||
.point_for(ToQP::point_origin));
|
||||
} else {
|
||||
// new unit may have a larger unit magnitude; we first need to convert to the new unit (potentially causing
|
||||
@@ -184,7 +184,7 @@ template<QuantityPoint ToQP, typename FwdFromQP, typename FromQP = std::remove_c
|
||||
// representation types. Then, we can perform the offset computation.
|
||||
return sudo_cast<ToQP>(
|
||||
sudo_cast<quantity_point<make_reference(FromQP::quantity_spec, ToQP::unit), FromQP::point_origin, c_rep_type>>(
|
||||
std::forward<FromQP>(qp))
|
||||
std::forward<FwdFromQP>(qp))
|
||||
.point_for(ToQP::point_origin));
|
||||
}
|
||||
}
|
||||
|
@@ -39,22 +39,19 @@ namespace mp_units {
|
||||
|
||||
template<Reference R>
|
||||
struct delta_ {
|
||||
template<typename Rep>
|
||||
requires RepresentationOf<std::remove_cvref_t<Rep>, get_quantity_spec(R{}).character>
|
||||
[[nodiscard]] constexpr quantity<R{}, std::remove_cvref_t<Rep>> operator()(Rep&& lhs) const
|
||||
template<typename FwdRep, RepresentationOf<get_quantity_spec(R{}).character> Rep = std::remove_cvref_t<FwdRep>>
|
||||
[[nodiscard]] constexpr quantity<R{}, Rep> operator()(FwdRep&& lhs) const
|
||||
{
|
||||
return quantity{std::forward<Rep>(lhs), R{}};
|
||||
return quantity{std::forward<FwdRep>(lhs), R{}};
|
||||
}
|
||||
};
|
||||
|
||||
template<Reference R>
|
||||
struct absolute_ {
|
||||
template<typename Rep>
|
||||
requires RepresentationOf<std::remove_cvref_t<Rep>, get_quantity_spec(R{}).character>
|
||||
[[nodiscard]] constexpr quantity_point<R{}, default_point_origin(R{}), std::remove_cvref_t<Rep>> operator()(
|
||||
Rep&& lhs) const
|
||||
template<typename FwdRep, RepresentationOf<get_quantity_spec(R{}).character> Rep = std::remove_cvref_t<FwdRep>>
|
||||
[[nodiscard]] constexpr quantity_point<R{}, default_point_origin(R{}), Rep> operator()(FwdRep&& lhs) const
|
||||
{
|
||||
return quantity_point{quantity{std::forward<Rep>(lhs), R{}}};
|
||||
return quantity_point{quantity{std::forward<FwdRep>(lhs), R{}}};
|
||||
}
|
||||
};
|
||||
|
||||
|
@@ -168,22 +168,23 @@ public:
|
||||
quantity(quantity&&) = default;
|
||||
~quantity() = default;
|
||||
|
||||
template<typename Value, Reference R2>
|
||||
requires detail::SameValueAs<R2{}, R, std::remove_cvref_t<Value>, Rep>
|
||||
constexpr quantity(Value&& v, R2) : numerical_value_is_an_implementation_detail_(std::forward<Value>(v))
|
||||
template<typename FwdValue, Reference R2>
|
||||
requires detail::SameValueAs<R2{}, R, std::remove_cvref_t<FwdValue>, Rep>
|
||||
constexpr quantity(FwdValue&& v, R2) : numerical_value_is_an_implementation_detail_(std::forward<FwdValue>(v))
|
||||
{
|
||||
}
|
||||
|
||||
template<typename Value, Reference R2>
|
||||
requires(!detail::SameValueAs<R2{}, R, std::remove_cvref_t<Value>, Rep>) &&
|
||||
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<typename FwdValue, Reference R2, typename Value = std::remove_cvref_t<FwdValue>>
|
||||
requires(!detail::SameValueAs<R2{}, R, Value, Rep>) &&
|
||||
detail::QuantityConvertibleTo<quantity<R2{}, Value>, quantity>
|
||||
constexpr quantity(FwdValue&& v, R2) : quantity(quantity<R2{}, Value>{std::forward<FwdValue>(v), R2{}})
|
||||
{
|
||||
}
|
||||
|
||||
template<detail::ValuePreservingTo<Rep> Value>
|
||||
template<detail::ValuePreservingTo<Rep> FwdValue>
|
||||
requires(unit == ::mp_units::one)
|
||||
constexpr explicit(false) quantity(Value&& v) : numerical_value_is_an_implementation_detail_(std::forward<Value>(v))
|
||||
constexpr explicit(false) quantity(FwdValue&& v) :
|
||||
numerical_value_is_an_implementation_detail_(std::forward<FwdValue>(v))
|
||||
{
|
||||
}
|
||||
|
||||
@@ -209,11 +210,11 @@ public:
|
||||
quantity& operator=(const quantity&) = default;
|
||||
quantity& operator=(quantity&&) = default;
|
||||
|
||||
template<detail::ValuePreservingTo<Rep> Value>
|
||||
template<detail::ValuePreservingTo<Rep> FwdValue>
|
||||
requires(unit == ::mp_units::one)
|
||||
constexpr quantity& operator=(Value&& v)
|
||||
constexpr quantity& operator=(FwdValue&& v)
|
||||
{
|
||||
numerical_value_is_an_implementation_detail_ = std::forward<Value>(v);
|
||||
numerical_value_is_an_implementation_detail_ = std::forward<FwdValue>(v);
|
||||
return *this;
|
||||
}
|
||||
|
||||
@@ -355,16 +356,16 @@ public:
|
||||
return ::mp_units::quantity{-numerical_value_is_an_implementation_detail_, reference};
|
||||
}
|
||||
|
||||
template<typename Q>
|
||||
friend constexpr decltype(auto) operator++(Q&& q)
|
||||
requires std::derived_from<std::remove_cvref_t<Q>, quantity> && requires(rep v) {
|
||||
template<typename FwdQ, std::derived_from<quantity> Q = std::remove_cvref_t<FwdQ>>
|
||||
friend constexpr decltype(auto) operator++(FwdQ&& q)
|
||||
requires requires(rep v) {
|
||||
{
|
||||
++v
|
||||
} -> std::same_as<rep&>;
|
||||
}
|
||||
{
|
||||
++q.numerical_value_is_an_implementation_detail_;
|
||||
return std::forward<Q>(q);
|
||||
return std::forward<FwdQ>(q);
|
||||
}
|
||||
|
||||
[[nodiscard]] constexpr QuantityOf<quantity_spec> auto operator++(int)
|
||||
@@ -377,16 +378,16 @@ public:
|
||||
return ::mp_units::quantity{numerical_value_is_an_implementation_detail_++, reference};
|
||||
}
|
||||
|
||||
template<typename Q>
|
||||
friend constexpr decltype(auto) operator--(Q&& q)
|
||||
requires std::derived_from<std::remove_cvref_t<Q>, quantity> && requires(rep v) {
|
||||
template<typename FwdQ, std::derived_from<quantity> Q = std::remove_cvref_t<FwdQ>>
|
||||
friend constexpr decltype(auto) operator--(FwdQ&& q)
|
||||
requires requires(rep v) {
|
||||
{
|
||||
--v
|
||||
} -> std::same_as<rep&>;
|
||||
}
|
||||
{
|
||||
--q.numerical_value_is_an_implementation_detail_;
|
||||
return std::forward<Q>(q);
|
||||
return std::forward<FwdQ>(q);
|
||||
}
|
||||
|
||||
[[nodiscard]] constexpr QuantityOf<quantity_spec> auto operator--(int)
|
||||
@@ -400,97 +401,92 @@ public:
|
||||
}
|
||||
|
||||
// compound assignment operators
|
||||
template<typename Q>
|
||||
requires std::derived_from<std::remove_cvref_t<Q>, quantity> && requires(rep a, rep b) {
|
||||
template<typename FwdQ, std::derived_from<quantity> Q = std::remove_cvref_t<FwdQ>>
|
||||
requires requires(rep a, rep b) {
|
||||
{
|
||||
a += b
|
||||
} -> std::same_as<rep&>;
|
||||
}
|
||||
friend constexpr decltype(auto) operator+=(Q&& lhs, const quantity& rhs)
|
||||
friend constexpr decltype(auto) operator+=(FwdQ&& lhs, const quantity& rhs)
|
||||
{
|
||||
lhs.numerical_value_is_an_implementation_detail_ += rhs.numerical_value_is_an_implementation_detail_;
|
||||
return std::forward<Q>(lhs);
|
||||
return std::forward<FwdQ>(lhs);
|
||||
}
|
||||
|
||||
template<typename Q>
|
||||
requires std::derived_from<std::remove_cvref_t<Q>, quantity> && requires(rep a, rep b) {
|
||||
template<typename FwdQ, std::derived_from<quantity> Q = std::remove_cvref_t<FwdQ>>
|
||||
requires requires(rep a, rep b) {
|
||||
{
|
||||
a -= b
|
||||
} -> std::same_as<rep&>;
|
||||
}
|
||||
friend constexpr decltype(auto) operator-=(Q&& lhs, const quantity& rhs)
|
||||
friend constexpr decltype(auto) operator-=(FwdQ&& lhs, const quantity& rhs)
|
||||
{
|
||||
lhs.numerical_value_is_an_implementation_detail_ -= rhs.numerical_value_is_an_implementation_detail_;
|
||||
return std::forward<Q>(lhs);
|
||||
return std::forward<FwdQ>(lhs);
|
||||
}
|
||||
|
||||
template<typename Q>
|
||||
requires std::derived_from<std::remove_cvref_t<Q>, quantity> && (!treat_as_floating_point<rep>) &&
|
||||
requires(rep a, rep b) {
|
||||
{
|
||||
a %= b
|
||||
} -> std::same_as<rep&>;
|
||||
}
|
||||
friend constexpr decltype(auto) operator%=(Q&& lhs, const quantity& rhs)
|
||||
template<typename FwdQ, std::derived_from<quantity> Q = std::remove_cvref_t<FwdQ>>
|
||||
requires(!treat_as_floating_point<rep>) && requires(rep a, rep b) {
|
||||
{
|
||||
a %= b
|
||||
} -> std::same_as<rep&>;
|
||||
}
|
||||
friend constexpr decltype(auto) operator%=(FwdQ&& lhs, const quantity& rhs)
|
||||
|
||||
{
|
||||
MP_UNITS_EXPECTS_DEBUG(rhs != zero());
|
||||
lhs.numerical_value_is_an_implementation_detail_ %= rhs.numerical_value_is_an_implementation_detail_;
|
||||
return std::forward<Q>(lhs);
|
||||
return std::forward<FwdQ>(lhs);
|
||||
}
|
||||
|
||||
template<typename Q, typename Value>
|
||||
requires std::derived_from<std::remove_cvref_t<Q>, quantity> && (!Quantity<Value>) &&
|
||||
requires(rep a, const Value b) {
|
||||
{
|
||||
a *= b
|
||||
} -> std::same_as<rep&>;
|
||||
}
|
||||
friend constexpr decltype(auto) operator*=(Q&& lhs, const Value& v)
|
||||
template<typename FwdQ, typename Value, std::derived_from<quantity> Q = std::remove_cvref_t<FwdQ>>
|
||||
requires(!Quantity<Value>) && requires(rep a, const Value b) {
|
||||
{
|
||||
a *= b
|
||||
} -> std::same_as<rep&>;
|
||||
}
|
||||
friend constexpr decltype(auto) operator*=(FwdQ&& lhs, const Value& v)
|
||||
{
|
||||
lhs.numerical_value_is_an_implementation_detail_ *= v;
|
||||
return std::forward<Q>(lhs);
|
||||
return std::forward<FwdQ>(lhs);
|
||||
}
|
||||
|
||||
template<typename Q1, QuantityOf<dimensionless> Q2>
|
||||
requires std::derived_from<std::remove_cvref_t<Q1>, quantity> && (Q2::unit == ::mp_units::one) &&
|
||||
requires(rep a, const typename Q2::rep b) {
|
||||
{
|
||||
a *= b
|
||||
} -> std::same_as<rep&>;
|
||||
}
|
||||
friend constexpr decltype(auto) operator*=(Q1&& lhs, const Q2& rhs)
|
||||
template<typename FwdQ1, QuantityOf<dimensionless> Q2, std::derived_from<quantity> Q1 = std::remove_cvref_t<FwdQ1>>
|
||||
requires(Q2::unit == ::mp_units::one) && requires(rep a, const typename Q2::rep b) {
|
||||
{
|
||||
a *= b
|
||||
} -> std::same_as<rep&>;
|
||||
}
|
||||
friend constexpr decltype(auto) operator*=(FwdQ1&& lhs, const Q2& rhs)
|
||||
{
|
||||
lhs.numerical_value_is_an_implementation_detail_ *= rhs.numerical_value_is_an_implementation_detail_;
|
||||
return std::forward<Q1>(lhs);
|
||||
return std::forward<FwdQ1>(lhs);
|
||||
}
|
||||
|
||||
template<typename Q, typename Value>
|
||||
requires std::derived_from<std::remove_cvref_t<Q>, quantity> && (!Quantity<Value>) &&
|
||||
requires(rep a, const Value b) {
|
||||
{
|
||||
a /= b
|
||||
} -> std::same_as<rep&>;
|
||||
}
|
||||
friend constexpr decltype(auto) operator/=(Q&& lhs, const Value& v)
|
||||
template<typename FwdQ, typename Value, std::derived_from<quantity> Q = std::remove_cvref_t<FwdQ>>
|
||||
requires(!Quantity<Value>) && requires(rep a, const Value b) {
|
||||
{
|
||||
a /= b
|
||||
} -> std::same_as<rep&>;
|
||||
}
|
||||
friend constexpr decltype(auto) operator/=(FwdQ&& lhs, const Value& v)
|
||||
{
|
||||
MP_UNITS_EXPECTS_DEBUG(v != quantity_values<Value>::zero());
|
||||
lhs.numerical_value_is_an_implementation_detail_ /= v;
|
||||
return std::forward<Q>(lhs);
|
||||
return std::forward<FwdQ>(lhs);
|
||||
}
|
||||
|
||||
template<typename Q1, QuantityOf<dimensionless> Q2>
|
||||
requires std::derived_from<std::remove_cvref_t<Q1>, quantity> && (Q2::unit == ::mp_units::one) &&
|
||||
requires(rep a, const typename Q2::rep b) {
|
||||
{
|
||||
a /= b
|
||||
} -> std::same_as<rep&>;
|
||||
}
|
||||
friend constexpr decltype(auto) operator/=(Q1&& lhs, const Q2& rhs)
|
||||
template<typename FwdQ1, QuantityOf<dimensionless> Q2, std::derived_from<quantity> Q1 = std::remove_cvref_t<FwdQ1>>
|
||||
requires(Q2::unit == ::mp_units::one) && requires(rep a, const typename Q2::rep b) {
|
||||
{
|
||||
a /= b
|
||||
} -> std::same_as<rep&>;
|
||||
}
|
||||
friend constexpr decltype(auto) operator/=(FwdQ1&& lhs, const Q2& rhs)
|
||||
{
|
||||
MP_UNITS_EXPECTS_DEBUG(rhs != rhs.zero());
|
||||
lhs.numerical_value_is_an_implementation_detail_ /= rhs.numerical_value_is_an_implementation_detail_;
|
||||
return std::forward<Q1>(lhs);
|
||||
return std::forward<FwdQ1>(lhs);
|
||||
}
|
||||
|
||||
// binary operators on quantities
|
||||
|
@@ -56,13 +56,11 @@ namespace mp_units {
|
||||
*
|
||||
* @tparam ToQS a quantity specification to use for a target quantity
|
||||
*/
|
||||
template<QuantitySpec auto ToQS, typename Q>
|
||||
requires Quantity<std::remove_cvref_t<Q>> &&
|
||||
detail::QuantitySpecCastableTo<std::remove_reference_t<Q>::quantity_spec, ToQS>
|
||||
[[nodiscard]] constexpr Quantity auto quantity_cast(Q&& q)
|
||||
template<QuantitySpec auto ToQS, typename FwdQ, Quantity Q = std::remove_cvref_t<FwdQ>>
|
||||
requires detail::QuantitySpecCastableTo<Q::quantity_spec, ToQS>
|
||||
[[nodiscard]] constexpr Quantity auto quantity_cast(FwdQ&& q)
|
||||
{
|
||||
return quantity{std::forward<Q>(q).numerical_value_is_an_implementation_detail_,
|
||||
make_reference(ToQS, std::remove_reference_t<Q>::unit)};
|
||||
return quantity{std::forward<FwdQ>(q).numerical_value_is_an_implementation_detail_, make_reference(ToQS, Q::unit)};
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -82,13 +80,12 @@ template<QuantitySpec auto ToQS, typename Q>
|
||||
*
|
||||
* @tparam ToQS a quantity specification to use for a target quantity point
|
||||
*/
|
||||
template<QuantitySpec auto ToQS, typename QP>
|
||||
requires QuantityPoint<std::remove_cvref_t<QP>> &&
|
||||
detail::QuantitySpecCastableTo<std::remove_reference_t<QP>::quantity_spec, ToQS>
|
||||
[[nodiscard]] constexpr QuantityPoint auto quantity_cast(QP&& qp)
|
||||
template<QuantitySpec auto ToQS, typename FwdQP, QuantityPoint QP = std::remove_cvref_t<FwdQP>>
|
||||
requires detail::QuantitySpecCastableTo<QP::quantity_spec, ToQS>
|
||||
[[nodiscard]] constexpr QuantityPoint auto quantity_cast(FwdQP&& qp)
|
||||
{
|
||||
return QP{quantity_cast<ToQS>(std::forward<QP>(qp).quantity_from_origin_is_an_implementation_detail_),
|
||||
std::remove_reference_t<QP>::point_origin};
|
||||
return QP{quantity_cast<ToQS>(std::forward<FwdQP>(qp).quantity_from_origin_is_an_implementation_detail_),
|
||||
QP::point_origin};
|
||||
}
|
||||
|
||||
} // namespace mp_units
|
||||
|
@@ -52,18 +52,16 @@ template<PointOrigin PO>
|
||||
}
|
||||
|
||||
struct point_origin_interface {
|
||||
template<PointOrigin PO, Quantity Q>
|
||||
requires ReferenceOf<std::remove_const_t<decltype(Q::reference)>, PO::quantity_spec>
|
||||
[[nodiscard]] friend constexpr quantity_point<Q::reference, PO{}, typename Q::rep> operator+(PO, Q&& q)
|
||||
template<PointOrigin PO, typename FwdQ, QuantityOf<PO::quantity_spec> Q = std::remove_cvref_t<FwdQ>>
|
||||
[[nodiscard]] friend constexpr quantity_point<Q::reference, PO{}, typename Q::rep> operator+(PO, FwdQ&& q)
|
||||
{
|
||||
return quantity_point{std::forward<Q>(q), PO{}};
|
||||
return quantity_point{std::forward<FwdQ>(q), PO{}};
|
||||
}
|
||||
|
||||
template<Quantity Q, PointOrigin PO>
|
||||
requires ReferenceOf<std::remove_const_t<decltype(Q::reference)>, PO::quantity_spec>
|
||||
[[nodiscard]] friend constexpr quantity_point<Q::reference, PO{}, typename Q::rep> operator+(Q&& q, PO po)
|
||||
template<Quantity FwdQ, PointOrigin PO, QuantityOf<PO::quantity_spec> Q = std::remove_cvref_t<FwdQ>>
|
||||
[[nodiscard]] friend constexpr quantity_point<Q::reference, PO{}, typename Q::rep> operator+(FwdQ&& q, PO po)
|
||||
{
|
||||
return po + std::forward<Q>(q);
|
||||
return po + std::forward<FwdQ>(q);
|
||||
}
|
||||
|
||||
template<PointOrigin PO, Quantity Q>
|
||||
@@ -206,27 +204,26 @@ public:
|
||||
quantity_point(quantity_point&&) = default;
|
||||
~quantity_point() = default;
|
||||
|
||||
template<typename Q>
|
||||
requires QuantityOf<std::remove_cvref_t<Q>, quantity_spec> && std::constructible_from<quantity_type, Q> &&
|
||||
(point_origin == default_point_origin(R)) && (implicitly_convertible(Q::quantity_spec, quantity_spec))
|
||||
constexpr explicit quantity_point(Q&& q) : quantity_from_origin_is_an_implementation_detail_(std::forward<Q>(q))
|
||||
template<typename FwdQ, QuantityOf<quantity_spec> Q = std::remove_cvref_t<FwdQ>>
|
||||
requires std::constructible_from<quantity_type, FwdQ> && (point_origin == default_point_origin(R)) &&
|
||||
(implicitly_convertible(Q::quantity_spec, quantity_spec))
|
||||
constexpr explicit quantity_point(FwdQ&& q) : quantity_from_origin_is_an_implementation_detail_(std::forward<FwdQ>(q))
|
||||
{
|
||||
}
|
||||
|
||||
template<typename Q>
|
||||
requires QuantityOf<std::remove_cvref_t<Q>, quantity_spec> && std::constructible_from<quantity_type, Q>
|
||||
constexpr quantity_point(Q&& q, decltype(PO)) : quantity_from_origin_is_an_implementation_detail_(std::forward<Q>(q))
|
||||
template<typename FwdQ, QuantityOf<quantity_spec> Q = std::remove_cvref_t<FwdQ>>
|
||||
requires std::constructible_from<quantity_type, FwdQ>
|
||||
constexpr quantity_point(FwdQ&& q, decltype(PO)) :
|
||||
quantity_from_origin_is_an_implementation_detail_(std::forward<FwdQ>(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>
|
||||
constexpr quantity_point(Q&& q, PO2) :
|
||||
template<typename FwdQ, PointOrigin PO2, QuantityOf<PO2::quantity_spec> Q = std::remove_cvref_t<FwdQ>>
|
||||
requires std::constructible_from<quantity_type, FwdQ> && detail::SameAbsolutePointOriginAs<PO2, PO>
|
||||
constexpr quantity_point(FwdQ&& 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{}})
|
||||
std::forward<FwdQ>(q), PO2{}})
|
||||
{
|
||||
}
|
||||
|
||||
@@ -413,13 +410,12 @@ public:
|
||||
}
|
||||
|
||||
// member unary operators
|
||||
template<typename QP>
|
||||
friend constexpr decltype(auto) operator++(QP&& qp)
|
||||
requires std::derived_from<std::remove_cvref_t<QP>, quantity_point> &&
|
||||
requires { ++qp.quantity_from_origin_is_an_implementation_detail_; }
|
||||
template<typename FwdQP, std::derived_from<quantity_point> QP = std::remove_cvref_t<FwdQP>>
|
||||
friend constexpr decltype(auto) operator++(FwdQP&& qp)
|
||||
requires requires { ++qp.quantity_from_origin_is_an_implementation_detail_; }
|
||||
{
|
||||
++qp.quantity_from_origin_is_an_implementation_detail_;
|
||||
return std::forward<QP>(qp);
|
||||
return std::forward<FwdQP>(qp);
|
||||
}
|
||||
|
||||
[[nodiscard]] constexpr quantity_point operator++(int)
|
||||
@@ -428,13 +424,12 @@ public:
|
||||
return {quantity_from_origin_is_an_implementation_detail_++, PO};
|
||||
}
|
||||
|
||||
template<typename QP>
|
||||
friend constexpr decltype(auto) operator--(QP&& qp)
|
||||
requires std::derived_from<std::remove_cvref_t<QP>, quantity_point> &&
|
||||
requires { --qp.quantity_from_origin_is_an_implementation_detail_; }
|
||||
template<typename FwdQP, std::derived_from<quantity_point> QP = std::remove_cvref_t<FwdQP>>
|
||||
friend constexpr decltype(auto) operator--(FwdQP&& qp)
|
||||
requires requires { --qp.quantity_from_origin_is_an_implementation_detail_; }
|
||||
{
|
||||
--qp.quantity_from_origin_is_an_implementation_detail_;
|
||||
return std::forward<QP>(qp);
|
||||
return std::forward<FwdQP>(qp);
|
||||
}
|
||||
|
||||
[[nodiscard]] constexpr quantity_point operator--(int)
|
||||
@@ -444,22 +439,20 @@ public:
|
||||
}
|
||||
|
||||
// compound assignment operators
|
||||
template<typename QP>
|
||||
requires std::derived_from<std::remove_cvref_t<QP>, quantity_point> &&
|
||||
requires(quantity_type q) { quantity_from_origin_is_an_implementation_detail_ += q; }
|
||||
friend constexpr decltype(auto) operator+=(QP&& qp, const quantity_type& q)
|
||||
template<typename FwdQP, std::derived_from<quantity_point> QP = std::remove_cvref_t<FwdQP>>
|
||||
requires requires(quantity_type q) { quantity_from_origin_is_an_implementation_detail_ += q; }
|
||||
friend constexpr decltype(auto) operator+=(FwdQP&& qp, const quantity_type& q)
|
||||
{
|
||||
qp.quantity_from_origin_is_an_implementation_detail_ += q;
|
||||
return std::forward<QP>(qp);
|
||||
return std::forward<FwdQP>(qp);
|
||||
}
|
||||
|
||||
template<typename QP>
|
||||
requires std::derived_from<std::remove_cvref_t<QP>, quantity_point> &&
|
||||
requires(quantity_type q) { quantity_from_origin_is_an_implementation_detail_ -= q; }
|
||||
friend constexpr decltype(auto) operator-=(QP&& qp, const quantity_type& q)
|
||||
template<typename FwdQP, std::derived_from<quantity_point> QP = std::remove_cvref_t<FwdQP>>
|
||||
requires requires(quantity_type q) { quantity_from_origin_is_an_implementation_detail_ -= q; }
|
||||
friend constexpr decltype(auto) operator-=(FwdQP&& qp, const quantity_type& q)
|
||||
{
|
||||
qp.quantity_from_origin_is_an_implementation_detail_ -= q;
|
||||
return std::forward<QP>(qp);
|
||||
return std::forward<FwdQP>(qp);
|
||||
}
|
||||
|
||||
// binary operators on quantity points
|
||||
|
@@ -159,13 +159,11 @@ struct quantity_spec_interface : quantity_spec_interface_base {
|
||||
return make_reference(self, u);
|
||||
}
|
||||
|
||||
template<typename Self, typename Q>
|
||||
requires Quantity<std::remove_cvref_t<Q>> &&
|
||||
QuantitySpecExplicitlyConvertibleTo<std::remove_reference_t<Q>::quantity_spec, Self{}>
|
||||
[[nodiscard]] constexpr Quantity auto operator()(this Self self, Q&& q)
|
||||
template<typename Self, typename FwdQ, Quantity Q = std::remove_cvref_t<FwdQ>>
|
||||
requires QuantitySpecExplicitlyConvertibleTo<Q::quantity_spec, Self{}>
|
||||
[[nodiscard]] constexpr Quantity auto operator()(this Self self, FwdQ&& q)
|
||||
{
|
||||
return quantity{std::forward<Q>(q).numerical_value_is_an_implementation_detail_,
|
||||
make_reference(self, std::remove_cvref_t<Q>::unit)};
|
||||
return quantity{std::forward<FwdQ>(q).numerical_value_is_an_implementation_detail_, make_reference(self, Q::unit)};
|
||||
}
|
||||
#else
|
||||
template<typename Self_ = Self, UnitOf<Self_{}> U>
|
||||
@@ -174,13 +172,12 @@ struct quantity_spec_interface : quantity_spec_interface_base {
|
||||
return make_reference(Self{}, u);
|
||||
}
|
||||
|
||||
template<typename Q, typename Self_ = Self>
|
||||
requires Quantity<std::remove_cvref_t<Q>> &&
|
||||
QuantitySpecExplicitlyConvertibleTo<std::remove_reference_t<Q>::quantity_spec, Self_{}>
|
||||
[[nodiscard]] constexpr Quantity auto operator()(Q&& q) const
|
||||
template<typename FwdQ, Quantity Q = std::remove_cvref_t<FwdQ>, typename Self_ = Self>
|
||||
requires QuantitySpecExplicitlyConvertibleTo<Q::quantity_spec, Self_{}>
|
||||
[[nodiscard]] constexpr Quantity auto operator()(FwdQ&& q) const
|
||||
{
|
||||
return quantity{std::forward<Q>(q).numerical_value_is_an_implementation_detail_,
|
||||
make_reference(Self{}, std::remove_cvref_t<Q>::unit)};
|
||||
return quantity{std::forward<FwdQ>(q).numerical_value_is_an_implementation_detail_,
|
||||
make_reference(Self{}, Q::unit)};
|
||||
}
|
||||
#endif
|
||||
};
|
||||
@@ -371,13 +368,12 @@ struct quantity_spec<Self, QS, Args...> : detail::propagate_equation<QS>, detail
|
||||
return detail::make_reference(Self{}, u);
|
||||
}
|
||||
|
||||
template<typename Q, typename Self_ = Self>
|
||||
requires Quantity<std::remove_cvref_t<Q>> &&
|
||||
detail::QuantitySpecExplicitlyConvertibleTo<std::remove_reference_t<Q>::quantity_spec, Self_{}>
|
||||
[[nodiscard]] constexpr Quantity auto operator()(Q&& q) const
|
||||
template<typename FwdQ, Quantity Q = std::remove_cvref_t<FwdQ>, typename Self_ = Self>
|
||||
requires detail::QuantitySpecExplicitlyConvertibleTo<Q::quantity_spec, Self_{}>
|
||||
[[nodiscard]] constexpr Quantity auto operator()(FwdQ&& q) const
|
||||
{
|
||||
return quantity{std::forward<Q>(q).numerical_value_is_an_implementation_detail_,
|
||||
detail::make_reference(Self{}, std::remove_cvref_t<Q>::unit)};
|
||||
return quantity{std::forward<FwdQ>(q).numerical_value_is_an_implementation_detail_,
|
||||
detail::make_reference(Self{}, Q::unit)};
|
||||
}
|
||||
#endif
|
||||
};
|
||||
|
@@ -178,36 +178,36 @@ struct reference {
|
||||
};
|
||||
|
||||
|
||||
template<typename Rep, Reference R>
|
||||
requires(!detail::OffsetUnit<decltype(get_unit(R{}))>) &&
|
||||
RepresentationOf<std::remove_cvref_t<Rep>, get_quantity_spec(R{}).character>
|
||||
[[nodiscard]] constexpr quantity<R{}, std::remove_cvref_t<Rep>> operator*(Rep&& lhs, R)
|
||||
template<typename FwdRep, Reference R,
|
||||
RepresentationOf<get_quantity_spec(R{}).character> Rep = std::remove_cvref_t<FwdRep>>
|
||||
requires(!detail::OffsetUnit<decltype(get_unit(R{}))>)
|
||||
[[nodiscard]] constexpr quantity<R{}, Rep> operator*(FwdRep&& lhs, R)
|
||||
{
|
||||
return quantity{std::forward<Rep>(lhs), R{}};
|
||||
return quantity{std::forward<FwdRep>(lhs), R{}};
|
||||
}
|
||||
|
||||
template<typename Rep, Reference R>
|
||||
requires(!detail::OffsetUnit<decltype(get_unit(R{}))>) &&
|
||||
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)
|
||||
template<typename FwdRep, Reference R,
|
||||
RepresentationOf<get_quantity_spec(R{}).character> Rep = std::remove_cvref_t<FwdRep>>
|
||||
requires(!detail::OffsetUnit<decltype(get_unit(R{}))>)
|
||||
[[nodiscard]] constexpr quantity<inverse(R{}), Rep> operator/(FwdRep&& lhs, R)
|
||||
{
|
||||
return quantity{std::forward<Rep>(lhs), inverse(R{})};
|
||||
return quantity{std::forward<FwdRep>(lhs), inverse(R{})};
|
||||
}
|
||||
|
||||
template<typename Rep, Reference R>
|
||||
requires detail::OffsetUnit<decltype(get_unit(R{}))> &&
|
||||
RepresentationOf<std::remove_cvref_t<Rep>, get_quantity_spec(R{}).character>
|
||||
[[noreturn]] constexpr auto operator*(Rep&&, R)
|
||||
template<typename FwdRep, Reference R,
|
||||
RepresentationOf<get_quantity_spec(R{}).character> Rep = std::remove_cvref_t<FwdRep>>
|
||||
requires detail::OffsetUnit<decltype(get_unit(R{}))>
|
||||
[[noreturn]] constexpr auto operator*(FwdRep&&, R)
|
||||
{
|
||||
static_assert(!detail::OffsetUnit<decltype(get_unit(R{}))>,
|
||||
"References using offset units (e.g., temperatures) may be constructed only with the `delta` or "
|
||||
"`absolute` helpers");
|
||||
}
|
||||
|
||||
template<typename Rep, Reference R>
|
||||
requires detail::OffsetUnit<decltype(get_unit(R{}))> &&
|
||||
RepresentationOf<std::remove_cvref_t<Rep>, get_quantity_spec(R{}).character>
|
||||
[[noreturn]] constexpr auto operator/(Rep&&, R)
|
||||
template<typename FwdRep, Reference R,
|
||||
RepresentationOf<get_quantity_spec(R{}).character> Rep = std::remove_cvref_t<FwdRep>>
|
||||
requires detail::OffsetUnit<decltype(get_unit(R{}))>
|
||||
[[noreturn]] constexpr auto operator/(FwdRep&&, R)
|
||||
{
|
||||
static_assert(!detail::OffsetUnit<decltype(get_unit(R{}))>,
|
||||
"References using offset units (e.g., temperatures) may be constructed only with the `delta` or "
|
||||
@@ -234,20 +234,16 @@ constexpr auto operator/(R, Rep&&)
|
||||
= delete;
|
||||
#endif
|
||||
|
||||
template<typename Q, Reference R>
|
||||
requires Quantity<std::remove_cvref_t<Q>>
|
||||
[[nodiscard]] constexpr Quantity auto operator*(Q&& q, R)
|
||||
template<typename FwdQ, Reference R, Quantity Q = std::remove_cvref_t<FwdQ>>
|
||||
[[nodiscard]] constexpr Quantity auto operator*(FwdQ&& q, R)
|
||||
{
|
||||
return quantity{std::forward<Q>(q).numerical_value_is_an_implementation_detail_,
|
||||
std::remove_cvref_t<Q>::reference * R{}};
|
||||
return quantity{std::forward<FwdQ>(q).numerical_value_is_an_implementation_detail_, Q::reference * R{}};
|
||||
}
|
||||
|
||||
template<typename Q, Reference R>
|
||||
requires Quantity<std::remove_cvref_t<Q>>
|
||||
[[nodiscard]] constexpr Quantity auto operator/(Q&& q, R)
|
||||
template<typename FwdQ, Reference R, Quantity Q = std::remove_cvref_t<FwdQ>>
|
||||
[[nodiscard]] constexpr Quantity auto operator/(FwdQ&& q, R)
|
||||
{
|
||||
return quantity{std::forward<Q>(q).numerical_value_is_an_implementation_detail_,
|
||||
std::remove_cvref_t<Q>::reference / R{}};
|
||||
return quantity{std::forward<FwdQ>(q).numerical_value_is_an_implementation_detail_, Q::reference / R{}};
|
||||
}
|
||||
|
||||
template<Reference R, typename Q>
|
||||
|
@@ -44,13 +44,12 @@ namespace mp_units {
|
||||
*
|
||||
* @tparam ToU a unit to use for a target quantity
|
||||
*/
|
||||
template<Unit auto ToU, typename Q>
|
||||
requires Quantity<std::remove_cvref_t<Q>> && (convertible(std::remove_reference_t<Q>::reference, ToU))
|
||||
[[nodiscard]] constexpr Quantity auto value_cast(Q&& q)
|
||||
template<Unit auto ToU, typename FwdQ, Quantity Q = std::remove_cvref_t<FwdQ>>
|
||||
requires(convertible(Q::reference, ToU))
|
||||
[[nodiscard]] constexpr Quantity auto value_cast(FwdQ&& q)
|
||||
{
|
||||
using q_type = std::remove_reference_t<Q>;
|
||||
return detail::sudo_cast<quantity<detail::make_reference(q_type::quantity_spec, ToU), typename q_type::rep>>(
|
||||
std::forward<Q>(q));
|
||||
return detail::sudo_cast<quantity<detail::make_reference(Q::quantity_spec, ToU), typename Q::rep>>(
|
||||
std::forward<FwdQ>(q));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -63,13 +62,11 @@ template<Unit auto ToU, typename Q>
|
||||
*
|
||||
* @tparam ToRep a representation type to use for a target quantity
|
||||
*/
|
||||
template<Representation ToRep, typename Q>
|
||||
requires Quantity<std::remove_cvref_t<Q>> &&
|
||||
RepresentationOf<ToRep, std::remove_reference_t<Q>::quantity_spec.character> &&
|
||||
std::constructible_from<ToRep, typename std::remove_reference_t<Q>::rep>
|
||||
[[nodiscard]] constexpr quantity<std::remove_reference_t<Q>::reference, ToRep> value_cast(Q&& q)
|
||||
template<Representation ToRep, typename FwdQ, Quantity Q = std::remove_cvref_t<FwdQ>>
|
||||
requires RepresentationOf<ToRep, Q::quantity_spec.character> && std::constructible_from<ToRep, typename Q::rep>
|
||||
[[nodiscard]] constexpr quantity<Q::reference, ToRep> value_cast(FwdQ&& q)
|
||||
{
|
||||
return detail::sudo_cast<quantity<std::remove_reference_t<Q>::reference, ToRep>>(std::forward<Q>(q));
|
||||
return detail::sudo_cast<quantity<Q::reference, ToRep>>(std::forward<FwdQ>(q));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -83,14 +80,12 @@ template<Representation ToRep, typename Q>
|
||||
* @tparam ToU a unit to use for the target quantity
|
||||
* @tparam ToRep a representation type to use for the target quantity
|
||||
*/
|
||||
template<Unit auto ToU, Representation ToRep, typename Q>
|
||||
requires Quantity<std::remove_cvref_t<Q>> && (convertible(std::remove_reference_t<Q>::reference, ToU)) &&
|
||||
RepresentationOf<ToRep, std::remove_reference_t<Q>::quantity_spec.character> &&
|
||||
std::constructible_from<ToRep, typename std::remove_reference_t<Q>::rep>
|
||||
[[nodiscard]] constexpr Quantity auto value_cast(Q&& q)
|
||||
template<Unit auto ToU, Representation ToRep, typename FwdQ, Quantity Q = std::remove_cvref_t<FwdQ>>
|
||||
requires(convertible(Q::reference, ToU)) && RepresentationOf<ToRep, Q::quantity_spec.character> &&
|
||||
std::constructible_from<ToRep, typename Q::rep>
|
||||
[[nodiscard]] constexpr Quantity auto value_cast(FwdQ&& q)
|
||||
{
|
||||
using q_type = std::remove_reference_t<Q>;
|
||||
return detail::sudo_cast<quantity<detail::make_reference(q_type::quantity_spec, ToU), ToRep>>(std::forward<Q>(q));
|
||||
return detail::sudo_cast<quantity<detail::make_reference(Q::quantity_spec, ToU), ToRep>>(std::forward<FwdQ>(q));
|
||||
}
|
||||
|
||||
|
||||
@@ -108,13 +103,12 @@ template<Unit auto ToU, Representation ToRep, typename Q>
|
||||
*
|
||||
* @tparam ToQ a target quantity type to which to cast the representation
|
||||
*/
|
||||
template<Quantity ToQ, typename Q>
|
||||
requires Quantity<std::remove_cvref_t<Q>> && (convertible(std::remove_reference_t<Q>::reference, ToQ::unit)) &&
|
||||
(ToQ::quantity_spec == std::remove_reference_t<Q>::quantity_spec) &&
|
||||
std::constructible_from<typename ToQ::rep, typename std::remove_reference_t<Q>::rep>
|
||||
[[nodiscard]] constexpr Quantity auto value_cast(Q&& q)
|
||||
template<Quantity ToQ, typename FwdQ, Quantity Q = std::remove_cvref_t<FwdQ>>
|
||||
requires(convertible(Q::reference, ToQ::unit)) &&
|
||||
(ToQ::quantity_spec == Q::quantity_spec) && std::constructible_from<typename ToQ::rep, typename Q::rep>
|
||||
[[nodiscard]] constexpr Quantity auto value_cast(FwdQ&& q)
|
||||
{
|
||||
return detail::sudo_cast<ToQ>(std::forward<Q>(q));
|
||||
return detail::sudo_cast<ToQ>(std::forward<FwdQ>(q));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -127,12 +121,12 @@ template<Quantity ToQ, typename Q>
|
||||
*
|
||||
* @tparam ToU a unit to use for a target quantity point
|
||||
*/
|
||||
template<Unit auto ToU, typename QP>
|
||||
requires QuantityPoint<std::remove_cvref_t<QP>> && (convertible(std::remove_reference_t<QP>::reference, ToU))
|
||||
[[nodiscard]] constexpr QuantityPoint auto value_cast(QP&& qp)
|
||||
template<Unit auto ToU, typename FwdQP, QuantityPoint QP = std::remove_cvref_t<FwdQP>>
|
||||
requires(convertible(QP::reference, ToU))
|
||||
[[nodiscard]] constexpr QuantityPoint auto value_cast(FwdQP&& qp)
|
||||
{
|
||||
return quantity_point{value_cast<ToU>(std::forward<QP>(qp).quantity_from_origin_is_an_implementation_detail_),
|
||||
std::remove_reference_t<QP>::point_origin};
|
||||
return quantity_point{value_cast<ToU>(std::forward<FwdQP>(qp).quantity_from_origin_is_an_implementation_detail_),
|
||||
QP::point_origin};
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -145,16 +139,12 @@ template<Unit auto ToU, typename QP>
|
||||
*
|
||||
* @tparam ToRep a representation type to use for a target quantity point
|
||||
*/
|
||||
template<Representation ToRep, typename QP>
|
||||
requires QuantityPoint<std::remove_cvref_t<QP>> &&
|
||||
RepresentationOf<ToRep, std::remove_reference_t<QP>::quantity_spec.character> &&
|
||||
std::constructible_from<ToRep, typename std::remove_reference_t<QP>::rep>
|
||||
[[nodiscard]] constexpr quantity_point<std::remove_reference_t<QP>::reference,
|
||||
std::remove_reference_t<QP>::point_origin, ToRep>
|
||||
value_cast(QP&& qp)
|
||||
template<Representation ToRep, typename FwdQP, QuantityPoint QP = std::remove_cvref_t<FwdQP>>
|
||||
requires RepresentationOf<ToRep, QP::quantity_spec.character> && std::constructible_from<ToRep, typename QP::rep>
|
||||
[[nodiscard]] constexpr quantity_point<QP::reference, QP::point_origin, ToRep> value_cast(FwdQP&& qp)
|
||||
{
|
||||
return {value_cast<ToRep>(std::forward<QP>(qp).quantity_from_origin_is_an_implementation_detail_),
|
||||
std::remove_reference_t<QP>::point_origin};
|
||||
return {value_cast<ToRep>(std::forward<FwdQP>(qp).quantity_from_origin_is_an_implementation_detail_),
|
||||
QP::point_origin};
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -168,14 +158,14 @@ value_cast(QP&& qp)
|
||||
* @tparam ToU a unit to use for the target quantity
|
||||
* @tparam ToRep a representation type to use for the target quantity
|
||||
*/
|
||||
template<Unit auto ToU, Representation ToRep, typename QP>
|
||||
requires QuantityPoint<std::remove_cvref_t<QP>> && (convertible(std::remove_reference_t<QP>::reference, ToU)) &&
|
||||
RepresentationOf<ToRep, std::remove_reference_t<QP>::quantity_spec.character> &&
|
||||
std::constructible_from<ToRep, typename std::remove_reference_t<QP>::rep>
|
||||
[[nodiscard]] constexpr QuantityPoint auto value_cast(QP&& qp)
|
||||
template<Unit auto ToU, Representation ToRep, typename FwdQP, QuantityPoint QP = std::remove_cvref_t<FwdQP>>
|
||||
requires(convertible(QP::reference, ToU)) && RepresentationOf<ToRep, QP::quantity_spec.character> &&
|
||||
std::constructible_from<ToRep, typename QP::rep>
|
||||
[[nodiscard]] constexpr QuantityPoint auto value_cast(FwdQP&& qp)
|
||||
{
|
||||
return quantity_point{value_cast<ToU, ToRep>(std::forward<QP>(qp).quantity_from_origin_is_an_implementation_detail_),
|
||||
std::remove_reference_t<QP>::point_origin};
|
||||
return quantity_point{
|
||||
value_cast<ToU, ToRep>(std::forward<FwdQP>(qp).quantity_from_origin_is_an_implementation_detail_),
|
||||
QP::point_origin};
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -194,14 +184,13 @@ template<Unit auto ToU, Representation ToRep, typename QP>
|
||||
*
|
||||
* @tparam ToQ a target quantity type to which to cast the representation of the point
|
||||
*/
|
||||
template<Quantity ToQ, typename QP>
|
||||
requires QuantityPoint<std::remove_cvref_t<QP>> && (convertible(std::remove_reference_t<QP>::reference, ToQ::unit)) &&
|
||||
(ToQ::quantity_spec == std::remove_reference_t<QP>::quantity_spec) &&
|
||||
std::constructible_from<typename ToQ::rep, typename std::remove_reference_t<QP>::rep>
|
||||
[[nodiscard]] constexpr QuantityPoint auto value_cast(QP&& qp)
|
||||
template<Quantity ToQ, typename FwdQP, QuantityPoint QP = std::remove_cvref_t<FwdQP>>
|
||||
requires(convertible(QP::reference, ToQ::unit)) &&
|
||||
(ToQ::quantity_spec == QP::quantity_spec) && std::constructible_from<typename ToQ::rep, typename QP::rep>
|
||||
[[nodiscard]] constexpr QuantityPoint auto value_cast(FwdQP&& qp)
|
||||
{
|
||||
return quantity_point{value_cast<ToQ>(std::forward<QP>(qp).quantity_from_origin_is_an_implementation_detail_),
|
||||
std::remove_reference_t<QP>::point_origin};
|
||||
return quantity_point{value_cast<ToQ>(std::forward<FwdQP>(qp).quantity_from_origin_is_an_implementation_detail_),
|
||||
QP::point_origin};
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -232,16 +221,13 @@ template<Quantity ToQ, typename QP>
|
||||
*
|
||||
* @tparam ToQP a target quantity point type to which to cast the representation of the point
|
||||
*/
|
||||
template<QuantityPoint ToQP, typename QP>
|
||||
requires QuantityPoint<std::remove_cvref_t<QP>> &&
|
||||
(convertible(std::remove_reference_t<QP>::reference, ToQP::unit)) &&
|
||||
(ToQP::quantity_spec == std::remove_reference_t<QP>::quantity_spec) &&
|
||||
(detail::same_absolute_point_origins(ToQP::point_origin, std::remove_reference_t<QP>::point_origin)) &&
|
||||
std::constructible_from<typename ToQP::rep, typename std::remove_reference_t<QP>::rep>
|
||||
[[nodiscard]] constexpr QuantityPoint auto value_cast(QP&& qp)
|
||||
template<QuantityPoint ToQP, typename FwdQP, QuantityPoint QP = std::remove_cvref_t<FwdQP>>
|
||||
requires(convertible(QP::reference, ToQP::unit)) && (ToQP::quantity_spec == QP::quantity_spec) &&
|
||||
(detail::same_absolute_point_origins(ToQP::point_origin, QP::point_origin)) &&
|
||||
std::constructible_from<typename ToQP::rep, typename QP::rep>
|
||||
[[nodiscard]] constexpr QuantityPoint auto value_cast(FwdQP&& qp)
|
||||
{
|
||||
return detail::sudo_cast<ToQP>(std::forward<QP>(qp));
|
||||
return detail::sudo_cast<ToQP>(std::forward<FwdQP>(qp));
|
||||
}
|
||||
|
||||
|
||||
} // namespace mp_units
|
||||
|
Reference in New Issue
Block a user