_t postfix removed from the interface (resolves #9)

This commit is contained in:
Mateusz Pusz
2019-10-04 16:22:49 +02:00
parent 9c436812f5
commit 2fddb494d3
8 changed files with 167 additions and 148 deletions

View File

@@ -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>;
``` ```

View File

@@ -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

View File

@@ -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())));
} }

View File

@@ -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();
} }

View File

@@ -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))>);

View File

@@ -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

View File

@@ -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

View File

@@ -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