forked from mpusz/mp-units
fix: unknown_coherent_unit fixed
This commit is contained in:
@@ -54,6 +54,7 @@ template<basic_fixed_string Symbol, NamedUnit U>
|
||||
struct base_dimension {
|
||||
static constexpr auto symbol = Symbol; ///< Unique base dimension identifier
|
||||
using base_unit = U; ///< Base unit adopted for this dimension
|
||||
static constexpr UNITS_MSVC_WORKAROUND(Magnitude) auto mag = magnitude{};
|
||||
};
|
||||
|
||||
// base_dimension_less
|
||||
|
||||
@@ -42,7 +42,7 @@ namespace units::detail {
|
||||
template<typename... Es>
|
||||
constexpr Magnitude auto absolute_magnitude(exponent_list<Es...>)
|
||||
{
|
||||
return (pow<ratio{Es::num, Es::den}>(Es::dimension::base_unit::mag) * ... * magnitude<>{});
|
||||
return (magnitude<>{} * ... * pow<ratio{Es::num, Es::den}>(Es::dimension::base_unit::mag));
|
||||
}
|
||||
|
||||
} // namespace units::detail
|
||||
|
||||
@@ -66,15 +66,13 @@ struct common_quantity_reference_impl<reference<D1, U1>, reference<D2, U2>> {
|
||||
|
||||
template<typename D1, typename U1, typename D2, typename U2>
|
||||
struct common_quantity_reference_impl<reference<D1, U1>, reference<D2, U2>> {
|
||||
static constexpr UNITS_MSVC_WORKAROUND(Magnitude) auto mag = common_magnitude(reference<D1, U1>::mag,
|
||||
reference<D2, U2>::mag);
|
||||
using dimension = conditional<is_specialization_of<D1, unknown_dimension>, D2, D1>;
|
||||
static constexpr UNITS_MSVC_WORKAROUND(Magnitude) auto m1 = D1::base_units_ratio * U1::mag;
|
||||
static constexpr UNITS_MSVC_WORKAROUND(Magnitude) auto m2 = D2::base_units_ratio * U2::mag;
|
||||
static constexpr UNITS_MSVC_WORKAROUND(Magnitude) auto cm = common_magnitude(m1, m2);
|
||||
using unit = downcast_unit<dimension, cm / dimension::base_units_ratio>;
|
||||
using unit = downcast_unit<dimension, mag / dimension::mag>;
|
||||
using type = reference<dimension, unit>;
|
||||
};
|
||||
|
||||
|
||||
template<Quantity Q1, QuantityEquivalentTo<Q1> Q2>
|
||||
using common_quantity_reference =
|
||||
TYPENAME detail::common_quantity_reference_impl<std::remove_const_t<decltype(Q1::reference)>,
|
||||
|
||||
@@ -39,7 +39,7 @@ inline constexpr bool compatible_units<exponent_list<Es...>, Us...> = (UnitOf<Us
|
||||
template<Unit... Us, typename... Es>
|
||||
constexpr Magnitude auto derived_mag(exponent_list<Es...>)
|
||||
{
|
||||
return (mag<1>() * ... * pow<ratio{Es::num, Es::den}>(Us::mag / dimension_unit<typename Es::dimension>::mag));
|
||||
return (magnitude<>{} * ... * pow<ratio{Es::num, Es::den}>(Us::mag / dimension_unit<typename Es::dimension>::mag));
|
||||
}
|
||||
|
||||
template<DerivedDimension D, Unit... Us>
|
||||
|
||||
@@ -37,12 +37,12 @@ namespace units {
|
||||
*
|
||||
* Sometimes a temporary partial result of a complex calculation may not result in a predefined
|
||||
* dimension. In such a case an `unknown_dimension` is created with a coherent unit of `unknown_coherent_unit`
|
||||
* and ratio(1).
|
||||
* with a magnitude being the absolute one of all the exponents of such a dimension.
|
||||
*
|
||||
* @tparam Es the list of exponents of ingredient dimensions
|
||||
*/
|
||||
template<Exponent... Es>
|
||||
struct unknown_dimension : derived_dimension<unknown_dimension<Es...>, unknown_coherent_unit, Es...> {};
|
||||
struct unknown_dimension : derived_dimension<unknown_dimension<Es...>, unknown_coherent_unit<Es...>, Es...> {};
|
||||
|
||||
namespace detail {
|
||||
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <units/bits/basic_concepts.h>
|
||||
#include <units/reference.h>
|
||||
#include <units/unit.h>
|
||||
|
||||
namespace units {
|
||||
@@ -72,8 +73,7 @@ struct equivalent_impl<D1, D2> :
|
||||
// additionally accounts for unknown dimensions
|
||||
template<Unit U1, Dimension D1, Unit U2, Dimension D2>
|
||||
struct equivalent_unit :
|
||||
std::disjunction<equivalent_impl<U1, U2>,
|
||||
std::bool_constant<U1::mag / dimension_unit<D1>::mag == U2::mag / dimension_unit<D2>::mag>> {};
|
||||
std::disjunction<equivalent_impl<U1, U2>, std::bool_constant<reference<D1, U1>::mag == reference<D2, U2>::mag>> {};
|
||||
|
||||
// point origins
|
||||
|
||||
|
||||
@@ -37,9 +37,10 @@ inline constexpr bool same_exponents_of = false;
|
||||
|
||||
template<Exponent... Es, template<typename...> typename DimTemplate>
|
||||
inline constexpr bool same_exponents_of<unknown_dimension<Es...>, DimTemplate> =
|
||||
requires { typename DimTemplate<unknown_dimension<Es...>, unknown_coherent_unit, typename Es::dimension...>; } &&
|
||||
std::same_as<exponent_list<Es...>, typename DimTemplate<unknown_dimension<Es...>, unknown_coherent_unit,
|
||||
typename Es::dimension...>::recipe>;
|
||||
requires {
|
||||
typename DimTemplate<unknown_dimension<Es...>, unknown_coherent_unit<Es...>, typename Es::dimension...>;
|
||||
}&& std::same_as<exponent_list<Es...>, typename DimTemplate<unknown_dimension<Es...>, unknown_coherent_unit<Es...>,
|
||||
typename Es::dimension...>::recipe>;
|
||||
|
||||
} // namespace detail
|
||||
|
||||
|
||||
@@ -72,8 +72,8 @@ using make_dimension = TYPENAME to_derived_dimension_base<
|
||||
* and in CGS barye. Those two units are not directly related with each other with some ratio. As they both are
|
||||
* coherent units of their dimensions, the ratio between them is directly determined by the ratios of base units
|
||||
* defined in base dimensions end their exponents in the derived dimension recipe. To provide interoperability of
|
||||
* such quantities of different systems base_units_ratio is being used. The result of the division of two
|
||||
* base_units_ratio of two quantities of equivalent dimensions in two different systems gives a ratio between their
|
||||
* such quantities of different systems mag is being used. The result of the division of two
|
||||
* mag of two quantities of equivalent dimensions in two different systems gives a ratio between their
|
||||
* coherent units. Alternatively, the user would always have to directly define a barye in terms of pascal or vice
|
||||
* versa.
|
||||
*
|
||||
@@ -85,8 +85,8 @@ template<typename Child, Unit U, Exponent... Es>
|
||||
struct derived_dimension : downcast_dispatch<Child, typename detail::make_dimension<Es...>> {
|
||||
using recipe = exponent_list<Es...>;
|
||||
using coherent_unit = U;
|
||||
static constexpr UNITS_MSVC_WORKAROUND(Magnitude) auto base_units_ratio =
|
||||
detail::absolute_magnitude(typename derived_dimension::exponents());
|
||||
static constexpr UNITS_MSVC_WORKAROUND(Magnitude) auto mag =
|
||||
detail::absolute_magnitude(typename derived_dimension::exponents()) / U::mag;
|
||||
};
|
||||
|
||||
} // namespace units
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
#include <units/concepts.h>
|
||||
#include <units/customization_points.h>
|
||||
#include <units/magnitude.h>
|
||||
#include <units/reference.h>
|
||||
|
||||
UNITS_DIAGNOSTIC_PUSH
|
||||
// warning C4244: 'argument': conversion from 'intmax_t' to 'T', possible loss of data with T=int
|
||||
@@ -49,17 +50,8 @@ class quantity_point_kind;
|
||||
|
||||
namespace detail {
|
||||
|
||||
template<typename T>
|
||||
inline constexpr Magnitude auto quantity_magnitude = std::enable_if_t<!Quantity<T>, magnitude<>>{};
|
||||
|
||||
template<typename D, typename U, typename Rep>
|
||||
inline constexpr Magnitude auto quantity_magnitude<quantity<D, U, Rep>> = [] {
|
||||
if constexpr (BaseDimension<D>) {
|
||||
return U::mag;
|
||||
} else {
|
||||
return D::base_units_ratio * U::mag / D::coherent_unit::mag;
|
||||
}
|
||||
}();
|
||||
template<Quantity Q>
|
||||
inline constexpr Magnitude auto quantity_magnitude = decltype(Q::reference)::mag;
|
||||
|
||||
template<Quantity Q>
|
||||
inline constexpr ratio quantity_ratio = as_ratio(quantity_magnitude<Q>);
|
||||
@@ -79,8 +71,8 @@ template<typename From, typename To>
|
||||
struct cast_traits;
|
||||
|
||||
template<typename From, typename To>
|
||||
requires common_type_with_<std::common_type_t<From, To>,
|
||||
std::intmax_t> struct cast_traits<From, To> {
|
||||
requires common_type_with_<std::common_type_t<From, To>, std::intmax_t>
|
||||
struct cast_traits<From, To> {
|
||||
using ratio_type = std::common_type_t<std::common_type_t<From, To>, std::intmax_t>;
|
||||
using rep_type = ratio_type;
|
||||
};
|
||||
|
||||
@@ -35,27 +35,21 @@ struct reference;
|
||||
|
||||
namespace detail {
|
||||
|
||||
template<typename D, typename D1, typename U1, typename D2, typename U2>
|
||||
using reference_multiply_impl =
|
||||
reference<D, downcast_unit<D, (U1::mag / dimension_unit<D1>::mag) * (U2::mag / dimension_unit<D2>::mag) *
|
||||
dimension_unit<D>::mag>>;
|
||||
template<Dimension D, Reference R1, Reference R2>
|
||||
using reference_multiply_impl = reference<D, downcast_unit<D, R1::mag * R2::mag / D::mag>>;
|
||||
|
||||
template<typename D, typename D1, typename U1, typename D2, typename U2>
|
||||
using reference_divide_impl =
|
||||
reference<D, downcast_unit<D, (U1::mag / dimension_unit<D1>::mag) / (U2::mag / dimension_unit<D2>::mag) *
|
||||
dimension_unit<D>::mag>>;
|
||||
template<typename D, Reference R1, Reference R2>
|
||||
using reference_divide_impl = reference<D, downcast_unit<D, R1::mag / R2::mag / D::mag>>;
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template<Reference R1, Reference R2>
|
||||
using reference_multiply =
|
||||
detail::reference_multiply_impl<dimension_multiply<typename R1::dimension, typename R2::dimension>,
|
||||
typename R1::dimension, typename R1::unit, typename R2::dimension, typename R2::unit>;
|
||||
detail::reference_multiply_impl<dimension_multiply<typename R1::dimension, typename R2::dimension>, R1, R2>;
|
||||
|
||||
template<Reference R1, Reference R2>
|
||||
using reference_divide =
|
||||
detail::reference_divide_impl<dimension_divide<typename R1::dimension, typename R2::dimension>,
|
||||
typename R1::dimension, typename R1::unit, typename R2::dimension, typename R2::unit>;
|
||||
detail::reference_divide_impl<dimension_divide<typename R1::dimension, typename R2::dimension>, R1, R2>;
|
||||
|
||||
/**
|
||||
* @brief The type for quantity references
|
||||
@@ -100,6 +94,7 @@ template<Dimension D, UnitOf<D> U>
|
||||
struct reference {
|
||||
using dimension = D;
|
||||
using unit = U;
|
||||
static constexpr UNITS_MSVC_WORKAROUND(Magnitude) auto mag = dimension::mag * unit::mag;
|
||||
|
||||
// Hidden Friends
|
||||
// Below friend functions are to be found via argument-dependent lookup only
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
|
||||
#include <units/bits/derived_symbol_text.h>
|
||||
#include <units/bits/external/downcasting.h>
|
||||
#include <units/bits/external/type_traits.h>
|
||||
|
||||
// IWYU pragma: begin_exports
|
||||
#include <units/bits/derived_scaled_unit.h>
|
||||
@@ -58,6 +59,7 @@ inline constexpr bool can_be_prefixed = false;
|
||||
* @tparam M a Magnitude representing the (relative) size of this unit
|
||||
* @tparam U a unit to use as a reference for this dimension
|
||||
*/
|
||||
// TODO Replace `typename` with `Unit`
|
||||
template<Magnitude auto M, typename U>
|
||||
struct scaled_unit : downcast_base<scaled_unit<M, U>> {
|
||||
static constexpr UNITS_MSVC_WORKAROUND(Magnitude) auto mag = M;
|
||||
@@ -188,7 +190,10 @@ struct prefixed_alias_unit : U {
|
||||
*
|
||||
* Used as a coherent unit of an unknown dimension.
|
||||
*/
|
||||
struct unknown_coherent_unit : derived_unit<unknown_coherent_unit> {};
|
||||
template<Exponent... Es>
|
||||
struct unknown_coherent_unit :
|
||||
downcast_dispatch<unknown_coherent_unit<Es...>,
|
||||
scaled_unit<detail::absolute_magnitude(exponent_list<Es...>()), unknown_coherent_unit<Es...>>> {};
|
||||
|
||||
namespace detail {
|
||||
|
||||
|
||||
Reference in New Issue
Block a user