mirror of
https://github.com/mpusz/mp-units.git
synced 2025-07-30 02:17:16 +02:00
Strong units support added
This commit is contained in:
@ -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<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>, unit_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<dim, std::ratio_multiply<typename U1::ratio, typename U2::ratio>>, std::common_type_t<Rep1, Rep2>>;
|
||||
using ret = quantity<dim, unit_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<dim_invert_t<D>, std::ratio<U::ratio::den, U::ratio::num>>, std::common_type_t<Rep1, 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>>
|
||||
constexpr operator/(const Rep1& v,
|
||||
const quantity<D, U, Rep2>& q)
|
||||
{
|
||||
using dim = dim_invert_t<D>;
|
||||
using ret = quantity<dim, unit<dim, std::ratio<U::ratio::den, U::ratio::num>>, std::common_type_t<Rep1, Rep2>>;
|
||||
using ret = quantity<dim, unit_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<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>, unit_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<dim, std::ratio_divide<typename U1::ratio, typename U2::ratio>>, std::common_type_t<Rep1, Rep2>>;
|
||||
using ret = quantity<dim, unit_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<D, units::common_ratio_t<typename U1::ratio, typename U2::ratio>>,
|
||||
using type = units::quantity<D, units::unit_traits_t<units::unit<D, units::common_ratio_t<typename U1::ratio, typename U2::ratio>>>,
|
||||
std::common_type_t<Rep1, Rep2>>;
|
||||
};
|
||||
|
||||
|
@ -27,16 +27,27 @@
|
||||
|
||||
namespace units {
|
||||
|
||||
|
||||
using millihertz = unit<dimension_frequency, std::milli>;
|
||||
using hertz = unit<dimension_frequency, std::ratio<1>>;
|
||||
using kilohertz = unit<dimension_frequency, std::kilo>;
|
||||
using megahertz = unit<dimension_frequency, std::mega>;
|
||||
using gigahertz = unit<dimension_frequency, std::giga>;
|
||||
using terahertz = unit<dimension_frequency, std::tera>;
|
||||
struct dimension_frequency : make_dimension_t<exp<base_dim_time, -1>> {};
|
||||
template<> struct dimension_traits<typename dimension_frequency::type> : std::type_identity<dimension_frequency> {};
|
||||
|
||||
struct millihertz : unit<dimension_frequency, std::milli> {};
|
||||
template<> struct unit_traits<typename millihertz::type> : std::type_identity<millihertz> {};
|
||||
|
||||
struct hertz : unit<dimension_frequency, std::ratio<1>> {};
|
||||
template<> struct unit_traits<typename hertz::type> : std::type_identity<hertz> {};
|
||||
|
||||
struct kilohertz : unit<dimension_frequency, std::kilo> {};
|
||||
template<> struct unit_traits<typename kilohertz::type> : std::type_identity<kilohertz> {};
|
||||
|
||||
struct megahertz : unit<dimension_frequency, std::mega> {};
|
||||
template<> struct unit_traits<typename megahertz::type> : std::type_identity<megahertz> {};
|
||||
|
||||
struct gigahertz : unit<dimension_frequency, std::giga> {};
|
||||
template<> struct unit_traits<typename gigahertz::type> : std::type_identity<gigahertz> {};
|
||||
|
||||
struct terahertz : unit<dimension_frequency, std::tera> {};
|
||||
template<> struct unit_traits<typename terahertz::type> : std::type_identity<terahertz> {};
|
||||
|
||||
template<Unit U = hertz, Number Rep = std::intmax_t>
|
||||
using frequency = quantity<dimension_frequency, U, Rep>;
|
||||
|
||||
|
@ -30,10 +30,17 @@ namespace units {
|
||||
struct dimension_length : make_dimension_t<exp<base_dim_length, 1>> {};
|
||||
template<> struct dimension_traits<typename dimension_length::type> : std::type_identity<dimension_length> {};
|
||||
|
||||
using millimeter = unit<dimension_length, std::milli>;
|
||||
using centimeter = unit<dimension_length, std::ratio<1, 100>>;
|
||||
using meter = unit<dimension_length, std::ratio<1>>;
|
||||
using kilometer = unit<dimension_length, std::kilo>;
|
||||
struct millimeter : unit<dimension_length, std::milli> {};
|
||||
template<> struct unit_traits<typename millimeter::type> : std::type_identity<millimeter> {};
|
||||
|
||||
struct centimeter : unit<dimension_length, std::ratio<1, 100>> {};
|
||||
template<> struct unit_traits<typename centimeter::type> : std::type_identity<centimeter> {};
|
||||
|
||||
struct meter : unit<dimension_length, std::ratio<1>> {};
|
||||
template<> struct unit_traits<typename meter::type> : std::type_identity<meter> {};
|
||||
|
||||
struct kilometer : unit<dimension_length, std::kilo> {};
|
||||
template<> struct unit_traits<typename kilometer::type> : std::type_identity<kilometer> {};
|
||||
|
||||
template<Unit U = meter, Number Rep = std::intmax_t>
|
||||
using length = quantity<dimension_length, U, Rep>;
|
||||
|
@ -27,15 +27,26 @@
|
||||
|
||||
namespace units {
|
||||
|
||||
using nanosecond = unit<dimension_time, std::nano>;
|
||||
using microsecond = unit<dimension_time, std::micro>;
|
||||
using millisecond = unit<dimension_time, std::milli>;
|
||||
using second = unit<dimension_time, std::ratio<1>>;
|
||||
using minute = unit<dimension_time, std::ratio<60>>;
|
||||
using hour = unit<dimension_time, std::ratio<3600>>;
|
||||
struct dimension_time : make_dimension_t<exp<base_dim_time, 1>> {};
|
||||
template<> struct dimension_traits<typename dimension_time::type> : std::type_identity<dimension_time> {};
|
||||
|
||||
struct nanosecond : unit<dimension_time, std::nano> {};
|
||||
template<> struct unit_traits<typename nanosecond::type> : std::type_identity<nanosecond> {};
|
||||
|
||||
struct microsecond : unit<dimension_time, std::micro> {};
|
||||
template<> struct unit_traits<typename microsecond::type> : std::type_identity<microsecond> {};
|
||||
|
||||
struct millisecond : unit<dimension_time, std::milli> {};
|
||||
template<> struct unit_traits<typename millisecond::type> : std::type_identity<millisecond> {};
|
||||
|
||||
struct second : unit<dimension_time, std::ratio<1>> {};
|
||||
template<> struct unit_traits<typename second::type> : std::type_identity<second> {};
|
||||
|
||||
struct minute : unit<dimension_time, std::ratio<60>> {};
|
||||
template<> struct unit_traits<typename minute::type> : std::type_identity<minute> {};
|
||||
|
||||
struct hour : unit<dimension_time, std::ratio<3600>> {};
|
||||
template<> struct unit_traits<typename hour::type> : std::type_identity<hour> {};
|
||||
|
||||
template<Unit U = second, Number Rep = std::intmax_t>
|
||||
using time = quantity<dimension_time, U, Rep>;
|
||||
|
@ -31,9 +31,14 @@ 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::type> : std::type_identity<dimension_velocity> {};
|
||||
|
||||
using meter_per_second = unit<dimension_velocity, std::ratio<1>>;
|
||||
using kilometer_per_hour = unit<dimension_velocity, std::ratio<1000, 3600>>;
|
||||
using mile_per_hour = unit<dimension_velocity, std::ratio<44'704, 100'000>>;
|
||||
struct meter_per_second : unit<dimension_velocity, std::ratio<1>> {};
|
||||
template<> struct unit_traits<typename meter_per_second::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::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::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>;
|
||||
|
@ -28,7 +28,7 @@
|
||||
namespace units {
|
||||
|
||||
template<Dimension D, Ratio R>
|
||||
struct unit {
|
||||
struct unit : std::type_identity<unit<D, R>> {
|
||||
using dimension = D;
|
||||
using ratio = R;
|
||||
static_assert(ratio::num > 0, "ratio must be positive");
|
||||
@ -47,14 +47,14 @@ namespace units {
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
concept bool Unit = detail::is_unit<T>;
|
||||
concept bool Unit = detail::is_unit<typename T::type>;
|
||||
|
||||
// template<Unit U1, Unit U2>
|
||||
// auto operator/(U1, U2)
|
||||
// {
|
||||
// return ;
|
||||
// }
|
||||
//
|
||||
// unit<dimension_divide_t<D1, D2>, std::ratio_divide<typename U1::ratio, typename::U2::ratio>>
|
||||
// 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
|
||||
|
@ -21,6 +21,7 @@
|
||||
// SOFTWARE.
|
||||
|
||||
#include "units/si/velocity.h"
|
||||
#include "units/si/frequency.h"
|
||||
#include <utility>
|
||||
#include <chrono>
|
||||
|
||||
@ -190,12 +191,13 @@ namespace {
|
||||
|
||||
static_assert(std::is_same_v<decltype(length<meter, int>() + length<meter, double>()), quantity<dimension_length, meter, double>>);
|
||||
static_assert(std::is_same_v<decltype(length<meter, int>() + length<meter, double>()), quantity<dimension_length, meter, double>>);
|
||||
static_assert(std::is_same_v<decltype(length<kilometer, int>() + length<meter, double>()), quantity<dimension_length, unit<dimension_length, std::ratio<1>>, double>>);
|
||||
static_assert(std::is_same_v<decltype(length<kilometer, int>() + length<meter, double>()), quantity<dimension_length, meter, double>>);
|
||||
static_assert(std::is_same_v<decltype(length<meter, double>() - length<meter, int>()), quantity<dimension_length, meter, double>>);
|
||||
static_assert(std::is_same_v<decltype(length<kilometer, double>() - length<meter, int>()), quantity<dimension_length, unit<dimension_length, std::ratio<1>>, double>>);
|
||||
static_assert(std::is_same_v<decltype(length<kilometer, double>() - length<meter, int>()), quantity<dimension_length, meter, double>>);
|
||||
static_assert(std::is_same_v<decltype(length<meter, int>() * 1.0), quantity<dimension_length, meter, double>>);
|
||||
static_assert(std::is_same_v<decltype(1.0 * length<meter, int>()), quantity<dimension_length, meter, double>>);
|
||||
static_assert(std::is_same_v<decltype(velocity<meter_per_second, int>() * units::time<second, int>()), quantity<dimension_length, unit<dimension_length, std::ratio<1>>, int>>);
|
||||
static_assert(std::is_same_v<decltype(velocity<meter_per_second, int>() * units::time<second, int>()), quantity<dimension_length, units::meter, int>>);
|
||||
static_assert(std::is_same_v<decltype(1 / units::time<second, int>()), quantity<dimension_frequency, hertz, int>>);
|
||||
static_assert(std::is_same_v<decltype(length<meter, int>() / 1.0), quantity<dimension_length, meter, double>>);
|
||||
static_assert(std::is_same_v<decltype(length<meter, int>() / length<meter, double>()), double>);
|
||||
static_assert(std::is_same_v<decltype(length<kilometer, int>() / length<meter, double>()), double>);
|
||||
@ -253,9 +255,9 @@ namespace {
|
||||
|
||||
// common_type
|
||||
|
||||
static_assert(std::is_same_v<std::common_type_t<length<meter, int>, length<kilometer, int>>, length<unit<dimension_length, std::ratio<1>>, int>>);
|
||||
static_assert(std::is_same_v<std::common_type_t<length<kilometer, long long>, length<meter, int>>, length<unit<dimension_length, std::ratio<1>>, long long>>);
|
||||
static_assert(std::is_same_v<std::common_type_t<length<kilometer, long long>, length<millimeter, double>>, length<unit<dimension_length, std::ratio<1, 1000>>, double>>);
|
||||
static_assert(std::is_same_v<std::common_type_t<length<meter, int>, length<kilometer, int>>, length<meter, int>>);
|
||||
static_assert(std::is_same_v<std::common_type_t<length<kilometer, long long>, length<meter, int>>, length<meter, long long>>);
|
||||
static_assert(std::is_same_v<std::common_type_t<length<kilometer, long long>, length<millimeter, double>>, length<millimeter, double>>);
|
||||
|
||||
// quantity_cast
|
||||
|
||||
|
Reference in New Issue
Block a user