forked from mpusz/mp-units
fix: add quantity_point::origin, like std::chrono::time_point::clock
This commit is contained in:
committed by
Mateusz Pusz
parent
7ed29807a6
commit
80eefec97c
@@ -24,6 +24,7 @@
|
||||
#pragma once
|
||||
|
||||
// IWYU pragma: begin_exports
|
||||
#include <units/point_origin.h>
|
||||
#include <units/quantity.h>
|
||||
#include <compare>
|
||||
// IWYU pragma: end_exports
|
||||
@@ -34,18 +35,32 @@
|
||||
namespace units {
|
||||
|
||||
/**
|
||||
* @brief A quantity point
|
||||
* @brief A statically unspecified quantity point origin
|
||||
*
|
||||
* An absolute quantity with respect to zero (which represents some origin).
|
||||
* An origin, unspecified in the type system, from which an absolute quantity is measured from.
|
||||
*
|
||||
* @tparam D a dimension of the quantity point (can be either a BaseDimension or a DerivedDimension)
|
||||
*/
|
||||
template<Dimension D>
|
||||
struct dynamic_origin : point_origin<D> {
|
||||
template<Dimension D2>
|
||||
using rebind = dynamic_origin<D2>;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief A quantity point
|
||||
*
|
||||
* An absolute quantity measured from an origin.
|
||||
*
|
||||
* @tparam O a type that represents the origin from which the quantity point is measured from
|
||||
* @tparam U a measurement unit of the quantity point
|
||||
* @tparam Rep a type to be used to represent values of a quantity point
|
||||
*/
|
||||
template<Dimension D, UnitOf<D> U, Representation Rep = double>
|
||||
template<PointOrigin O, UnitOf<typename O::dimension> U, Representation Rep = double>
|
||||
class quantity_point {
|
||||
public:
|
||||
using quantity_type = quantity<D, U, Rep>;
|
||||
using origin = O;
|
||||
using quantity_type = quantity<typename origin::dimension, U, Rep>;
|
||||
using dimension = typename quantity_type::dimension;
|
||||
using unit = typename quantity_type::unit;
|
||||
using rep = typename quantity_type::rep;
|
||||
@@ -63,13 +78,14 @@ public:
|
||||
requires std::constructible_from<quantity_type, T>
|
||||
constexpr explicit quantity_point(T&& t) : q_(std::forward<T>(t)) {}
|
||||
|
||||
template<QuantityPoint QP2>
|
||||
template<QuantityPointOf<origin> QP2>
|
||||
requires std::convertible_to<typename QP2::quantity_type, quantity_type>
|
||||
constexpr explicit(false) quantity_point(const QP2& qp) : q_(qp.relative()) {}
|
||||
|
||||
template<QuantityPointLike QP>
|
||||
constexpr explicit quantity_point(const QP& qp)
|
||||
requires std::is_constructible_v<quantity_type, decltype(quantity_point_like_traits<QP>::relative(qp))>
|
||||
requires std::is_constructible_v<quantity_type, decltype(quantity_point_like_traits<QP>::relative(qp))> &&
|
||||
equivalent<origin, typename quantity_point_like_traits<QP>::origin>
|
||||
: q_(quantity_point_like_traits<QP>::relative(qp)) {}
|
||||
|
||||
quantity_point& operator=(const quantity_point&) = default;
|
||||
@@ -141,7 +157,8 @@ public:
|
||||
{
|
||||
const auto q = lhs.relative() + rhs;
|
||||
using q_type = decltype(q);
|
||||
return quantity_point<typename q_type::dimension, typename q_type::unit, typename q_type::rep>(q);
|
||||
return quantity_point<rebind_point_origin_dimension<origin, typename q_type::dimension>, typename q_type::unit,
|
||||
typename q_type::rep>(q);
|
||||
}
|
||||
|
||||
template<Quantity Q>
|
||||
@@ -157,24 +174,25 @@ public:
|
||||
{
|
||||
const auto q = lhs.relative() - rhs;
|
||||
using q_type = decltype(q);
|
||||
return quantity_point<typename q_type::dimension, typename q_type::unit, typename q_type::rep>(q);
|
||||
return quantity_point<rebind_point_origin_dimension<origin, typename q_type::dimension>, typename q_type::unit,
|
||||
typename q_type::rep>(q);
|
||||
}
|
||||
|
||||
template<QuantityPoint QP>
|
||||
template<QuantityPointOf<origin> QP>
|
||||
[[nodiscard]] friend constexpr Quantity auto operator-(const quantity_point& lhs, const QP& rhs)
|
||||
requires requires(quantity_type q) { q - rhs.relative(); }
|
||||
{
|
||||
return lhs.relative() - rhs.relative();
|
||||
}
|
||||
|
||||
template<QuantityPoint QP>
|
||||
template<QuantityPointOf<origin> QP>
|
||||
requires std::three_way_comparable_with<quantity_type, typename QP::quantity_type>
|
||||
[[nodiscard]] friend constexpr auto operator<=>(const quantity_point& lhs, const QP& rhs)
|
||||
{
|
||||
return lhs.relative() <=> rhs.relative();
|
||||
}
|
||||
|
||||
template<QuantityPoint QP>
|
||||
template<QuantityPointOf<origin> QP>
|
||||
requires std::equality_comparable_with<quantity_type, typename QP::quantity_type>
|
||||
[[nodiscard]] friend constexpr bool operator==(const quantity_point& lhs, const QP& rhs)
|
||||
{
|
||||
@@ -183,24 +201,24 @@ public:
|
||||
};
|
||||
|
||||
template<Representation Rep>
|
||||
explicit quantity_point(Rep) -> quantity_point<dim_one, one, Rep>;
|
||||
explicit quantity_point(Rep) -> quantity_point<dynamic_origin<dim_one>, one, Rep>;
|
||||
|
||||
template<Quantity Q>
|
||||
explicit quantity_point(Q) -> quantity_point<typename Q::dimension, typename Q::unit, typename Q::rep>;
|
||||
explicit quantity_point(Q) -> quantity_point<dynamic_origin<typename Q::dimension>, typename Q::unit, typename Q::rep>;
|
||||
|
||||
template<QuantityLike Q>
|
||||
explicit quantity_point(Q) -> quantity_point<typename quantity_like_traits<Q>::dimension,
|
||||
explicit quantity_point(Q) -> quantity_point<dynamic_origin<typename quantity_like_traits<Q>::dimension>,
|
||||
typename quantity_like_traits<Q>::unit, typename quantity_like_traits<Q>::rep>;
|
||||
|
||||
template<QuantityPointLike QP>
|
||||
explicit quantity_point(QP) -> quantity_point<typename quantity_point_like_traits<QP>::dimension,
|
||||
explicit quantity_point(QP) -> quantity_point<typename quantity_point_like_traits<QP>::origin,
|
||||
typename quantity_point_like_traits<QP>::unit,
|
||||
typename quantity_point_like_traits<QP>::rep>;
|
||||
|
||||
namespace detail {
|
||||
|
||||
template<typename D, typename U, typename Rep>
|
||||
inline constexpr bool is_quantity_point<quantity_point<D, U, Rep>> = true;
|
||||
template<typename O, typename U, typename Rep>
|
||||
inline constexpr bool is_quantity_point<quantity_point<O, U, Rep>> = true;
|
||||
|
||||
} // namespace detail
|
||||
|
||||
|
||||
Reference in New Issue
Block a user