mirror of
https://github.com/mpusz/mp-units.git
synced 2025-08-05 21:24:27 +02:00
refactor: quantity
op+()
and op-()
reimplemented in terms of reference
rather then quantity
types
`common_quantity`, `common_quantity_for`, `common_quantity_point`, `common_quantity_kind`, and `common_quantity_point_kind` removed Resolves #290
This commit is contained in:
@@ -1,6 +1,8 @@
|
||||
# Release notes
|
||||
|
||||
- **0.8.0 WIP**
|
||||
- (!) refactor: `common_quantity`, `common_quantity_for`, `common_quantity_point`, `common_quantity_kind`, and `common_quantity_point_kind` removed
|
||||
- refactor: `quantity` `op+()` and `op-()` reimplemented in terms of `reference` rather then `quantity` types
|
||||
- (!) fix: add `quantity_point::origin`, like `std::chrono::time_point::clock`
|
||||
- fix: account for different dimensions in `quantity_point_cast`'s constraint
|
||||
- build: doxygen updated to 1.9.1
|
||||
|
@@ -28,6 +28,9 @@
|
||||
|
||||
namespace units {
|
||||
|
||||
template<Dimension D, UnitOf<D> U>
|
||||
struct reference;
|
||||
|
||||
template<Dimension D, UnitOf<D> U, Representation Rep>
|
||||
class quantity;
|
||||
|
||||
@@ -42,49 +45,42 @@ class quantity_point_kind;
|
||||
|
||||
namespace detail {
|
||||
|
||||
template<typename Q1, typename Q2, typename Rep>
|
||||
struct common_quantity_impl;
|
||||
template<typename R1, typename R2>
|
||||
struct common_quantity_reference_impl;
|
||||
|
||||
template<typename D, typename U, typename Rep1, typename Rep2, typename Rep>
|
||||
struct common_quantity_impl<quantity<D, U, Rep1>, quantity<D, U, Rep2>, Rep> {
|
||||
using type = quantity<D, U, Rep>;
|
||||
template<typename D, typename U>
|
||||
struct common_quantity_reference_impl<reference<D, U>, reference<D, U>> {
|
||||
using type = reference<D, U>;
|
||||
};
|
||||
|
||||
template<typename D, typename U1, typename Rep1, typename U2, typename Rep2, typename Rep>
|
||||
struct common_quantity_impl<quantity<D, U1, Rep1>, quantity<D, U2, Rep2>, Rep> {
|
||||
using type = quantity<D, downcast_unit<D, common_ratio(U1::ratio, U2::ratio)>, Rep>;
|
||||
template<typename D, typename U1, typename U2>
|
||||
struct common_quantity_reference_impl<reference<D, U1>, reference<D, U2>> {
|
||||
using type = reference<D, downcast_unit<D, common_ratio(U1::ratio, U2::ratio)>>;
|
||||
};
|
||||
|
||||
template<typename D1, typename U1, typename Rep1, typename D2, typename U2, typename Rep2, typename Rep>
|
||||
template<typename D1, typename U1, typename D2, typename U2>
|
||||
requires same_unit_reference<dimension_unit<D1>, dimension_unit<D2>>::value
|
||||
struct common_quantity_impl<quantity<D1, U1, Rep1>, quantity<D2, U2, Rep2>, Rep> {
|
||||
using type = quantity<D1, downcast_unit<D1, common_ratio(U1::ratio, U2::ratio)>, Rep>;
|
||||
struct common_quantity_reference_impl<reference<D1, U1>, reference<D2, U2>> {
|
||||
using type = reference<D1, downcast_unit<D1, common_ratio(U1::ratio, U2::ratio)>>;
|
||||
};
|
||||
|
||||
template<typename D1, typename U1, typename Rep1, typename D2, typename U2, typename Rep2, typename Rep>
|
||||
struct common_quantity_impl<quantity<D1, U1, Rep1>, quantity<D2, U2, Rep2>, Rep> {
|
||||
template<typename D1, typename U1, typename D2, typename U2>
|
||||
struct common_quantity_reference_impl<reference<D1, U1>, reference<D2, U2>> {
|
||||
using dimension = conditional<is_specialization_of<D1, unknown_dimension>, D2, D1>;
|
||||
static constexpr ratio r1 = D1::base_units_ratio * U1::ratio;
|
||||
static constexpr ratio r2 = D2::base_units_ratio * U2::ratio;
|
||||
static constexpr ratio cr = common_ratio(r1, r2);
|
||||
using unit = downcast_unit<dimension, cr / dimension::base_units_ratio>;
|
||||
using type = quantity<dimension, unit, Rep>;
|
||||
using type = reference<dimension, unit>;
|
||||
};
|
||||
|
||||
|
||||
template<Quantity Q1, QuantityEquivalentTo<Q1> Q2>
|
||||
using common_quantity_reference =
|
||||
TYPENAME detail::common_quantity_reference_impl <
|
||||
std::remove_const_t<decltype(Q1::reference)>, std::remove_const_t<decltype(Q2::reference)>>::type;
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template<Quantity Q1, QuantityEquivalentTo<Q1> Q2, Representation Rep = std::common_type_t<typename Q1::rep, typename Q2::rep>>
|
||||
using common_quantity = TYPENAME detail::common_quantity_impl<Q1, Q2, Rep>::type;
|
||||
|
||||
template<QuantityPoint QP1, QuantityPointEquivalentTo<QP1> QP2>
|
||||
using common_quantity_point = std::common_type_t<QP1, QP2>;
|
||||
|
||||
template<QuantityKind QK1, QuantityKindEquivalentTo<QK1> QK2>
|
||||
using common_quantity_kind = std::common_type_t<QK1, QK2>;
|
||||
|
||||
template<QuantityPointKind QPK1, QuantityPointKindEquivalentTo<QPK1> QPK2>
|
||||
using common_quantity_point_kind = std::common_type_t<QPK1, QPK2>;
|
||||
|
||||
} // namespace units
|
||||
|
||||
namespace std {
|
||||
@@ -92,7 +88,10 @@ namespace std {
|
||||
template<units::Quantity Q1, units::QuantityEquivalentTo<Q1> Q2>
|
||||
requires requires { typename common_type_t<typename Q1::rep, typename Q2::rep>; }
|
||||
struct common_type<Q1, Q2> {
|
||||
using type = units::common_quantity<Q1, Q2>;
|
||||
private:
|
||||
using ref = units::detail::common_quantity_reference<Q1, Q2>;
|
||||
public:
|
||||
using type = units::quantity<typename ref::dimension, typename ref::unit, common_type_t<typename Q1::rep, typename Q2::rep>>;
|
||||
};
|
||||
|
||||
template<units::QuantityPoint QP1, units::QuantityPointEquivalentTo<QP1> QP2>
|
@@ -23,7 +23,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <units/bits/common_quantity.h>
|
||||
#include <units/bits/common_type.h>
|
||||
#include <units/generic/dimensionless.h>
|
||||
|
||||
// IWYU pragma: begin_exports
|
||||
@@ -90,10 +90,6 @@ concept have_quantity_for_ =
|
||||
(!Quantity<V>) &&
|
||||
quantity_value_for_<Func, typename Q::rep, V>;
|
||||
|
||||
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>;
|
||||
|
||||
@@ -400,7 +396,8 @@ 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)
|
||||
{
|
||||
using ret = common_quantity_for<std::plus<>, Q1, Q2>;
|
||||
using ref = detail::common_quantity_reference<Q1, Q2>;
|
||||
using ret = quantity<typename ref::dimension, typename ref::unit, decltype(lhs.number() + rhs.number())>;
|
||||
return ret(ret(lhs).number() + ret(rhs).number());
|
||||
}
|
||||
|
||||
@@ -408,7 +405,8 @@ template<Quantity Q1, QuantityEquivalentTo<Q1> Q2>
|
||||
requires quantity_value_for_<std::minus<>, typename Q1::rep, typename Q2::rep>
|
||||
[[nodiscard]] constexpr Quantity auto operator-(const Q1& lhs, const Q2& rhs)
|
||||
{
|
||||
using ret = common_quantity_for<std::minus<>, Q1, Q2>;
|
||||
using ref = detail::common_quantity_reference<Q1, Q2>;
|
||||
using ret = quantity<typename ref::dimension, typename ref::unit, decltype(lhs.number() - rhs.number())>;
|
||||
return ret(ret(lhs).number() - ret(rhs).number());
|
||||
}
|
||||
|
||||
@@ -442,7 +440,7 @@ template<Quantity Q1, QuantityEquivalentTo<Q1> Q2>
|
||||
requires std::three_way_comparable_with<typename Q1::rep, typename Q2::rep>
|
||||
[[nodiscard]] constexpr auto operator<=>(const Q1& lhs, const Q2& rhs)
|
||||
{
|
||||
using cq = common_quantity<Q1, Q2>;
|
||||
using cq = std::common_type_t<Q1, Q2>;
|
||||
return cq(lhs).number() <=> cq(rhs).number();
|
||||
}
|
||||
|
||||
@@ -450,7 +448,7 @@ template<Quantity Q1, QuantityEquivalentTo<Q1> Q2>
|
||||
requires std::equality_comparable_with<typename Q1::rep, typename Q2::rep>
|
||||
[[nodiscard]] constexpr bool operator==(const Q1& lhs, const Q2& rhs)
|
||||
{
|
||||
using cq = common_quantity<Q1, Q2>;
|
||||
using cq = std::common_type_t<Q1, Q2>;
|
||||
return cq(lhs).number() == cq(rhs).number();
|
||||
}
|
||||
|
||||
|
@@ -22,7 +22,7 @@
|
||||
|
||||
#include <units/quantity_point.h>
|
||||
#include "test_tools.h"
|
||||
#include <units/bits/common_quantity.h>
|
||||
#include <units/bits/common_type.h>
|
||||
#include <units/bits/external/type_traits.h>
|
||||
#include <units/chrono.h>
|
||||
#include <units/isq/si/length.h>
|
||||
@@ -233,17 +233,17 @@ static_assert(2_q_dm3 + quantity_point(2_q_cm3) == quantity_point(2002_q_ml));
|
||||
|
||||
static_assert(QuantityPoint<quantity_point<dynamic_origin<dim_length>, millimetre, int>>);
|
||||
|
||||
// common_quantity_point
|
||||
// common_type
|
||||
|
||||
static_assert(compare<
|
||||
common_quantity_point<quantity_point<dynamic_origin<dim_length>, metre, int>, quantity_point<dynamic_origin<dim_length>, kilometre, int>>,
|
||||
quantity_point<dynamic_origin<dim_length>, metre, int>>);
|
||||
static_assert(compare<common_quantity_point<quantity_point<dynamic_origin<dim_length>, kilometre, long long>,
|
||||
quantity_point<dynamic_origin<dim_length>, metre, int>>,
|
||||
quantity_point<dynamic_origin<dim_length>, metre, long long>>);
|
||||
static_assert(compare<common_quantity_point<quantity_point<dynamic_origin<dim_length>, kilometre, long long>,
|
||||
quantity_point<dynamic_origin<dim_length>, millimetre, double>>,
|
||||
quantity_point<dynamic_origin<dim_length>, millimetre, double>>);
|
||||
static_assert(compare<std::common_type_t<quantity_point<dynamic_origin<dim_length>, metre, int>,
|
||||
quantity_point<dynamic_origin<dim_length>, kilometre, int>>,
|
||||
quantity_point<dynamic_origin<dim_length>, metre, int>>);
|
||||
static_assert(compare<std::common_type_t<quantity_point<dynamic_origin<dim_length>, kilometre, long long>,
|
||||
quantity_point<dynamic_origin<dim_length>, metre, int>>,
|
||||
quantity_point<dynamic_origin<dim_length>, metre, long long>>);
|
||||
static_assert(compare<std::common_type_t<quantity_point<dynamic_origin<dim_length>, kilometre, long long>,
|
||||
quantity_point<dynamic_origin<dim_length>, millimetre, double>>,
|
||||
quantity_point<dynamic_origin<dim_length>, millimetre, double>>);
|
||||
|
||||
// common_type
|
||||
|
||||
|
Reference in New Issue
Block a user