refactor: interoperability with quantity-like types simplified
Type trait specialization for each `quantity` type is not needed anymore. Relates to #33.
This commit is contained in:
1 parent
2dd8c90250
commit
d64d26a4c4
9 files changed
+66
-78
No files matched your search
@@ -36,8 +36,8 @@ namespace units {
|
||||
|
||||
template<typename T>
|
||||
concept floating_point_ = // exposition only
|
||||
(QuantityLike<T> && treat_as_floating_point<typename quantity_traits<T>::rep>) ||
|
||||
(!QuantityLike<T> && treat_as_floating_point<T>);
|
||||
(Quantity<T> && treat_as_floating_point<typename T::rep>) ||
|
||||
(!Quantity<T> && treat_as_floating_point<T>);
|
||||
|
||||
template<typename From, typename To>
|
||||
concept safe_convertible_to_ = // exposition only
|
||||
@@ -49,15 +49,15 @@ concept safe_convertible_to_ = // exposition only
|
||||
// QFrom ratio is an exact multiple of QTo
|
||||
template<typename QFrom, typename QTo>
|
||||
concept harmonic_ = // exposition only
|
||||
QuantityLike<QFrom> &&
|
||||
Quantity<QFrom> &&
|
||||
Quantity<QTo> &&
|
||||
requires(QFrom from, QTo to) { requires is_integral(detail::quantity_ratio(from) / detail::quantity_ratio(to)); };
|
||||
|
||||
template<typename QFrom, typename QTo>
|
||||
concept safe_castable_to_ = // exposition only
|
||||
QuantityLike<QFrom> &&
|
||||
QuantityOf<QTo, typename quantity_traits<QFrom>::dimension> &&
|
||||
scalable_with_<typename quantity_traits<QFrom>::rep, typename QTo::rep> &&
|
||||
Quantity<QFrom> &&
|
||||
QuantityOf<QTo, typename QFrom::dimension> &&
|
||||
scalable_with_<typename QFrom::rep, typename QTo::rep> &&
|
||||
(floating_point_<QTo> || (!floating_point_<QFrom> && harmonic_<QFrom, QTo>));
|
||||
|
||||
template<typename Func, typename T, typename U>
|
||||
@@ -81,6 +81,9 @@ template<typename Func, Quantity Q1, QuantityEquivalentTo<Q1> Q2>
|
||||
requires quantity_value_for_<Func, typename Q1::rep, typename Q2::rep>
|
||||
using common_quantity_for = common_quantity<Q1, Q2, std::invoke_result_t<Func, typename Q1::rep, typename Q2::rep>>;
|
||||
|
||||
template<QuantityLike Q>
|
||||
using quantity_like_type = quantity<typename quantity_like_traits<Q>::dimension, typename quantity_like_traits<Q>::unit, typename quantity_like_traits<Q>::rep>;
|
||||
|
||||
/**
|
||||
* @brief A quantity
|
||||
*
|
||||
@@ -133,8 +136,12 @@ public:
|
||||
template<safe_convertible_to_<rep> Value>
|
||||
explicit(!(equivalent<quantity, dimensionless<::units::one, rep>>)) constexpr quantity(const Value& v) : value_(static_cast<rep>(v)) {}
|
||||
|
||||
template<QuantityLike Q>
|
||||
requires std::same_as<quantity, quantity_like_type<Q>>
|
||||
explicit constexpr quantity(const Q& q) : value_(q.count()) {}
|
||||
|
||||
template<safe_castable_to_<quantity> Q>
|
||||
explicit(!Quantity<Q>) constexpr quantity(const Q& q) : value_(quantity_cast<quantity>(q).count()) {}
|
||||
constexpr quantity(const Q& q) : value_(quantity_cast<quantity>(q).count()) {}
|
||||
|
||||
quantity& operator=(const quantity&) = default;
|
||||
quantity& operator=(quantity&&) = default;
|
||||
@@ -328,10 +335,10 @@ template<QuantityValue V>
|
||||
explicit(false) quantity(V) -> quantity<dim_one, one, V>;
|
||||
|
||||
template<QuantityLike Q>
|
||||
explicit(!Quantity<Q>) quantity(Q) -> quantity<typename quantity_traits<Q>::dimension, typename quantity_traits<Q>::unit, typename quantity_traits<Q>::rep>;
|
||||
explicit quantity(Q) -> quantity_like_type<Q>;
|
||||
|
||||
// non-member binary operators
|
||||
template<QuantityLike Q1, QuantityEquivalentTo<Q1> Q2>
|
||||
template<Quantity Q1, QuantityEquivalentTo<Q1> Q2>
|
||||
requires quantity_value_for_<std::plus<>, typename Q1::rep, typename Q2::rep>
|
||||
[[nodiscard]] constexpr Quantity auto operator+(const Q1& lhs, const Q2& rhs)
|
||||
{
|
||||
@@ -404,14 +411,6 @@ template<Quantity Q1, QuantityEquivalentTo<Q1> Q2>
|
||||
}
|
||||
|
||||
// type traits
|
||||
template<typename D, typename U, typename Rep>
|
||||
struct quantity_traits<quantity<D, U, Rep>> {
|
||||
using dimension = D;
|
||||
using unit = U;
|
||||
using rep = Rep;
|
||||
static constexpr rep count(const quantity<D, U, Rep>& q) { return q.count(); }
|
||||
};
|
||||
|
||||
namespace detail {
|
||||
|
||||
template<typename D, typename U, typename Rep>
|
||||
|
||||
Reference in new issue
Block a user