forked from mpusz/mp-units
fix: constraits for magnitude added for scaled_unit
and fixed common_unit
instantiating it incorrectly
This commit is contained in:
@@ -59,6 +59,9 @@ import std;
|
|||||||
|
|
||||||
namespace mp_units {
|
namespace mp_units {
|
||||||
|
|
||||||
|
template<Unit U1, Unit U2, Unit... Rest>
|
||||||
|
struct common_unit;
|
||||||
|
|
||||||
namespace detail {
|
namespace detail {
|
||||||
|
|
||||||
template<Magnitude auto M, Unit U>
|
template<Magnitude auto M, Unit U>
|
||||||
@@ -112,6 +115,9 @@ template<Unit T, typename... Expr>
|
|||||||
template<Unit T, auto M, typename U>
|
template<Unit T, auto M, typename U>
|
||||||
[[nodiscard]] consteval auto get_canonical_unit_impl(T, const scaled_unit_impl<M, U>&);
|
[[nodiscard]] consteval auto get_canonical_unit_impl(T, const scaled_unit_impl<M, U>&);
|
||||||
|
|
||||||
|
template<Unit T, typename... Us>
|
||||||
|
[[nodiscard]] consteval auto get_canonical_unit_impl(T, const common_unit<Us...>&);
|
||||||
|
|
||||||
template<Unit Lhs, Unit Rhs>
|
template<Unit Lhs, Unit Rhs>
|
||||||
struct unit_less : std::bool_constant<type_name<Lhs>() < type_name<Rhs>()> {};
|
struct unit_less : std::bool_constant<type_name<Lhs>() < type_name<Rhs>()> {};
|
||||||
|
|
||||||
@@ -237,6 +243,7 @@ struct scaled_unit_impl : detail::unit_interface, detail::propagate_point_origin
|
|||||||
* instantiate this type automatically based on the unit arithmetic equation provided by the user.
|
* instantiate this type automatically based on the unit arithmetic equation provided by the user.
|
||||||
*/
|
*/
|
||||||
template<Magnitude auto M, Unit U>
|
template<Magnitude auto M, Unit U>
|
||||||
|
requires(M != magnitude<>{} && M != mag<1>)
|
||||||
struct scaled_unit final : detail::scaled_unit_impl<M, U> {};
|
struct scaled_unit final : detail::scaled_unit_impl<M, U> {};
|
||||||
|
|
||||||
namespace detail {
|
namespace detail {
|
||||||
@@ -412,7 +419,10 @@ template<Unit U1, Unit U2>
|
|||||||
constexpr auto canonical_lhs = get_canonical_unit(U1{});
|
constexpr auto canonical_lhs = get_canonical_unit(U1{});
|
||||||
constexpr auto canonical_rhs = get_canonical_unit(U2{});
|
constexpr auto canonical_rhs = get_canonical_unit(U2{});
|
||||||
constexpr auto common_magnitude = _common_magnitude(canonical_lhs.mag, canonical_rhs.mag);
|
constexpr auto common_magnitude = _common_magnitude(canonical_lhs.mag, canonical_rhs.mag);
|
||||||
return scaled_unit<common_magnitude, decltype(canonical_lhs.reference_unit)>{};
|
if constexpr (common_magnitude == mag<1>)
|
||||||
|
return canonical_lhs.reference_unit;
|
||||||
|
else
|
||||||
|
return scaled_unit<common_magnitude, std::remove_const_t<decltype(canonical_lhs.reference_unit)>>{};
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]] consteval Unit auto get_common_scaled_unit(Unit auto u1, Unit auto u2, Unit auto u3, Unit auto... rest)
|
[[nodiscard]] consteval Unit auto get_common_scaled_unit(Unit auto u1, Unit auto u2, Unit auto u3, Unit auto... rest)
|
||||||
@@ -441,6 +451,7 @@ template<Unit U1, Unit U2, Unit... Rest>
|
|||||||
struct common_unit final : decltype(detail::get_common_scaled_unit(U1{}, U2{}, Rest{}...))::_base_type_
|
struct common_unit final : decltype(detail::get_common_scaled_unit(U1{}, U2{}, Rest{}...))::_base_type_
|
||||||
{
|
{
|
||||||
using _base_type_ = common_unit; // exposition only
|
using _base_type_ = common_unit; // exposition only
|
||||||
|
static constexpr auto _common_unit_ = detail::get_common_scaled_unit(U1{}, U2{}, Rest{}...);
|
||||||
};
|
};
|
||||||
|
|
||||||
namespace detail {
|
namespace detail {
|
||||||
@@ -524,6 +535,12 @@ template<Unit T, auto M, typename U>
|
|||||||
return canonical_unit{M * base.mag, base.reference_unit};
|
return canonical_unit{M * base.mag, base.reference_unit};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<Unit T, typename... Us>
|
||||||
|
[[nodiscard]] consteval auto get_canonical_unit_impl(T, const common_unit<Us...>& u)
|
||||||
|
{
|
||||||
|
return get_canonical_unit_impl(u._common_unit_, u._common_unit_);
|
||||||
|
}
|
||||||
|
|
||||||
template<Unit T, symbol_text Symbol, auto... Args>
|
template<Unit T, symbol_text Symbol, auto... Args>
|
||||||
[[nodiscard]] consteval auto get_canonical_unit_impl(T t, const named_unit<Symbol, Args...>&)
|
[[nodiscard]] consteval auto get_canonical_unit_impl(T t, const named_unit<Symbol, Args...>&)
|
||||||
{
|
{
|
||||||
|
@@ -46,6 +46,7 @@ MP_UNITS_EXPORT template<typename T>
|
|||||||
concept Unit = std::derived_from<T, detail::unit_interface> && std::is_final_v<T>;
|
concept Unit = std::derived_from<T, detail::unit_interface> && std::is_final_v<T>;
|
||||||
|
|
||||||
template<Magnitude auto M, Unit U>
|
template<Magnitude auto M, Unit U>
|
||||||
|
requires(M != magnitude<>{} && M != mag<1>)
|
||||||
struct scaled_unit;
|
struct scaled_unit;
|
||||||
|
|
||||||
MP_UNITS_EXPORT template<symbol_text Symbol, auto...>
|
MP_UNITS_EXPORT template<symbol_text Symbol, auto...>
|
||||||
|
Reference in New Issue
Block a user