dimension_traits and unit_traits merged as upcasting_traits

This commit is contained in:
Mateusz Pusz
2018-11-17 12:39:45 +01:00
parent 45f7b4f19f
commit ee7518d0a1
8 changed files with 41 additions and 48 deletions

View File

@@ -110,4 +110,13 @@ namespace units {
template<Ratio Ratio1, Ratio Ratio2>
using common_ratio_t = typename common_ratio<Ratio1, Ratio2>::type;
// upcasting_traits
template<typename T>
struct upcasting_traits : std::type_identity<T> {};
template<typename T>
using upcasting_traits_t = typename upcasting_traits<T>::type;
} // namespace units

View File

@@ -84,14 +84,6 @@ namespace units {
template<Exponent E>
using exp_invert_t = typename exp_invert<E>::type;
// dimension_traits
template<typename T>
struct dimension_traits : std::type_identity<T> {};
template<typename T>
using dimension_traits_t = typename dimension_traits<T>::type;
// dimension
template<Exponent... Es>
@@ -121,7 +113,7 @@ namespace units {
struct dim_invert;
template<Exponent... Es>
struct dim_invert<dimension<Es...>> : std::type_identity<dimension_traits_t<dimension<exp_invert_t<Es>...>>> {};
struct dim_invert<dimension<Es...>> : std::type_identity<upcasting_traits_t<dimension<exp_invert_t<Es>...>>> {};
template<Dimension D>
using dim_invert_t = typename dim_invert<typename D::base_type>::type;
@@ -176,7 +168,7 @@ namespace units {
struct dimension_multiply;
template<Exponent... E1, Exponent... E2>
struct dimension_multiply<dimension<E1...>, dimension<E2...>> : std::type_identity<dimension_traits_t<make_dimension_t<E1..., E2...>>> {};
struct dimension_multiply<dimension<E1...>, dimension<E2...>> : std::type_identity<upcasting_traits_t<make_dimension_t<E1..., E2...>>> {};
template<Dimension D1, Dimension D2>
using dimension_multiply_t = typename dimension_multiply<typename D1::base_type, typename D2::base_type>::type;

View File

@@ -245,22 +245,22 @@ namespace units {
template<Dimension D1, Unit U1, Number Rep1, Dimension D2, Unit U2, Number Rep2>
requires treat_as_floating_point<std::common_type_t<Rep1, Rep2>> || std::ratio_multiply<typename U1::ratio, typename U2::ratio>::den == 1
quantity<dimension_multiply_t<D1, D2>, unit_traits_t<unit<dimension_multiply_t<D1, D2>, std::ratio_multiply<typename U1::ratio, typename U2::ratio>>>, std::common_type_t<Rep1, Rep2>>
quantity<dimension_multiply_t<D1, D2>, upcasting_traits_t<unit<dimension_multiply_t<D1, D2>, std::ratio_multiply<typename U1::ratio, typename U2::ratio>>>, std::common_type_t<Rep1, Rep2>>
constexpr operator*(const quantity<D1, U1, Rep1>& lhs,
const quantity<D2, U2, Rep2>& rhs)
{
using dim = dimension_multiply_t<D1, D2>;
using ret = quantity<dim, unit_traits_t<unit<dim, std::ratio_multiply<typename U1::ratio, typename U2::ratio>>>, std::common_type_t<Rep1, Rep2>>;
using ret = quantity<dim, upcasting_traits_t<unit<dim, std::ratio_multiply<typename U1::ratio, typename U2::ratio>>>, std::common_type_t<Rep1, Rep2>>;
return ret(lhs.count() * rhs.count());
}
template<Number Rep1, Dimension D, Unit U, Number Rep2>
quantity<dim_invert_t<D>, unit_traits_t<unit<dim_invert_t<D>, std::ratio<U::ratio::den, U::ratio::num>>>, std::common_type_t<Rep1, Rep2>>
quantity<dim_invert_t<D>, upcasting_traits_t<unit<dim_invert_t<D>, std::ratio<U::ratio::den, U::ratio::num>>>, std::common_type_t<Rep1, Rep2>>
constexpr operator/(const Rep1& v,
const quantity<D, U, Rep2>& q)
{
using dim = dim_invert_t<D>;
using ret = quantity<dim, unit_traits_t<unit<dim, std::ratio<U::ratio::den, U::ratio::num>>>, std::common_type_t<Rep1, Rep2>>;
using ret = quantity<dim, upcasting_traits_t<unit<dim, std::ratio<U::ratio::den, U::ratio::num>>>, std::common_type_t<Rep1, Rep2>>;
using den = quantity<D, U, std::common_type_t<Rep1, Rep2>>;
return ret(v / den(q).count());
}
@@ -285,12 +285,12 @@ namespace units {
template<Dimension D1, Unit U1, Number Rep1, Dimension D2, Unit U2, Number Rep2>
requires treat_as_floating_point<std::common_type_t<Rep1, Rep2>> || std::ratio_divide<typename U1::ratio, typename U2::ratio>::den == 1
quantity<dimension_divide_t<D1, D2>, unit_traits_t<unit<dimension_divide_t<D1, D2>, std::ratio_divide<typename U1::ratio, typename U2::ratio>>>, std::common_type_t<Rep1, Rep2>>
quantity<dimension_divide_t<D1, D2>, upcasting_traits_t<unit<dimension_divide_t<D1, D2>, std::ratio_divide<typename U1::ratio, typename U2::ratio>>>, std::common_type_t<Rep1, Rep2>>
constexpr operator/(const quantity<D1, U1, Rep1>& lhs,
const quantity<D2, U2, Rep2>& rhs)
{
using dim = dimension_divide_t<D1, D2>;
using ret = quantity<dim, unit_traits_t<unit<dim, std::ratio_divide<typename U1::ratio, typename U2::ratio>>>, std::common_type_t<Rep1, Rep2>>;
using ret = quantity<dim, upcasting_traits_t<unit<dim, std::ratio_divide<typename U1::ratio, typename U2::ratio>>>, std::common_type_t<Rep1, Rep2>>;
return ret(lhs.count() / rhs.count());
}
@@ -364,7 +364,7 @@ namespace std {
// todo: simplified
template<units::Dimension D, units::Unit U1, units::Number Rep1, units::Unit U2, units::Number Rep2>
struct common_type<units::quantity<D, U1, Rep1>, units::quantity<D, U2, Rep2>> {
using type = units::quantity<D, units::unit_traits_t<units::unit<D, units::common_ratio_t<typename U1::ratio, typename U2::ratio>>>,
using type = units::quantity<D, units::upcasting_traits_t<units::unit<D, units::common_ratio_t<typename U1::ratio, typename U2::ratio>>>,
std::common_type_t<Rep1, Rep2>>;
};

View File

@@ -28,25 +28,25 @@
namespace units {
struct dimension_frequency : make_dimension_t<exp<base_dim_time, -1>> {};
template<> struct dimension_traits<typename dimension_frequency::base_type> : std::type_identity<dimension_frequency> {};
template<> struct upcasting_traits<typename dimension_frequency::base_type> : std::type_identity<dimension_frequency> {};
struct millihertz : unit<dimension_frequency, std::milli> {};
template<> struct unit_traits<typename millihertz::base_type> : std::type_identity<millihertz> {};
template<> struct upcasting_traits<typename millihertz::base_type> : std::type_identity<millihertz> {};
struct hertz : unit<dimension_frequency, std::ratio<1>> {};
template<> struct unit_traits<typename hertz::base_type> : std::type_identity<hertz> {};
template<> struct upcasting_traits<typename hertz::base_type> : std::type_identity<hertz> {};
struct kilohertz : unit<dimension_frequency, std::kilo> {};
template<> struct unit_traits<typename kilohertz::base_type> : std::type_identity<kilohertz> {};
template<> struct upcasting_traits<typename kilohertz::base_type> : std::type_identity<kilohertz> {};
struct megahertz : unit<dimension_frequency, std::mega> {};
template<> struct unit_traits<typename megahertz::base_type> : std::type_identity<megahertz> {};
template<> struct upcasting_traits<typename megahertz::base_type> : std::type_identity<megahertz> {};
struct gigahertz : unit<dimension_frequency, std::giga> {};
template<> struct unit_traits<typename gigahertz::base_type> : std::type_identity<gigahertz> {};
template<> struct upcasting_traits<typename gigahertz::base_type> : std::type_identity<gigahertz> {};
struct terahertz : unit<dimension_frequency, std::tera> {};
template<> struct unit_traits<typename terahertz::base_type> : std::type_identity<terahertz> {};
template<> struct upcasting_traits<typename terahertz::base_type> : std::type_identity<terahertz> {};
template<Unit U = hertz, Number Rep = std::intmax_t>
using frequency = quantity<dimension_frequency, U, Rep>;

View File

@@ -28,19 +28,19 @@
namespace units {
struct dimension_length : make_dimension_t<exp<base_dim_length, 1>> {};
template<> struct dimension_traits<typename dimension_length::base_type> : std::type_identity<dimension_length> {};
template<> struct upcasting_traits<typename dimension_length::base_type> : std::type_identity<dimension_length> {};
struct millimeter : unit<dimension_length, std::milli> {};
template<> struct unit_traits<typename millimeter::base_type> : std::type_identity<millimeter> {};
template<> struct upcasting_traits<typename millimeter::base_type> : std::type_identity<millimeter> {};
struct centimeter : unit<dimension_length, std::ratio<1, 100>> {};
template<> struct unit_traits<typename centimeter::base_type> : std::type_identity<centimeter> {};
template<> struct upcasting_traits<typename centimeter::base_type> : std::type_identity<centimeter> {};
struct meter : unit<dimension_length, std::ratio<1>> {};
template<> struct unit_traits<typename meter::base_type> : std::type_identity<meter> {};
template<> struct upcasting_traits<typename meter::base_type> : std::type_identity<meter> {};
struct kilometer : unit<dimension_length, std::kilo> {};
template<> struct unit_traits<typename kilometer::base_type> : std::type_identity<kilometer> {};
template<> struct upcasting_traits<typename kilometer::base_type> : std::type_identity<kilometer> {};
template<Unit U = meter, Number Rep = std::intmax_t>
using length = quantity<dimension_length, U, Rep>;

View File

@@ -28,25 +28,25 @@
namespace units {
struct dimension_time : make_dimension_t<exp<base_dim_time, 1>> {};
template<> struct dimension_traits<typename dimension_time::base_type> : std::type_identity<dimension_time> {};
template<> struct upcasting_traits<typename dimension_time::base_type> : std::type_identity<dimension_time> {};
struct nanosecond : unit<dimension_time, std::nano> {};
template<> struct unit_traits<typename nanosecond::base_type> : std::type_identity<nanosecond> {};
template<> struct upcasting_traits<typename nanosecond::base_type> : std::type_identity<nanosecond> {};
struct microsecond : unit<dimension_time, std::micro> {};
template<> struct unit_traits<typename microsecond::base_type> : std::type_identity<microsecond> {};
template<> struct upcasting_traits<typename microsecond::base_type> : std::type_identity<microsecond> {};
struct millisecond : unit<dimension_time, std::milli> {};
template<> struct unit_traits<typename millisecond::base_type> : std::type_identity<millisecond> {};
template<> struct upcasting_traits<typename millisecond::base_type> : std::type_identity<millisecond> {};
struct second : unit<dimension_time, std::ratio<1>> {};
template<> struct unit_traits<typename second::base_type> : std::type_identity<second> {};
template<> struct upcasting_traits<typename second::base_type> : std::type_identity<second> {};
struct minute : unit<dimension_time, std::ratio<60>> {};
template<> struct unit_traits<typename minute::base_type> : std::type_identity<minute> {};
template<> struct upcasting_traits<typename minute::base_type> : std::type_identity<minute> {};
struct hour : unit<dimension_time, std::ratio<3600>> {};
template<> struct unit_traits<typename hour::base_type> : std::type_identity<hour> {};
template<> struct upcasting_traits<typename hour::base_type> : std::type_identity<hour> {};
template<Unit U = second, Number Rep = std::intmax_t>
using time = quantity<dimension_time, U, Rep>;

View File

@@ -29,16 +29,16 @@
namespace units {
struct dimension_velocity : make_dimension_t<exp<base_dim_length, 1>, exp<base_dim_time, -1>> {};
template<> struct dimension_traits<typename dimension_velocity::base_type> : std::type_identity<dimension_velocity> {};
template<> struct upcasting_traits<typename dimension_velocity::base_type> : std::type_identity<dimension_velocity> {};
struct meter_per_second : unit<dimension_velocity, std::ratio<1>> {};
template<> struct unit_traits<typename meter_per_second::base_type> : std::type_identity<meter_per_second> {};
template<> struct upcasting_traits<typename meter_per_second::base_type> : std::type_identity<meter_per_second> {};
struct kilometer_per_hour : unit<dimension_velocity, std::ratio<1000, 3600>> {};
template<> struct unit_traits<typename kilometer_per_hour::base_type> : std::type_identity<kilometer_per_hour> {};
template<> struct upcasting_traits<typename kilometer_per_hour::base_type> : std::type_identity<kilometer_per_hour> {};
struct mile_per_hour : unit<dimension_velocity, std::ratio<44'704, 100'000>> {};
template<> struct unit_traits<typename mile_per_hour::base_type> : std::type_identity<mile_per_hour> {};
template<> struct upcasting_traits<typename mile_per_hour::base_type> : std::type_identity<mile_per_hour> {};
template<Unit U = meter_per_second, Number Rep = std::intmax_t>
using velocity = quantity<dimension_velocity, U, Rep>;

View File

@@ -53,12 +53,4 @@ namespace units {
detail::is_unit<typename T::base_type> &&
DerivedFrom<T, typename T::base_type>;
// dimension_traits
template<typename T>
struct unit_traits : std::type_identity<T> {};
template<typename T>
using unit_traits_t = typename unit_traits<T>::type;
} // namespace units