mirror of
https://github.com/mpusz/mp-units.git
synced 2025-08-03 20:34:26 +02:00
refactor: underlying_type
split to wrapped_type
and value_type
and used in code
This commit is contained in:
@@ -70,13 +70,13 @@ template<Quantity To, typename From>
|
||||
constexpr Magnitude auto irr = c_mag * (den / num);
|
||||
using c_rep_type = maybe_common_type<typename std::remove_reference_t<From>::rep, typename To::rep>;
|
||||
using c_mag_type = common_magnitude_type<c_mag>;
|
||||
using multiplier_type = conditional<treat_as_floating_point<c_rep_type>,
|
||||
// ensure that the multiplier is also floating-point
|
||||
conditional<std::is_arithmetic_v<underlying_type_t<c_rep_type>>,
|
||||
// reuse user's type if possible
|
||||
std::common_type_t<c_mag_type, underlying_type_t<c_rep_type>>,
|
||||
std::common_type_t<c_mag_type, double>>,
|
||||
c_mag_type>;
|
||||
using multiplier_type = conditional<
|
||||
treat_as_floating_point<c_rep_type>,
|
||||
// ensure that the multiplier is also floating-point
|
||||
conditional<std::is_arithmetic_v<value_type_t<c_rep_type>>,
|
||||
// reuse user's type if possible
|
||||
std::common_type_t<c_mag_type, value_type_t<c_rep_type>>, std::common_type_t<c_mag_type, double>>,
|
||||
c_mag_type>;
|
||||
using c_type = maybe_common_type<c_rep_type, multiplier_type>;
|
||||
constexpr auto val = [](Magnitude auto m) { return get_value<multiplier_type>(m); };
|
||||
if constexpr (std::is_floating_point_v<multiplier_type>) {
|
||||
|
@@ -106,20 +106,30 @@ struct get_element_type {
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template<typename T>
|
||||
struct underlying_type {
|
||||
using type = T;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
requires requires { typename T::value_type; } || requires { typename T::element_type; }
|
||||
struct underlying_type<T> {
|
||||
struct wrapped_type {
|
||||
using type = MP_UNITS_TYPENAME
|
||||
conditional<requires { typename T::value_type; }, detail::get_value_type<T>, detail::get_element_type<T>>::type;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
using underlying_type_t = MP_UNITS_TYPENAME underlying_type<T>::type;
|
||||
requires requires { typename T::value_type; } || requires { typename T::element_type; }
|
||||
using wrapped_type_t = MP_UNITS_TYPENAME wrapped_type<T>::type;
|
||||
|
||||
template<typename T>
|
||||
struct value_type {
|
||||
using type = T;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
requires requires { typename wrapped_type_t<T>; }
|
||||
struct value_type<T> {
|
||||
using type = MP_UNITS_TYPENAME wrapped_type_t<T>;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
using value_type_t = MP_UNITS_TYPENAME value_type<T>::type;
|
||||
|
||||
template<typename T, typename... Ts>
|
||||
concept one_of = (false || ... || std::same_as<T, Ts>);
|
||||
|
@@ -48,14 +48,8 @@ template<typename Rep>
|
||||
inline constexpr bool treat_as_floating_point = std::is_floating_point_v<Rep>;
|
||||
|
||||
template<typename Rep>
|
||||
requires requires { typename Rep::value_type; } || requires { typename Rep::element_type; }
|
||||
inline constexpr bool treat_as_floating_point<Rep> = requires {
|
||||
typename Rep::value_type;
|
||||
requires treat_as_floating_point<typename Rep::value_type>;
|
||||
} || requires {
|
||||
typename Rep::element_type;
|
||||
requires treat_as_floating_point<std::remove_reference_t<typename Rep::element_type>>;
|
||||
};
|
||||
requires requires { typename wrapped_type_t<Rep>; }
|
||||
inline constexpr bool treat_as_floating_point<Rep> = treat_as_floating_point<wrapped_type_t<Rep>>;
|
||||
|
||||
/**
|
||||
* @brief Specifies a type to have a scalar character
|
||||
|
@@ -72,11 +72,8 @@ concept CastableNumber = CommonTypeWith<T, std::intmax_t> && ScalableNumber<std:
|
||||
// TODO Fix it according to sudo_cast implementation
|
||||
template<typename T>
|
||||
concept Scalable =
|
||||
CastableNumber<T> ||
|
||||
(requires { typename T::value_type; } && CastableNumber<typename T::value_type> &&
|
||||
ScalableNumber<T, std::common_type_t<typename T::value_type, std::intmax_t>>) ||
|
||||
(requires { typename T::element_type; } && CastableNumber<std::remove_reference_t<typename T::element_type>> &&
|
||||
ScalableNumber<T, std::common_type_t<std::remove_reference_t<typename T::element_type>, std::intmax_t>>);
|
||||
CastableNumber<T> || (requires { typename wrapped_type_t<T>; } && CastableNumber<wrapped_type_t<T>> &&
|
||||
ScalableNumber<T, std::common_type_t<wrapped_type_t<T>, std::intmax_t>>);
|
||||
|
||||
} // namespace detail
|
||||
|
||||
|
Reference in New Issue
Block a user