mirror of
https://github.com/mpusz/mp-units.git
synced 2025-06-25 01:01:33 +02:00
feat: some constraints refactored to throw exceptions with nice error messages
This commit is contained in:
@ -26,6 +26,7 @@
|
||||
#include <mp-units/bits/hacks.h>
|
||||
#include <mp-units/bits/module_macros.h>
|
||||
#include <mp-units/bits/sudo_cast.h>
|
||||
#include <mp-units/bits/unsatisfied.h>
|
||||
#include <mp-units/compat_macros.h>
|
||||
#include <mp-units/framework/customization_points.h>
|
||||
#include <mp-units/framework/dimension_concepts.h>
|
||||
@ -76,8 +77,11 @@ template<typename T, typename Arg>
|
||||
concept ValuePreservingAssignment = std::assignable_from<T&, Arg> && is_value_preserving<std::remove_cvref_t<Arg>, T>;
|
||||
|
||||
template<auto FromUnit, auto ToUnit, typename Rep>
|
||||
concept ValuePreservingScaling1Rep = SaneScaling<FromUnit, ToUnit, Rep> &&
|
||||
(treat_as_floating_point<Rep> || (integral_conversion_factor(FromUnit, ToUnit)));
|
||||
concept ValuePreservingScaling1Rep =
|
||||
SaneScaling<FromUnit, ToUnit, Rep> &&
|
||||
(treat_as_floating_point<Rep> || (integral_conversion_factor(FromUnit, ToUnit)) ||
|
||||
unsatisfied<"Scaling from '{}' to '{}' is not value-preserving for '{}' representation type">(
|
||||
unit_symbol(FromUnit), unit_symbol(ToUnit), type_name<Rep>()));
|
||||
|
||||
template<auto FromUnit, typename FromRep, auto ToUnit, typename ToRep>
|
||||
concept ValuePreservingScaling2Reps =
|
||||
@ -85,7 +89,9 @@ concept ValuePreservingScaling2Reps =
|
||||
// CastableReps<FromRep, ToRep, FromUnit, ToUnit> &&
|
||||
SaneScaling<FromUnit, ToUnit, ToRep> &&
|
||||
(treat_as_floating_point<ToRep> ||
|
||||
(!treat_as_floating_point<FromRep> && integral_conversion_factor(FromUnit, ToUnit)));
|
||||
(!treat_as_floating_point<FromRep> && integral_conversion_factor(FromUnit, ToUnit)) ||
|
||||
unsatisfied<"Scaling from '{}' as '{}' to '{}' as '{}' is not value-preserving">(
|
||||
unit_symbol(FromUnit), type_name<FromRep>(), unit_symbol(ToUnit), type_name<ToRep>()));
|
||||
|
||||
template<typename QTo, typename QFrom>
|
||||
concept QuantityConstructibleFrom =
|
||||
|
@ -24,6 +24,7 @@
|
||||
|
||||
// IWYU pragma: private, include <mp-units/framework.h>
|
||||
#include <mp-units/bits/module_macros.h>
|
||||
#include <mp-units/bits/unsatisfied.h>
|
||||
#include <mp-units/framework/quantity_spec_concepts.h>
|
||||
#include <mp-units/framework/symbolic_expression.h>
|
||||
#include <mp-units/framework/unit_magnitude.h>
|
||||
@ -97,8 +98,11 @@ concept AssociatedUnit = Unit<U> && detail::has_associated_quantity(U{});
|
||||
* the provided @c QS value.
|
||||
*/
|
||||
MP_UNITS_EXPORT template<typename U, auto QS>
|
||||
concept UnitOf = AssociatedUnit<U> && QuantitySpec<MP_UNITS_REMOVE_CONST(decltype(QS))> &&
|
||||
(implicitly_convertible(get_quantity_spec(U{}), QS));
|
||||
concept UnitOf =
|
||||
AssociatedUnit<U> && QuantitySpec<MP_UNITS_REMOVE_CONST(decltype(QS))> &&
|
||||
(implicitly_convertible(get_quantity_spec(U{}), QS) ||
|
||||
(unsatisfied<"Unit '{}' is associated with quantity of kind '{}' which is not convertible to the '{}' quantity">(
|
||||
U{}, type_name(get_quantity_spec(U{})._quantity_spec_), type_name(QS))));
|
||||
|
||||
namespace detail {
|
||||
|
||||
@ -107,10 +111,17 @@ concept WeakUnitOf =
|
||||
Unit<U> && QuantitySpec<MP_UNITS_REMOVE_CONST(decltype(QS))> && ((!AssociatedUnit<U>) || UnitOf<U, QS>);
|
||||
|
||||
template<auto U1, auto U2>
|
||||
concept UnitsOfCompatibleQuantities = explicitly_convertible(get_quantity_spec(U1), get_quantity_spec(U2));
|
||||
concept UnitsOfCompatibleQuantities =
|
||||
explicitly_convertible(get_quantity_spec(U1), get_quantity_spec(U2)) ||
|
||||
unsatisfied<"'{}' and '{}' units are of quantities of incompatible kinds ('{}' and '{}')">(
|
||||
U1, U2, type_name(get_quantity_spec(U1)._quantity_spec_), type_name(get_quantity_spec(U2)._quantity_spec_));
|
||||
|
||||
template<auto U1, auto U2>
|
||||
concept ConvertibleUnits = (get_canonical_unit(U1).reference_unit == get_canonical_unit(U2).reference_unit);
|
||||
concept ConvertibleUnits = (get_canonical_unit(U1).reference_unit == get_canonical_unit(U2).reference_unit) ||
|
||||
unsatisfied<
|
||||
"Units '{}' and '{}' are not convertible because they are defined in terms of "
|
||||
"different reference units ('{}' and '{}')">(U1, U2, get_canonical_unit(U1).reference_unit,
|
||||
get_canonical_unit(U2).reference_unit);
|
||||
|
||||
template<typename U1, auto U2>
|
||||
concept UnitConvertibleTo =
|
||||
|
@ -58,7 +58,9 @@ template<typename Rep, Unit UFrom, Unit UTo>
|
||||
|
||||
template<auto FromU, auto ToU, typename Rep>
|
||||
concept SaneScaling = UnitConvertibleTo<MP_UNITS_REMOVE_CONST(decltype(FromU)), ToU> &&
|
||||
(!detail::scaling_overflows_non_zero_values<Rep>(FromU, ToU));
|
||||
((!detail::scaling_overflows_non_zero_values<Rep>(FromU, ToU)) ||
|
||||
unsatisfied<"The result of scaling '{}' to '{}' overflows the '{}' representation type">(
|
||||
FromU, ToU, type_name<Rep>()));
|
||||
|
||||
} // namespace detail
|
||||
|
||||
|
Reference in New Issue
Block a user