forked from mpusz/mp-units
_t
postfix removed from the interface (resolves #9)
This commit is contained in:
@@ -221,7 +221,7 @@ struct dimension_multiply<dimension<E1...>, dimension<E2...>> {
|
|||||||
};
|
};
|
||||||
|
|
||||||
template<Dimension D1, Dimension D2>
|
template<Dimension D1, Dimension D2>
|
||||||
using dimension_multiply_t = dimension_multiply<typename D1::base_type, typename D2::base_type>::type;
|
using dimension_multiply = dimension_multiply<typename D1::base_type, typename D2::base_type>::type;
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
@@ -343,12 +343,12 @@ public:
|
|||||||
[[nodiscard]] static constexpr quantity one() noexcept { return quantity(quantity_values<Rep>::one()); }
|
[[nodiscard]] static constexpr quantity one() noexcept { return quantity(quantity_values<Rep>::one()); }
|
||||||
|
|
||||||
template<Unit U1, Scalar Rep1, Unit U2, Scalar Rep2>
|
template<Unit U1, Scalar Rep1, Unit U2, Scalar Rep2>
|
||||||
requires std::same_as<typename U1::dimension, dim_invert_t<typename U2::dimension>>
|
requires std::same_as<typename U1::dimension, dim_invert<typename U2::dimension>>
|
||||||
[[nodiscard]] constexpr Scalar operator*(const quantity<U1, Rep1>& lhs,
|
[[nodiscard]] constexpr Scalar operator*(const quantity<U1, Rep1>& lhs,
|
||||||
const quantity<U2, Rep2>& rhs);
|
const quantity<U2, Rep2>& rhs);
|
||||||
|
|
||||||
template<Unit U1, Scalar Rep1, Unit U2, Scalar Rep2>
|
template<Unit U1, Scalar Rep1, Unit U2, Scalar Rep2>
|
||||||
requires (!std::same_as<typename U1::dimension, dim_invert_t<typename U2::dimension>>) &&
|
requires (!std::same_as<typename U1::dimension, dim_invert<typename U2::dimension>>) &&
|
||||||
(treat_as_floating_point<decltype(lhs.count() * rhs.count())> ||
|
(treat_as_floating_point<decltype(lhs.count() * rhs.count())> ||
|
||||||
(std::ratio_multiply<typename U1::ratio, typename U2::ratio>::den == 1))
|
(std::ratio_multiply<typename U1::ratio, typename U2::ratio>::den == 1))
|
||||||
[[nodiscard]] constexpr Quantity operator*(const quantity<U1, Rep1>& lhs,
|
[[nodiscard]] constexpr Quantity operator*(const quantity<U1, Rep1>& lhs,
|
||||||
@@ -579,7 +579,7 @@ for a given specialization in a base type.
|
|||||||
For example to determine a downcasted type of a quantity multiply operation the following can be done:
|
For example to determine a downcasted type of a quantity multiply operation the following can be done:
|
||||||
|
|
||||||
```cpp
|
```cpp
|
||||||
using dim = dimension_multiply_t<typename U1::dimension, typename U2::dimension>;
|
using dim = dimension_multiply<typename U1::dimension, typename U2::dimension>;
|
||||||
using common_rep = decltype(lhs.count() * rhs.count());
|
using common_rep = decltype(lhs.count() * rhs.count());
|
||||||
using ret = quantity<downcast_target<unit<dim, ratio_multiply<typename U1::ratio, typename U2::ratio>>>, common_rep>;
|
using ret = quantity<downcast_target<unit<dim, ratio_multiply<typename U1::ratio, typename U2::ratio>>>, common_rep>;
|
||||||
```
|
```
|
||||||
|
@@ -90,7 +90,6 @@ namespace units {
|
|||||||
detail::is_dimension<downcast_base_t<T>>;
|
detail::is_dimension<downcast_base_t<T>>;
|
||||||
|
|
||||||
// exp
|
// exp
|
||||||
|
|
||||||
template<typename Dim, int Num, int Den = 1>
|
template<typename Dim, int Num, int Den = 1>
|
||||||
requires BaseDimension<Dim> || Dimension<Dim>
|
requires BaseDimension<Dim> || Dimension<Dim>
|
||||||
struct exp {
|
struct exp {
|
||||||
@@ -108,68 +107,70 @@ namespace units {
|
|||||||
} // namespace detail
|
} // namespace detail
|
||||||
|
|
||||||
// exp_less
|
// exp_less
|
||||||
|
|
||||||
template<Exponent E1, Exponent E2>
|
template<Exponent E1, Exponent E2>
|
||||||
struct exp_less : base_dimension_less<typename E1::dimension, typename E2::dimension> {
|
struct exp_less : base_dimension_less<typename E1::dimension, typename E2::dimension> {
|
||||||
};
|
};
|
||||||
|
|
||||||
// exp_invert
|
// exp_invert
|
||||||
|
namespace detail {
|
||||||
|
|
||||||
template<Exponent E>
|
template<Exponent E>
|
||||||
struct exp_invert;
|
struct exp_invert_impl;
|
||||||
|
|
||||||
template<typename Dim, int Num, int Den>
|
template<typename Dim, int Num, int Den>
|
||||||
struct exp_invert<exp<Dim, Num, Den>> {
|
struct exp_invert_impl<exp<Dim, Num, Den>> {
|
||||||
using type = exp<Dim, -Num, Den>;
|
using type = exp<Dim, -Num, Den>;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
template<Exponent E>
|
template<Exponent E>
|
||||||
using exp_invert_t = exp_invert<E>::type;
|
using exp_invert = detail::exp_invert_impl<E>::type;
|
||||||
|
|
||||||
// exp_multiply
|
// exp_multiply
|
||||||
|
namespace detail {
|
||||||
|
|
||||||
template<Exponent E, int Num, int Den>
|
template<Exponent E, int Num, int Den>
|
||||||
struct exp_multiply {
|
struct exp_multiply_impl {
|
||||||
using r1 = ratio<E::num, E::den>;
|
using r1 = ratio<E::num, E::den>;
|
||||||
using r2 = ratio<Num, Den>;
|
using r2 = ratio<Num, Den>;
|
||||||
using r = ratio_multiply<r1, r2>;
|
using r = ratio_multiply<r1, r2>;
|
||||||
using type = exp<typename E::dimension, r::num, r::den>;
|
using type = exp<typename E::dimension, r::num, r::den>;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
template<Exponent E, int Num, int Den>
|
template<Exponent E, int Num, int Den>
|
||||||
using exp_multiply_t = exp_multiply<E, Num, Den>::type;
|
using exp_multiply = detail::exp_multiply_impl<E, Num, Den>::type;
|
||||||
|
|
||||||
// dimension
|
// dimension
|
||||||
|
|
||||||
template<Exponent... Es>
|
template<Exponent... Es>
|
||||||
struct dimension : downcast_base<dimension<Es...>> {};
|
struct dimension : downcast_base<dimension<Es...>> {};
|
||||||
|
|
||||||
// same_dim
|
// same_dim
|
||||||
|
|
||||||
template<Dimension D1, Dimension D2>
|
template<Dimension D1, Dimension D2>
|
||||||
inline constexpr bool same_dim = std::is_same_v<typename D1::base_type, typename D2::base_type>;
|
inline constexpr bool same_dim = std::is_same_v<typename D1::base_type, typename D2::base_type>;
|
||||||
|
|
||||||
// dim_invert
|
// dim_invert
|
||||||
|
namespace detail {
|
||||||
|
|
||||||
template<Dimension E>
|
template<Dimension E>
|
||||||
struct dim_invert;
|
struct dim_invert_impl;
|
||||||
|
|
||||||
template<typename... Es>
|
template<typename... Es>
|
||||||
struct dim_invert<dimension<Es...>> : std::type_identity<downcast_target<dimension<exp_invert_t<Es>...>>> {};
|
struct dim_invert_impl<dimension<Es...>> : std::type_identity<downcast_target<dimension<exp_invert<Es>...>>> {};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
template<Dimension D>
|
template<Dimension D>
|
||||||
using dim_invert_t = dim_invert<downcast_base_t<D>>::type;
|
using dim_invert = detail::dim_invert_impl<downcast_base_t<D>>::type;
|
||||||
|
|
||||||
// make_dimension
|
// make_dimension
|
||||||
|
|
||||||
namespace detail {
|
namespace detail {
|
||||||
|
|
||||||
template<Dimension D>
|
template<Dimension D>
|
||||||
struct dim_consolidate;
|
struct dim_consolidate;
|
||||||
|
|
||||||
template<Dimension D>
|
|
||||||
using dim_consolidate_t = dim_consolidate<D>::type;
|
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
struct dim_consolidate<dimension<>> {
|
struct dim_consolidate<dimension<>> {
|
||||||
using type = dimension<>;
|
using type = dimension<>;
|
||||||
@@ -182,7 +183,7 @@ namespace units {
|
|||||||
|
|
||||||
template<typename E1, typename... ERest>
|
template<typename E1, typename... ERest>
|
||||||
struct dim_consolidate<dimension<E1, ERest...>> {
|
struct dim_consolidate<dimension<E1, ERest...>> {
|
||||||
using type = type_list_push_front<dim_consolidate_t<dimension<ERest...>>, E1>;
|
using type = type_list_push_front<typename dim_consolidate<dimension<ERest...>>::type, E1>;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<BaseDimension D, int Num1, int Den1, int Num2, int Den2, typename... ERest>
|
template<BaseDimension D, int Num1, int Den1, int Num2, int Den2, typename... ERest>
|
||||||
@@ -191,16 +192,13 @@ namespace units {
|
|||||||
using r1 = std::ratio<Num1, Den1>;
|
using r1 = std::ratio<Num1, Den1>;
|
||||||
using r2 = std::ratio<Num2, Den2>;
|
using r2 = std::ratio<Num2, Den2>;
|
||||||
using r = std::ratio_add<r1, r2>;
|
using r = std::ratio_add<r1, r2>;
|
||||||
using type = conditional<r::num == 0, dim_consolidate_t<dimension<ERest...>>,
|
using type = conditional<r::num == 0, typename dim_consolidate<dimension<ERest...>>::type,
|
||||||
dim_consolidate_t<dimension<exp<D, r::num, r::den>, ERest...>>>;
|
typename dim_consolidate<dimension<exp<D, r::num, r::den>, ERest...>>::type>;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<Exponent... Es>
|
template<Exponent... Es>
|
||||||
struct extract;
|
struct extract;
|
||||||
|
|
||||||
template<Exponent... Es>
|
|
||||||
using extract_t = extract<Es...>::type;
|
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
struct extract<> {
|
struct extract<> {
|
||||||
using type = dimension<>;
|
using type = dimension<>;
|
||||||
@@ -208,88 +206,99 @@ namespace units {
|
|||||||
|
|
||||||
template<BaseDimension Dim, int Num, int Den, Exponent... ERest>
|
template<BaseDimension Dim, int Num, int Den, Exponent... ERest>
|
||||||
struct extract<exp<Dim, Num, Den>, ERest...> {
|
struct extract<exp<Dim, Num, Den>, ERest...> {
|
||||||
using type = type_list_push_front<extract_t<ERest...>, exp<Dim, Num, Den>>;
|
using type = type_list_push_front<typename extract<ERest...>::type, exp<Dim, Num, Den>>;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<Exponent... Es, int Num, int Den, Exponent... ERest>
|
template<Exponent... Es, int Num, int Den, Exponent... ERest>
|
||||||
struct extract<exp<dimension<Es...>, Num, Den>, ERest...> {
|
struct extract<exp<dimension<Es...>, Num, Den>, ERest...> {
|
||||||
using type = type_list_push_front<extract_t<ERest...>, exp_multiply_t<Es, Num, Den>...>;
|
using type = type_list_push_front<typename extract<ERest...>::type, exp_multiply<Es, Num, Den>...>;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<Dimension Dim, int Num, int Den, Exponent... ERest>
|
template<Dimension Dim, int Num, int Den, Exponent... ERest>
|
||||||
struct extract<exp<Dim, Num, Den>, ERest...> {
|
struct extract<exp<Dim, Num, Den>, ERest...> {
|
||||||
using type = extract_t<exp<downcast_base_t<Dim>, Num, Den>, ERest...>;
|
using type = extract<exp<downcast_base_t<Dim>, Num, Den>, ERest...>::type;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<Exponent... Es>
|
template<Exponent... Es>
|
||||||
struct make_dimension {
|
struct make_dimension {
|
||||||
using type = detail::dim_consolidate_t<type_list_sort<detail::extract_t<Es...>, exp_less>>;
|
using type = detail::dim_consolidate<type_list_sort<typename detail::extract<Es...>::type, exp_less>>::type;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<Exponent... Es>
|
|
||||||
using make_dimension_t = make_dimension<Es...>::type;
|
|
||||||
|
|
||||||
} // namespace detail
|
} // namespace detail
|
||||||
|
|
||||||
// derived_dimension
|
// derived_dimension
|
||||||
|
|
||||||
template<typename Child, Exponent... Es>
|
template<typename Child, Exponent... Es>
|
||||||
struct derived_dimension : downcast_helper<Child, detail::make_dimension_t<Es...>> {};
|
struct derived_dimension : downcast_helper<Child, typename detail::make_dimension<Es...>::type> {};
|
||||||
|
|
||||||
// merge_dimension
|
// merge_dimension
|
||||||
|
namespace detail {
|
||||||
|
|
||||||
template<Dimension D1, Dimension D2>
|
template<Dimension D1, Dimension D2>
|
||||||
struct merge_dimension {
|
struct merge_dimension_impl {
|
||||||
using type = detail::dim_consolidate_t<type_list_merge_sorted<D1, D2, exp_less>>;
|
using type = detail::dim_consolidate<type_list_merge_sorted<D1, D2, exp_less>>::type;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
template<Dimension D1, Dimension D2>
|
template<Dimension D1, Dimension D2>
|
||||||
using merge_dimension_t = merge_dimension<D1, D2>::type;
|
using merge_dimension = detail::merge_dimension_impl<D1, D2>::type;
|
||||||
|
|
||||||
// dimension_multiply
|
// dimension_multiply
|
||||||
|
namespace detail {
|
||||||
|
|
||||||
template<Dimension D1, Dimension D2>
|
template<Dimension D1, Dimension D2>
|
||||||
struct dimension_multiply;
|
struct dimension_multiply_impl;
|
||||||
|
|
||||||
template<typename... E1, typename... E2>
|
template<typename... E1, typename... E2>
|
||||||
struct dimension_multiply<dimension<E1...>, dimension<E2...>> : std::type_identity<downcast_target<merge_dimension_t<dimension<E1...>, dimension<E2...>>>> {};
|
struct dimension_multiply_impl<dimension<E1...>, dimension<E2...>> : std::type_identity<downcast_target<merge_dimension<dimension<E1...>, dimension<E2...>>>> {};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
template<Dimension D1, Dimension D2>
|
template<Dimension D1, Dimension D2>
|
||||||
using dimension_multiply_t = dimension_multiply<typename D1::base_type, typename D2::base_type>::type;
|
using dimension_multiply = detail::dimension_multiply_impl<typename D1::base_type, typename D2::base_type>::type;
|
||||||
|
|
||||||
// dimension_divide
|
// dimension_divide
|
||||||
|
namespace detail {
|
||||||
|
|
||||||
template<Dimension D1, Dimension D2>
|
template<Dimension D1, Dimension D2>
|
||||||
struct dimension_divide;
|
struct dimension_divide_impl;
|
||||||
|
|
||||||
template<typename... E1, typename... E2>
|
template<typename... E1, typename... E2>
|
||||||
struct dimension_divide<dimension<E1...>, dimension<E2...>>
|
struct dimension_divide_impl<dimension<E1...>, dimension<E2...>>
|
||||||
: dimension_multiply<dimension<E1...>, dimension<exp_invert_t<E2>...>> {
|
: dimension_multiply_impl<dimension<E1...>, dimension<exp_invert<E2>...>> {
|
||||||
};
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
template<Dimension D1, Dimension D2>
|
template<Dimension D1, Dimension D2>
|
||||||
using dimension_divide_t = dimension_divide<typename D1::base_type, typename D2::base_type>::type;
|
using dimension_divide = detail::dimension_divide_impl<typename D1::base_type, typename D2::base_type>::type;
|
||||||
|
|
||||||
// dimension_sqrt
|
// dimension_sqrt
|
||||||
|
namespace detail {
|
||||||
|
|
||||||
template<Dimension D>
|
template<Dimension D>
|
||||||
struct dimension_sqrt;
|
struct dimension_sqrt_impl;
|
||||||
|
|
||||||
template<typename... Es>
|
template<typename... Es>
|
||||||
struct dimension_sqrt<dimension<Es...>> : std::type_identity<downcast_target<dimension<exp_multiply_t<Es, 1, 2>...>>> {};
|
struct dimension_sqrt_impl<dimension<Es...>> : std::type_identity<downcast_target<dimension<exp_multiply<Es, 1, 2>...>>> {};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
template<Dimension D>
|
template<Dimension D>
|
||||||
using dimension_sqrt_t = dimension_sqrt<typename D::base_type>::type;
|
using dimension_sqrt = detail::dimension_sqrt_impl<typename D::base_type>::type;
|
||||||
|
|
||||||
// dimension_pow
|
// dimension_pow
|
||||||
|
namespace detail {
|
||||||
|
|
||||||
template<Dimension D, std::size_t N>
|
template<Dimension D, std::size_t N>
|
||||||
struct dimension_pow;
|
struct dimension_pow_impl;
|
||||||
|
|
||||||
template<typename... Es, std::size_t N>
|
template<typename... Es, std::size_t N>
|
||||||
struct dimension_pow<dimension<Es...>, N> : std::type_identity<downcast_target<dimension<exp_multiply_t<Es, N, 1>...>>> {};
|
struct dimension_pow_impl<dimension<Es...>, N> : std::type_identity<downcast_target<dimension<exp_multiply<Es, N, 1>...>>> {};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
template<Dimension D, std::size_t N>
|
template<Dimension D, std::size_t N>
|
||||||
using dimension_pow_t = dimension_pow<typename D::base_type, N>::type;
|
using dimension_pow = detail::dimension_pow_impl<typename D::base_type, N>::type;
|
||||||
|
|
||||||
} // namespace units
|
} // namespace units
|
||||||
|
@@ -30,7 +30,7 @@ namespace units {
|
|||||||
template<std::size_t N, typename U, typename Rep>
|
template<std::size_t N, typename U, typename Rep>
|
||||||
inline Quantity pow(const quantity<U, Rep>& q) noexcept
|
inline Quantity pow(const quantity<U, Rep>& q) noexcept
|
||||||
{
|
{
|
||||||
using dim = dimension_pow_t<typename U::dimension, N>;
|
using dim = dimension_pow<typename U::dimension, N>;
|
||||||
using r = ratio_pow<typename U::ratio, N>;
|
using r = ratio_pow<typename U::ratio, N>;
|
||||||
return quantity<downcast_target<unit<dim, r>>, Rep>(static_cast<Rep>(std::pow(q.count(), N)));
|
return quantity<downcast_target<unit<dim, r>>, Rep>(static_cast<Rep>(std::pow(q.count(), N)));
|
||||||
}
|
}
|
||||||
@@ -38,7 +38,7 @@ namespace units {
|
|||||||
template<typename U, typename Rep>
|
template<typename U, typename Rep>
|
||||||
inline Quantity sqrt(const quantity<U, Rep>& q) noexcept
|
inline Quantity sqrt(const quantity<U, Rep>& q) noexcept
|
||||||
{
|
{
|
||||||
using dim = dimension_sqrt_t<typename U::dimension>;
|
using dim = dimension_sqrt<typename U::dimension>;
|
||||||
using r = ratio_sqrt<typename U::ratio>;
|
using r = ratio_sqrt<typename U::ratio>;
|
||||||
return quantity<downcast_target<unit<dim, r>>, Rep>(static_cast<Rep>(std::sqrt(q.count())));
|
return quantity<downcast_target<unit<dim, r>>, Rep>(static_cast<Rep>(std::sqrt(q.count())));
|
||||||
}
|
}
|
||||||
|
@@ -60,22 +60,26 @@ namespace units {
|
|||||||
} // namespace detail
|
} // namespace detail
|
||||||
|
|
||||||
// common_quantity
|
// common_quantity
|
||||||
|
namespace detail {
|
||||||
|
|
||||||
template<Quantity Q1, Quantity Q2, Scalar Rep>
|
template<Quantity Q1, Quantity Q2, Scalar Rep>
|
||||||
struct common_quantity;
|
struct common_quantity_impl;
|
||||||
|
|
||||||
template<typename U, typename Rep1, typename Rep2, typename Rep>
|
template<typename U, typename Rep1, typename Rep2, typename Rep>
|
||||||
struct common_quantity<quantity<U, Rep1>, quantity<U, Rep2>, Rep> {
|
struct common_quantity_impl<quantity<U, Rep1>, quantity<U, Rep2>, Rep> {
|
||||||
using type = quantity<U, Rep>;
|
using type = quantity<U, Rep>;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename U1, typename Rep1, typename U2, typename Rep2, typename Rep>
|
template<typename U1, typename Rep1, typename U2, typename Rep2, typename Rep>
|
||||||
requires same_dim<typename U1::dimension, typename U2::dimension>
|
requires same_dim<typename U1::dimension, typename U2::dimension>
|
||||||
struct common_quantity<quantity<U1, Rep1>, quantity<U2, Rep2>, Rep> {
|
struct common_quantity_impl<quantity<U1, Rep1>, quantity<U2, Rep2>, Rep> {
|
||||||
using type = quantity<downcast_target<unit<typename U1::dimension, common_ratio<typename U1::ratio, typename U2::ratio>>>, Rep>;
|
using type = quantity<downcast_target<unit<typename U1::dimension, common_ratio<typename U1::ratio, typename U2::ratio>>>, Rep>;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
template<Quantity Q1, Quantity Q2, Scalar Rep = std::common_type_t<typename Q1::rep, typename Q2::rep>>
|
template<Quantity Q1, Quantity Q2, Scalar Rep = std::common_type_t<typename Q1::rep, typename Q2::rep>>
|
||||||
using common_quantity_t = common_quantity<Q1, Q2, Rep>::type;
|
using common_quantity = detail::common_quantity_impl<Q1, Q2, Rep>::type;
|
||||||
|
|
||||||
// treat_as_floating_point
|
// treat_as_floating_point
|
||||||
|
|
||||||
@@ -280,7 +284,7 @@ namespace units {
|
|||||||
requires same_dim<typename U1::dimension, typename U2::dimension>
|
requires same_dim<typename U1::dimension, typename U2::dimension>
|
||||||
{
|
{
|
||||||
using common_rep = decltype(lhs.count() + rhs.count());
|
using common_rep = decltype(lhs.count() + rhs.count());
|
||||||
using ret = common_quantity_t<quantity<U1, Rep1>, quantity<U2, Rep2>, common_rep>;
|
using ret = common_quantity<quantity<U1, Rep1>, quantity<U2, Rep2>, common_rep>;
|
||||||
return ret(ret(lhs).count() + ret(rhs).count());
|
return ret(ret(lhs).count() + ret(rhs).count());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -290,7 +294,7 @@ namespace units {
|
|||||||
requires same_dim<typename U1::dimension, typename U2::dimension>
|
requires same_dim<typename U1::dimension, typename U2::dimension>
|
||||||
{
|
{
|
||||||
using common_rep = decltype(lhs.count() - rhs.count());
|
using common_rep = decltype(lhs.count() - rhs.count());
|
||||||
using ret = common_quantity_t<quantity<U1, Rep1>, quantity<U2, Rep2>, common_rep>;
|
using ret = common_quantity<quantity<U1, Rep1>, quantity<U2, Rep2>, common_rep>;
|
||||||
return ret(ret(lhs).count() - ret(rhs).count());
|
return ret(ret(lhs).count() - ret(rhs).count());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -317,7 +321,7 @@ namespace units {
|
|||||||
template<typename U1, typename Rep1, typename U2, typename Rep2>
|
template<typename U1, typename Rep1, typename U2, typename Rep2>
|
||||||
[[nodiscard]] constexpr Scalar operator*(const quantity<U1, Rep1>& lhs,
|
[[nodiscard]] constexpr Scalar operator*(const quantity<U1, Rep1>& lhs,
|
||||||
const quantity<U2, Rep2>& rhs)
|
const quantity<U2, Rep2>& rhs)
|
||||||
requires same_dim<typename U1::dimension, dim_invert_t<typename U2::dimension>>
|
requires same_dim<typename U1::dimension, dim_invert<typename U2::dimension>>
|
||||||
{
|
{
|
||||||
using common_rep = decltype(lhs.count() * rhs.count());
|
using common_rep = decltype(lhs.count() * rhs.count());
|
||||||
using ratio = ratio_multiply<typename U1::ratio, typename U2::ratio>;
|
using ratio = ratio_multiply<typename U1::ratio, typename U2::ratio>;
|
||||||
@@ -327,11 +331,11 @@ namespace units {
|
|||||||
template<typename U1, typename Rep1, typename U2, typename Rep2>
|
template<typename U1, typename Rep1, typename U2, typename Rep2>
|
||||||
[[nodiscard]] constexpr Quantity operator*(const quantity<U1, Rep1>& lhs,
|
[[nodiscard]] constexpr Quantity operator*(const quantity<U1, Rep1>& lhs,
|
||||||
const quantity<U2, Rep2>& rhs)
|
const quantity<U2, Rep2>& rhs)
|
||||||
requires (!same_dim<typename U1::dimension, dim_invert_t<typename U2::dimension>>) &&
|
requires (!same_dim<typename U1::dimension, dim_invert<typename U2::dimension>>) &&
|
||||||
(treat_as_floating_point<decltype(lhs.count() * rhs.count())> ||
|
(treat_as_floating_point<decltype(lhs.count() * rhs.count())> ||
|
||||||
(std::ratio_multiply<typename U1::ratio, typename U2::ratio>::den == 1))
|
(std::ratio_multiply<typename U1::ratio, typename U2::ratio>::den == 1))
|
||||||
{
|
{
|
||||||
using dim = dimension_multiply_t<typename U1::dimension, typename U2::dimension>;
|
using dim = dimension_multiply<typename U1::dimension, typename U2::dimension>;
|
||||||
using common_rep = decltype(lhs.count() * rhs.count());
|
using common_rep = decltype(lhs.count() * rhs.count());
|
||||||
using ret = quantity<downcast_target<unit<dim, ratio_multiply<typename U1::ratio, typename U2::ratio>>>, common_rep>;
|
using ret = quantity<downcast_target<unit<dim, ratio_multiply<typename U1::ratio, typename U2::ratio>>>, common_rep>;
|
||||||
return ret(lhs.count() * rhs.count());
|
return ret(lhs.count() * rhs.count());
|
||||||
@@ -345,7 +349,7 @@ namespace units {
|
|||||||
{
|
{
|
||||||
Expects(q != std::remove_cvref_t<decltype(q)>(0));
|
Expects(q != std::remove_cvref_t<decltype(q)>(0));
|
||||||
|
|
||||||
using dim = dim_invert_t<typename U::dimension>;
|
using dim = dim_invert<typename U::dimension>;
|
||||||
using common_rep = decltype(v / q.count());
|
using common_rep = decltype(v / q.count());
|
||||||
using ret = quantity<downcast_target<unit<dim, ratio<U::ratio::den, U::ratio::num>>>, common_rep>;
|
using ret = quantity<downcast_target<unit<dim, ratio<U::ratio::den, U::ratio::num>>>, common_rep>;
|
||||||
using den = quantity<U, common_rep>;
|
using den = quantity<U, common_rep>;
|
||||||
@@ -373,7 +377,7 @@ namespace units {
|
|||||||
Expects(rhs != std::remove_cvref_t<decltype(rhs)>(0));
|
Expects(rhs != std::remove_cvref_t<decltype(rhs)>(0));
|
||||||
|
|
||||||
using common_rep = decltype(lhs.count() / rhs.count());
|
using common_rep = decltype(lhs.count() / rhs.count());
|
||||||
using cq = common_quantity_t<quantity<U1, Rep1>, quantity<U2, Rep2>, common_rep>;
|
using cq = common_quantity<quantity<U1, Rep1>, quantity<U2, Rep2>, common_rep>;
|
||||||
return cq(lhs).count() / cq(rhs).count();
|
return cq(lhs).count() / cq(rhs).count();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -387,7 +391,7 @@ namespace units {
|
|||||||
Expects(rhs != std::remove_cvref_t<decltype(rhs)>(0));
|
Expects(rhs != std::remove_cvref_t<decltype(rhs)>(0));
|
||||||
|
|
||||||
using common_rep = decltype(lhs.count() / rhs.count());
|
using common_rep = decltype(lhs.count() / rhs.count());
|
||||||
using dim = dimension_divide_t<typename U1::dimension, typename U2::dimension>;
|
using dim = dimension_divide<typename U1::dimension, typename U2::dimension>;
|
||||||
using ret = quantity<downcast_target<unit<dim, ratio_divide<typename U1::ratio, typename U2::ratio>>>, common_rep>;
|
using ret = quantity<downcast_target<unit<dim, ratio_divide<typename U1::ratio, typename U2::ratio>>>, common_rep>;
|
||||||
return ret(lhs.count() / rhs.count());
|
return ret(lhs.count() / rhs.count());
|
||||||
}
|
}
|
||||||
@@ -406,7 +410,7 @@ namespace units {
|
|||||||
const quantity<U2, Rep2>& rhs)
|
const quantity<U2, Rep2>& rhs)
|
||||||
{
|
{
|
||||||
using common_rep = decltype(lhs.count() % rhs.count());
|
using common_rep = decltype(lhs.count() % rhs.count());
|
||||||
using ret = common_quantity_t<quantity<U1, Rep1>, quantity<U2, Rep2>, common_rep>;
|
using ret = common_quantity<quantity<U1, Rep1>, quantity<U2, Rep2>, common_rep>;
|
||||||
return ret(ret(lhs).count() % ret(rhs).count());
|
return ret(ret(lhs).count() % ret(rhs).count());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -416,7 +420,7 @@ namespace units {
|
|||||||
[[nodiscard]] constexpr bool operator==(const quantity<U1, Rep1>& lhs, const quantity<U2, Rep2>& rhs)
|
[[nodiscard]] constexpr bool operator==(const quantity<U1, Rep1>& lhs, const quantity<U2, Rep2>& rhs)
|
||||||
requires same_dim<typename U1::dimension, typename U2::dimension>
|
requires same_dim<typename U1::dimension, typename U2::dimension>
|
||||||
{
|
{
|
||||||
using ct = common_quantity_t<quantity<U1, Rep1>, quantity<U2, Rep2>>;
|
using ct = common_quantity<quantity<U1, Rep1>, quantity<U2, Rep2>>;
|
||||||
return ct(lhs).count() == ct(rhs).count();
|
return ct(lhs).count() == ct(rhs).count();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -431,7 +435,7 @@ namespace units {
|
|||||||
[[nodiscard]] constexpr bool operator<(const quantity<U1, Rep1>& lhs, const quantity<U2, Rep2>& rhs)
|
[[nodiscard]] constexpr bool operator<(const quantity<U1, Rep1>& lhs, const quantity<U2, Rep2>& rhs)
|
||||||
requires same_dim<typename U1::dimension, typename U2::dimension>
|
requires same_dim<typename U1::dimension, typename U2::dimension>
|
||||||
{
|
{
|
||||||
using ct = common_quantity_t<quantity<U1, Rep1>, quantity<U2, Rep2>>;
|
using ct = common_quantity<quantity<U1, Rep1>, quantity<U2, Rep2>>;
|
||||||
return ct(lhs).count() < ct(rhs).count();
|
return ct(lhs).count() < ct(rhs).count();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -72,8 +72,8 @@ namespace {
|
|||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
static_assert(std::is_same_v<dimension_sqrt_t<power_spectral_density>, amplitude_spectral_density>);
|
static_assert(std::is_same_v<dimension_sqrt<power_spectral_density>, amplitude_spectral_density>);
|
||||||
static_assert(std::is_same_v<dimension_pow_t<amplitude_spectral_density, 2>, power_spectral_density>);
|
static_assert(std::is_same_v<dimension_pow<amplitude_spectral_density, 2>, power_spectral_density>);
|
||||||
|
|
||||||
static_assert(std::is_same_v<decltype(pow<2>(quantity<volt_per_sqrt_hertz>(4))), decltype(quantity<sq_volt_per_hertz>(16))>);
|
static_assert(std::is_same_v<decltype(pow<2>(quantity<volt_per_sqrt_hertz>(4))), decltype(quantity<sq_volt_per_hertz>(16))>);
|
||||||
static_assert(std::is_same_v<decltype(sqrt(quantity<sq_volt_per_hertz>(16))), decltype(quantity<volt_per_sqrt_hertz>(4))>);
|
static_assert(std::is_same_v<decltype(sqrt(quantity<sq_volt_per_hertz>(16))), decltype(quantity<volt_per_sqrt_hertz>(4))>);
|
||||||
|
@@ -34,59 +34,65 @@ namespace {
|
|||||||
|
|
||||||
// exp_invert
|
// exp_invert
|
||||||
|
|
||||||
static_assert(std::is_same_v<exp_invert_t<exp<d0, 1>>, exp<d0, -1>>);
|
static_assert(std::is_same_v<exp_invert<exp<d0, 1>>, exp<d0, -1>>);
|
||||||
static_assert(std::is_same_v<exp_invert_t<exp<d1, -1>>, exp<d1, 1>>);
|
static_assert(std::is_same_v<exp_invert<exp<d1, -1>>, exp<d1, 1>>);
|
||||||
|
|
||||||
// extract
|
// extract
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
struct typeinfo;
|
struct typeinfo;
|
||||||
|
|
||||||
static_assert(std::is_same_v<detail::extract_t<>, dimension<>>);
|
template<typename... Ts>
|
||||||
static_assert(std::is_same_v<detail::extract_t<exp<d0, 1>>, dimension<exp<d0, 1>>>);
|
using extract = detail::extract<Ts...>::type;
|
||||||
static_assert(std::is_same_v<detail::extract_t<exp<d0, 1>, exp<d1, 2>>, dimension<exp<d0, 1>, exp<d1, 2>>>);
|
|
||||||
|
static_assert(std::is_same_v<extract<>, dimension<>>);
|
||||||
|
static_assert(std::is_same_v<extract<exp<d0, 1>>, dimension<exp<d0, 1>>>);
|
||||||
|
static_assert(std::is_same_v<extract<exp<d0, 1>, exp<d1, 2>>, dimension<exp<d0, 1>, exp<d1, 2>>>);
|
||||||
using dim0 = dimension<>;
|
using dim0 = dimension<>;
|
||||||
using dim1 = dimension<exp<d0, 1>>;
|
using dim1 = dimension<exp<d0, 1>>;
|
||||||
using dim2 = dimension<exp<d0, 1>, exp<d1, 2>>;
|
using dim2 = dimension<exp<d0, 1>, exp<d1, 2>>;
|
||||||
static_assert(std::is_same_v<detail::extract_t<exp<dim0, 2>, exp<d0, 1>>, dimension<exp<d0, 1>>>);
|
static_assert(std::is_same_v<extract<exp<dim0, 2>, exp<d0, 1>>, dimension<exp<d0, 1>>>);
|
||||||
static_assert(std::is_same_v<detail::extract_t<exp<dim1, 2>, exp<d0, 1>>, dimension<exp<d0, 2>, exp<d0, 1>>>);
|
static_assert(std::is_same_v<extract<exp<dim1, 2>, exp<d0, 1>>, dimension<exp<d0, 2>, exp<d0, 1>>>);
|
||||||
static_assert(std::is_same_v<detail::extract_t<exp<dim2, -2>, exp<d0, 1>, exp<d1, 2>>, dimension<exp<d0, -2>, exp<d1, -4>, exp<d0, 1>, exp<d1, 2>>>);
|
static_assert(std::is_same_v<extract<exp<dim2, -2>, exp<d0, 1>, exp<d1, 2>>, dimension<exp<d0, -2>, exp<d1, -4>, exp<d0, 1>, exp<d1, 2>>>);
|
||||||
|
|
||||||
// make_dimension
|
// make_dimension
|
||||||
|
|
||||||
static_assert(std::is_same_v<detail::make_dimension_t<exp<d0, 1>>, dimension<exp<d0, 1>>>);
|
template<typename... Ts>
|
||||||
static_assert(std::is_same_v<detail::make_dimension_t<exp<d0, 1>, exp<d1, 1>>, dimension<exp<d0, 1>, exp<d1, 1>>>);
|
using make_dimension = detail::make_dimension<Ts...>::type;
|
||||||
static_assert(std::is_same_v<detail::make_dimension_t<exp<d1, 1>, exp<d0, 1>>, dimension<exp<d0, 1>, exp<d1, 1>>>);
|
|
||||||
static_assert(std::is_same_v<detail::make_dimension_t<exp<d1, 1>, exp<d1, 1>>, dimension<exp<d1, 2>>>);
|
|
||||||
static_assert(std::is_same_v<detail::make_dimension_t<exp<d1, 1>, exp<d1, -1>>, dimension<>>);
|
|
||||||
static_assert(std::is_same_v<detail::make_dimension_t<exp<d1, 1>, exp<d1, 1, 2>>, dimension<exp<d1, 3, 2>>>);
|
|
||||||
static_assert(std::is_same_v<detail::make_dimension_t<exp<d1, 1, 2>, exp<d1, 1, 2>>, dimension<exp<d1, 1>>>);
|
|
||||||
static_assert(std::is_same_v<detail::make_dimension_t<exp<d1, 2>, exp<d1, 1, 2>>, dimension<exp<d1, 5, 2>>>);
|
|
||||||
|
|
||||||
static_assert(std::is_same_v<detail::make_dimension_t<exp<d0, 1>, exp<d1, 1>, exp<d0, 1>, exp<d1, 1>>, dimension<exp<d0, 2>, exp<d1, 2>>>);
|
static_assert(std::is_same_v<make_dimension<exp<d0, 1>>, dimension<exp<d0, 1>>>);
|
||||||
|
static_assert(std::is_same_v<make_dimension<exp<d0, 1>, exp<d1, 1>>, dimension<exp<d0, 1>, exp<d1, 1>>>);
|
||||||
|
static_assert(std::is_same_v<make_dimension<exp<d1, 1>, exp<d0, 1>>, dimension<exp<d0, 1>, exp<d1, 1>>>);
|
||||||
|
static_assert(std::is_same_v<make_dimension<exp<d1, 1>, exp<d1, 1>>, dimension<exp<d1, 2>>>);
|
||||||
|
static_assert(std::is_same_v<make_dimension<exp<d1, 1>, exp<d1, -1>>, dimension<>>);
|
||||||
|
static_assert(std::is_same_v<make_dimension<exp<d1, 1>, exp<d1, 1, 2>>, dimension<exp<d1, 3, 2>>>);
|
||||||
|
static_assert(std::is_same_v<make_dimension<exp<d1, 1, 2>, exp<d1, 1, 2>>, dimension<exp<d1, 1>>>);
|
||||||
|
static_assert(std::is_same_v<make_dimension<exp<d1, 2>, exp<d1, 1, 2>>, dimension<exp<d1, 5, 2>>>);
|
||||||
|
|
||||||
|
static_assert(std::is_same_v<make_dimension<exp<d0, 1>, exp<d1, 1>, exp<d0, 1>, exp<d1, 1>>, dimension<exp<d0, 2>, exp<d1, 2>>>);
|
||||||
static_assert(
|
static_assert(
|
||||||
std::is_same_v<detail::make_dimension_t<exp<d0, -1>, exp<d1, -1>, exp<d0, -1>, exp<d1, -1>>, dimension<exp<d0, -2>, exp<d1, -2>>>);
|
std::is_same_v<make_dimension<exp<d0, -1>, exp<d1, -1>, exp<d0, -1>, exp<d1, -1>>, dimension<exp<d0, -2>, exp<d1, -2>>>);
|
||||||
|
|
||||||
static_assert(std::is_same_v<detail::make_dimension_t<exp<d0, 1>, exp<d1, 1>, exp<d1, -1>>, dimension<exp<d0, 1>>>);
|
static_assert(std::is_same_v<make_dimension<exp<d0, 1>, exp<d1, 1>, exp<d1, -1>>, dimension<exp<d0, 1>>>);
|
||||||
static_assert(std::is_same_v<detail::make_dimension_t<exp<d0, 1>, exp<d0, -1>, exp<d1, 1>>, dimension<exp<d1, 1>>>);
|
static_assert(std::is_same_v<make_dimension<exp<d0, 1>, exp<d0, -1>, exp<d1, 1>>, dimension<exp<d1, 1>>>);
|
||||||
static_assert(std::is_same_v<detail::make_dimension_t<exp<d0, 1>, exp<d1, 1>, exp<d0, -1>>, dimension<exp<d1, 1>>>);
|
static_assert(std::is_same_v<make_dimension<exp<d0, 1>, exp<d1, 1>, exp<d0, -1>>, dimension<exp<d1, 1>>>);
|
||||||
static_assert(std::is_same_v<detail::make_dimension_t<exp<d0, 1>, exp<d1, 1>, exp<d0, -1>, exp<d1, -1>>, dimension<>>);
|
static_assert(std::is_same_v<make_dimension<exp<d0, 1>, exp<d1, 1>, exp<d0, -1>, exp<d1, -1>>, dimension<>>);
|
||||||
|
|
||||||
// dimension_multiply
|
// dimension_multiply
|
||||||
|
|
||||||
static_assert(
|
static_assert(
|
||||||
std::is_same_v<dimension_multiply_t<dimension<exp<d0, 1>>, dimension<exp<d1, 1>>>, dimension<exp<d0, 1>, exp<d1, 1>>>);
|
std::is_same_v<dimension_multiply<dimension<exp<d0, 1>>, dimension<exp<d1, 1>>>, dimension<exp<d0, 1>, exp<d1, 1>>>);
|
||||||
static_assert(std::is_same_v<dimension_multiply_t<dimension<exp<d0, 1>, exp<d1, 1>, exp<d2, 1>>, dimension<exp<d3, 1>>>,
|
static_assert(std::is_same_v<dimension_multiply<dimension<exp<d0, 1>, exp<d1, 1>, exp<d2, 1>>, dimension<exp<d3, 1>>>,
|
||||||
dimension<exp<d0, 1>, exp<d1, 1>, exp<d2, 1>, exp<d3, 1>>>);
|
dimension<exp<d0, 1>, exp<d1, 1>, exp<d2, 1>, exp<d3, 1>>>);
|
||||||
static_assert(std::is_same_v<dimension_multiply_t<dimension<exp<d0, 1>, exp<d1, 1>, exp<d2, 1>>, dimension<exp<d1, 1>>>,
|
static_assert(std::is_same_v<dimension_multiply<dimension<exp<d0, 1>, exp<d1, 1>, exp<d2, 1>>, dimension<exp<d1, 1>>>,
|
||||||
dimension<exp<d0, 1>, exp<d1, 2>, exp<d2, 1>>>);
|
dimension<exp<d0, 1>, exp<d1, 2>, exp<d2, 1>>>);
|
||||||
static_assert(std::is_same_v<dimension_multiply_t<dimension<exp<d0, 1>, exp<d1, 1>, exp<d2, 1>>, dimension<exp<d1, -1>>>,
|
static_assert(std::is_same_v<dimension_multiply<dimension<exp<d0, 1>, exp<d1, 1>, exp<d2, 1>>, dimension<exp<d1, -1>>>,
|
||||||
dimension<exp<d0, 1>, exp<d2, 1>>>);
|
dimension<exp<d0, 1>, exp<d2, 1>>>);
|
||||||
|
|
||||||
// dimension_divide
|
// dimension_divide
|
||||||
|
|
||||||
static_assert(
|
static_assert(
|
||||||
std::is_same_v<dimension_divide_t<dimension<exp<d0, 1>>, dimension<exp<d1, 1>>>, dimension<exp<d0, 1>, exp<d1, -1>>>);
|
std::is_same_v<dimension_divide<dimension<exp<d0, 1>>, dimension<exp<d1, 1>>>, dimension<exp<d0, 1>, exp<d1, -1>>>);
|
||||||
static_assert(std::is_same_v<dimension_divide_t<dimension<exp<d0, 1>>, dimension<exp<d0, 1>>>, dimension<>>);
|
static_assert(std::is_same_v<dimension_divide<dimension<exp<d0, 1>>, dimension<exp<d0, 1>>>, dimension<>>);
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
@@ -263,9 +263,9 @@ namespace {
|
|||||||
|
|
||||||
// common_quantity
|
// common_quantity
|
||||||
|
|
||||||
static_assert(std::is_same_v<common_quantity_t<quantity<metre, int>, quantity<kilometre, int>>, quantity<metre, int>>);
|
static_assert(std::is_same_v<common_quantity<quantity<metre, int>, quantity<kilometre, int>>, quantity<metre, int>>);
|
||||||
static_assert(std::is_same_v<common_quantity_t<quantity<kilometre, long long>, quantity<metre, int>>, quantity<metre, long long>>);
|
static_assert(std::is_same_v<common_quantity<quantity<kilometre, long long>, quantity<metre, int>>, quantity<metre, long long>>);
|
||||||
static_assert(std::is_same_v<common_quantity_t<quantity<kilometre, long long>, quantity<millimetre, double>>, quantity<millimetre, double>>);
|
static_assert(std::is_same_v<common_quantity<quantity<kilometre, long long>, quantity<millimetre, double>>, quantity<millimetre, double>>);
|
||||||
|
|
||||||
// quantity_cast
|
// quantity_cast
|
||||||
|
|
||||||
|
@@ -93,10 +93,10 @@ namespace {
|
|||||||
// type_list_sort
|
// type_list_sort
|
||||||
|
|
||||||
template<TypeList List>
|
template<TypeList List>
|
||||||
using exp_sort_t = type_list_sort<List, exp_less>;
|
using exp_sort = type_list_sort<List, exp_less>;
|
||||||
|
|
||||||
static_assert(std::is_same_v<exp_sort_t<dimension<exp<d0, 1>>>, dimension<exp<d0, 1>>>);
|
static_assert(std::is_same_v<exp_sort<dimension<exp<d0, 1>>>, dimension<exp<d0, 1>>>);
|
||||||
static_assert(std::is_same_v<exp_sort_t<dimension<exp<d0, 1>, exp<d1, -1>>>, dimension<exp<d0, 1>, exp<d1, -1>>>);
|
static_assert(std::is_same_v<exp_sort<dimension<exp<d0, 1>, exp<d1, -1>>>, dimension<exp<d0, 1>, exp<d1, -1>>>);
|
||||||
static_assert(std::is_same_v<exp_sort_t<dimension<exp<d1, 1>, exp<d0, -1>>>, dimension<exp<d0, -1>, exp<d1, 1>>>);
|
static_assert(std::is_same_v<exp_sort<dimension<exp<d1, 1>, exp<d0, -1>>>, dimension<exp<d0, -1>, exp<d1, 1>>>);
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
Reference in New Issue
Block a user