mirror of
https://github.com/mpusz/mp-units.git
synced 2025-07-30 02:17:16 +02:00
Strong dimensions support added
This commit is contained in:
@ -26,6 +26,16 @@
|
||||
#include <ratio>
|
||||
#include <type_traits>
|
||||
|
||||
namespace std {
|
||||
|
||||
template<typename T>
|
||||
struct type_identity { using type = T; };
|
||||
|
||||
template<typename T>
|
||||
using type_identity_t = typename type_identity<T>::type;
|
||||
|
||||
}
|
||||
|
||||
namespace units {
|
||||
|
||||
using namespace mp::std_concepts; // todo Remove when std::concepts will arrive
|
||||
|
@ -78,10 +78,18 @@ 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>
|
||||
struct dimension;
|
||||
struct dimension : std::type_identity<dimension<Es...>> {};
|
||||
|
||||
// is_dimension
|
||||
namespace detail {
|
||||
@ -93,7 +101,20 @@ namespace units {
|
||||
} // namespace detail
|
||||
|
||||
template<typename T>
|
||||
concept bool Dimension = detail::is_dimension<T>;
|
||||
concept bool Dimension = detail::is_dimension<typename T::type>;
|
||||
|
||||
|
||||
// dim_invert
|
||||
|
||||
template<Dimension E>
|
||||
struct dim_invert;
|
||||
|
||||
template<Exponent... Es>
|
||||
struct dim_invert<dimension<Es...>> : std::type_identity<dimension_traits_t<dimension<exp_invert_t<Es>...>>> {};
|
||||
|
||||
template<Dimension D>
|
||||
using dim_invert_t = typename dim_invert<typename D::type>::type;
|
||||
|
||||
|
||||
// make_dimension
|
||||
|
||||
@ -144,12 +165,10 @@ namespace units {
|
||||
struct dimension_multiply;
|
||||
|
||||
template<Exponent... E1, Exponent... E2>
|
||||
struct dimension_multiply<dimension<E1...>, dimension<E2...>> {
|
||||
using type = make_dimension_t<E1..., E2...>;
|
||||
};
|
||||
struct dimension_multiply<dimension<E1...>, dimension<E2...>> : std::type_identity<dimension_traits_t<make_dimension_t<E1..., E2...>>> {};
|
||||
|
||||
template<Dimension D1, Dimension D2>
|
||||
using dimension_multiply_t = typename dimension_multiply<D1, D2>::type;
|
||||
using dimension_multiply_t = typename dimension_multiply<typename D1::type, typename D2::type>::type;
|
||||
|
||||
// dimension_divide
|
||||
|
||||
@ -162,6 +181,6 @@ namespace units {
|
||||
};
|
||||
|
||||
template<Dimension D1, Dimension D2>
|
||||
using dimension_divide_t = typename dimension_divide<D1, D2>::type;
|
||||
using dimension_divide_t = typename dimension_divide<typename D1::type, typename D2::type>::type;
|
||||
|
||||
} // namespace units
|
||||
|
@ -254,14 +254,14 @@ namespace units {
|
||||
return ret(lhs.count() * rhs.count());
|
||||
}
|
||||
|
||||
template<Number Rep1, Exponent... E, Unit U, Number Rep2>
|
||||
quantity<dimension<exp_invert_t<E>...>, unit<dimension<exp_invert_t<E>...>, std::ratio<U::ratio::den, U::ratio::num>>, std::common_type_t<Rep1, Rep2>>
|
||||
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>>
|
||||
constexpr operator/(const Rep1& v,
|
||||
const quantity<dimension<E...>, U, Rep2>& q)
|
||||
const quantity<D, U, Rep2>& q)
|
||||
{
|
||||
using dim = dimension<exp_invert_t<E>...>;
|
||||
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 den = quantity<dimension<E...>, U, std::common_type_t<Rep1, Rep2>>;
|
||||
using den = quantity<D, U, std::common_type_t<Rep1, Rep2>>;
|
||||
return ret(v / den(q).count());
|
||||
}
|
||||
|
||||
|
@ -27,7 +27,6 @@
|
||||
|
||||
namespace units {
|
||||
|
||||
using dimension_frequency = make_dimension_t<exp<base_dim_time, -1>>;
|
||||
|
||||
using millihertz = unit<dimension_frequency, std::milli>;
|
||||
using hertz = unit<dimension_frequency, std::ratio<1>>;
|
||||
@ -35,6 +34,8 @@ namespace units {
|
||||
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> {};
|
||||
|
||||
template<Unit U = hertz, Number Rep = std::intmax_t>
|
||||
using frequency = quantity<dimension_frequency, U, Rep>;
|
||||
|
@ -27,7 +27,8 @@
|
||||
|
||||
namespace units {
|
||||
|
||||
using dimension_length = make_dimension_t<exp<base_dim_length, 1>>;
|
||||
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>>;
|
||||
|
@ -27,14 +27,15 @@
|
||||
|
||||
namespace units {
|
||||
|
||||
using dimension_time = make_dimension_t<exp<base_dim_time, 1>>;
|
||||
|
||||
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> {};
|
||||
|
||||
|
||||
template<Unit U = second, Number Rep = std::intmax_t>
|
||||
using time = quantity<dimension_time, U, Rep>;
|
||||
|
@ -28,7 +28,8 @@
|
||||
|
||||
namespace units {
|
||||
|
||||
using dimension_velocity = make_dimension_t<exp<base_dim_length, 1>, exp<base_dim_time, -1>>;
|
||||
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>>;
|
||||
|
Reference in New Issue
Block a user