forked from mpusz/mp-units
refactor: might_store_converted_value
refactored to overflows_non_zero_values
This commit is contained in:
@@ -69,7 +69,7 @@ concept ValuePreservingTo = Representation<std::remove_cvref_t<FromRep>> && Repr
|
|||||||
Unit<MP_UNITS_REMOVE_CONST(decltype(ToUnit))> && std::assignable_from<ToRep&, FromRep> &&
|
Unit<MP_UNITS_REMOVE_CONST(decltype(ToUnit))> && std::assignable_from<ToRep&, FromRep> &&
|
||||||
(IsFloatingPoint<ToRep> || (!IsFloatingPoint<std::remove_cvref_t<FromRep>> &&
|
(IsFloatingPoint<ToRep> || (!IsFloatingPoint<std::remove_cvref_t<FromRep>> &&
|
||||||
integral_conversion_factor(FromUnit, ToUnit) &&
|
integral_conversion_factor(FromUnit, ToUnit) &&
|
||||||
might_store_converted_value<ToRep>(FromUnit, ToUnit)));
|
!overflows_non_zero_values<ToRep>(FromUnit, ToUnit)));
|
||||||
|
|
||||||
template<typename QFrom, typename QTo>
|
template<typename QFrom, typename QTo>
|
||||||
concept QuantityConvertibleTo =
|
concept QuantityConvertibleTo =
|
||||||
@@ -103,10 +103,10 @@ using common_quantity_for = quantity<get_common_reference(Q1::reference, Q2::ref
|
|||||||
std::invoke_result_t<Func, typename Q1::rep, typename Q2::rep>>;
|
std::invoke_result_t<Func, typename Q1::rep, typename Q2::rep>>;
|
||||||
|
|
||||||
template<Representation Rep, Unit U1, Unit U2>
|
template<Representation Rep, Unit U1, Unit U2>
|
||||||
[[nodiscard]] consteval bool might_store_converted_common_value(U1 u1, U2 u2)
|
[[nodiscard]] consteval bool overflows_non_zero_common_values(U1 u1, U2 u2)
|
||||||
{
|
{
|
||||||
constexpr Unit auto cu = get_common_unit(U1{}, U2{});
|
constexpr Unit auto cu = get_common_unit(U1{}, U2{});
|
||||||
return might_store_converted_value<Rep>(u1, cu) && might_store_converted_value<Rep>(u2, cu);
|
return overflows_non_zero_values<Rep>(u1, cu) || overflows_non_zero_values<Rep>(u2, cu);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Func, typename Q1, typename Q2>
|
template<typename Func, typename Q1, typename Q2>
|
||||||
@@ -115,8 +115,8 @@ concept CommonlyInvocableQuantities =
|
|||||||
std::convertible_to<Q1, common_quantity_for<Func, Q1, Q2>> &&
|
std::convertible_to<Q1, common_quantity_for<Func, Q1, Q2>> &&
|
||||||
std::convertible_to<Q2, common_quantity_for<Func, Q1, Q2>> &&
|
std::convertible_to<Q2, common_quantity_for<Func, Q1, Q2>> &&
|
||||||
InvocableQuantities<Func, Q1, Q2, get_common_quantity_spec(Q1::quantity_spec, Q2::quantity_spec)> &&
|
InvocableQuantities<Func, Q1, Q2, get_common_quantity_spec(Q1::quantity_spec, Q2::quantity_spec)> &&
|
||||||
might_store_converted_common_value<std::invoke_result_t<Func, typename Q1::rep, typename Q2::rep>>(Q1::unit,
|
(!overflows_non_zero_common_values<std::invoke_result_t<Func, typename Q1::rep, typename Q2::rep>>(Q1::unit,
|
||||||
Q2::unit);
|
Q2::unit));
|
||||||
|
|
||||||
template<auto R1, auto R2, typename Rep1, typename Rep2>
|
template<auto R1, auto R2, typename Rep1, typename Rep2>
|
||||||
concept SameValueAs = (equivalent(get_unit(R1), get_unit(R2))) && std::convertible_to<Rep1, Rep2>;
|
concept SameValueAs = (equivalent(get_unit(R1), get_unit(R2))) && std::convertible_to<Rep1, Rep2>;
|
||||||
@@ -651,7 +651,7 @@ template<mp_units::Quantity Q1, mp_units::Quantity Q2>
|
|||||||
{ mp_units::get_common_reference(Q1::reference, Q2::reference) } -> mp_units::Reference;
|
{ mp_units::get_common_reference(Q1::reference, Q2::reference) } -> mp_units::Reference;
|
||||||
typename std::common_type_t<typename Q1::rep, typename Q2::rep>;
|
typename std::common_type_t<typename Q1::rep, typename Q2::rep>;
|
||||||
requires(
|
requires(
|
||||||
might_store_converted_common_value<std::common_type_t<typename Q1::rep, typename Q2::rep>>(Q1::unit, Q2::unit));
|
!overflows_non_zero_common_values<std::common_type_t<typename Q1::rep, typename Q2::rep>>(Q1::unit, Q2::unit));
|
||||||
requires mp_units::RepresentationOf<std::common_type_t<typename Q1::rep, typename Q2::rep>,
|
requires mp_units::RepresentationOf<std::common_type_t<typename Q1::rep, typename Q2::rep>,
|
||||||
mp_units::get_common_quantity_spec(Q1::quantity_spec, Q2::quantity_spec)>;
|
mp_units::get_common_quantity_spec(Q1::quantity_spec, Q2::quantity_spec)>;
|
||||||
}
|
}
|
||||||
|
@@ -38,22 +38,22 @@ namespace mp_units {
|
|||||||
namespace detail {
|
namespace detail {
|
||||||
|
|
||||||
template<Representation Rep, Unit UFrom, Unit UTo>
|
template<Representation Rep, Unit UFrom, Unit UTo>
|
||||||
[[nodiscard]] consteval bool might_store_converted_value(UFrom from, UTo to)
|
[[nodiscard]] consteval bool overflows_non_zero_values(UFrom from, UTo to)
|
||||||
{
|
{
|
||||||
if constexpr (is_same_v<UFrom, UTo> || treat_as_floating_point<Rep>)
|
if constexpr (is_same_v<UFrom, UTo> || treat_as_floating_point<Rep>)
|
||||||
return true;
|
return false;
|
||||||
else if constexpr (std::totally_ordered_with<Rep, std::uintmax_t> &&
|
else if constexpr (std::totally_ordered_with<Rep, std::uintmax_t> &&
|
||||||
requires(Rep v) { representation_values<Rep>::max(); }) {
|
requires(Rep v) { representation_values<Rep>::max(); }) {
|
||||||
constexpr auto factor =
|
constexpr auto factor =
|
||||||
get_value<std::uintmax_t>(numerator(get_canonical_unit(from).mag / get_canonical_unit(to).mag));
|
get_value<std::uintmax_t>(numerator(get_canonical_unit(from).mag / get_canonical_unit(to).mag));
|
||||||
if constexpr (std::is_integral_v<Rep>)
|
if constexpr (std::is_integral_v<Rep>)
|
||||||
return std::in_range<Rep>(factor);
|
return !std::in_range<Rep>(factor);
|
||||||
else
|
else
|
||||||
return factor <= representation_values<Rep>::max();
|
return factor > representation_values<Rep>::max();
|
||||||
} else
|
} else
|
||||||
// if the representation is not totally ordered with std::uintmax_t or does not have max() defined
|
// if the representation is not totally ordered with std::uintmax_t or does not have max() defined
|
||||||
// then we assume that it might store any value
|
// then we assume that it might store any value
|
||||||
return true;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace detail
|
} // namespace detail
|
||||||
@@ -70,7 +70,7 @@ template<Representation Rep, Unit UFrom, Unit UTo>
|
|||||||
*/
|
*/
|
||||||
template<auto ToU, typename FwdQ, Quantity Q = std::remove_cvref_t<FwdQ>>
|
template<auto ToU, typename FwdQ, Quantity Q = std::remove_cvref_t<FwdQ>>
|
||||||
requires detail::UnitCompatibleWith<MP_UNITS_REMOVE_CONST(decltype(ToU)), Q::unit, Q::quantity_spec> &&
|
requires detail::UnitCompatibleWith<MP_UNITS_REMOVE_CONST(decltype(ToU)), Q::unit, Q::quantity_spec> &&
|
||||||
(detail::might_store_converted_value<typename Q::rep>(Q::unit, ToU))
|
(!detail::overflows_non_zero_values<typename Q::rep>(Q::unit, ToU))
|
||||||
[[nodiscard]] constexpr Quantity auto value_cast(FwdQ&& q)
|
[[nodiscard]] constexpr Quantity auto value_cast(FwdQ&& q)
|
||||||
{
|
{
|
||||||
return detail::sudo_cast<quantity<detail::make_reference(Q::quantity_spec, ToU), typename Q::rep>>(
|
return detail::sudo_cast<quantity<detail::make_reference(Q::quantity_spec, ToU), typename Q::rep>>(
|
||||||
@@ -107,7 +107,7 @@ template<Representation ToRep, typename FwdQ, Quantity Q = std::remove_cvref_t<F
|
|||||||
*/
|
*/
|
||||||
template<Unit auto ToU, Representation ToRep, typename FwdQ, Quantity Q = std::remove_cvref_t<FwdQ>>
|
template<Unit auto ToU, Representation ToRep, typename FwdQ, Quantity Q = std::remove_cvref_t<FwdQ>>
|
||||||
requires detail::UnitCompatibleWith<MP_UNITS_REMOVE_CONST(decltype(ToU)), Q::unit, Q::quantity_spec> &&
|
requires detail::UnitCompatibleWith<MP_UNITS_REMOVE_CONST(decltype(ToU)), Q::unit, Q::quantity_spec> &&
|
||||||
(detail::might_store_converted_value<ToRep>(Q::unit, ToU)) &&
|
(!detail::overflows_non_zero_values<ToRep>(Q::unit, ToU)) &&
|
||||||
RepresentationOf<ToRep, Q::quantity_spec> && std::constructible_from<ToRep, typename Q::rep>
|
RepresentationOf<ToRep, Q::quantity_spec> && std::constructible_from<ToRep, typename Q::rep>
|
||||||
[[nodiscard]] constexpr Quantity auto value_cast(FwdQ&& q)
|
[[nodiscard]] constexpr Quantity auto value_cast(FwdQ&& q)
|
||||||
{
|
{
|
||||||
@@ -116,7 +116,7 @@ template<Unit auto ToU, Representation ToRep, typename FwdQ, Quantity Q = std::r
|
|||||||
|
|
||||||
template<Representation ToRep, Unit auto ToU, typename FwdQ, Quantity Q = std::remove_cvref_t<FwdQ>>
|
template<Representation ToRep, Unit auto ToU, typename FwdQ, Quantity Q = std::remove_cvref_t<FwdQ>>
|
||||||
requires detail::UnitCompatibleWith<MP_UNITS_REMOVE_CONST(decltype(ToU)), Q::unit, Q::quantity_spec> &&
|
requires detail::UnitCompatibleWith<MP_UNITS_REMOVE_CONST(decltype(ToU)), Q::unit, Q::quantity_spec> &&
|
||||||
(detail::might_store_converted_value<ToRep>(Q::unit, ToU)) &&
|
(!detail::overflows_non_zero_values<ToRep>(Q::unit, ToU)) &&
|
||||||
RepresentationOf<ToRep, Q::quantity_spec> && std::constructible_from<ToRep, typename Q::rep>
|
RepresentationOf<ToRep, Q::quantity_spec> && std::constructible_from<ToRep, typename Q::rep>
|
||||||
[[nodiscard]] constexpr Quantity auto value_cast(FwdQ&& q)
|
[[nodiscard]] constexpr Quantity auto value_cast(FwdQ&& q)
|
||||||
{
|
{
|
||||||
@@ -140,7 +140,7 @@ template<Representation ToRep, Unit auto ToU, typename FwdQ, Quantity Q = std::r
|
|||||||
*/
|
*/
|
||||||
template<Quantity ToQ, typename FwdQ, Quantity Q = std::remove_cvref_t<FwdQ>>
|
template<Quantity ToQ, typename FwdQ, Quantity Q = std::remove_cvref_t<FwdQ>>
|
||||||
requires detail::UnitCompatibleWith<MP_UNITS_NONCONST_TYPE(ToQ::unit), Q::unit, Q::quantity_spec> &&
|
requires detail::UnitCompatibleWith<MP_UNITS_NONCONST_TYPE(ToQ::unit), Q::unit, Q::quantity_spec> &&
|
||||||
(detail::might_store_converted_value<typename ToQ::rep>(Q::unit, ToQ::unit)) &&
|
(!detail::overflows_non_zero_values<typename ToQ::rep>(Q::unit, ToQ::unit)) &&
|
||||||
(ToQ::quantity_spec == Q::quantity_spec) && std::constructible_from<typename ToQ::rep, typename Q::rep>
|
(ToQ::quantity_spec == Q::quantity_spec) && std::constructible_from<typename ToQ::rep, typename Q::rep>
|
||||||
[[nodiscard]] constexpr Quantity auto value_cast(FwdQ&& q)
|
[[nodiscard]] constexpr Quantity auto value_cast(FwdQ&& q)
|
||||||
{
|
{
|
||||||
@@ -159,7 +159,7 @@ template<Quantity ToQ, typename FwdQ, Quantity Q = std::remove_cvref_t<FwdQ>>
|
|||||||
*/
|
*/
|
||||||
template<Unit auto ToU, typename FwdQP, QuantityPoint QP = std::remove_cvref_t<FwdQP>>
|
template<Unit auto ToU, typename FwdQP, QuantityPoint QP = std::remove_cvref_t<FwdQP>>
|
||||||
requires detail::UnitCompatibleWith<MP_UNITS_REMOVE_CONST(decltype(ToU)), QP::unit, QP::quantity_spec> &&
|
requires detail::UnitCompatibleWith<MP_UNITS_REMOVE_CONST(decltype(ToU)), QP::unit, QP::quantity_spec> &&
|
||||||
(detail::might_store_converted_value<typename QP::rep>(QP::unit, ToU))
|
(!detail::overflows_non_zero_values<typename QP::rep>(QP::unit, ToU))
|
||||||
[[nodiscard]] constexpr QuantityPoint auto value_cast(FwdQP&& qp)
|
[[nodiscard]] constexpr QuantityPoint auto value_cast(FwdQP&& qp)
|
||||||
{
|
{
|
||||||
return quantity_point{value_cast<ToU>(std::forward<FwdQP>(qp).quantity_from_origin_is_an_implementation_detail_),
|
return quantity_point{value_cast<ToU>(std::forward<FwdQP>(qp).quantity_from_origin_is_an_implementation_detail_),
|
||||||
@@ -197,7 +197,7 @@ template<Representation ToRep, typename FwdQP, QuantityPoint QP = std::remove_cv
|
|||||||
*/
|
*/
|
||||||
template<Unit auto ToU, Representation ToRep, typename FwdQP, QuantityPoint QP = std::remove_cvref_t<FwdQP>>
|
template<Unit auto ToU, Representation ToRep, typename FwdQP, QuantityPoint QP = std::remove_cvref_t<FwdQP>>
|
||||||
requires detail::UnitCompatibleWith<MP_UNITS_REMOVE_CONST(decltype(ToU)), QP::unit, QP::quantity_spec> &&
|
requires detail::UnitCompatibleWith<MP_UNITS_REMOVE_CONST(decltype(ToU)), QP::unit, QP::quantity_spec> &&
|
||||||
(detail::might_store_converted_value<ToRep>(QP::unit, ToU)) &&
|
(!detail::overflows_non_zero_values<ToRep>(QP::unit, ToU)) &&
|
||||||
RepresentationOf<ToRep, QP::quantity_spec> && std::constructible_from<ToRep, typename QP::rep>
|
RepresentationOf<ToRep, QP::quantity_spec> && std::constructible_from<ToRep, typename QP::rep>
|
||||||
[[nodiscard]] constexpr QuantityPoint auto value_cast(FwdQP&& qp)
|
[[nodiscard]] constexpr QuantityPoint auto value_cast(FwdQP&& qp)
|
||||||
{
|
{
|
||||||
@@ -208,7 +208,7 @@ template<Unit auto ToU, Representation ToRep, typename FwdQP, QuantityPoint QP =
|
|||||||
|
|
||||||
template<Representation ToRep, Unit auto ToU, typename FwdQP, QuantityPoint QP = std::remove_cvref_t<FwdQP>>
|
template<Representation ToRep, Unit auto ToU, typename FwdQP, QuantityPoint QP = std::remove_cvref_t<FwdQP>>
|
||||||
requires detail::UnitCompatibleWith<MP_UNITS_REMOVE_CONST(decltype(ToU)), QP::unit, QP::quantity_spec> &&
|
requires detail::UnitCompatibleWith<MP_UNITS_REMOVE_CONST(decltype(ToU)), QP::unit, QP::quantity_spec> &&
|
||||||
(detail::might_store_converted_value<ToRep>(QP::unit, ToU)) &&
|
(!detail::overflows_non_zero_values<ToRep>(QP::unit, ToU)) &&
|
||||||
RepresentationOf<ToRep, QP::quantity_spec> && std::constructible_from<ToRep, typename QP::rep>
|
RepresentationOf<ToRep, QP::quantity_spec> && std::constructible_from<ToRep, typename QP::rep>
|
||||||
[[nodiscard]] constexpr QuantityPoint auto value_cast(FwdQP&& qp)
|
[[nodiscard]] constexpr QuantityPoint auto value_cast(FwdQP&& qp)
|
||||||
{
|
{
|
||||||
@@ -233,7 +233,7 @@ template<Representation ToRep, Unit auto ToU, typename FwdQP, QuantityPoint QP =
|
|||||||
*/
|
*/
|
||||||
template<Quantity ToQ, typename FwdQP, QuantityPoint QP = std::remove_cvref_t<FwdQP>>
|
template<Quantity ToQ, typename FwdQP, QuantityPoint QP = std::remove_cvref_t<FwdQP>>
|
||||||
requires detail::UnitCompatibleWith<MP_UNITS_NONCONST_TYPE(ToQ::unit), QP::unit, QP::quantity_spec> &&
|
requires detail::UnitCompatibleWith<MP_UNITS_NONCONST_TYPE(ToQ::unit), QP::unit, QP::quantity_spec> &&
|
||||||
(detail::might_store_converted_value<typename ToQ::rep>(QP::unit, ToQ::unit)) &&
|
(!detail::overflows_non_zero_values<typename ToQ::rep>(QP::unit, ToQ::unit)) &&
|
||||||
(ToQ::quantity_spec == QP::quantity_spec) && std::constructible_from<typename ToQ::rep, typename QP::rep>
|
(ToQ::quantity_spec == QP::quantity_spec) && std::constructible_from<typename ToQ::rep, typename QP::rep>
|
||||||
[[nodiscard]] constexpr QuantityPoint auto value_cast(FwdQP&& qp)
|
[[nodiscard]] constexpr QuantityPoint auto value_cast(FwdQP&& qp)
|
||||||
{
|
{
|
||||||
@@ -271,7 +271,7 @@ template<Quantity ToQ, typename FwdQP, QuantityPoint QP = std::remove_cvref_t<Fw
|
|||||||
*/
|
*/
|
||||||
template<QuantityPoint ToQP, typename FwdQP, QuantityPoint QP = std::remove_cvref_t<FwdQP>>
|
template<QuantityPoint ToQP, typename FwdQP, QuantityPoint QP = std::remove_cvref_t<FwdQP>>
|
||||||
requires detail::UnitCompatibleWith<MP_UNITS_NONCONST_TYPE(ToQP::unit), QP::unit, QP::quantity_spec> &&
|
requires detail::UnitCompatibleWith<MP_UNITS_NONCONST_TYPE(ToQP::unit), QP::unit, QP::quantity_spec> &&
|
||||||
(detail::might_store_converted_value<typename ToQP::rep>(QP::unit, ToQP::unit)) &&
|
(!detail::overflows_non_zero_values<typename ToQP::rep>(QP::unit, ToQP::unit)) &&
|
||||||
(ToQP::quantity_spec == QP::quantity_spec) &&
|
(ToQP::quantity_spec == QP::quantity_spec) &&
|
||||||
(detail::same_absolute_point_origins(ToQP::point_origin, QP::point_origin)) &&
|
(detail::same_absolute_point_origins(ToQP::point_origin, QP::point_origin)) &&
|
||||||
std::constructible_from<typename ToQP::rep, typename QP::rep>
|
std::constructible_from<typename ToQP::rep, typename QP::rep>
|
||||||
|
@@ -405,7 +405,7 @@ template<Unit auto To, auto R, typename Rep>
|
|||||||
*/
|
*/
|
||||||
template<Unit auto To, auto R, typename Rep>
|
template<Unit auto To, auto R, typename Rep>
|
||||||
[[nodiscard]] constexpr Quantity auto inverse(const quantity<R, Rep>& q)
|
[[nodiscard]] constexpr Quantity auto inverse(const quantity<R, Rep>& q)
|
||||||
requires(detail::might_store_converted_value<Rep>(one / get_unit(R), To)) && requires {
|
requires(!detail::overflows_non_zero_values<Rep>(one / get_unit(R), To)) && requires {
|
||||||
representation_values<Rep>::one();
|
representation_values<Rep>::one();
|
||||||
value_cast<To>(representation_values<Rep>::one() / q);
|
value_cast<To>(representation_values<Rep>::one() / q);
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user